Skip to content

Commit

Permalink
w
Browse files Browse the repository at this point in the history
  • Loading branch information
Tommytrg committed Oct 20, 2023
1 parent a21c0a8 commit 77ef20d
Show file tree
Hide file tree
Showing 10 changed files with 477 additions and 14 deletions.
202 changes: 194 additions & 8 deletions data_structures/src/chain/mod.rs

Large diffs are not rendered by default.

34 changes: 31 additions & 3 deletions data_structures/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,12 +284,34 @@ pub enum TransactionError {
min_stake, stake
)]
StakeBelowMinimum { min_stake: u64, stake: u64 },
/// A stake output with zero value does not make sense
/// Unstaking more than the total staked
#[fail(
display = "Transaction {} contains a stake output with zero value",
tx_hash
display = "Unstaking ({}) more than the total staked ({})",
unstake, stake
)]
UnstakingMoreThanStaked { stake: u64, unstake: u64 },
/// An stake output with zero value does not make sense
#[fail(display = "Transaction {} has a zero value stake output", tx_hash)]
ZeroValueStakeOutput { tx_hash: Hash },
/// Invalid unstake signature
#[fail(
display = "Invalid unstake signature: ({}), withdrawal ({}), operator ({})",
signature, withdrawal, operator
)]
InvalidUnstakeSignature {
signature: Hash,
withdrawal: Hash,
operator: Hash,
},
/// Invalid unstake time_lock
#[fail(
display = "The unstake timelock: ({}) is lower than the minimum unstaking delay ({})",
time_lock, unstaking_delay_seconds
)]
InvalidUnstakeTimelock {
time_lock: u64,
unstaking_delay_seconds: u32,
},
#[fail(
display = "The reward-to-collateral ratio for this data request is {}, but must be equal or less than {}",
reward_collateral_ratio, required_reward_collateral_ratio
Expand Down Expand Up @@ -419,6 +441,12 @@ pub enum BlockError {
weight, max_weight
)]
TotalStakeWeightLimitExceeded { weight: u32, max_weight: u32 },
/// Unstake weight limit exceeded
#[fail(
display = "Total weight of Unstake Transactions in a block ({}) exceeds the limit ({})",
weight, max_weight
)]
TotalUnstakeWeightLimitExceeded { weight: u32, max_weight: u32 },
/// Repeated operator Stake
#[fail(
display = "A single operator is receiving stake more than once in a block: ({}) ",
Expand Down
3 changes: 3 additions & 0 deletions data_structures/src/superblock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,7 @@ mod tests {
reveal_hash_merkle_root: default_hash,
tally_hash_merkle_root: tally_merkle_root_1,
stake_hash_merkle_root: default_hash,
unstake_hash_merkle_root: default_hash,
},
proof: default_proof,
bn256_public_key: None,
Expand Down Expand Up @@ -857,6 +858,7 @@ mod tests {
reveal_hash_merkle_root: default_hash,
tally_hash_merkle_root: tally_merkle_root_1,
stake_hash_merkle_root: default_hash,
unstake_hash_merkle_root: default_hash,
},
proof: default_proof.clone(),
bn256_public_key: None,
Expand All @@ -873,6 +875,7 @@ mod tests {
reveal_hash_merkle_root: default_hash,
tally_hash_merkle_root: tally_merkle_root_2,
stake_hash_merkle_root: default_hash,
unstake_hash_merkle_root: default_hash,
},
proof: default_proof,
bn256_public_key: None,
Expand Down
82 changes: 81 additions & 1 deletion data_structures/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
proto::{schema::witnet, ProtobufConvert},
vrf::DataRequestEligibilityClaim,
};

pub const UNSTAKE_TRANSACTION_WEIGHT: u32 = 153;
// These constants were calculated in:
// https://github.com/witnet/WIPs/blob/master/wip-0007.md
pub const INPUT_SIZE: u32 = 133;
Expand Down Expand Up @@ -132,6 +132,7 @@ pub enum Transaction {
Tally(TallyTransaction),
Mint(MintTransaction),
Stake(StakeTransaction),
Unstake(UnstakeTransaction),
}

impl From<VTTransaction> for Transaction {
Expand Down Expand Up @@ -176,6 +177,12 @@ impl From<StakeTransaction> for Transaction {
}
}

impl From<UnstakeTransaction> for Transaction {
fn from(transaction: UnstakeTransaction) -> Self {
Self::Unstake(transaction)
}
}

impl AsRef<Transaction> for Transaction {
fn as_ref(&self) -> &Self {
self
Expand Down Expand Up @@ -762,6 +769,64 @@ impl StakeOutput {
}
}

#[derive(Debug, Default, Eq, PartialEq, Clone, Serialize, Deserialize, ProtobufConvert, Hash)]
#[protobuf_convert(pb = "witnet::UnstakeTransaction")]
pub struct UnstakeTransaction {
pub body: UnstakeTransactionBody,
pub signature: KeyedSignature,
}
impl UnstakeTransaction {
// Creates a new unstake transaction.
pub fn new(body: UnstakeTransactionBody, signature: KeyedSignature) -> Self {
UnstakeTransaction { body, signature }
}

/// Returns the weight of a unstake transaction.
/// This is the weight that will be used to calculate
/// how many transactions can fit inside one block
pub fn weight(&self) -> u32 {
self.body.weight()
}
}

#[derive(Debug, Default, Eq, PartialEq, Clone, Serialize, Deserialize, ProtobufConvert, Hash)]
#[protobuf_convert(pb = "witnet::UnstakeTransactionBody")]
pub struct UnstakeTransactionBody {
pub operator: PublicKeyHash,
pub withdrawal: ValueTransferOutput,
pub change: Option<ValueTransferOutput>,

#[protobuf_convert(skip)]
#[serde(skip)]
hash: MemoHash,
}

impl UnstakeTransactionBody {
/// Creates a new stake transaction body.
pub fn new(
operator: PublicKeyHash,
withdrawal: ValueTransferOutput,
change: Option<ValueTransferOutput>,
) -> Self {
UnstakeTransactionBody {
operator,
withdrawal,
change,
hash: MemoHash::new(),
}
}

/// Stake transaction weight. It is calculated as:
///
/// ```text
/// ST_weight = 153
///
/// ```
pub fn weight(&self) -> u32 {
UNSTAKE_TRANSACTION_WEIGHT
}
}

impl MemoizedHashable for VTTransactionBody {
fn hashable_bytes(&self) -> Vec<u8> {
self.to_pb_bytes().unwrap()
Expand Down Expand Up @@ -810,6 +875,15 @@ impl MemoizedHashable for StakeTransactionBody {
&self.hash
}
}
impl MemoizedHashable for UnstakeTransactionBody {
fn hashable_bytes(&self) -> Vec<u8> {
self.to_pb_bytes().unwrap()
}

fn memoized_hash(&self) -> &MemoHash {
&self.hash
}
}
impl MemoizedHashable for TallyTransaction {
fn hashable_bytes(&self) -> Vec<u8> {
let Hash::SHA256(data_bytes) = self.data_poi_hash();
Expand Down Expand Up @@ -858,6 +932,11 @@ impl Hashable for StakeTransaction {
self.body.hash()
}
}
impl Hashable for UnstakeTransaction {
fn hash(&self) -> Hash {
self.body.hash()
}
}

impl Hashable for Transaction {
fn hash(&self) -> Hash {
Expand All @@ -869,6 +948,7 @@ impl Hashable for Transaction {
Transaction::Tally(tx) => tx.hash(),
Transaction::Mint(tx) => tx.hash(),
Transaction::Stake(tx) => tx.hash(),
Transaction::Unstake(tx) => tx.hash(),
}
}
}
Expand Down
1 change: 1 addition & 0 deletions data_structures/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ impl fmt::Display for Command {
Transaction::Tally(_) => f.write_str("TALLY_TRANSACTION")?,
Transaction::Mint(_) => f.write_str("MINT_TRANSACTION")?,
Transaction::Stake(_) => f.write_str("STAKE_TRANSACTION")?,
Transaction::Unstake(_) => f.write_str("UNSTAKE_TRANSACTION")?,
}
write!(f, ": {}", tx.hash())
}
Expand Down
5 changes: 5 additions & 0 deletions node/src/actors/chain_manager/mining.rs
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,8 @@ pub fn build_block(
let mut tally_txns = Vec::new();
// TODO: handle stake tx
let stake_txns = Vec::new();
// TODO: handle unstake tx
let unstake_txns = Vec::new();

let min_vt_weight =
VTTransactionBody::new(vec![Input::default()], vec![ValueTransferOutput::default()])
Expand Down Expand Up @@ -1003,6 +1005,7 @@ pub fn build_block(
let reveal_hash_merkle_root = merkle_tree_root(&reveal_txns);
let tally_hash_merkle_root = merkle_tree_root(&tally_txns);
let stake_hash_merkle_root = merkle_tree_root(&stake_txns);
let unstake_hash_merkle_root = merkle_tree_root(&unstake_txns);
let merkle_roots = BlockMerkleRoots {
mint_hash: mint.hash(),
vt_hash_merkle_root,
Expand All @@ -1011,6 +1014,7 @@ pub fn build_block(
reveal_hash_merkle_root,
tally_hash_merkle_root,
stake_hash_merkle_root,
unstake_hash_merkle_root,
};

let block_header = BlockHeader {
Expand All @@ -1029,6 +1033,7 @@ pub fn build_block(
reveal_txns,
tally_txns,
stake_txns,
unstake_txns,
};

(block_header, txns)
Expand Down
14 changes: 14 additions & 0 deletions schemas/witnet/witnet.proto
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ message Block {
Hash reveal_hash_merkle_root = 5;
Hash tally_hash_merkle_root = 6;
Hash stake_hash_merkle_root = 7;
Hash unstake_hash_merkle_root = 8;
}
uint32 signals = 1;
CheckpointBeacon beacon = 2;
Expand All @@ -75,6 +76,7 @@ message Block {
repeated RevealTransaction reveal_txns = 5;
repeated TallyTransaction tally_txns = 6;
repeated StakeTransaction stake_txns = 7;
repeated UnstakeTransaction unstake_txns = 8;
}

BlockHeader block_header = 1;
Expand Down Expand Up @@ -247,6 +249,17 @@ message StakeTransaction {
repeated KeyedSignature signatures = 2;
}

message UnstakeTransactionBody {
PublicKeyHash operator = 1;
ValueTransferOutput withdrawal = 2;
ValueTransferOutput change = 3;
}

message UnstakeTransaction {
UnstakeTransactionBody body = 1 ;
KeyedSignature signature = 2;
}

message Transaction {
oneof kind {
VTTransaction ValueTransfer = 1;
Expand All @@ -256,6 +269,7 @@ message Transaction {
TallyTransaction Tally = 5;
MintTransaction Mint = 6;
StakeTransaction Stake = 7;
UnstakeTransaction Unstake = 8;
}
}

Expand Down
Loading

0 comments on commit 77ef20d

Please sign in to comment.