mirror of
https://github.com/serai-dex/serai.git
synced 2024-12-22 19:49:22 +00:00
Fix #48
Removes monero, yet we still use monero-rs's base58 and epee libraries.
This commit is contained in:
parent
d12507e612
commit
c5beee5648
9 changed files with 209 additions and 113 deletions
66
Cargo.lock
generated
66
Cargo.lock
generated
|
@ -406,15 +406,6 @@ version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581"
|
checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "base58-monero"
|
|
||||||
version = "0.3.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "935c90240f9b7749c80746bf88ad9cb346f34b01ee30ad4d566dfdecd6e3cc6a"
|
|
||||||
dependencies = [
|
|
||||||
"thiserror",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base58-monero"
|
name = "base58-monero"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
@ -907,7 +898,7 @@ version = "3.2.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "13547f7012c01ab4a0e8f8967730ada8f9fdf419e8b6c792788f39cf4e46eefa"
|
checksum = "13547f7012c01ab4a0e8f8967730ada8f9fdf419e8b6c792788f39cf4e46eefa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.4.0",
|
"heck",
|
||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -1699,7 +1690,7 @@ version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "21cdad81446a7f7dc43f6a77409efeb9733d2fa65553efef6018ef257c959b73"
|
checksum = "21cdad81446a7f7dc43f6a77409efeb9733d2fa65553efef6018ef257c959b73"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.4.0",
|
"heck",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
|
@ -2856,15 +2847,6 @@ dependencies = [
|
||||||
"fxhash",
|
"fxhash",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "heck"
|
|
||||||
version = "0.3.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-segmentation",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
@ -3244,7 +3226,7 @@ dependencies = [
|
||||||
"blake2",
|
"blake2",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"either",
|
"either",
|
||||||
"heck 0.4.0",
|
"heck",
|
||||||
"impl-serde",
|
"impl-serde",
|
||||||
"ink_lang_ir",
|
"ink_lang_ir",
|
||||||
"itertools",
|
"itertools",
|
||||||
|
@ -4557,22 +4539,6 @@ dependencies = [
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "monero"
|
|
||||||
version = "0.16.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e3732061cea7e75dc68ef986e0d5a393b3606c258c996abb4a81b759613ea1a0"
|
|
||||||
dependencies = [
|
|
||||||
"base58-monero 0.3.2",
|
|
||||||
"curve25519-dalek 3.2.0",
|
|
||||||
"fixed-hash",
|
|
||||||
"hex",
|
|
||||||
"hex-literal",
|
|
||||||
"sealed",
|
|
||||||
"thiserror",
|
|
||||||
"tiny-keccak",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "monero-epee-bin-serde"
|
name = "monero-epee-bin-serde"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -4599,7 +4565,7 @@ dependencies = [
|
||||||
name = "monero-serai"
|
name = "monero-serai"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base58-monero 1.0.0",
|
"base58-monero",
|
||||||
"blake2",
|
"blake2",
|
||||||
"curve25519-dalek 3.2.0",
|
"curve25519-dalek 3.2.0",
|
||||||
"dalek-ff-group",
|
"dalek-ff-group",
|
||||||
|
@ -4610,7 +4576,6 @@ dependencies = [
|
||||||
"hex-literal",
|
"hex-literal",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"modular-frost",
|
"modular-frost",
|
||||||
"monero",
|
|
||||||
"monero-epee-bin-serde",
|
"monero-epee-bin-serde",
|
||||||
"monero-generators",
|
"monero-generators",
|
||||||
"multiexp",
|
"multiexp",
|
||||||
|
@ -5840,7 +5805,7 @@ dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cmake",
|
"cmake",
|
||||||
"heck 0.4.0",
|
"heck",
|
||||||
"itertools",
|
"itertools",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
|
@ -7334,18 +7299,6 @@ dependencies = [
|
||||||
"untrusted",
|
"untrusted",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "sealed"
|
|
||||||
version = "0.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "636b9882a0f4cc2039488df89a10eb4b7976d4b6c1917fc0518f3f0f5e2c72ca"
|
|
||||||
dependencies = [
|
|
||||||
"heck 0.3.3",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sec1"
|
name = "sec1"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
@ -7548,7 +7501,6 @@ dependencies = [
|
||||||
"hex",
|
"hex",
|
||||||
"k256",
|
"k256",
|
||||||
"modular-frost",
|
"modular-frost",
|
||||||
"monero",
|
|
||||||
"monero-serai",
|
"monero-serai",
|
||||||
"rand_core 0.6.3",
|
"rand_core 0.6.3",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -8587,7 +8539,7 @@ version = "0.24.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59"
|
checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck 0.4.0",
|
"heck",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"rustversion",
|
"rustversion",
|
||||||
|
@ -9260,12 +9212,6 @@ dependencies = [
|
||||||
"tinyvec",
|
"tinyvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-segmentation"
|
|
||||||
version = "1.9.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-width"
|
||||||
version = "0.1.9"
|
version = "0.1.9"
|
||||||
|
|
|
@ -40,7 +40,6 @@ serde_json = "1.0"
|
||||||
|
|
||||||
base58-monero = "1"
|
base58-monero = "1"
|
||||||
monero-epee-bin-serde = "1.0"
|
monero-epee-bin-serde = "1.0"
|
||||||
monero = "0.16"
|
|
||||||
|
|
||||||
reqwest = { version = "0.11", features = ["json"] }
|
reqwest = { version = "0.11", features = ["json"] }
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,10 @@ pub fn varint_len(varint: usize) -> usize {
|
||||||
((usize::try_from(usize::BITS - varint.leading_zeros()).unwrap().saturating_sub(1)) / 7) + 1
|
((usize::try_from(usize::BITS - varint.leading_zeros()).unwrap().saturating_sub(1)) / 7) + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn write_byte<W: io::Write>(byte: &u8, w: &mut W) -> io::Result<()> {
|
||||||
|
w.write_all(&[*byte])
|
||||||
|
}
|
||||||
|
|
||||||
pub fn write_varint<W: io::Write>(varint: &u64, w: &mut W) -> io::Result<()> {
|
pub fn write_varint<W: io::Write>(varint: &u64, w: &mut W) -> io::Result<()> {
|
||||||
let mut varint = *varint;
|
let mut varint = *varint;
|
||||||
while {
|
while {
|
||||||
|
@ -19,7 +23,7 @@ pub fn write_varint<W: io::Write>(varint: &u64, w: &mut W) -> io::Result<()> {
|
||||||
if varint != 0 {
|
if varint != 0 {
|
||||||
b |= VARINT_CONTINUATION_MASK;
|
b |= VARINT_CONTINUATION_MASK;
|
||||||
}
|
}
|
||||||
w.write_all(&[b])?;
|
write_byte(&b, w)?;
|
||||||
varint != 0
|
varint != 0
|
||||||
} {}
|
} {}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
165
coins/monero/src/wallet/extra.rs
Normal file
165
coins/monero/src/wallet/extra.rs
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
use std::io::{self, Read, Write};
|
||||||
|
|
||||||
|
use zeroize::Zeroize;
|
||||||
|
|
||||||
|
use curve25519_dalek::edwards::EdwardsPoint;
|
||||||
|
|
||||||
|
use crate::serialize::{
|
||||||
|
read_byte, read_bytes, read_varint, read_point, read_vec, write_byte, write_varint, write_point,
|
||||||
|
write_vec,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)]
|
||||||
|
pub(crate) enum PaymentId {
|
||||||
|
Unencrypted([u8; 32]),
|
||||||
|
Encrypted([u8; 8]),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PaymentId {
|
||||||
|
fn serialize<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
||||||
|
match self {
|
||||||
|
PaymentId::Unencrypted(id) => {
|
||||||
|
w.write_all(&[0])?;
|
||||||
|
w.write_all(id)?;
|
||||||
|
}
|
||||||
|
PaymentId::Encrypted(id) => {
|
||||||
|
w.write_all(&[1])?;
|
||||||
|
w.write_all(id)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize<R: Read>(r: &mut R) -> io::Result<PaymentId> {
|
||||||
|
Ok(match read_byte(r)? {
|
||||||
|
0 => PaymentId::Unencrypted(read_bytes(r)?),
|
||||||
|
1 => PaymentId::Encrypted(read_bytes(r)?),
|
||||||
|
_ => Err(io::Error::new(io::ErrorKind::Other, "unknown payment ID type"))?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Debug, Zeroize)]
|
||||||
|
pub(crate) enum ExtraField {
|
||||||
|
Padding(Vec<u8>),
|
||||||
|
PublicKey(EdwardsPoint),
|
||||||
|
PaymentId(PaymentId), // Technically Nonce, an arbitrary data field, yet solely used as PaymentId
|
||||||
|
MergeMining(usize, [u8; 32]),
|
||||||
|
PublicKeys(Vec<EdwardsPoint>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExtraField {
|
||||||
|
fn serialize<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
||||||
|
match self {
|
||||||
|
ExtraField::Padding(data) => {
|
||||||
|
w.write_all(&[0])?;
|
||||||
|
write_vec(write_byte, data, w)?;
|
||||||
|
}
|
||||||
|
ExtraField::PublicKey(key) => {
|
||||||
|
w.write_all(&[1])?;
|
||||||
|
w.write_all(&key.compress().to_bytes())?;
|
||||||
|
}
|
||||||
|
ExtraField::PaymentId(id) => {
|
||||||
|
w.write_all(&[2])?;
|
||||||
|
let mut buf = Vec::with_capacity(1 + 8);
|
||||||
|
id.serialize(&mut buf)?;
|
||||||
|
write_vec(write_byte, &buf, w)?;
|
||||||
|
}
|
||||||
|
ExtraField::MergeMining(height, merkle) => {
|
||||||
|
w.write_all(&[3])?;
|
||||||
|
write_varint(&u64::try_from(*height).unwrap(), w)?;
|
||||||
|
w.write_all(merkle)?;
|
||||||
|
}
|
||||||
|
ExtraField::PublicKeys(keys) => {
|
||||||
|
w.write_all(&[4])?;
|
||||||
|
write_vec(write_point, keys, w)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize<R: Read>(r: &mut R) -> io::Result<ExtraField> {
|
||||||
|
Ok(match read_byte(r)? {
|
||||||
|
0 => {
|
||||||
|
let res = read_vec(read_byte, r)?;
|
||||||
|
if res.len() > 255 {
|
||||||
|
Err(io::Error::new(io::ErrorKind::Other, "too long padding"))?;
|
||||||
|
}
|
||||||
|
ExtraField::Padding(res)
|
||||||
|
}
|
||||||
|
1 => ExtraField::PublicKey(read_point(r)?),
|
||||||
|
2 => ExtraField::PaymentId(PaymentId::deserialize(r)?),
|
||||||
|
3 => ExtraField::MergeMining(
|
||||||
|
usize::try_from(read_varint(r)?)
|
||||||
|
.map_err(|_| io::Error::new(io::ErrorKind::Other, "varint for height exceeds usize"))?,
|
||||||
|
read_bytes(r)?,
|
||||||
|
),
|
||||||
|
4 => ExtraField::PublicKeys(read_vec(read_point, r)?),
|
||||||
|
_ => Err(io::Error::new(io::ErrorKind::Other, "unknown extra field"))?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Debug, Zeroize)]
|
||||||
|
pub(crate) struct Extra(Vec<ExtraField>);
|
||||||
|
impl Extra {
|
||||||
|
pub(crate) fn keys(&self) -> Vec<EdwardsPoint> {
|
||||||
|
let mut keys = Vec::with_capacity(2);
|
||||||
|
for field in &self.0 {
|
||||||
|
match field.clone() {
|
||||||
|
ExtraField::PublicKey(key) => keys.push(key),
|
||||||
|
ExtraField::PublicKeys(additional) => keys.extend(additional),
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keys
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn data(&self) -> Option<Vec<u8>> {
|
||||||
|
for field in &self.0 {
|
||||||
|
if let ExtraField::Padding(data) = field {
|
||||||
|
return Some(data.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn new(mut keys: Vec<EdwardsPoint>) -> Extra {
|
||||||
|
let mut res = Extra(Vec::with_capacity(3));
|
||||||
|
if !keys.is_empty() {
|
||||||
|
res.push(ExtraField::PublicKey(keys[0]));
|
||||||
|
}
|
||||||
|
if keys.len() > 1 {
|
||||||
|
res.push(ExtraField::PublicKeys(keys.drain(1 ..).collect()));
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn push(&mut self, field: ExtraField) {
|
||||||
|
self.0.push(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn fee_weight(outputs: usize) -> usize {
|
||||||
|
// PublicKey, key, PublicKeys, length, additional keys, PaymentId, length, encrypted, ID
|
||||||
|
33 + 2 + (outputs.saturating_sub(1) * 32) + 11
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn serialize<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
||||||
|
for field in &self.0 {
|
||||||
|
field.serialize(w)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn deserialize<R: Read>(r: &mut R) -> io::Result<Extra> {
|
||||||
|
let mut res = Extra(vec![]);
|
||||||
|
let mut field;
|
||||||
|
while {
|
||||||
|
field = ExtraField::deserialize(r);
|
||||||
|
field.is_ok()
|
||||||
|
} {
|
||||||
|
res.0.push(field.unwrap());
|
||||||
|
}
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,9 @@ use curve25519_dalek::{scalar::Scalar, edwards::EdwardsPoint};
|
||||||
|
|
||||||
use crate::{hash, hash_to_scalar, serialize::write_varint, transaction::Input};
|
use crate::{hash, hash_to_scalar, serialize::write_varint, transaction::Input};
|
||||||
|
|
||||||
|
mod extra;
|
||||||
|
pub(crate) use extra::{PaymentId, ExtraField, Extra};
|
||||||
|
|
||||||
pub mod address;
|
pub mod address;
|
||||||
|
|
||||||
mod scan;
|
mod scan;
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
use std::convert::TryFrom;
|
use std::io::Cursor;
|
||||||
|
|
||||||
use zeroize::{Zeroize, ZeroizeOnDrop};
|
use zeroize::{Zeroize, ZeroizeOnDrop};
|
||||||
|
|
||||||
use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE, scalar::Scalar, edwards::EdwardsPoint};
|
use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE, scalar::Scalar, edwards::EdwardsPoint};
|
||||||
|
|
||||||
use monero::{consensus::deserialize, blockdata::transaction::ExtraField};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Commitment,
|
Commitment,
|
||||||
serialize::{write_varint, read_byte, read_bytes, read_u64, read_scalar, read_point},
|
serialize::{read_byte, read_u64, read_bytes, read_scalar, read_point},
|
||||||
transaction::{Timelock, Transaction},
|
transaction::{Timelock, Transaction},
|
||||||
wallet::{ViewPair, uniqueness, shared_key, amount_decryption, commitment_mask},
|
wallet::{ViewPair, Extra, uniqueness, shared_key, amount_decryption, commitment_mask},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Zeroize, ZeroizeOnDrop)]
|
#[derive(Clone, PartialEq, Eq, Debug, Zeroize, ZeroizeOnDrop)]
|
||||||
|
@ -72,34 +70,21 @@ impl SpendableOutput {
|
||||||
|
|
||||||
impl Transaction {
|
impl Transaction {
|
||||||
pub fn scan(&self, view: &ViewPair, guaranteed: bool) -> Timelocked {
|
pub fn scan(&self, view: &ViewPair, guaranteed: bool) -> Timelocked {
|
||||||
let mut extra = vec![];
|
let extra = Extra::deserialize(&mut Cursor::new(&self.prefix.extra));
|
||||||
write_varint(&u64::try_from(self.prefix.extra.len()).unwrap(), &mut extra).unwrap();
|
let keys;
|
||||||
extra.extend(&self.prefix.extra);
|
|
||||||
let extra = deserialize::<ExtraField>(&extra);
|
|
||||||
|
|
||||||
let pubkeys: Vec<EdwardsPoint>;
|
|
||||||
if let Ok(extra) = extra {
|
if let Ok(extra) = extra {
|
||||||
let mut m_pubkeys = vec![];
|
keys = extra.keys();
|
||||||
if let Some(key) = extra.tx_pubkey() {
|
|
||||||
m_pubkeys.push(key);
|
|
||||||
}
|
|
||||||
if let Some(keys) = extra.tx_additional_pubkeys() {
|
|
||||||
m_pubkeys.extend(&keys);
|
|
||||||
}
|
|
||||||
|
|
||||||
pubkeys = m_pubkeys.iter().filter_map(|key| key.point.decompress()).collect();
|
|
||||||
} else {
|
} else {
|
||||||
return Timelocked(self.prefix.timelock, vec![]);
|
return Timelocked(self.prefix.timelock, vec![]);
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut res = vec![];
|
let mut res = vec![];
|
||||||
for (o, output) in self.prefix.outputs.iter().enumerate() {
|
for (o, output) in self.prefix.outputs.iter().enumerate() {
|
||||||
// TODO: This may be replaceable by pubkeys[o]
|
for key in &keys {
|
||||||
for pubkey in &pubkeys {
|
|
||||||
let (view_tag, key_offset) = shared_key(
|
let (view_tag, key_offset) = shared_key(
|
||||||
Some(uniqueness(&self.prefix.inputs)).filter(|_| guaranteed),
|
Some(uniqueness(&self.prefix.inputs)).filter(|_| guaranteed),
|
||||||
&view.view,
|
&view.view,
|
||||||
pubkey,
|
key,
|
||||||
o,
|
o,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,6 @@ use zeroize::{Zeroize, ZeroizeOnDrop};
|
||||||
|
|
||||||
use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE, scalar::Scalar, edwards::EdwardsPoint};
|
use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE, scalar::Scalar, edwards::EdwardsPoint};
|
||||||
|
|
||||||
use monero::{consensus::Encodable, PublicKey, blockdata::transaction::SubField};
|
|
||||||
|
|
||||||
#[cfg(feature = "multisig")]
|
#[cfg(feature = "multisig")]
|
||||||
use frost::FrostError;
|
use frost::FrostError;
|
||||||
|
|
||||||
|
@ -24,8 +22,8 @@ use crate::{
|
||||||
rpc::{Rpc, RpcError},
|
rpc::{Rpc, RpcError},
|
||||||
wallet::{
|
wallet::{
|
||||||
address::{AddressType, Address},
|
address::{AddressType, Address},
|
||||||
SpendableOutput, Decoys, key_image_sort, uniqueness, shared_key, commitment_mask,
|
SpendableOutput, Decoys, PaymentId, ExtraField, Extra, key_image_sort, uniqueness, shared_key,
|
||||||
amount_encryption,
|
commitment_mask, amount_encryption,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
#[cfg(feature = "multisig")]
|
#[cfg(feature = "multisig")]
|
||||||
|
@ -210,9 +208,8 @@ impl SignableTransaction {
|
||||||
}
|
}
|
||||||
let outputs = payments.len() + (if change { 1 } else { 0 });
|
let outputs = payments.len() + (if change { 1 } else { 0 });
|
||||||
|
|
||||||
// Calculate the extra length.
|
// Calculate the extra length
|
||||||
// Type, length, value, with 1 field for the first key and 1 field for the rest
|
let extra = Extra::fee_weight(outputs);
|
||||||
let extra = (outputs * (2 + 32)) - (outputs.saturating_sub(2) * 2);
|
|
||||||
|
|
||||||
// Calculate the fee.
|
// Calculate the fee.
|
||||||
let mut fee = fee_rate.calculate(Transaction::fee_weight(
|
let mut fee = fee_rate.calculate(Transaction::fee_weight(
|
||||||
|
@ -279,16 +276,18 @@ impl SignableTransaction {
|
||||||
let bp = Bulletproofs::prove(rng, &commitments, self.protocol.bp_plus()).unwrap();
|
let bp = Bulletproofs::prove(rng, &commitments, self.protocol.bp_plus()).unwrap();
|
||||||
|
|
||||||
// Create the TX extra
|
// Create the TX extra
|
||||||
// TODO: Review this for canonicity with Monero
|
let extra = {
|
||||||
let mut extra = vec![];
|
let mut extra = Extra::new(outputs.iter().map(|output| output.R).collect());
|
||||||
SubField::TxPublicKey(PublicKey { point: outputs[0].R.compress() })
|
|
||||||
.consensus_encode(&mut extra)
|
// Additionally include a random payment ID
|
||||||
.unwrap();
|
let mut id = [0; 8];
|
||||||
SubField::AdditionalPublickKey(
|
rng.fill_bytes(&mut id);
|
||||||
outputs[1 ..].iter().map(|output| PublicKey { point: output.R.compress() }).collect(),
|
extra.push(ExtraField::PaymentId(PaymentId::Encrypted(id)));
|
||||||
)
|
|
||||||
.consensus_encode(&mut extra)
|
let mut serialized = Vec::with_capacity(Extra::fee_weight(outputs.len()));
|
||||||
.unwrap();
|
extra.serialize(&mut serialized).unwrap();
|
||||||
|
serialized
|
||||||
|
};
|
||||||
|
|
||||||
let mut tx_outputs = Vec::with_capacity(outputs.len());
|
let mut tx_outputs = Vec::with_capacity(outputs.len());
|
||||||
let mut ecdh_info = Vec::with_capacity(outputs.len());
|
let mut ecdh_info = Vec::with_capacity(outputs.len());
|
||||||
|
|
|
@ -4,13 +4,9 @@ use curve25519_dalek::constants::ED25519_BASEPOINT_TABLE;
|
||||||
|
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
use monero::{
|
|
||||||
network::Network,
|
|
||||||
util::{key::PublicKey, address::Address},
|
|
||||||
};
|
|
||||||
|
|
||||||
use monero_serai::{
|
use monero_serai::{
|
||||||
Protocol, random_scalar,
|
Protocol, random_scalar,
|
||||||
|
wallet::address::{Network, AddressType, AddressMeta, Address},
|
||||||
rpc::{EmptyResponse, RpcError, Rpc},
|
rpc::{EmptyResponse, RpcError, Rpc},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -22,11 +18,11 @@ pub async fn rpc() -> Rpc {
|
||||||
return rpc;
|
return rpc;
|
||||||
}
|
}
|
||||||
|
|
||||||
let addr = Address::standard(
|
let addr = Address {
|
||||||
Network::Mainnet,
|
meta: AddressMeta { network: Network::Mainnet, kind: AddressType::Standard, guaranteed: false },
|
||||||
PublicKey { point: (&random_scalar(&mut OsRng) * &ED25519_BASEPOINT_TABLE).compress() },
|
spend: &random_scalar(&mut OsRng) * &ED25519_BASEPOINT_TABLE,
|
||||||
PublicKey { point: (&random_scalar(&mut OsRng) * &ED25519_BASEPOINT_TABLE).compress() },
|
view: &random_scalar(&mut OsRng) * &ED25519_BASEPOINT_TABLE,
|
||||||
)
|
}
|
||||||
.to_string();
|
.to_string();
|
||||||
|
|
||||||
// Mine 20 blocks to ensure decoy availability
|
// Mine 20 blocks to ensure decoy availability
|
||||||
|
|
|
@ -29,7 +29,6 @@ transcript = { package = "flexible-transcript", path = "../crypto/transcript", f
|
||||||
dalek-ff-group = { path = "../crypto/dalek-ff-group" }
|
dalek-ff-group = { path = "../crypto/dalek-ff-group" }
|
||||||
frost = { package = "modular-frost", path = "../crypto/frost", features = ["secp256k1", "ed25519"] }
|
frost = { package = "modular-frost", path = "../crypto/frost", features = ["secp256k1", "ed25519"] }
|
||||||
|
|
||||||
monero = { version = "0.16", features = ["experimental"] }
|
|
||||||
monero-serai = { path = "../coins/monero", features = ["multisig"] }
|
monero-serai = { path = "../coins/monero", features = ["multisig"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
Loading…
Reference in a new issue