mirror of
https://github.com/serai-dex/serai.git
synced 2024-11-17 01:17:36 +00:00
Update procesor/correct prior commit
This commit is contained in:
parent
839734354a
commit
9157f8d0a0
11 changed files with 64 additions and 45 deletions
|
@ -140,9 +140,9 @@ impl Metadata {
|
||||||
/// A received output, defined as its absolute ID, data, and metadara.
|
/// A received output, defined as its absolute ID, data, and metadara.
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Zeroize, ZeroizeOnDrop)]
|
#[derive(Clone, PartialEq, Eq, Debug, Zeroize, ZeroizeOnDrop)]
|
||||||
pub struct ReceivedOutput {
|
pub struct ReceivedOutput {
|
||||||
pub(crate) absolute: AbsoluteId,
|
pub absolute: AbsoluteId,
|
||||||
pub(crate) data: OutputData,
|
pub data: OutputData,
|
||||||
pub(crate) metadata: Metadata,
|
pub metadata: Metadata,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReceivedOutput {
|
impl ReceivedOutput {
|
||||||
|
|
|
@ -550,7 +550,7 @@ impl SignableTransaction {
|
||||||
|
|
||||||
let mut serialized = Vec::with_capacity(extra_len);
|
let mut serialized = Vec::with_capacity(extra_len);
|
||||||
extra.write(&mut serialized).unwrap();
|
extra.write(&mut serialized).unwrap();
|
||||||
debug_assert_eq!(extra_len, extra);
|
debug_assert_eq!(extra_len, serialized.len());
|
||||||
serialized
|
serialized
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,10 +10,9 @@ use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
use dkg::{Participant, ThresholdParams};
|
use dkg::{Participant, ThresholdParams};
|
||||||
|
|
||||||
use serai_primitives::WithAmount;
|
use in_instructions_primitives::InInstructionWithBalance;
|
||||||
use in_instructions_primitives::InInstruction;
|
use tokens_primitives::OutInstructionWithBalance;
|
||||||
use tokens_primitives::OutInstruction;
|
use validator_sets_primitives::ValidatorSet;
|
||||||
use validator_sets_primitives::ValidatorSetInstance;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize, Serialize, Deserialize)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize, Serialize, Deserialize)]
|
||||||
pub struct SubstrateContext {
|
pub struct SubstrateContext {
|
||||||
|
@ -26,7 +25,7 @@ pub mod key_gen {
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Zeroize, Serialize, Deserialize)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Zeroize, Serialize, Deserialize)]
|
||||||
pub struct KeyGenId {
|
pub struct KeyGenId {
|
||||||
pub set: ValidatorSetInstance,
|
pub set: ValidatorSet,
|
||||||
pub attempt: u32,
|
pub attempt: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,12 +122,12 @@ pub mod substrate {
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Zeroize, Serialize, Deserialize)]
|
#[derive(Clone, PartialEq, Eq, Debug, Zeroize, Serialize, Deserialize)]
|
||||||
pub enum CoordinatorMessage {
|
pub enum CoordinatorMessage {
|
||||||
BlockAcknowledged { context: SubstrateContext, key: Vec<u8>, block: Vec<u8> },
|
BlockAcknowledged { context: SubstrateContext, key: Vec<u8>, block: Vec<u8> },
|
||||||
Burns { context: SubstrateContext, burns: Vec<WithAmount<OutInstruction>> },
|
Burns { context: SubstrateContext, burns: Vec<OutInstructionWithBalance> },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Zeroize, Serialize, Deserialize)]
|
#[derive(Clone, PartialEq, Eq, Debug, Zeroize, Serialize, Deserialize)]
|
||||||
pub enum ProcessorMessage {
|
pub enum ProcessorMessage {
|
||||||
Update { key: Vec<u8>, block: Vec<u8>, instructions: Vec<WithAmount<InInstruction>> },
|
Update { key: Vec<u8>, block: Vec<u8>, instructions: Vec<InInstructionWithBalance> },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,10 @@ use bitcoin_serai::bitcoin::{
|
||||||
PackedLockTime, Sequence, Script, Witness, TxIn, TxOut, Address as BAddress,
|
PackedLockTime, Sequence, Script, Witness, TxIn, TxOut, Address as BAddress,
|
||||||
};
|
};
|
||||||
|
|
||||||
use serai_client::{primitives::MAX_DATA_LEN, coins::bitcoin::Address};
|
use serai_client::{
|
||||||
|
primitives::{MAX_DATA_LEN, BITCOIN, Amount, Balance},
|
||||||
|
coins::bitcoin::Address,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
coins::{
|
coins::{
|
||||||
|
@ -93,8 +96,8 @@ impl OutputTrait for Output {
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
fn amount(&self) -> u64 {
|
fn balance(&self) -> Balance {
|
||||||
self.output.value()
|
Balance { coin: BITCOIN, amount: Amount(self.output.value()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn data(&self) -> &[u8] {
|
fn data(&self) -> &[u8] {
|
||||||
|
@ -342,7 +345,7 @@ impl Coin for Bitcoin {
|
||||||
let offset_repr_ref: &[u8] = offset_repr.as_ref();
|
let offset_repr_ref: &[u8] = offset_repr.as_ref();
|
||||||
let kind = kinds[offset_repr_ref];
|
let kind = kinds[offset_repr_ref];
|
||||||
|
|
||||||
let data = if kind == OutputType::External {
|
let mut data = if kind == OutputType::External {
|
||||||
(|| {
|
(|| {
|
||||||
for output in &tx.output {
|
for output in &tx.output {
|
||||||
if output.script_pubkey.is_op_return() {
|
if output.script_pubkey.is_op_return() {
|
||||||
|
|
|
@ -10,6 +10,8 @@ use frost::{
|
||||||
sign::PreprocessMachine,
|
sign::PreprocessMachine,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use serai_client::primitives::Balance;
|
||||||
|
|
||||||
#[cfg(feature = "bitcoin")]
|
#[cfg(feature = "bitcoin")]
|
||||||
pub mod bitcoin;
|
pub mod bitcoin;
|
||||||
#[cfg(feature = "bitcoin")]
|
#[cfg(feature = "bitcoin")]
|
||||||
|
@ -94,8 +96,11 @@ pub trait Output: Send + Sync + Sized + Clone + PartialEq + Eq + Debug {
|
||||||
fn kind(&self) -> OutputType;
|
fn kind(&self) -> OutputType;
|
||||||
|
|
||||||
fn id(&self) -> Self::Id;
|
fn id(&self) -> Self::Id;
|
||||||
fn amount(&self) -> u64;
|
|
||||||
|
|
||||||
|
fn balance(&self) -> Balance;
|
||||||
|
fn amount(&self) -> u64 {
|
||||||
|
self.balance().amount.0
|
||||||
|
}
|
||||||
fn data(&self) -> &[u8];
|
fn data(&self) -> &[u8];
|
||||||
|
|
||||||
fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()>;
|
fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()>;
|
||||||
|
|
|
@ -25,7 +25,10 @@ use monero_serai::{
|
||||||
|
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
|
|
||||||
pub use serai_client::{primitives::MAX_DATA_LEN, coins::monero::Address};
|
pub use serai_client::{
|
||||||
|
primitives::{MAX_DATA_LEN, MONERO, Amount, Balance},
|
||||||
|
coins::monero::Address,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Payment, Plan, additional_key,
|
Payment, Plan, additional_key,
|
||||||
|
@ -62,8 +65,8 @@ impl OutputTrait for Output {
|
||||||
self.0.output.data.key.compress().to_bytes()
|
self.0.output.data.key.compress().to_bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn amount(&self) -> u64 {
|
fn balance(&self) -> Balance {
|
||||||
self.0.commitment().amount
|
Balance { coin: MONERO, amount: Amount(self.0.commitment().amount) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn data(&self) -> &[u8] {
|
fn data(&self) -> &[u8] {
|
||||||
|
|
|
@ -15,7 +15,7 @@ use frost::{
|
||||||
|
|
||||||
use log::info;
|
use log::info;
|
||||||
|
|
||||||
use serai_client::validator_sets::primitives::ValidatorSetInstance;
|
use serai_client::validator_sets::primitives::ValidatorSet;
|
||||||
use messages::key_gen::*;
|
use messages::key_gen::*;
|
||||||
|
|
||||||
use crate::{DbTxn, Db, coins::Coin};
|
use crate::{DbTxn, Db, coins::Coin};
|
||||||
|
@ -33,18 +33,18 @@ impl<C: Coin, D: Db> KeyGenDb<C, D> {
|
||||||
D::key(b"KEY_GEN", dst, key)
|
D::key(b"KEY_GEN", dst, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn params_key(set: &ValidatorSetInstance) -> Vec<u8> {
|
fn params_key(set: &ValidatorSet) -> Vec<u8> {
|
||||||
Self::key_gen_key(b"params", bincode::serialize(set).unwrap())
|
Self::key_gen_key(b"params", bincode::serialize(set).unwrap())
|
||||||
}
|
}
|
||||||
fn save_params(
|
fn save_params(
|
||||||
&mut self,
|
&mut self,
|
||||||
txn: &mut D::Transaction,
|
txn: &mut D::Transaction,
|
||||||
set: &ValidatorSetInstance,
|
set: &ValidatorSet,
|
||||||
params: &ThresholdParams,
|
params: &ThresholdParams,
|
||||||
) {
|
) {
|
||||||
txn.put(Self::params_key(set), bincode::serialize(params).unwrap());
|
txn.put(Self::params_key(set), bincode::serialize(params).unwrap());
|
||||||
}
|
}
|
||||||
fn params(&self, set: &ValidatorSetInstance) -> ThresholdParams {
|
fn params(&self, set: &ValidatorSet) -> ThresholdParams {
|
||||||
// Directly unwraps the .get() as this will only be called after being set
|
// Directly unwraps the .get() as this will only be called after being set
|
||||||
bincode::deserialize(&self.0.get(Self::params_key(set)).unwrap()).unwrap()
|
bincode::deserialize(&self.0.get(Self::params_key(set)).unwrap()).unwrap()
|
||||||
}
|
}
|
||||||
|
@ -121,8 +121,8 @@ pub struct KeyGen<C: Coin, D: Db> {
|
||||||
db: KeyGenDb<C, D>,
|
db: KeyGenDb<C, D>,
|
||||||
entropy: Zeroizing<[u8; 32]>,
|
entropy: Zeroizing<[u8; 32]>,
|
||||||
|
|
||||||
active_commit: HashMap<ValidatorSetInstance, SecretShareMachine<C::Curve>>,
|
active_commit: HashMap<ValidatorSet, SecretShareMachine<C::Curve>>,
|
||||||
active_share: HashMap<ValidatorSetInstance, KeyMachine<C::Curve>>,
|
active_share: HashMap<ValidatorSet, KeyMachine<C::Curve>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: Coin, D: Db> KeyGen<C, D> {
|
impl<C: Coin, D: Db> KeyGen<C, D> {
|
||||||
|
@ -145,8 +145,8 @@ impl<C: Coin, D: Db> KeyGen<C, D> {
|
||||||
let context = |id: &KeyGenId| {
|
let context = |id: &KeyGenId| {
|
||||||
// TODO2: Also embed the chain ID/genesis block
|
// TODO2: Also embed the chain ID/genesis block
|
||||||
format!(
|
format!(
|
||||||
"Serai Key Gen. Session: {}, Index: {}, Attempt: {}",
|
"Serai Key Gen. Session: {:?}, Network: {:?}, Attempt: {}",
|
||||||
id.set.session.0, id.set.index.0, id.attempt
|
id.set.session, id.set.network, id.attempt
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,9 +19,9 @@ use tokio::time::sleep;
|
||||||
use scale::Decode;
|
use scale::Decode;
|
||||||
|
|
||||||
use serai_client::{
|
use serai_client::{
|
||||||
primitives::{MAX_DATA_LEN, Amount, WithAmount},
|
primitives::MAX_DATA_LEN,
|
||||||
tokens::primitives::OutInstruction,
|
tokens::primitives::{OutInstruction, OutInstructionWithBalance},
|
||||||
in_instructions::primitives::{Shorthand, RefundableInInstruction},
|
in_instructions::primitives::{Shorthand, RefundableInInstruction, InInstructionWithBalance},
|
||||||
};
|
};
|
||||||
|
|
||||||
use messages::{SubstrateContext, sign, substrate, CoordinatorMessage, ProcessorMessage};
|
use messages::{SubstrateContext, sign, substrate, CoordinatorMessage, ProcessorMessage};
|
||||||
|
@ -383,12 +383,15 @@ async fn run<C: Coin, D: Db, Co: Coordinator>(raw_db: D, coin: C, mut coordinato
|
||||||
|
|
||||||
let mut payments = vec![];
|
let mut payments = vec![];
|
||||||
for out in burns.clone() {
|
for out in burns.clone() {
|
||||||
let WithAmount { data: OutInstruction { address, data }, amount } = out;
|
let OutInstructionWithBalance {
|
||||||
|
instruction: OutInstruction { address, data },
|
||||||
|
balance,
|
||||||
|
} = out;
|
||||||
if let Ok(address) = C::Address::try_from(address.consume()) {
|
if let Ok(address) = C::Address::try_from(address.consume()) {
|
||||||
payments.push(Payment {
|
payments.push(Payment {
|
||||||
address,
|
address,
|
||||||
data: data.map(|data| data.consume()),
|
data: data.map(|data| data.consume()),
|
||||||
amount: amount.0,
|
amount: balance.amount.0,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -425,20 +428,24 @@ async fn run<C: Coin, D: Db, Co: Coordinator>(raw_db: D, coin: C, mut coordinato
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let data = output.data();
|
let mut data = output.data();
|
||||||
if data.len() > MAX_DATA_LEN {
|
let max_data_len = MAX_DATA_LEN.try_into().unwrap();
|
||||||
|
if data.len() > max_data_len {
|
||||||
error!(
|
error!(
|
||||||
"data in output {} exceeded MAX_DATA_LEN ({MAX_DATA_LEN}): {}",
|
"data in output {} exceeded MAX_DATA_LEN ({MAX_DATA_LEN}): {}",
|
||||||
hex::encode(output.id()),
|
hex::encode(output.id()),
|
||||||
data.len(),
|
data.len(),
|
||||||
);
|
);
|
||||||
data = data[.. MAX_DATA_LEN];
|
data = &data[.. max_data_len];
|
||||||
}
|
}
|
||||||
|
|
||||||
let shorthand = Shorthand::decode(&mut data).ok()?;
|
let shorthand = Shorthand::decode(&mut data).ok()?;
|
||||||
let instruction = RefundableInInstruction::try_from(shorthand).ok()?;
|
let instruction = RefundableInInstruction::try_from(shorthand).ok()?;
|
||||||
// TODO2: Set instruction.origin if not set (and handle refunds in general)
|
// TODO2: Set instruction.origin if not set (and handle refunds in general)
|
||||||
Some(WithAmount { data: instruction.instruction, amount: Amount(output.amount()) })
|
Some(InInstructionWithBalance {
|
||||||
|
instruction: instruction.instruction,
|
||||||
|
balance: output.balance(),
|
||||||
|
})
|
||||||
}).collect(),
|
}).collect(),
|
||||||
})).await;
|
})).await;
|
||||||
},
|
},
|
||||||
|
|
|
@ -377,7 +377,7 @@ impl<C: Coin, D: Db> Scanner<C, D> {
|
||||||
"block {} had output {} worth {}",
|
"block {} had output {} worth {}",
|
||||||
hex::encode(&block_id),
|
hex::encode(&block_id),
|
||||||
hex::encode(&id),
|
hex::encode(&id),
|
||||||
output.amount()
|
output.amount(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// On Bitcoin, the output ID should be unique for a given chain
|
// On Bitcoin, the output ID should be unique for a given chain
|
||||||
|
|
|
@ -117,15 +117,16 @@ impl<C: Coin> Scheduler<C> {
|
||||||
// If we can fulfill planned TXs with this output, do so
|
// If we can fulfill planned TXs with this output, do so
|
||||||
// We could limit this to UTXOs where `utxo.kind() == OutputType::Branch`, yet there's no
|
// We could limit this to UTXOs where `utxo.kind() == OutputType::Branch`, yet there's no
|
||||||
// practical benefit in doing so
|
// practical benefit in doing so
|
||||||
if let Some(plans) = self.plans.get_mut(&utxo.amount()) {
|
let amount = utxo.amount();
|
||||||
|
if let Some(plans) = self.plans.get_mut(&amount) {
|
||||||
// Execute the first set of payments possible with an output of this amount
|
// Execute the first set of payments possible with an output of this amount
|
||||||
let payments = plans.pop_front().unwrap();
|
let payments = plans.pop_front().unwrap();
|
||||||
// They won't be equal if we dropped payments due to being dust
|
// They won't be equal if we dropped payments due to being dust
|
||||||
assert!(utxo.amount() >= payments.iter().map(|payment| payment.amount).sum::<u64>());
|
assert!(amount >= payments.iter().map(|payment| payment.amount).sum::<u64>());
|
||||||
|
|
||||||
// If we've grabbed the last plan for this output amount, remove it from the map
|
// If we've grabbed the last plan for this output amount, remove it from the map
|
||||||
if plans.is_empty() {
|
if plans.is_empty() {
|
||||||
self.plans.remove(&utxo.amount());
|
self.plans.remove(&amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a TX for these payments
|
// Create a TX for these payments
|
||||||
|
|
|
@ -7,7 +7,10 @@ use rand_core::{RngCore, OsRng};
|
||||||
use group::GroupEncoding;
|
use group::GroupEncoding;
|
||||||
use frost::{Participant, ThresholdParams, tests::clone_without};
|
use frost::{Participant, ThresholdParams, tests::clone_without};
|
||||||
|
|
||||||
use serai_client::validator_sets::primitives::{Session, ValidatorSetIndex, ValidatorSetInstance};
|
use serai_client::{
|
||||||
|
primitives::MONERO_NET_ID,
|
||||||
|
validator_sets::primitives::{Session, ValidatorSet},
|
||||||
|
};
|
||||||
|
|
||||||
use messages::{SubstrateContext, key_gen::*};
|
use messages::{SubstrateContext, key_gen::*};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -16,10 +19,8 @@ use crate::{
|
||||||
tests::util::db::MemDb,
|
tests::util::db::MemDb,
|
||||||
};
|
};
|
||||||
|
|
||||||
const ID: KeyGenId = KeyGenId {
|
const ID: KeyGenId =
|
||||||
set: ValidatorSetInstance { session: Session(1), index: ValidatorSetIndex(2) },
|
KeyGenId { set: ValidatorSet { session: Session(1), network: MONERO_NET_ID }, attempt: 3 };
|
||||||
attempt: 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub async fn test_key_gen<C: Coin>() {
|
pub async fn test_key_gen<C: Coin>() {
|
||||||
let mut entropies = HashMap::new();
|
let mut entropies = HashMap::new();
|
||||||
|
|
Loading…
Reference in a new issue