mirror of
https://github.com/serai-dex/serai.git
synced 2025-01-03 17:40:34 +00:00
add new address functions & comments
This commit is contained in:
parent
461504ccbf
commit
5123c7f121
2 changed files with 79 additions and 19 deletions
|
@ -182,6 +182,14 @@ impl<B: AddressBytes> ToString for Address<B> {
|
|||
}
|
||||
|
||||
impl<B: AddressBytes> Address<B> {
|
||||
/// Generates an Address type according to the specification provided in the meta.
|
||||
///
|
||||
/// WARNING: Specification on the meta are not "commands" and are
|
||||
/// just "specifications" for the address. This function relies on the
|
||||
/// caller to make sure all the passed parameters makes sense and assumes
|
||||
/// specifications provided in the meta are correct and applicable for the passed in keys.
|
||||
/// For example, passing `AddressType::Subaddress` type in the meta wont generate
|
||||
/// a correct subaddress if the keys aren't already for a valid subaddress.
|
||||
pub fn new(meta: AddressMeta<B>, spend: EdwardsPoint, view: EdwardsPoint) -> Self {
|
||||
Address { meta, spend, view }
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ pub use send::{Fee, TransactionError, SignableTransaction, SignableTransactionBu
|
|||
#[cfg(feature = "multisig")]
|
||||
pub use send::TransactionMachine;
|
||||
|
||||
use self::address::MoneroAddressBytes;
|
||||
|
||||
fn key_image_sort(x: &EdwardsPoint, y: &EdwardsPoint) -> std::cmp::Ordering {
|
||||
x.compress().to_bytes().cmp(&y.compress().to_bytes()).reverse()
|
||||
}
|
||||
|
@ -121,12 +123,19 @@ impl ViewPair {
|
|||
.concat(),
|
||||
))
|
||||
}
|
||||
|
||||
/// returns the MoneroAddress type according to specifications in the meta
|
||||
pub fn address(&self, meta: AddressMeta<MoneroAddressBytes>) -> MoneroAddress {
|
||||
MoneroAddress::new(meta, self.spend, self.view.deref() * &ED25519_BASEPOINT_TABLE)
|
||||
}
|
||||
}
|
||||
|
||||
/// Transaction scanner.
|
||||
/// This scanner is capable of generating subaddresses, additionally scanning for them once they've
|
||||
/// been explicitly generated. If the burning bug is attempted, any secondary outputs will be
|
||||
/// ignored.
|
||||
/// - This scanner is capable of generating subaddresses, additionally scanning for
|
||||
/// them once they've been explicitly generated by using `subaddress()` member function.
|
||||
/// It wont be able to track the outputs for subaddresses that aren't generated this way.
|
||||
/// - If the burning bug is attempted, any secondary outputs will be ignored.
|
||||
/// or standard address type if none passed.
|
||||
#[derive(Clone)]
|
||||
pub struct Scanner {
|
||||
pair: ViewPair,
|
||||
|
@ -167,8 +176,13 @@ impl Scanner {
|
|||
/// burning_bug is a HashSet of used keys, intended to prevent key reuse which would burn funds.
|
||||
/// When an output is successfully scanned, the output key MUST be saved to disk.
|
||||
/// When a new scanner is created, ALL saved output keys must be passed in to be secure.
|
||||
/// If None is passed, a modified shared key derivation is used which is immune to the burning
|
||||
/// bug (specifically the Guaranteed feature from Featured Addresses).
|
||||
/// If None is passed, a modified shared key derivation is used to generate new addresses
|
||||
/// through this scanner which is immune to the burning bug (specifically
|
||||
/// the Guaranteed feature from Featured Addresses).
|
||||
///
|
||||
/// If you want to use guaranteed feature for both generating addresses and
|
||||
/// decoding outputs with such addresses pass `None` to the `burning_bug`. if you
|
||||
/// just wanna support standard monero addresses then pass `Some`.
|
||||
// TODO: Should this take in a DB access handle to ensure output keys are saved?
|
||||
pub fn from_view(
|
||||
pair: ViewPair,
|
||||
|
@ -180,23 +194,33 @@ impl Scanner {
|
|||
Scanner { pair, network, subaddresses, burning_bug }
|
||||
}
|
||||
|
||||
/// Return the main address for this view pair.
|
||||
/// Returns the main address for this view pair.
|
||||
pub fn address(&self) -> MoneroAddress {
|
||||
MoneroAddress::new(
|
||||
AddressMeta::new(
|
||||
self.network,
|
||||
if self.burning_bug.is_none() {
|
||||
AddressType::Featured(false, None, true)
|
||||
} else {
|
||||
AddressType::Standard
|
||||
},
|
||||
),
|
||||
self.pair.spend,
|
||||
self.pair.view.deref() * &ED25519_BASEPOINT_TABLE,
|
||||
)
|
||||
let meta = AddressMeta::new(
|
||||
self.network,
|
||||
if self.burning_bug.is_none() {
|
||||
AddressType::Featured(false, None, true)
|
||||
} else {
|
||||
AddressType::Standard
|
||||
},
|
||||
);
|
||||
self.pair.address(meta)
|
||||
}
|
||||
|
||||
/// Return the specified subaddress for this view pair.
|
||||
/// Returns the integrated address for a given payment id.
|
||||
pub fn integrated_address(&self, payment_id: [u8; 8]) -> MoneroAddress {
|
||||
let meta = AddressMeta::new(
|
||||
self.network,
|
||||
if self.burning_bug.is_none() {
|
||||
AddressType::Featured(false, Some(payment_id), true)
|
||||
} else {
|
||||
AddressType::Integrated(payment_id)
|
||||
},
|
||||
);
|
||||
self.pair.address(meta)
|
||||
}
|
||||
|
||||
/// Returns the specified subaddress for this view pair.
|
||||
pub fn subaddress(&mut self, index: (u32, u32)) -> MoneroAddress {
|
||||
if index == (0, 0) {
|
||||
return self.address();
|
||||
|
@ -218,4 +242,32 @@ impl Scanner {
|
|||
self.pair.view.deref() * spend,
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns a featured address.
|
||||
///
|
||||
/// if you created the scanner with `Some` value for `burning_bug` be aware that
|
||||
/// even though you can pass `true` for the `guaranteed` parameter and generate
|
||||
/// a guaranteed address, scanner wont be able decode incoming outputs for this address.
|
||||
/// If you want to support guaranteed addresses please create a scanner with `None` value to
|
||||
/// `burning_bug`. Reverse of the case also holds.
|
||||
pub fn featured_address(
|
||||
&mut self,
|
||||
index: Option<(u32, u32)>,
|
||||
payment_id: Option<[u8; 8]>,
|
||||
guaranteed: bool,
|
||||
) -> MoneroAddress {
|
||||
let subaddress = index.is_some() && (index.unwrap() != (0, 0));
|
||||
|
||||
let mut spend = self.pair.spend;
|
||||
let mut view: EdwardsPoint = self.pair.view.deref() * &ED25519_BASEPOINT_TABLE;
|
||||
if subaddress {
|
||||
spend = self.pair.spend + (&self.pair.subaddress(index.unwrap()) * &ED25519_BASEPOINT_TABLE);
|
||||
self.subaddresses.insert(spend.compress(), index.unwrap());
|
||||
view = self.pair.view.deref() * spend;
|
||||
}
|
||||
|
||||
let meta =
|
||||
AddressMeta::new(self.network, AddressType::Featured(subaddress, payment_id, guaranteed));
|
||||
MoneroAddress::new(meta, spend, view)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue