diff --git a/core/src/consensus/mod.rs b/core/src/consensus/mod.rs index a95c84cb3a..3ddc199881 100644 --- a/core/src/consensus/mod.rs +++ b/core/src/consensus/mod.rs @@ -43,7 +43,7 @@ use ckey::{Address, Signature}; use cnetwork::NetworkService; use cstate::{DoubleVoteHandler, StateDB, StateResult}; use ctypes::errors::SyntaxError; -use ctypes::transaction::{Action, StakeAction}; +use ctypes::transaction::Action; use ctypes::util::unexpected::{Mismatch, OutOfBounds}; use ctypes::{BlockHash, CommonParams, Header}; use primitives::{Bytes, H256}; @@ -322,24 +322,14 @@ pub trait CodeChainEngine: ConsensusEngine { tx: &UnverifiedTransaction, common_params: &CommonParams, ) -> Result<(), Error> { - if let Action::Custom { - bytes, - .. + if let Action::ReportDoubleVote { + message1, + message2, } = &tx.transaction().action { - let action = rlp::decode(bytes).map_err(|err| SyntaxError::InvalidCustomAction(err.to_string()))?; - let handler = self.stake_handler().ok_or_else(|| SyntaxError::InvalidCustomAction("no valid handler".to_string()))?; - if let StakeAction::ReportDoubleVote { - message1, - message2, - } = &action - { - handler.verify(message1, message2)?; - } - - action.verify(common_params)?; + handler.verify(message1, message2)?; } tx.verify_with_params(common_params)?; Ok(()) diff --git a/core/src/consensus/stake/mod.rs b/core/src/consensus/stake/mod.rs index 4d939349de..b680366aca 100644 --- a/core/src/consensus/stake/mod.rs +++ b/core/src/consensus/stake/mod.rs @@ -164,10 +164,8 @@ mod tests { use ckey::Ed25519Public as Public; use cstate::tests::helpers; use cstate::{ - execute_stake_action, init_stake, self_nominate, Candidate, Candidates, Delegation, Jail, StakeAccount, - TopStateView, + delegate_ccs, init_stake, self_nominate, Candidate, Candidates, Delegation, Jail, StakeAccount, TopStateView, }; - use ctypes::transaction::StakeAction; use ctypes::CommonParams; use std::collections::HashMap; @@ -230,7 +228,6 @@ mod tests { fn self_nominate_reverts_delegations_after_expiration() { let address_pubkey = Public::random(); let address = public_to_address(&address_pubkey); - let delegator_pubkey = Public::random(); let delegator = public_to_address(&address_pubkey); let mut state = metadata_for_election(); @@ -247,11 +244,8 @@ mod tests { // TODO: change with stake::execute() self_nominate(&mut state, &address, &address_pubkey, 0, 0, 30, b"".to_vec()).unwrap(); - let action = StakeAction::DelegateCCS { - address, - quantity: 40, - }; - execute_stake_action(action, &mut state, &delegator, &delegator_pubkey).unwrap(); + let quantity = 40; + delegate_ccs(&mut state, &delegator, &address, quantity).unwrap(); let result = on_term_close(&mut state, pseudo_term_to_block_num_calculator(29), &[]); assert_eq!(result, Ok(())); @@ -426,22 +420,14 @@ mod tests { jail(&mut state, &[address], custody_until, released_at).unwrap(); for current_term in 0..=released_at { - let action = StakeAction::DelegateCCS { - address, - quantity: 1, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert_ne!(Ok(()), result); + let quantity = 1; + delegate_ccs(&mut state, &delegator, &address, quantity).unwrap_err(); on_term_close(&mut state, pseudo_term_to_block_num_calculator(current_term), &[]).unwrap(); } - let action = StakeAction::DelegateCCS { - address, - quantity: 1, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert!(result.is_err()); + let quantity = 1; + delegate_ccs(&mut state, &delegator, &address, quantity).unwrap_err(); } #[test] @@ -468,11 +454,8 @@ mod tests { let released_at = 20; self_nominate(&mut state, &address, &address_pubkey, deposit, 0, nominate_expire, b"".to_vec()).unwrap(); - let action = StakeAction::DelegateCCS { - address, - quantity: 40, - }; - execute_stake_action(action, &mut state, &delegator, &delegator_pubkey).unwrap(); + let quantity = 40; + delegate_ccs(&mut state, &delegator, &address, quantity).unwrap(); jail(&mut state, &[address], custody_until, released_at).unwrap(); @@ -510,11 +493,8 @@ mod tests { let released_at = 20; self_nominate(&mut state, &address, &address_pubkey, 0, 0, nominate_expire, b"".to_vec()).unwrap(); - let action = StakeAction::DelegateCCS { - address, - quantity: 40, - }; - execute_stake_action(action, &mut state, &delegator, &delegator_pubkey).unwrap(); + let quantity = 40; + delegate_ccs(&mut state, &delegator, &address, quantity).unwrap(); jail(&mut state, &[address], custody_until, released_at).unwrap(); diff --git a/core/src/consensus/tendermint/vote_collector.rs b/core/src/consensus/tendermint/vote_collector.rs index 6f8d08f4d1..999f5ffa73 100644 --- a/core/src/consensus/tendermint/vote_collector.rs +++ b/core/src/consensus/tendermint/vote_collector.rs @@ -17,7 +17,7 @@ use super::{ConsensusMessage, VoteStep}; use crate::consensus::BitSet; use ckey::Signature; -use ctypes::transaction::StakeAction; +use ctypes::transaction::Action; use ctypes::BlockHash; use rlp::{Encodable, RlpStream}; use std::collections::{BTreeMap, HashMap}; @@ -44,8 +44,8 @@ pub struct DoubleVote { } impl DoubleVote { - pub fn to_action(&self) -> StakeAction { - StakeAction::ReportDoubleVote { + pub fn to_action(&self) -> Action { + Action::ReportDoubleVote { message1: self.vote_one.rlp_bytes(), message2: self.vote_two.rlp_bytes(), } diff --git a/core/src/consensus/tendermint/worker.rs b/core/src/consensus/tendermint/worker.rs index 66cfe4b709..9b0a2fd94f 100644 --- a/core/src/consensus/tendermint/worker.rs +++ b/core/src/consensus/tendermint/worker.rs @@ -41,7 +41,7 @@ use crate::BlockId; use ckey::{public_to_address, verify, Address, Signature}; use cnetwork::{EventSender, NodeId}; use crossbeam_channel as crossbeam; -use ctypes::transaction::{Action, Transaction}; +use ctypes::transaction::Transaction; use ctypes::util::unexpected::Mismatch; use ctypes::{BlockHash, BlockNumber, Header}; use primitives::Bytes; @@ -1432,10 +1432,7 @@ impl Worker { seq, fee: 0, network_id, - action: Action::Custom { - handler_id: 0, - bytes: double.to_action().rlp_bytes(), - }, + action: double.to_action(), }; let signature = match self.signer.sign_ed25519(*tx.hash()) { Ok(signature) => signature, diff --git a/foundry/auto_self_nominate.rs b/foundry/auto_self_nominate.rs index 8514939b5c..4112a100e7 100644 --- a/foundry/auto_self_nominate.rs +++ b/foundry/auto_self_nominate.rs @@ -21,8 +21,8 @@ use ckey::{Address, Ed25519Public as Public, Signature}; use ckeystore::DecryptedAccount; use clap::ArgMatches; use cstate::{Banned, Candidates, Jail}; -use ctypes::transaction::StakeAction::SelfNominate; -use ctypes::transaction::{Action, Transaction}; +use ctypes::transaction::Action::SelfNominate; +use ctypes::transaction::Transaction; use primitives::{Bytes, H256}; use std::convert::TryInto; use std::sync::Arc; @@ -178,10 +178,7 @@ impl AutoSelfNomination { seq, fee: 0, network_id, - action: Action::Custom { - handler_id: 0, - bytes: selfnominate.rlp_bytes(), - }, + action: selfnominate, }; let signature = match signer.sign_ed25519(*tx.hash()) { diff --git a/key/src/ed25519/signature.rs b/key/src/ed25519/signature.rs index d8712ab534..a260055c1a 100644 --- a/key/src/ed25519/signature.rs +++ b/key/src/ed25519/signature.rs @@ -17,7 +17,7 @@ use super::{Private, Public}; use primitives::H512; use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream}; -use serde::{Serialize, Serializer}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; pub use sodiumoxide::crypto::sign::SIGNATUREBYTES; use sodiumoxide::crypto::sign::{sign_detached, verify_detached, Signature}; use std::fmt; @@ -102,6 +102,15 @@ impl Serialize for Ed25519Signature { } } +impl<'de> Deserialize<'de> for Ed25519Signature { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, { + let h512_signature = H512::deserialize(deserializer)?; + Ok(Self::from_slice(&h512_signature).expect("Bytes length was verified")) + } +} + #[cfg(test)] mod tests { use rlp::rlp_encode_and_decode_test; diff --git a/rpc/src/v1/types/action.rs b/rpc/src/v1/types/action.rs index 36c29c8679..1238abd609 100644 --- a/rpc/src/v1/types/action.rs +++ b/rpc/src/v1/types/action.rs @@ -16,10 +16,11 @@ use super::super::errors::ConversionError; use cjson::uint::Uint; -use ckey::{NetworkId, PlatformAddress}; -use ctypes::transaction::Action as ActionType; +use ckey::{Error as KeyError, NetworkId, PlatformAddress}; +use ctypes::transaction::{Action as ActionType, Approval}; use ctypes::{ShardId, Tracker}; use primitives::Bytes; +use rlp::Encodable; use std::convert::TryFrom; #[derive(Debug, Deserialize, PartialEq)] @@ -42,16 +43,43 @@ pub enum Action { shard_id: ShardId, users: Vec, }, - #[serde(rename_all = "camelCase")] - Custom { - handler_id: Uint, - bytes: Bytes, - }, ShardStore { network_id: NetworkId, shard_id: ShardId, content: String, }, + TransferCCS { + address: PlatformAddress, + quantity: Uint, + }, + DelegateCCS { + address: PlatformAddress, + quantity: Uint, + }, + Revoke { + address: PlatformAddress, + quantity: Uint, + }, + #[serde(rename_all = "camelCase")] + Redelegate { + prev_delegatee: PlatformAddress, + next_delegatee: PlatformAddress, + quantity: Uint, + }, + SelfNominate { + deposit: Uint, + metadata: Bytes, + }, + #[serde(rename_all = "camelCase")] + ChangeParams { + metadata_seq: Uint, + params: Bytes, + approvals: Vec, + }, + ReportDoubleVote { + message1: Bytes, + message2: Bytes, + }, } #[derive(Debug, Serialize)] @@ -74,17 +102,44 @@ pub enum ActionWithTracker { shard_id: ShardId, users: Vec, }, - #[serde(rename_all = "camelCase")] - Custom { - handler_id: Uint, - bytes: Bytes, - }, ShardStore { network_id: NetworkId, shard_id: ShardId, content: String, tracker: Tracker, }, + TransferCCS { + address: PlatformAddress, + quantity: Uint, + }, + DelegateCCS { + address: PlatformAddress, + quantity: Uint, + }, + Revoke { + address: PlatformAddress, + quantity: Uint, + }, + #[serde(rename_all = "camelCase")] + Redelegate { + prev_delegatee: PlatformAddress, + next_delegatee: PlatformAddress, + quantity: Uint, + }, + SelfNominate { + deposit: Uint, + metadata: Bytes, + }, + #[serde(rename_all = "camelCase")] + ChangeParams { + metadata_seq: Uint, + params: Bytes, + approvals: Vec, + }, + ReportDoubleVote { + message1: Bytes, + message2: Bytes, + }, } impl ActionWithTracker { @@ -120,13 +175,6 @@ impl ActionWithTracker { shard_id, users: users.into_iter().map(|user| PlatformAddress::new_v1(network_id, user)).collect(), }, - ActionType::Custom { - handler_id, - bytes, - } => ActionWithTracker::Custom { - handler_id: handler_id.into(), - bytes, - }, ActionType::ShardStore { network_id, shard_id, @@ -137,6 +185,59 @@ impl ActionWithTracker { content, tracker: tracker.unwrap(), }, + ActionType::TransferCCS { + address, + quantity, + } => ActionWithTracker::TransferCCS { + address: PlatformAddress::new_v1(network_id, address), + quantity: quantity.into(), + }, + ActionType::DelegateCCS { + address, + quantity, + } => ActionWithTracker::DelegateCCS { + address: PlatformAddress::new_v1(network_id, address), + quantity: quantity.into(), + }, + ActionType::Revoke { + address, + quantity, + } => ActionWithTracker::Revoke { + address: PlatformAddress::new_v1(network_id, address), + quantity: quantity.into(), + }, + ActionType::Redelegate { + prev_delegatee, + next_delegatee, + quantity, + } => ActionWithTracker::Redelegate { + prev_delegatee: PlatformAddress::new_v1(network_id, prev_delegatee), + next_delegatee: PlatformAddress::new_v1(network_id, next_delegatee), + quantity: quantity.into(), + }, + ActionType::SelfNominate { + deposit, + metadata, + } => ActionWithTracker::SelfNominate { + deposit: deposit.into(), + metadata, + }, + ActionType::ChangeParams { + metadata_seq, + params, + approvals, + } => ActionWithTracker::ChangeParams { + metadata_seq: metadata_seq.into(), + params: params.rlp_bytes(), + approvals, + }, + ActionType::ReportDoubleVote { + message1, + message2, + } => ActionWithTracker::ReportDoubleVote { + message1, + message2, + }, } } } @@ -180,13 +281,6 @@ impl TryFrom for ActionType { users: users?, } } - Action::Custom { - handler_id, - bytes, - } => ActionType::Custom { - handler_id: handler_id.into(), - bytes, - }, Action::ShardStore { network_id, shard_id, @@ -196,6 +290,59 @@ impl TryFrom for ActionType { shard_id, content, }, + Action::TransferCCS { + address, + quantity, + } => ActionType::TransferCCS { + address: address.try_into_address()?, + quantity: quantity.into(), + }, + Action::DelegateCCS { + address, + quantity, + } => ActionType::DelegateCCS { + address: address.try_into_address()?, + quantity: quantity.into(), + }, + Action::Revoke { + address, + quantity, + } => ActionType::Revoke { + address: address.try_into_address()?, + quantity: quantity.into(), + }, + Action::Redelegate { + prev_delegatee, + next_delegatee, + quantity, + } => ActionType::Redelegate { + prev_delegatee: prev_delegatee.try_into_address()?, + next_delegatee: next_delegatee.try_into_address()?, + quantity: quantity.into(), + }, + Action::SelfNominate { + deposit, + metadata, + } => ActionType::SelfNominate { + deposit: deposit.into(), + metadata, + }, + Action::ChangeParams { + metadata_seq, + params, + approvals, + } => ActionType::ChangeParams { + metadata_seq: metadata_seq.into(), + params: Box::new(rlp::decode(¶ms).map_err(|err| KeyError::Custom(format!("{:?}", err)))?), + approvals, + }, + Action::ReportDoubleVote { + message1, + message2, + } => ActionType::ReportDoubleVote { + message1, + message2, + }, }) } } diff --git a/state/src/impls/top_level.rs b/state/src/impls/top_level.rs index 5bee5b149c..a4c13a6073 100644 --- a/state/src/impls/top_level.rs +++ b/state/src/impls/top_level.rs @@ -37,16 +37,17 @@ use crate::cache::{ShardCache, TopCache}; use crate::checkpoint::{CheckpointId, StateWithCheckpoint}; +use crate::stake::{change_params, delegate_ccs, redelegate, revoke, transfer_ccs}; use crate::traits::{ShardState, ShardStateView, StateWithCache, TopState, TopStateView}; use crate::{ - execute_stake_action, Account, ActionData, FindDoubleVoteHandler, Metadata, MetadataAddress, Shard, ShardAddress, + self_nominate, Account, ActionData, FindDoubleVoteHandler, Metadata, MetadataAddress, Shard, ShardAddress, ShardLevelState, StateDB, StateResult, }; use ccrypto::BLAKE_NULL_RLP; use cdb::{AsHashDB, DatabaseError}; use ckey::{public_to_address, Address, Ed25519Public as Public, NetworkId}; use ctypes::errors::RuntimeError; -use ctypes::transaction::{Action, ShardTransaction, StakeAction, Transaction}; +use ctypes::transaction::{Action, ShardTransaction, Transaction}; use ctypes::util::unexpected::Mismatch; #[cfg(test)] use ctypes::Tracker; @@ -363,20 +364,55 @@ impl TopLevelState { self.change_shard_users(*shard_id, users, sender_address)?; return Ok(()) } - Action::Custom { - bytes, + Action::TransferCCS { + address, + quantity, + } => return transfer_ccs(self, sender_address, &address, *quantity), + Action::DelegateCCS { + address, + quantity, + } => return delegate_ccs(self, sender_address, &address, *quantity), + Action::Revoke { + address, + quantity, + } => return revoke(self, sender_address, address, *quantity), + Action::Redelegate { + prev_delegatee, + next_delegatee, + quantity, + } => return redelegate(self, sender_address, prev_delegatee, next_delegatee, *quantity), + Action::SelfNominate { + deposit, + metadata, + } => { + let (current_term, nomination_ends_at) = { + let metadata = self.metadata()?.expect("Metadata must exist"); + let current_term = metadata.current_term_id(); + let expiration = metadata.params().nomination_expiration(); + let nomination_ends_at = current_term + expiration; + (current_term, nomination_ends_at) + }; + return self_nominate( + self, + sender_address, + sender_public, + *deposit, + current_term, + nomination_ends_at, + metadata.clone(), + ) + } + Action::ChangeParams { + metadata_seq, + params, + approvals, + } => return change_params(self, *metadata_seq, **params, &approvals), + Action::ReportDoubleVote { + message1, .. } => { - let action = rlp::decode(&bytes).expect("Verification passed"); let handler = client.double_vote_handler().expect("Unknown custom transaction applied!"); - if let StakeAction::ReportDoubleVote { - message1, - .. - } = &action - { - handler.execute(message1, self, sender_address)?; - } - execute_stake_action(action, self, sender_address, sender_public)?; + handler.execute(message1, self, sender_address)?; return Ok(()) } }; diff --git a/state/src/lib.rs b/state/src/lib.rs index cd3507d4f9..5be82df4e2 100644 --- a/state/src/lib.rs +++ b/state/src/lib.rs @@ -50,9 +50,9 @@ pub use crate::item::stake::{ NextValidators, Prisoner, ReleaseResult, StakeAccount, Stakeholders, Validator, }; pub use crate::stake::{ - ban, execute_stake_action, init_stake, jail, query as query_stake_state, release_jailed_prisoners, - revert_delegations, self_nominate, update_candidates, update_validator_weights, DoubleVoteHandler, - FindDoubleVoteHandler, StakeKeyBuilder, + ban, delegate_ccs, init_stake, jail, query as query_stake_state, release_jailed_prisoners, revert_delegations, + self_nominate, update_candidates, update_validator_weights, DoubleVoteHandler, FindDoubleVoteHandler, + StakeKeyBuilder, }; pub use crate::traits::{ShardState, ShardStateView, StateWithCache, TopState, TopStateView}; diff --git a/state/src/stake/actions.rs b/state/src/stake/actions.rs index f519669c93..fd197079e7 100644 --- a/state/src/stake/actions.rs +++ b/state/src/stake/actions.rs @@ -20,7 +20,7 @@ use crate::{ }; use ckey::{public_to_address, Address, Ed25519Public as Public}; use ctypes::errors::RuntimeError; -use ctypes::transaction::{Approval, StakeAction}; +use ctypes::transaction::Approval; use ctypes::util::unexpected::Mismatch; use ctypes::{CommonParams, Deposit}; use primitives::Bytes; @@ -105,55 +105,7 @@ pub fn init_stake( Ok(()) } -pub fn execute_stake_action( - action: StakeAction, - state: &mut TopLevelState, - sender_address: &Address, - sender_public: &Public, -) -> StateResult<()> { - match action { - StakeAction::TransferCCS { - address, - quantity, - } => transfer_ccs(state, sender_address, &address, quantity), - StakeAction::DelegateCCS { - address, - quantity, - } => delegate_ccs(state, sender_address, &address, quantity), - StakeAction::Revoke { - address, - quantity, - } => revoke(state, sender_address, &address, quantity), - StakeAction::Redelegate { - prev_delegatee, - next_delegatee, - quantity, - } => redelegate(state, sender_address, &prev_delegatee, &next_delegatee, quantity), - StakeAction::SelfNominate { - deposit, - metadata, - } => { - let (current_term, nomination_ends_at) = { - let metadata = state.metadata()?.expect("Metadata must exist"); - let current_term = metadata.current_term_id(); - let expiration = metadata.params().nomination_expiration(); - let nomination_ends_at = current_term + expiration; - (current_term, nomination_ends_at) - }; - self_nominate(state, sender_address, sender_public, deposit, current_term, nomination_ends_at, metadata) - } - StakeAction::ChangeParams { - metadata_seq, - params, - approvals, - } => change_params(state, metadata_seq, *params, &approvals), - StakeAction::ReportDoubleVote { - .. - } => Ok(()), - } -} - -fn transfer_ccs(state: &mut TopLevelState, sender: &Address, receiver: &Address, quantity: u64) -> StateResult<()> { +pub fn transfer_ccs(state: &mut TopLevelState, sender: &Address, receiver: &Address, quantity: u64) -> StateResult<()> { let mut stakeholders = Stakeholders::load_from_state(state)?; let mut sender_account = StakeAccount::load_from_state(state, sender)?; let mut receiver_account = StakeAccount::load_from_state(state, receiver)?; @@ -173,7 +125,12 @@ fn transfer_ccs(state: &mut TopLevelState, sender: &Address, receiver: &Address, Ok(()) } -fn delegate_ccs(state: &mut TopLevelState, delegator: &Address, delegatee: &Address, quantity: u64) -> StateResult<()> { +pub fn delegate_ccs( + state: &mut TopLevelState, + delegator: &Address, + delegatee: &Address, + quantity: u64, +) -> StateResult<()> { let candidates = Candidates::load_from_state(state)?; if candidates.get_candidate(delegatee).is_none() { return Err(RuntimeError::FailedToHandleCustomAction("Can delegate to who is a candidate".into()).into()) @@ -198,7 +155,7 @@ fn delegate_ccs(state: &mut TopLevelState, delegator: &Address, delegatee: &Addr Ok(()) } -fn revoke(state: &mut TopLevelState, delegator: &Address, delegatee: &Address, quantity: u64) -> StateResult<()> { +pub fn revoke(state: &mut TopLevelState, delegator: &Address, delegatee: &Address, quantity: u64) -> StateResult<()> { let mut delegator_account = StakeAccount::load_from_state(state, delegator)?; let mut delegation = Delegation::load_from_state(state, &delegator)?; @@ -213,7 +170,7 @@ fn revoke(state: &mut TopLevelState, delegator: &Address, delegatee: &Address, q Ok(()) } -fn redelegate( +pub fn redelegate( state: &mut TopLevelState, delegator: &Address, prev_delegatee: &Address, @@ -294,7 +251,7 @@ pub fn self_nominate( Ok(()) } -fn change_params( +pub fn change_params( state: &mut TopLevelState, metadata_seq: u64, params: CommonParams, @@ -463,7 +420,6 @@ mod tests { get_delegation_key, get_stake_account_key, init_stake, Banned, Candidate, Candidates, Delegation, Jail, Prisoner, StakeAccount, Stakeholders, TopStateView, }; - use ctypes::transaction::StakeAction; use std::collections::HashMap; #[test] @@ -565,12 +521,8 @@ mod tests { init_stake(&mut state, genesis_stakes, Default::default(), Default::default()).unwrap(); self_nominate(&mut state, &delegatee, &delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = StakeAction::DelegateCCS { - address: delegatee, - quantity: 40, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert_eq!(result, Ok(())); + let quantity = 40; + delegate_ccs(&mut state, &delegator, &delegatee, quantity).unwrap(); let delegator_account = StakeAccount::load_from_state(&state, &delegator).unwrap(); assert_eq!(delegator_account.balance, 60); @@ -608,12 +560,8 @@ mod tests { init_stake(&mut state, genesis_stakes, Default::default(), Default::default()).unwrap(); self_nominate(&mut state, &delegatee, &delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = StakeAction::DelegateCCS { - address: delegatee, - quantity: 100, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert_eq!(result, Ok(())); + let quantity = 100; + delegate_ccs(&mut state, &delegator, &delegatee, quantity).unwrap(); let delegator_account = StakeAccount::load_from_state(&state, &delegator).unwrap(); assert_eq!(delegator_account.balance, 0); @@ -651,12 +599,8 @@ mod tests { }; init_stake(&mut state, genesis_stakes, Default::default(), Default::default()).unwrap(); - let action = StakeAction::DelegateCCS { - address: delegatee, - quantity: 40, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert!(result.is_err()); + let quantity = 40; + delegate_ccs(&mut state, &delegator, &delegatee, quantity).unwrap_err(); } #[test] @@ -676,12 +620,8 @@ mod tests { init_stake(&mut state, genesis_stakes, Default::default(), Default::default()).unwrap(); self_nominate(&mut state, &delegatee, &delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = StakeAction::DelegateCCS { - address: delegatee, - quantity: 200, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert!(result.is_err()); + let quantity = 200; + delegate_ccs(&mut state, &delegator, &delegatee, quantity).unwrap_err(); } #[test] @@ -701,18 +641,11 @@ mod tests { init_stake(&mut state, genesis_stakes, Default::default(), Default::default()).unwrap(); self_nominate(&mut state, &delegatee, &delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = StakeAction::DelegateCCS { - address: delegatee, - quantity: 50, - }; - execute_stake_action(action, &mut state, &delegator, &delegator_pubkey).unwrap(); + let quantity = 50; + delegate_ccs(&mut state, &delegator, &delegatee, quantity).unwrap(); - let action = StakeAction::TransferCCS { - address: delegatee, - quantity: 50, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert!(result.is_ok()); + let quantity = 50; + transfer_ccs(&mut state, &delegator, &delegatee, quantity).unwrap(); } #[test] @@ -732,18 +665,11 @@ mod tests { init_stake(&mut state, genesis_stakes, Default::default(), Default::default()).unwrap(); self_nominate(&mut state, &delegatee, &delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = StakeAction::DelegateCCS { - address: delegatee, - quantity: 50, - }; - execute_stake_action(action, &mut state, &delegator, &delegator_pubkey).unwrap(); + let quantity = 50; + delegate_ccs(&mut state, &delegator, &delegatee, quantity).unwrap(); - let action = StakeAction::TransferCCS { - address: delegatee, - quantity: 100, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert!(result.is_err()); + let quantity = 100; + transfer_ccs(&mut state, &delegator, &delegatee, quantity).unwrap_err(); } #[test] @@ -763,19 +689,11 @@ mod tests { init_stake(&mut state, genesis_stakes, Default::default(), Default::default()).unwrap(); self_nominate(&mut state, &delegatee, &delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = StakeAction::DelegateCCS { - address: delegatee, - quantity: 50, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert!(result.is_ok()); + let quantity = 50; + delegate_ccs(&mut state, &delegator, &delegatee, quantity).unwrap(); - let action = StakeAction::Revoke { - address: delegatee, - quantity: 20, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert_eq!(Ok(()), result); + let quantity = 20; + revoke(&mut state, &delegator, &delegatee, quantity).unwrap(); let delegator_account = StakeAccount::load_from_state(&state, &delegator).unwrap(); let delegation = Delegation::load_from_state(&state, &delegator).unwrap(); @@ -801,19 +719,11 @@ mod tests { init_stake(&mut state, genesis_stakes, Default::default(), Default::default()).unwrap(); self_nominate(&mut state, &delegatee, &delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = StakeAction::DelegateCCS { - address: delegatee, - quantity: 50, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert!(result.is_ok()); + let quantity = 50; + delegate_ccs(&mut state, &delegator, &delegatee, quantity).unwrap(); - let action = StakeAction::Revoke { - address: delegatee, - quantity: 70, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert!(result.is_err()); + let quantity = 70; + revoke(&mut state, &delegator, &delegatee, quantity).unwrap_err(); let delegator_account = StakeAccount::load_from_state(&state, &delegator).unwrap(); let delegation = Delegation::load_from_state(&state, &delegator).unwrap(); @@ -839,19 +749,11 @@ mod tests { init_stake(&mut state, genesis_stakes, Default::default(), Default::default()).unwrap(); self_nominate(&mut state, &delegatee, &delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = StakeAction::DelegateCCS { - address: delegatee, - quantity: 50, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert!(result.is_ok()); + let quantity = 50; + delegate_ccs(&mut state, &delegator, &delegatee, quantity).unwrap(); - let action = StakeAction::Revoke { - address: delegatee, - quantity: 50, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert_eq!(Ok(()), result); + let quantity = 50; + revoke(&mut state, &delegator, &delegatee, quantity).unwrap(); let delegator_account = StakeAccount::load_from_state(&state, &delegator).unwrap(); assert_eq!(delegator_account.balance, 100); @@ -877,20 +779,11 @@ mod tests { self_nominate(&mut state, &prev_delegatee, &prev_delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); self_nominate(&mut state, &next_delegatee, &next_delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = StakeAction::DelegateCCS { - address: prev_delegatee, - quantity: 50, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert!(result.is_ok()); + let quantity = 50; + delegate_ccs(&mut state, &delegator, &prev_delegatee, quantity).unwrap(); - let action = StakeAction::Redelegate { - prev_delegatee, - next_delegatee, - quantity: 20, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert_eq!(Ok(()), result); + let quantity = 20; + redelegate(&mut state, &delegator, &prev_delegatee, &next_delegatee, quantity).unwrap(); let delegator_account = StakeAccount::load_from_state(&state, &delegator).unwrap(); let delegation = Delegation::load_from_state(&state, &delegator).unwrap(); @@ -919,20 +812,11 @@ mod tests { self_nominate(&mut state, &prev_delegatee, &prev_delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); self_nominate(&mut state, &next_delegatee, &next_delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = StakeAction::DelegateCCS { - address: prev_delegatee, - quantity: 50, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert!(result.is_ok()); + let quantity = 50; + delegate_ccs(&mut state, &delegator, &prev_delegatee, quantity).unwrap(); - let action = StakeAction::Redelegate { - prev_delegatee, - next_delegatee, - quantity: 70, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert!(result.is_err()); + let quantity = 70; + redelegate(&mut state, &delegator, &prev_delegatee, &next_delegatee, quantity).unwrap_err(); let delegator_account = StakeAccount::load_from_state(&state, &delegator).unwrap(); let delegation = Delegation::load_from_state(&state, &delegator).unwrap(); @@ -961,20 +845,11 @@ mod tests { self_nominate(&mut state, &prev_delegatee, &prev_delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); self_nominate(&mut state, &next_delegatee, &next_delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = StakeAction::DelegateCCS { - address: prev_delegatee, - quantity: 50, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert!(result.is_ok()); + let quantity = 50; + delegate_ccs(&mut state, &delegator, &prev_delegatee, quantity).unwrap(); - let action = StakeAction::Redelegate { - prev_delegatee, - next_delegatee, - quantity: 50, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert_eq!(Ok(()), result); + let quantity = 50; + redelegate(&mut state, &delegator, &prev_delegatee, &next_delegatee, quantity).unwrap(); let delegator_account = StakeAccount::load_from_state(&state, &delegator).unwrap(); let delegation = Delegation::load_from_state(&state, &delegator).unwrap(); @@ -1003,20 +878,11 @@ mod tests { self_nominate(&mut state, &prev_delegatee, &prev_delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); - let action = StakeAction::DelegateCCS { - address: prev_delegatee, - quantity: 40, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert!(result.is_ok()); + let quantity = 40; + delegate_ccs(&mut state, &delegator, &prev_delegatee, quantity).unwrap(); - let action = StakeAction::Redelegate { - prev_delegatee, - next_delegatee, - quantity: 50, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert!(result.is_err()); + let quantity = 50; + redelegate(&mut state, &delegator, &prev_delegatee, &next_delegatee, quantity).unwrap_err(); } #[test] @@ -1042,16 +908,10 @@ mod tests { self_nominate(&mut state, &prev_delegatee, &prev_delegatee_pubkey, 0, 0, 10, b"".to_vec()).unwrap(); self_nominate(&mut state, &criminal, &criminal_pubkey, 100, 0, 10, b"".to_vec()).unwrap(); - let action = StakeAction::DelegateCCS { - address: criminal, - quantity: 40, - }; - execute_stake_action(action, &mut state, &delegator, &delegator_pubkey).unwrap(); - let action = StakeAction::DelegateCCS { - address: prev_delegatee, - quantity: 40, - }; - execute_stake_action(action, &mut state, &delegator, &delegator_pubkey).unwrap(); + let quantity = 40; + delegate_ccs(&mut state, &delegator, &criminal, quantity).unwrap(); + let quantity = 40; + delegate_ccs(&mut state, &delegator, &prev_delegatee, quantity).unwrap(); let candidates = Candidates::load_from_state(&state).unwrap(); assert_eq!(candidates.len(), 2); @@ -1064,13 +924,8 @@ mod tests { let candidates = Candidates::load_from_state(&state).unwrap(); assert_eq!(candidates.len(), 1); - let action = StakeAction::Redelegate { - prev_delegatee, - next_delegatee: criminal, - quantity: 40, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert!(result.is_err()); + let quantity = 40; + redelegate(&mut state, &delegator, &prev_delegatee, &criminal, quantity).unwrap_err(); } #[test] @@ -1096,11 +951,8 @@ mod tests { let deposit = 200; self_nominate(&mut state, &jail_address, &jail_pubkey, deposit, 0, 5, b"".to_vec()).unwrap(); - let action = StakeAction::DelegateCCS { - address: prev_delegatee, - quantity: 40, - }; - execute_stake_action(action, &mut state, &delegator, &delegator_pubkey).unwrap(); + let quantity = 40; + delegate_ccs(&mut state, &delegator, &prev_delegatee, quantity).unwrap(); let candidates = Candidates::load_from_state(&state).unwrap(); assert_eq!(candidates.len(), 2); @@ -1113,13 +965,8 @@ mod tests { let candidates = Candidates::load_from_state(&state).unwrap(); assert_eq!(candidates.len(), 1); - let action = StakeAction::Redelegate { - prev_delegatee, - next_delegatee: jail_address, - quantity: 40, - }; - let result = execute_stake_action(action, &mut state, &delegator, &delegator_pubkey); - assert!(result.is_err()); + let quantity = 40; + redelegate(&mut state, &delegator, &prev_delegatee, &jail_address, quantity).unwrap_err(); } #[test] @@ -1254,11 +1101,9 @@ mod tests { let deposit = 100; self_nominate(&mut state, &criminal, &criminal_pubkey, deposit, 0, 10, b"".to_vec()).unwrap(); - let action = StakeAction::DelegateCCS { - address: criminal, - quantity: 40, - }; - execute_stake_action(action, &mut state, &delegator, &delegator_pubkey).unwrap(); + + let quantity = 40; + delegate_ccs(&mut state, &delegator, &criminal, quantity).unwrap(); assert_eq!(Ok(()), ban(&mut state, &informant, criminal)); diff --git a/state/src/stake/mod.rs b/state/src/stake/mod.rs index 821f12006f..75c67978c5 100644 --- a/state/src/stake/mod.rs +++ b/state/src/stake/mod.rs @@ -17,8 +17,8 @@ mod actions; pub use self::actions::{ - ban, execute_stake_action, init_stake, jail, release_jailed_prisoners, revert_delegations, self_nominate, - update_candidates, update_validator_weights, + ban, change_params, delegate_ccs, init_stake, jail, redelegate, release_jailed_prisoners, revert_delegations, + revoke, self_nominate, transfer_ccs, update_candidates, update_validator_weights, }; use super::TopStateView; use crate::{StateResult, TopLevelState}; diff --git a/test/src/e2e.dynval/1/dv.changeParams.test.ts b/test/src/e2e.dynval/1/dv.changeParams.test.ts index cca2e17d78..802e1d8c69 100644 --- a/test/src/e2e.dynval/1/dv.changeParams.test.ts +++ b/test/src/e2e.dynval/1/dv.changeParams.test.ts @@ -83,12 +83,11 @@ describe("Change commonParams that affects validator set", function() { const revoked = validators.slice(0, 3); const untouched = validators.slice(3, 5); const revokeTxs = revoked.map((signer, idx) => - stake - .createRevokeTransaction( - checkingNode.testFramework, - signer.address, - 4_999 - ) + checkingNode.testFramework.core + .createRevokeTransaction({ + delegatee: signer.address, + quantity: 4_999 + }) .sign({ secret: faucetSecret, seq: faucetSeq + idx, @@ -239,11 +238,10 @@ describe("Change commonParams that doesn't affects validator set", function() { describe("Change the maximum size of candidate metadata", async function() { function nominationWithMetadata(size: number) { - return stake.createSelfNominateTransaction( - nodes[0].testFramework, - 1, - " ".repeat(size) - ); + return nodes[0].testFramework.core.createSelfNominateTransaction({ + deposit: 1, + metadata: " ".repeat(size) + }); } it("Should apply larger metadata limit after increment", async function() { diff --git a/test/src/e2e.dynval/1/dv.m-m'.test.ts b/test/src/e2e.dynval/1/dv.m-m'.test.ts index 239ce18d0e..f1f6a8c64a 100644 --- a/test/src/e2e.dynval/1/dv.m-m'.test.ts +++ b/test/src/e2e.dynval/1/dv.m-m'.test.ts @@ -139,12 +139,11 @@ describe("Dynamic Validator M -> M' (Changed the subset, M, M’ = maximum numbe const delegateToCharlie = await nodes[0].rpc.mempool.sendSignedTransaction( { - tx: stake - .createDelegateCCSTransaction( - nodes[0].testFramework, - validators[charlie].address, - charlieDelegationToCatchBob - ) + tx: nodes[0].testFramework.core + .createDelegateCCSTransaction({ + delegatee: validators[charlie].address, + quantity: charlieDelegationToCatchBob + }) .sign({ secret: faucetSecret, seq: (await nodes[0].rpc.chain.getSeq({ @@ -185,12 +184,11 @@ describe("Dynamic Validator M -> M' (Changed the subset, M, M’ = maximum numbe const depositDave = await nodes[ dave ].rpc.mempool.sendSignedTransaction({ - tx: stake - .createSelfNominateTransaction( - nodes[dave].testFramework, - daveDepositToCatchBob, - "" - ) + tx: nodes[dave].testFramework.core + .createSelfNominateTransaction({ + deposit: daveDepositToCatchBob, + metadata: "" + }) .sign({ secret: validators[dave].privateKey, seq: (await nodes[dave].rpc.chain.getSeq({ @@ -228,12 +226,11 @@ describe("Dynamic Validator M -> M' (Changed the subset, M, M’ = maximum numbe await expectAllValidatorsArePossibleAuthors(nodes[0].rpc); const revokeTx = await nodes[0].rpc.mempool.sendSignedTransaction({ - tx: stake - .createRevokeTransaction( - nodes[0].testFramework, - validators[alice].address, - aliceRevokeToBeLowerThanBob - ) + tx: nodes[0].testFramework.core + .createRevokeTransaction({ + delegatee: validators[alice].address, + quantity: aliceRevokeToBeLowerThanBob + }) .sign({ secret: faucetSecret, seq: (await nodes[0].rpc.chain.getSeq({ @@ -267,12 +264,11 @@ describe("Dynamic Validator M -> M' (Changed the subset, M, M’ = maximum numbe const delegateToCharlie = await nodes[0].rpc.mempool.sendSignedTransaction( { - tx: stake - .createDelegateCCSTransaction( - nodes[0].testFramework, - validators[charlie].address, - charlieDelegationToCatchBob - ) + tx: nodes[0].testFramework.core + .createDelegateCCSTransaction({ + delegatee: validators[charlie].address, + quantity: charlieDelegationToCatchBob + }) .sign({ secret: faucetSecret, seq: (await nodes[0].rpc.chain.getSeq({ @@ -301,12 +297,11 @@ describe("Dynamic Validator M -> M' (Changed the subset, M, M’ = maximum numbe const depositDave = await nodes[ dave ].rpc.mempool.sendSignedTransaction({ - tx: stake - .createSelfNominateTransaction( - nodes[dave].testFramework, - daveDepositToCatchBob, - "" - ) + tx: nodes[dave].testFramework.core + .createSelfNominateTransaction({ + deposit: daveDepositToCatchBob, + metadata: "" + }) .sign({ secret: validators[dave].privateKey, seq: (await nodes[dave].rpc.chain.getSeq({ @@ -341,12 +336,11 @@ describe("Dynamic Validator M -> M' (Changed the subset, M, M’ = maximum numbe const delegateToCharlie = await nodes[0].rpc.mempool.sendSignedTransaction( { - tx: stake - .createDelegateCCSTransaction( - nodes[0].testFramework, - validators[charlie].address, - charlieDelegationToCatchAlice - ) + tx: nodes[0].testFramework.core + .createDelegateCCSTransaction({ + delegatee: validators[charlie].address, + quantity: charlieDelegationToCatchAlice + }) .sign({ secret: faucetSecret, seq: (await nodes[0].rpc.chain.getSeq({ @@ -375,12 +369,11 @@ describe("Dynamic Validator M -> M' (Changed the subset, M, M’ = maximum numbe const depositDave = await nodes[ dave ].rpc.mempool.sendSignedTransaction({ - tx: stake - .createSelfNominateTransaction( - nodes[dave].testFramework, - daveDepositToCatchAlice, - "" - ) + tx: nodes[dave].testFramework.core + .createSelfNominateTransaction({ + deposit: daveDepositToCatchAlice, + metadata: "" + }) .sign({ secret: validators[dave].privateKey, seq: (await nodes[dave].rpc.chain.getSeq({ diff --git a/test/src/e2e.dynval/1/dv.n'.test.ts b/test/src/e2e.dynval/1/dv.n'.test.ts index 18f80c2ccd..3d918c32d0 100644 --- a/test/src/e2e.dynval/1/dv.n'.test.ts +++ b/test/src/e2e.dynval/1/dv.n'.test.ts @@ -75,12 +75,11 @@ describe("Dynamic Validator N -> N'", function() { alice ]); - const tx = stake - .createDelegateCCSTransaction( - rpcNode.testFramework, - betty.address, - 5_000 - ) + const tx = rpcNode.testFramework.core + .createDelegateCCSTransaction({ + delegatee: betty.address, + quantity: 5_000 + }) .sign({ secret: faucetSecret, seq: (await rpcNode.rpc.chain.getSeq({ @@ -142,12 +141,11 @@ describe("Dynamic Validator N -> N'", function() { ]); const bettyNode = findNode(nodes, betty); - const tx = stake - .createSelfNominateTransaction( - bettyNode.testFramework, - 100000, - "" - ) + const tx = bettyNode.testFramework.core + .createSelfNominateTransaction({ + deposit: 100000, + metadata: "" + }) .sign({ secret: betty.privateKey, seq: (await bettyNode.rpc.chain.getSeq({ @@ -208,23 +206,21 @@ describe("Dynamic Validator N -> N'", function() { const seq = (await rpcNode.rpc.chain.getSeq({ address: faucetAddress.toString() }))!; - const tx = stake - .createDelegateCCSTransaction( - rpcNode.testFramework, - betty.address, - 5_000 - ) + const tx = rpcNode.testFramework.core + .createDelegateCCSTransaction({ + delegatee: betty.address, + quantity: 5_000 + }) .sign({ secret: faucetSecret, seq, fee: 10 }); - const tx2 = stake - .createRevokeTransaction( - rpcNode.testFramework, - alice.address, - 4999 - ) + const tx2 = rpcNode.testFramework.core + .createRevokeTransaction({ + delegatee: alice.address, + quantity: 4999 + }) .sign({ secret: faucetSecret, seq: seq + 1, @@ -285,12 +281,11 @@ describe("Dynamic Validator N -> N'", function() { ]); const bettyNode = findNode(nodes, betty); - const tx = stake - .createSelfNominateTransaction( - bettyNode.testFramework, - 100000, - "" - ) + const tx = bettyNode.testFramework.core + .createSelfNominateTransaction({ + deposit: 100000, + metadata: "" + }) .sign({ secret: betty.privateKey, seq: (await bettyNode.rpc.chain.getSeq({ @@ -299,12 +294,11 @@ describe("Dynamic Validator N -> N'", function() { fee: 10 }); - const tx2 = stake - .createRevokeTransaction( - rpcNode.testFramework, - alice.address, - 4999 - ) + const tx2 = rpcNode.testFramework.core + .createRevokeTransaction({ + delegatee: alice.address, + quantity: 4_999 + }) .sign({ secret: faucetSecret, seq: (await rpcNode.rpc.chain.getSeq({ diff --git a/test/src/e2e.dynval/1/dv.n-1.test.ts b/test/src/e2e.dynval/1/dv.n-1.test.ts index 1a9ab0bb78..412c863b39 100644 --- a/test/src/e2e.dynval/1/dv.n-1.test.ts +++ b/test/src/e2e.dynval/1/dv.n-1.test.ts @@ -120,12 +120,11 @@ describe("Dynamic Validator N -> N-1", function() { address: faucetAddress.toString() }))!; // Revoke all the delegation deposits - const tx = stake - .createRevokeTransaction( - checkingNode.testFramework, - alice.address, - 5_000 - ) + const tx = checkingNode.testFramework.core + .createRevokeTransaction({ + delegatee: alice.address, + quantity: 5_000 + }) .sign({ secret: faucetSecret, seq: faucetSeq, @@ -156,12 +155,11 @@ describe("Dynamic Validator N -> N-1", function() { address: faucetAddress.toString() }))!; // make remaining deposits under threshold. - const tx = stake - .createRevokeTransaction( - checkingNode.testFramework, - alice.address, - 4_500 - ) + const tx = checkingNode.testFramework.core + .createRevokeTransaction({ + delegatee: alice.address, + quantity: 4_500 + }) .sign({ secret: faucetSecret, seq: faucetSeq, diff --git a/test/src/e2e.dynval/1/dv.n.test.ts b/test/src/e2e.dynval/1/dv.n.test.ts index 8912f170d1..76ab1d70af 100644 --- a/test/src/e2e.dynval/1/dv.n.test.ts +++ b/test/src/e2e.dynval/1/dv.n.test.ts @@ -119,12 +119,11 @@ describe("Dynamic Validator N -> N", function() { const insufficientDelegationTx = await nodes[0].rpc.mempool.sendSignedTransaction( { - tx: stake - .createDelegateCCSTransaction( - nodes[0].testFramework, - alice.address, - 50 - ) + tx: nodes[0].testFramework.core + .createDelegateCCSTransaction({ + delegatee: alice.address, + quantity: 50 + }) .sign({ secret: faucetSecret, seq: (await nodes[0].rpc.chain.getSeq({ @@ -190,12 +189,11 @@ describe("Dynamic Validator N -> N", function() { const insufficientDelegationTx = await nodes[0].rpc.mempool.sendSignedTransaction( { - tx: stake - .createDelegateCCSTransaction( - nodes[0].testFramework, - alice.address, - 50 - ) + tx: nodes[0].testFramework.core + .createDelegateCCSTransaction({ + delegatee: alice.address, + quantity: 50 + }) .sign({ secret: faucetSecret, seq: (await nodes[0].rpc.chain.getSeq({ @@ -261,12 +259,11 @@ describe("Dynamic Validator N -> N", function() { const insufficientDelegationTx = await nodes[0].rpc.mempool.sendSignedTransaction( { - tx: stake - .createRevokeTransaction( - nodes[0].testFramework, - alice.address, - 50 - ) + tx: nodes[0].testFramework.core + .createRevokeTransaction({ + delegatee: alice.address, + quantity: 50 + }) .sign({ secret: faucetSecret, seq: (await nodes[0].rpc.chain.getSeq({ @@ -332,12 +329,11 @@ describe("Dynamic Validator N -> N", function() { const insufficientDelegationTx = await nodes[0].rpc.mempool.sendSignedTransaction( { - tx: stake - .createRevokeTransaction( - nodes[0].testFramework, - alice.address, - 50 - ) + tx: nodes[0].testFramework.core + .createRevokeTransaction({ + delegatee: alice.address, + quantity: 50 + }) .sign({ secret: faucetSecret, seq: (await nodes[0].rpc.chain.getSeq({ @@ -429,12 +425,11 @@ describe("Dynamic Validator N -> N", function() { const aliceNode = findNode(nodes, alice); const nominationTx = await aliceNode.rpc.mempool.sendSignedTransaction( { - tx: stake - .createSelfNominateTransaction( - aliceNode.testFramework, + tx: aliceNode.testFramework.core + .createSelfNominateTransaction({ deposit, - "" - ) + metadata: "" + }) .sign({ secret: alice.privateKey, seq: (await aliceNode.rpc.chain.getSeq({ @@ -451,12 +446,11 @@ describe("Dynamic Validator N -> N", function() { if (delegation > 0) { const tx = await nodes[0].rpc.mempool.sendSignedTransaction( { - tx: stake - .createDelegateCCSTransaction( - nodes[0].testFramework, - alice.address, - delegation - ) + tx: nodes[0].testFramework.core + .createDelegateCCSTransaction({ + delegatee: alice.address, + quantity: delegation + }) .sign({ secret: faucetSecret, seq: (await nodes[0].rpc.chain.getSeq({ diff --git a/test/src/e2e.dynval/2/dv.n+1.test.ts b/test/src/e2e.dynval/2/dv.n+1.test.ts index a00e115b72..ff7290e304 100644 --- a/test/src/e2e.dynval/2/dv.n+1.test.ts +++ b/test/src/e2e.dynval/2/dv.n+1.test.ts @@ -90,12 +90,11 @@ describe("Dynamic Validator N -> N+1", function() { const checkingNode = nodes[0]; await beforeInsertionCheck(checkingNode.rpc); const bettyNode = findNode(nodes, betty); - const nominateTx = stake - .createSelfNominateTransaction( - bettyNode.testFramework, - 11_000_000, - "" - ) + const nominateTx = bettyNode.testFramework.core + .createSelfNominateTransaction({ + deposit: 11_000_000, + metadata: "" + }) .sign({ secret: betty.privateKey, seq: (await bettyNode.rpc.chain.getSeq({ @@ -106,12 +105,11 @@ describe("Dynamic Validator N -> N+1", function() { const nominateTxHash = await bettyNode.rpc.mempool.sendSignedTransaction( { tx: nominateTx.rlpBytes().toString("hex") } ); - const delegateTx = stake - .createDelegateCCSTransaction( - bettyNode.testFramework, - betty.address, - 5_000 - ) + const delegateTx = bettyNode.testFramework.core + .createDelegateCCSTransaction({ + delegatee: betty.address, + quantity: 5_000 + }) .sign({ secret: faucetSecret, seq: (await bettyNode.rpc.chain.getSeq({ @@ -155,12 +153,11 @@ describe("Dynamic Validator N -> N+1", function() { const checkingNode = nodes[0]; await beforeInsertionCheck(checkingNode.rpc); - const nominateTx = stake - .createSelfNominateTransaction( - checkingNode.testFramework, - 10_000, - "" - ) + const nominateTx = checkingNode.testFramework.core + .createSelfNominateTransaction({ + deposit: 10_000, + metadata: "" + }) .sign({ secret: betty.privateKey, seq: (await checkingNode.rpc.chain.getSeq({ @@ -204,12 +201,11 @@ describe("Dynamic Validator N -> N+1", function() { const faucetSeq = (await checkingNode.rpc.chain.getSeq({ address: faucetAddress.toString() }))!; - const delegateTx = stake - .createDelegateCCSTransaction( - checkingNode.testFramework, - betty.address, - 2 - ) + const delegateTx = checkingNode.testFramework.core + .createDelegateCCSTransaction({ + delegatee: betty.address, + quantity: 2 + }) .sign({ secret: faucetSecret, seq: faucetSeq, diff --git a/test/src/e2e.dynval/2/jail.test.ts b/test/src/e2e.dynval/2/jail.test.ts index 0d9637e1ee..aeabebe35f 100644 --- a/test/src/e2e.dynval/2/jail.test.ts +++ b/test/src/e2e.dynval/2/jail.test.ts @@ -131,10 +131,11 @@ describe("Jail state transition test", function() { await termWaiter.waitNodeUntilTerm(node, { target: 4, termPeriods: 2 }); - const nomination = await stake.createSelfNominateTransaction( - node.testFramework, - 10_000_000, - "" + const nomination = await node.testFramework.core.createSelfNominateTransaction( + { + deposit: 10_000_000, + metadata: "" + } ); const hash = await node.rpc.mempool.sendSignedTransaction({ tx: nomination @@ -160,10 +161,11 @@ describe("Jail state transition test", function() { }); const node = nodes[0]; - const nomination = await stake.createSelfNominateTransaction( - node.testFramework, - 10_000_000, - "" + const nomination = await node.testFramework.core.createSelfNominateTransaction( + { + deposit: 10_000_000, + metadata: "" + } ); const hash = await node.rpc.mempool.sendSignedTransaction({ tx: nomination diff --git a/test/src/e2e.dynval/2/snapshot.test.ts b/test/src/e2e.dynval/2/snapshot.test.ts index e201ccf51f..28d724adcb 100644 --- a/test/src/e2e.dynval/2/snapshot.test.ts +++ b/test/src/e2e.dynval/2/snapshot.test.ts @@ -193,8 +193,8 @@ async function makeItValidator(node: CodeChain, freshNodeValidator: Signer) { }) ) ); - const selfNominateTx = stake - .createSelfNominateTransaction(node.testFramework, 10000000, "") + const selfNominateTx = node.testFramework.core + .createSelfNominateTransaction({ deposit: 10000000, metadata: "" }) .sign({ secret: freshNodeValidator.privateKey, seq: (await node.rpc.chain.getSeq({ @@ -209,12 +209,11 @@ async function makeItValidator(node: CodeChain, freshNodeValidator: Signer) { }) ) ); - const delegateTx = stake - .createDelegateCCSTransaction( - node.testFramework, - freshNodeValidator.address, - 10000 - ) + const delegateTx = node.testFramework.core + .createDelegateCCSTransaction({ + delegatee: freshNodeValidator.address, + quantity: 10000 + }) .sign({ secret: faucetSecret, seq: faucetSeq + 1, diff --git a/test/src/e2e.dynval/dv.double-vote.test.ts b/test/src/e2e.dynval/dv.double-vote.test.ts index 2783a33841..e4cb1888a2 100644 --- a/test/src/e2e.dynval/dv.double-vote.test.ts +++ b/test/src/e2e.dynval/dv.double-vote.test.ts @@ -27,7 +27,6 @@ import RPC from "foundry-rpc"; import "mocha"; import * as RLP from "rlp"; import { SDK } from "../sdk"; -import { Custom } from "../sdk/core/transaction/Custom"; import * as stake from "../stakeholder"; import { validators as originalValidators } from "../../tendermint.dynval/constants"; @@ -36,6 +35,7 @@ import { PromiseExpect } from "../helper/promise"; import { Signer } from "../helper/spawn"; import CodeChain from "../helper/spawn"; import { findNode, setTermTestTimeout, withNodes } from "./setup"; +import { ReportDoubleVote } from "../sdk/core/transaction/ReportDoubleVote"; const HANDLER_ID = 2; const REPORT_DOUBLE_VOTE_ACTION_ID = 5; @@ -98,17 +98,6 @@ function createDoubleVoteMessages( ]; } -function createReportDoubleVoteTransaction( - sdk: SDK, - message1: RLP.Input, - message2: RLP.Input -): Custom { - return sdk.core.createCustomTransaction({ - handlerId: HANDLER_ID, - bytes: RLP.encode([REPORT_DOUBLE_VOTE_ACTION_ID, message1, message2]) - }); -} - const allDynValidators = originalValidators.slice(0, 4); const [alice, ...otherDynValidators] = allDynValidators; @@ -212,10 +201,11 @@ describe("Report Double Vote", function() { ) ); - const reportTx = createReportDoubleVoteTransaction( - checkingNode.testFramework, - message1, - message2 + const reportTx = checkingNode.testFramework.core.createReportDoubleVoteTransaction( + { + message1, + message2 + } ); const reportTxHash = await checkingNode.rpc.mempool.sendSignedTransaction( { @@ -324,10 +314,11 @@ describe("Report Double Vote", function() { ) ); - const reportTx = createReportDoubleVoteTransaction( - checkingNode.testFramework, - message1, - message2 + const reportTx = checkingNode.testFramework.core.createReportDoubleVoteTransaction( + { + message1, + message2 + } ); const reportTxHash = await checkingNode.rpc.mempool.sendSignedTransaction( { @@ -424,12 +415,11 @@ describe("Report Double Vote", function() { currentTermInitialBlockNumber ); - const revoketx = stake - .createRevokeTransaction( - checkingNode.testFramework, - alice.address, - 4_500 - ) + const revoketx = checkingNode.testFramework.core + .createRevokeTransaction({ + delegatee: alice.address, + quantity: 4_500 + }) .sign({ secret: faucetSecret, seq: (await checkingNode.rpc.chain.getSeq({ @@ -467,10 +457,11 @@ describe("Report Double Vote", function() { ) ); - const reportTx = createReportDoubleVoteTransaction( - checkingNode.testFramework, - message1, - message2 + const reportTx = checkingNode.testFramework.core.createReportDoubleVoteTransaction( + { + message1, + message2 + } ); const reportTxHash = await checkingNode.rpc.mempool.sendSignedTransaction( { diff --git a/test/src/e2e.dynval/setup.ts b/test/src/e2e.dynval/setup.ts index d79e115a0d..f420e6cdb2 100644 --- a/test/src/e2e.dynval/setup.ts +++ b/test/src/e2e.dynval/setup.ts @@ -216,12 +216,11 @@ async function createNodes(options: { if (deposit == null) { continue; } - const tx = stake - .createSelfNominateTransaction( - nodes[i].testFramework, + const tx = nodes[i].testFramework.core + .createSelfNominateTransaction({ deposit, - "" - ) + metadata: "" + }) .sign({ secret: validator.privateKey, seq: (await nodes[i].rpc.chain.getSeq({ @@ -259,12 +258,11 @@ async function createNodes(options: { if (delegation === 0) { continue; } - const tx = stake - .createDelegateCCSTransaction( - initialNodes[0].testFramework, - validator.address, - delegation - ) + const tx = initialNodes[0].testFramework.core + .createDelegateCCSTransaction({ + delegatee: validator.address, + quantity: delegation + }) .sign({ secret: faucetSecret, seq: faucetSeq2 + delegateTxs.length, @@ -326,13 +324,15 @@ export async function selfNominate( validator: ValidatorConfig["signer"], deposit: number ): Promise { - const tx = stake.createSelfNominateTransaction(sdk, deposit, "").sign({ - secret: validator.privateKey, - seq: (await rpc.chain.getSeq({ - address: validator.address.toString() - }))!, - fee: 10 - }); + const tx = sdk.core + .createSelfNominateTransaction({ deposit, metadata: "" }) + .sign({ + secret: validator.privateKey, + seq: (await rpc.chain.getSeq({ + address: validator.address.toString() + }))!, + fee: 10 + }); return new H256( await rpc.mempool.sendSignedTransaction({ @@ -347,8 +347,11 @@ export async function receiveDelegation( validator: ValidatorConfig["signer"], delegation: number ): Promise { - const tx = stake - .createDelegateCCSTransaction(sdk, validator.address, delegation) + const tx = sdk.core + .createDelegateCCSTransaction({ + delegatee: validator.address, + quantity: delegation + }) .sign({ secret: faucetSecret, seq: (await rpc.chain.getSeq({ @@ -407,7 +410,7 @@ interface EraCommonParams { type CommonParams = typeof defaultParams & Partial; -function encodeParams(params: CommonParams): any[] { +function encodeParams(params: CommonParams): (number | string)[] { const result = [ params.maxExtraDataSize, params.networkID, @@ -434,25 +437,27 @@ function encodeParams(params: CommonParams): any[] { export async function changeParams( node: CodeChain, metadataSeq: number, - params: CommonParams + commonParams: CommonParams ) { - const changeParamsActionRlp: [ - number, - number, - (number | string)[], - ...string[] - ] = [0xff, metadataSeq, encodeParams(params)]; + const params = encodeParams(commonParams); + const changeParamsActionRlp: [number, number, (number | string)[]] = [ + 0xff, + metadataSeq, + params + ]; const message = blake256(RLP.encode(changeParamsActionRlp).toString("hex")); - changeParamsActionRlp.push(approvalEncoded(node, message, faucetSecret)); - changeParamsActionRlp.push(approvalEncoded(node, message, aliceSecret)); - changeParamsActionRlp.push(approvalEncoded(node, message, bobSecret)); + const approvals = []; + approvals.push(approvalEncoded(node, message, faucetSecret)); + approvals.push(approvalEncoded(node, message, aliceSecret)); + approvals.push(approvalEncoded(node, message, bobSecret)); return new H256( await node.rpc.mempool.sendSignedTransaction({ tx: node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParamsActionRlp) + .createChangeParamsTransaction({ + metadataSeq, + params, + approvals }) .sign({ secret: faucetSecret, diff --git a/test/src/e2e.long/staking.test.ts b/test/src/e2e.long/staking.test.ts index 51ce86e1f6..d4e02461f1 100644 --- a/test/src/e2e.long/staking.test.ts +++ b/test/src/e2e.long/staking.test.ts @@ -198,15 +198,9 @@ describe("Staking", function() { : params.seq; const tx = nodes[0].testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: Buffer.from( - RLP.encode([ - 1, - params.receiverAddress.accountId.toEncodeObject(), - params.quantity - ]) - ) + .createTransferCCSTransaction({ + recipient: params.receiverAddress, + quantity: params.quantity }) .sign({ secret: params.senderSecret, @@ -237,15 +231,9 @@ describe("Staking", function() { : params.seq; const tx = nodes[0].testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: Buffer.from( - RLP.encode([ - 2, - params.receiverAddress.accountId.toEncodeObject(), - params.quantity - ]) - ) + .createDelegateCCSTransaction({ + delegatee: params.receiverAddress, + quantity: params.quantity }) .sign({ secret: params.senderSecret, @@ -276,15 +264,9 @@ describe("Staking", function() { : params.seq; const tx = nodes[0].testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: Buffer.from( - RLP.encode([ - 3, - params.delegateeAddress.accountId.toEncodeObject(), - params.quantity - ]) - ) + .createRevokeTransaction({ + delegatee: params.delegateeAddress, + quantity: params.quantity }) .sign({ secret: params.senderSecret, @@ -316,9 +298,9 @@ describe("Staking", function() { : params.seq; const tx = nodes[0].testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: Buffer.from(RLP.encode([4, deposit, metadata])) + .createSelfNominateTransaction({ + deposit, + metadata: metadata || Buffer.from([]) }) .sign({ secret: params.senderSecret, diff --git a/test/src/e2e/changeParams.test.ts b/test/src/e2e/changeParams.test.ts index 8d5bba3483..745acca8c3 100644 --- a/test/src/e2e/changeParams.test.ts +++ b/test/src/e2e/changeParams.test.ts @@ -68,7 +68,7 @@ describe("ChangeParams", function() { }); it("change", async function() { - const newParams = [ + const params = [ 0x30, // maxExtraDataSize "tc", // networkID 4194304, // maxBodySize @@ -84,20 +84,22 @@ describe("ChangeParams", function() { 500, // maxCandidateMetadataSize 0 // era ]; - const changeParams: (number | string | (number | string)[])[] = [ + const changeParams: [number, number, (number | string)[]] = [ 0xff, 0, - newParams + params ]; const message = blake256(RLP.encode(changeParams).toString("hex")); - changeParams.push(approvalEncoded(message, aliceSecret)); - changeParams.push(approvalEncoded(message, carolSecret)); + const approvals = []; + approvals.push(approvalEncoded(message, aliceSecret)); + approvals.push(approvalEncoded(message, carolSecret)); { const tx = node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParams) + .createChangeParamsTransaction({ + metadataSeq: 0, + params, + approvals }) .sign({ secret: faucetSecret, @@ -117,12 +119,12 @@ describe("ChangeParams", function() { }) ).be.true; } - const params = await node.rpc.chain.getCommonParams({}); - expect(+params!.maxExtraDataSize!).to.be.deep.equal(0x30); + const commonParams = await node.rpc.chain.getCommonParams({}); + expect(+commonParams!.maxExtraDataSize!).to.be.deep.equal(0x30); }); it("cannot change the network id", async function() { - const newParams = [ + const params = [ 0x20, // maxExtraDataSize "cc", // networkID 4194304, // maxBodySize @@ -138,19 +140,21 @@ describe("ChangeParams", function() { 500, // maxCandidateMetadataSize 0 // era ]; - const changeParams: (number | string | (number | string)[])[] = [ + const changeParams: [number, number, (number | string)[]] = [ 0xff, 0, - newParams + params ]; const message = blake256(RLP.encode(changeParams).toString("hex")); - changeParams.push(approvalEncoded(message, aliceSecret)); - changeParams.push(approvalEncoded(message, carolSecret)); + const approvals = []; + approvals.push(approvalEncoded(message, aliceSecret)); + approvals.push(approvalEncoded(message, carolSecret)); const tx = node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParams) + .createChangeParamsTransaction({ + metadataSeq: 0, + params, + approvals }) .sign({ secret: faucetSecret, @@ -177,7 +181,7 @@ describe("ChangeParams", function() { }); it("the parameter is applied from the next block", async function() { - const newParams = [ + const params = [ 0x44, // maxExtraDataSize "tc", // networkID 4194304, // maxBodySize @@ -193,15 +197,16 @@ describe("ChangeParams", function() { 500, // maxCandidateMetadataSize 0 // era ]; - const changeParams: (number | string | (number | string)[])[] = [ + const changeParams: [number, number, (number | string)[]] = [ 0xff, 0, - newParams + params ]; const message = blake256(RLP.encode(changeParams).toString("hex")); - changeParams.push(approvalEncoded(message, aliceSecret)); - changeParams.push(approvalEncoded(message, bobSecret)); - changeParams.push(approvalEncoded(message, carolSecret)); + const approvals = []; + approvals.push(approvalEncoded(message, aliceSecret)); + approvals.push(approvalEncoded(message, bobSecret)); + approvals.push(approvalEncoded(message, carolSecret)); { await node.rpc.devel!.stopSealing(); @@ -211,9 +216,10 @@ describe("ChangeParams", function() { blockNumber: null }))!; const tx = node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParams) + .createChangeParamsTransaction({ + metadataSeq: 0, + params, + approvals }) .sign({ secret: faucetSecret, @@ -240,12 +246,12 @@ describe("ChangeParams", function() { blockNumber + 1 ); } - const params = await node.rpc.chain.getCommonParams({}); - expect(+params!.maxExtraDataSize!).to.be.deep.equal(0x44); + const commonParams = await node.rpc.chain.getCommonParams({}); + expect(+commonParams!.maxExtraDataSize!).to.be.deep.equal(0x44); }); it("the parameter changed twice in the same block", async function() { - const newParams1 = [ + const params1 = [ 0x30, // maxExtraDataSize "tc", // networkID 4194304, // maxBodySize @@ -261,7 +267,7 @@ describe("ChangeParams", function() { 500, // maxCandidateMetadataSize 0 // era ]; - const newParams2 = [ + const params2 = [ 0x40, // maxExtraDataSize "tc", // networkID 4194304, // maxBodySize @@ -277,24 +283,26 @@ describe("ChangeParams", function() { 500, // maxCandidateMetadataSize 0 // era ]; - const changeParams1: (number | string | (number | string)[])[] = [ + const changeParams1: [number, number, (number | string)[]] = [ 0xff, 0, - newParams1 + params1 ]; - const changeParams2: (number | string | (number | string)[])[] = [ + const changeParams2: [number, number, (number | string)[]] = [ 0xff, 1, - newParams2 + params2 ]; const message1 = blake256(RLP.encode(changeParams1).toString("hex")); - changeParams1.push(approvalEncoded(message1, aliceSecret)); - changeParams1.push(approvalEncoded(message1, bobSecret)); - changeParams1.push(approvalEncoded(message1, carolSecret)); + const approvals1 = []; + approvals1.push(approvalEncoded(message1, aliceSecret)); + approvals1.push(approvalEncoded(message1, bobSecret)); + approvals1.push(approvalEncoded(message1, carolSecret)); const message2 = blake256(RLP.encode(changeParams2).toString("hex")); - changeParams2.push(approvalEncoded(message2, aliceSecret)); - changeParams2.push(approvalEncoded(message2, bobSecret)); - changeParams2.push(approvalEncoded(message2, carolSecret)); + const approvals2 = []; + approvals2.push(approvalEncoded(message2, aliceSecret)); + approvals2.push(approvalEncoded(message2, bobSecret)); + approvals2.push(approvalEncoded(message2, carolSecret)); { await node.rpc.devel!.stopSealing(); @@ -305,9 +313,10 @@ describe("ChangeParams", function() { }))!; const tx = node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParams1) + .createChangeParamsTransaction({ + metadataSeq: 0, + params: params1, + approvals: approvals1 }) .sign({ secret: faucetSecret, @@ -319,9 +328,10 @@ describe("ChangeParams", function() { tx: `0x${trans}` }); const tx2 = node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParams2) + .createChangeParamsTransaction({ + metadataSeq: 1, + params: params2, + approvals: approvals2 }) .sign({ secret: faucetSecret, @@ -354,12 +364,12 @@ describe("ChangeParams", function() { transactionHash: `0x${pay.hash().toString()}` }) ).be.true; - const params = await node.rpc.chain.getCommonParams({}); - expect(+params!.maxExtraDataSize!).to.be.deep.equal(0x40); + const commonParams = await node.rpc.chain.getCommonParams({}); + expect(+commonParams!.maxExtraDataSize!).to.be.deep.equal(0x40); }); it("cannot reuse the same signature", async function() { - const newParams1 = [ + const params1 = [ 0x30, // maxExtraDataSize "tc", // networkID 4194304, // maxBodySize @@ -375,7 +385,7 @@ describe("ChangeParams", function() { 500, // maxCandidateMetadataSize 0 // era ]; - const newParams2 = [ + const params2 = [ 0x40, // maxExtraDataSize "tc", // networkID 4194304, // maxBodySize @@ -391,24 +401,26 @@ describe("ChangeParams", function() { 500, // maxCandidateMetadataSize 0 // era ]; - const changeParams1: (number | string | (number | string)[])[] = [ + const changeParams1: [number, number, (number | string)[]] = [ 0xff, 0, - newParams1 + params1 ]; - const changeParams2: (number | string | (number | string)[])[] = [ + const changeParams2: [number, number, (number | string)[]] = [ 0xff, 1, - newParams2 + params2 ]; const message1 = blake256(RLP.encode(changeParams1).toString("hex")); - changeParams1.push(approvalEncoded(message1, aliceSecret)); - changeParams1.push(approvalEncoded(message1, bobSecret)); - changeParams1.push(approvalEncoded(message1, carolSecret)); + const approvals1 = []; + approvals1.push(approvalEncoded(message1, aliceSecret)); + approvals1.push(approvalEncoded(message1, bobSecret)); + approvals1.push(approvalEncoded(message1, carolSecret)); const message2 = blake256(RLP.encode(changeParams2).toString("hex")); - changeParams2.push(approvalEncoded(message2, aliceSecret)); - changeParams2.push(approvalEncoded(message2, bobSecret)); - changeParams2.push(approvalEncoded(message2, carolSecret)); + const approvals2 = []; + approvals2.push(approvalEncoded(message2, aliceSecret)); + approvals2.push(approvalEncoded(message2, bobSecret)); + approvals2.push(approvalEncoded(message2, carolSecret)); { await node.rpc.devel!.stopSealing(); @@ -418,9 +430,10 @@ describe("ChangeParams", function() { blockNumber: null }))!; const tx1 = node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParams1) + .createChangeParamsTransaction({ + metadataSeq: 0, + approvals: approvals1, + params: params1 }) .sign({ secret: faucetSecret, @@ -433,9 +446,10 @@ describe("ChangeParams", function() { tx: `0x${trans1}` }); const tx2 = node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParams2) + .createChangeParamsTransaction({ + metadataSeq: 1, + approvals: approvals2, + params: params2 }) .sign({ secret: faucetSecret, @@ -462,12 +476,12 @@ describe("ChangeParams", function() { ); } - const params = await node.rpc.chain.getCommonParams({}); - expect(+params!.maxExtraDataSize!).to.be.deep.equal(0x40); + const commonParams = await node.rpc.chain.getCommonParams({}); + expect(+commonParams!.maxExtraDataSize!).to.be.deep.equal(0x40); }); it("cannot change params with insufficient stakes", async function() { - const newParams = [ + const params = [ 0x30, // maxExtraDataSize "tc", // networkID 4194304, // maxBodySize @@ -483,20 +497,22 @@ describe("ChangeParams", function() { 500, // maxCandidateMetadataSize 0 // era ]; - const changeParams: (number | string | (number | string)[])[] = [ + const changeParams: [number, number, (number | string)[]] = [ 0xff, 0, - newParams + params ]; const message = blake256(RLP.encode(changeParams).toString("hex")); - changeParams.push(approvalEncoded(message, aliceSecret)); - changeParams.push(approvalEncoded(message, carolSecret)); + const approvals = []; + approvals.push(approvalEncoded(message, aliceSecret)); + approvals.push(approvalEncoded(message, carolSecret)); { const tx = node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParams) + .createChangeParamsTransaction({ + metadataSeq: 0, + approvals, + params }) .sign({ secret: faucetSecret, @@ -519,9 +535,10 @@ describe("ChangeParams", function() { { const tx2 = node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParams) + .createChangeParamsTransaction({ + metadataSeq: 0, + approvals, + params }) .sign({ secret: faucetSecret, @@ -539,7 +556,7 @@ describe("ChangeParams", function() { }); it("the amount of stakes not the number of stakeholders", async function() { - const newParams = [ + const params = [ 0x30, // maxExtraDataSize "tc", // networkID 4194304, // maxBodySize @@ -555,19 +572,21 @@ describe("ChangeParams", function() { 500, // maxCandidateMetadataSize 0 // era ]; - const changeParams: (number | string | (number | string)[])[] = [ + const changeParams: [number, number, (number | string)[]] = [ 0xff, 0, - newParams + params ]; const message = blake256(RLP.encode(changeParams).toString("hex")); - changeParams.push(approvalEncoded(message, bobSecret)); - changeParams.push(approvalEncoded(message, carolSecret)); + const approvals = []; + approvals.push(approvalEncoded(message, bobSecret)); + approvals.push(approvalEncoded(message, carolSecret)); const tx = node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParams) + .createChangeParamsTransaction({ + metadataSeq: 0, + approvals, + params }) .sign({ secret: faucetSecret, @@ -584,7 +603,7 @@ describe("ChangeParams", function() { }); it("needs more than half to change params", async function() { - const newParams = [ + const params = [ 0x30, // maxExtraDataSize "tc", // networkID 4194304, // maxBodySize @@ -601,20 +620,22 @@ describe("ChangeParams", function() { 0 // era ]; - const changeParams: (number | string | (number | string)[])[] = [ + const changeParams: [number, number, (number | string)[]] = [ 0xff, 0, - newParams + params ]; - { - const message = blake256(RLP.encode(changeParams).toString("hex")); - changeParams.push(approvalEncoded(message, bobSecret)); - changeParams.push(approvalEncoded(message, carolSecret)); + const message = blake256(RLP.encode(changeParams).toString("hex")); + const approvals = []; + approvals.push(approvalEncoded(message, bobSecret)); + approvals.push(approvalEncoded(message, carolSecret)); + { const tx = node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParams) + .createChangeParamsTransaction({ + metadataSeq: 0, + approvals, + params }) .sign({ secret: faucetSecret, @@ -641,9 +662,10 @@ describe("ChangeParams", function() { { const tx = node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParams) + .createChangeParamsTransaction({ + metadataSeq: 0, + approvals, + params }) .sign({ secret: faucetSecret, @@ -666,13 +688,13 @@ describe("ChangeParams", function() { await node.rpc.chain.getTransaction({ transactionHash: hash }) ).not.be.null; } - const params = await node.rpc.chain.getCommonParams({}); - expect(+params!.maxExtraDataSize!).to.be.deep.equal(0x30); + const commonParams = await node.rpc.chain.getCommonParams({}); + expect(+commonParams!.maxExtraDataSize!).to.be.deep.equal(0x30); }); describe("with stake parameters", async function() { it("change", async function() { - const newParams = [ + const params = [ 0x30, // maxExtraDataSize "tc", // networkID 4194304, // maxBodySize @@ -688,20 +710,22 @@ describe("ChangeParams", function() { 500, // maxCandidateMetadataSize 0 // era ]; - const changeParams: (number | string | (number | string)[])[] = [ + const changeParams: [number, number, (number | string)[]] = [ 0xff, 0, - newParams + params ]; const message = blake256(RLP.encode(changeParams).toString("hex")); - changeParams.push(approvalEncoded(message, aliceSecret)); - changeParams.push(approvalEncoded(message, carolSecret)); + const approvals = []; + approvals.push(approvalEncoded(message, aliceSecret)); + approvals.push(approvalEncoded(message, carolSecret)); { const tx = node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParams) + .createChangeParamsTransaction({ + metadataSeq: 0, + params, + approvals }) .sign({ secret: faucetSecret, @@ -722,12 +746,12 @@ describe("ChangeParams", function() { ).be.true; } - const params = await node.rpc.chain.getCommonParams({}); - expect(+params!.maxExtraDataSize!).to.be.deep.equal(0x30); + const commonParams = await node.rpc.chain.getCommonParams({}); + expect(+commonParams!.maxExtraDataSize!).to.be.deep.equal(0x30); }); it("nomination expiration cannot be zero", async function() { - const newParams = [ + const params = [ 0x20, // maxExtraDataSize "tc", // networkID 4194304, // maxBodySize @@ -743,19 +767,21 @@ describe("ChangeParams", function() { 128, // maxCandidateMetadataSize 0 // era ]; - const changeParams: (number | string | (number | string)[])[] = [ + const changeParams: [number, number, (number | string)[]] = [ 0xff, 0, - newParams + params ]; const message = blake256(RLP.encode(changeParams).toString("hex")); - changeParams.push(approvalEncoded(message, aliceSecret)); - changeParams.push(approvalEncoded(message, carolSecret)); + const approvals = []; + approvals.push(approvalEncoded(message, aliceSecret)); + approvals.push(approvalEncoded(message, carolSecret)); const tx = node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParams) + .createChangeParamsTransaction({ + metadataSeq: 0, + approvals, + params }) .sign({ secret: faucetSecret, @@ -777,7 +803,7 @@ describe("ChangeParams", function() { }); it("custody period cannot be zero", async function() { - const newParams = [ + const params = [ 0x20, // maxExtraDataSize "tc", // networkID 4194304, // maxBodySize @@ -793,19 +819,21 @@ describe("ChangeParams", function() { 128, // maxCandidateMetadataSize 0 // era ]; - const changeParams: (number | string | (number | string)[])[] = [ + const changeParams: [number, number, (number | string)[]] = [ 0xff, 0, - newParams + params ]; const message = blake256(RLP.encode(changeParams).toString("hex")); - changeParams.push(approvalEncoded(message, aliceSecret)); - changeParams.push(approvalEncoded(message, carolSecret)); + const approvals = []; + approvals.push(approvalEncoded(message, aliceSecret)); + approvals.push(approvalEncoded(message, carolSecret)); const tx = node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParams) + .createChangeParamsTransaction({ + metadataSeq: 0, + approvals, + params }) .sign({ secret: faucetSecret, @@ -827,7 +855,7 @@ describe("ChangeParams", function() { }); it("release period cannot be zero", async function() { - const newParams = [ + const params = [ 0x20, // maxExtraDataSize "tc", // networkID 4194304, // maxBodySize @@ -843,19 +871,21 @@ describe("ChangeParams", function() { 128, // maxCandidateMetadataSize 0 // era ]; - const changeParams: (number | string | (number | string)[])[] = [ + const changeParams: [number, number, (number | string)[]] = [ 0xff, 0, - newParams + params ]; const message = blake256(RLP.encode(changeParams).toString("hex")); - changeParams.push(approvalEncoded(message, aliceSecret)); - changeParams.push(approvalEncoded(message, carolSecret)); + const approvals = []; + approvals.push(approvalEncoded(message, aliceSecret)); + approvals.push(approvalEncoded(message, carolSecret)); const tx = node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParams) + .createChangeParamsTransaction({ + metadataSeq: 0, + approvals, + params }) .sign({ secret: faucetSecret, @@ -877,7 +907,7 @@ describe("ChangeParams", function() { }); it("A release period cannot be equal to a custody period", async function() { - const newParams = [ + const params = [ 0x20, // maxExtraDataSize "tc", // networkID 4194304, // maxBodySize @@ -893,19 +923,21 @@ describe("ChangeParams", function() { 128, // maxCandidateMetadataSize 0 // era ]; - const changeParams: (number | string | (number | string)[])[] = [ + const changeParams: [number, number, (number | string)[]] = [ 0xff, 0, - newParams + params ]; const message = blake256(RLP.encode(changeParams).toString("hex")); - changeParams.push(approvalEncoded(message, aliceSecret)); - changeParams.push(approvalEncoded(message, carolSecret)); + const approvals = []; + approvals.push(approvalEncoded(message, aliceSecret)); + approvals.push(approvalEncoded(message, carolSecret)); const tx = node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParams) + .createChangeParamsTransaction({ + metadataSeq: 0, + approvals, + params }) .sign({ secret: faucetSecret, @@ -927,7 +959,7 @@ describe("ChangeParams", function() { }); it("min deposit cannot be zero", async function() { - const newParams = [ + const params = [ 0x20, // maxExtraDataSize "tc", // networkID 4194304, // maxBodySize @@ -943,19 +975,21 @@ describe("ChangeParams", function() { 128, // maxCandidateMetadataSize 0 // era ]; - const changeParams: (number | string | (number | string)[])[] = [ + const changeParams: [number, number, (number | string)[]] = [ 0xff, 0, - newParams + params ]; const message = blake256(RLP.encode(changeParams).toString("hex")); - changeParams.push(approvalEncoded(message, aliceSecret)); - changeParams.push(approvalEncoded(message, carolSecret)); + const approvals = []; + approvals.push(approvalEncoded(message, aliceSecret)); + approvals.push(approvalEncoded(message, carolSecret)); const tx = node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParams) + .createChangeParamsTransaction({ + metadataSeq: 0, + approvals, + params }) .sign({ secret: faucetSecret, @@ -977,7 +1011,7 @@ describe("ChangeParams", function() { }); it("delegation threshold cannot be zero", async function() { - const newParams = [ + const params = [ 0x20, // maxExtraDataSize "tc", // networkID 4194304, // maxBodySize @@ -993,19 +1027,21 @@ describe("ChangeParams", function() { 100, // maxCandidateMetadataSize 0 // era ]; - const changeParams: (number | string | (number | string)[])[] = [ + const changeParams: [number, number, (number | string)[]] = [ 0xff, 0, - newParams + params ]; const message = blake256(RLP.encode(changeParams).toString("hex")); - changeParams.push(approvalEncoded(message, aliceSecret)); - changeParams.push(approvalEncoded(message, carolSecret)); + const approvals = []; + approvals.push(approvalEncoded(message, aliceSecret)); + approvals.push(approvalEncoded(message, carolSecret)); const tx = node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParams) + .createChangeParamsTransaction({ + metadataSeq: 0, + approvals, + params }) .sign({ secret: faucetSecret, @@ -1027,7 +1063,7 @@ describe("ChangeParams", function() { }); it("min number of validators cannot be zero", async function() { - const newParams = [ + const params = [ 0x20, // maxExtraDataSize "tc", // networkID 4194304, // maxBodySize @@ -1043,19 +1079,21 @@ describe("ChangeParams", function() { 100, // maxCandidateMetadataSize 0 // era ]; - const changeParams: (number | string | (number | string)[])[] = [ + const changeParams: [number, number, (number | string)[]] = [ 0xff, 0, - newParams + params ]; const message = blake256(RLP.encode(changeParams).toString("hex")); - changeParams.push(approvalEncoded(message, aliceSecret)); - changeParams.push(approvalEncoded(message, carolSecret)); + const approvals = []; + approvals.push(approvalEncoded(message, aliceSecret)); + approvals.push(approvalEncoded(message, carolSecret)); const tx = node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParams) + .createChangeParamsTransaction({ + metadataSeq: 0, + approvals, + params }) .sign({ secret: faucetSecret, @@ -1077,7 +1115,7 @@ describe("ChangeParams", function() { }); it("max number of validators cannot be zero", async function() { - const newParams = [ + const params = [ 0x20, // maxExtraDataSize "tc", // networkID 4194304, // maxBodySize @@ -1093,19 +1131,21 @@ describe("ChangeParams", function() { 100, // maxCandidateMetadataSize 0 // era ]; - const changeParams: (number | string | (number | string)[])[] = [ + const changeParams: [number, number, (number | string)[]] = [ 0xff, 0, - newParams + params ]; const message = blake256(RLP.encode(changeParams).toString("hex")); - changeParams.push(approvalEncoded(message, aliceSecret)); - changeParams.push(approvalEncoded(message, carolSecret)); + const approvals = []; + approvals.push(approvalEncoded(message, aliceSecret)); + approvals.push(approvalEncoded(message, carolSecret)); const tx = node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParams) + .createChangeParamsTransaction({ + metadataSeq: 0, + approvals, + params }) .sign({ secret: faucetSecret, @@ -1127,7 +1167,7 @@ describe("ChangeParams", function() { }); it("The maximum number of candidates cannot be equal to the minimum number of candidates", async function() { - const newParams = [ + const params = [ 0x20, // maxExtraDataSize "tc", // networkID 4194304, // maxBodySize @@ -1143,19 +1183,21 @@ describe("ChangeParams", function() { 128, // maxCandidateMetadataSize 0 // era ]; - const changeParams: (number | string | (number | string)[])[] = [ + const changeParams: [number, number, (number | string)[]] = [ 0xff, 0, - newParams + params ]; const message = blake256(RLP.encode(changeParams).toString("hex")); - changeParams.push(approvalEncoded(message, aliceSecret)); - changeParams.push(approvalEncoded(message, carolSecret)); + const approvals = []; + approvals.push(approvalEncoded(message, aliceSecret)); + approvals.push(approvalEncoded(message, carolSecret)); const tx = node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParams) + .createChangeParamsTransaction({ + metadataSeq: 0, + approvals, + params }) .sign({ secret: faucetSecret, @@ -1208,15 +1250,9 @@ async function sendStakeToken(params: { }))! } = params; const tx = node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: Buffer.from( - RLP.encode([ - 1, - receiverAddress.accountId.toEncodeObject(), - quantity - ]) - ) + .createTransferCCSTransaction({ + recipient: receiverAddress, + quantity }) .sign({ secret: senderSecret, diff --git a/test/src/e2e/staking.test.ts b/test/src/e2e/staking.test.ts index f5e295eeec..917d1d7236 100644 --- a/test/src/e2e/staking.test.ts +++ b/test/src/e2e/staking.test.ts @@ -146,15 +146,9 @@ describe("Staking", function() { "sendSignTransaction", node.rpc.mempool.sendSignedTransaction({ tx: node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: Buffer.from( - RLP.encode([ - 1, - params.receiverAddress.accountId.toEncodeObject(), - params.quantity - ]) - ) + .createTransferCCSTransaction({ + recipient: params.receiverAddress, + quantity: params.quantity }) .sign({ secret: params.senderSecret, @@ -188,15 +182,9 @@ describe("Staking", function() { "sendSignTransaction", node.rpc.mempool.sendSignedTransaction({ tx: node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: Buffer.from( - RLP.encode([ - 2, - params.receiverAddress.accountId.toEncodeObject(), - params.quantity - ]) - ) + .createDelegateCCSTransaction({ + delegatee: params.receiverAddress, + quantity: params.quantity }) .sign({ secret: params.senderSecret, @@ -230,15 +218,9 @@ describe("Staking", function() { "sendSignTransaction", node.rpc.mempool.sendSignedTransaction({ tx: node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: Buffer.from( - RLP.encode([ - 3, - params.delegateeAddress.accountId.toEncodeObject(), - params.quantity - ]) - ) + .createRevokeTransaction({ + delegatee: params.delegateeAddress, + quantity: params.quantity }) .sign({ secret: params.senderSecret, @@ -272,9 +254,9 @@ describe("Staking", function() { "sendSignTransaction", node.rpc.mempool.sendSignedTransaction({ tx: node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: Buffer.from(RLP.encode([4, deposit, metadata])) + .createSelfNominateTransaction({ + deposit, + metadata: metadata || Buffer.from([]) }) .sign({ secret: params.senderSecret, diff --git a/test/src/e2e/termChange.test.ts b/test/src/e2e/termChange.test.ts index 903fc00e24..3733746394 100644 --- a/test/src/e2e/termChange.test.ts +++ b/test/src/e2e/termChange.test.ts @@ -61,7 +61,7 @@ describe("Term change", function() { }); async function changeTermSeconds(metadataSeq: number, termSeconds: number) { - const newParams = [ + const params = [ 0x20, // maxExtraDataSize "tc", // networkID 4194304, // maxBodySize @@ -77,21 +77,23 @@ describe("Term change", function() { 128, // maxCandidateMetadataSize 0 // era ]; - const changeParams: (number | string | (number | string)[])[] = [ + const changeParams: [number, number, (number | string)[]] = [ 0xff, metadataSeq, - newParams + params ]; const message = blake256(RLP.encode(changeParams).toString("hex")); - changeParams.push(approvalEncoded(message, aliceSecret)); - changeParams.push(approvalEncoded(message, carolSecret)); + const approvals = []; + approvals.push(approvalEncoded(message, aliceSecret)); + approvals.push(approvalEncoded(message, carolSecret)); { const hash = await node.rpc.mempool.sendSignedTransaction({ tx: node.testFramework.core - .createCustomTransaction({ - handlerId: stakeActionHandlerId, - bytes: RLP.encode(changeParams) + .createChangeParamsTransaction({ + metadataSeq, + params, + approvals }) .sign({ secret: faucetSecret, diff --git a/test/src/sdk/core/Transaction.ts b/test/src/sdk/core/Transaction.ts index 910910c9f2..f217ba85da 100644 --- a/test/src/sdk/core/Transaction.ts +++ b/test/src/sdk/core/Transaction.ts @@ -3,13 +3,19 @@ import { H256, H512, H512Value, U64, U64Value } from "foundry-primitives"; import * as RLP from "rlp"; import { blake256, getPublicFromPrivate, signEd25519 } from "../utils"; import { SignedTransaction } from "./SignedTransaction"; +import { ChangeParamsActionJSON } from "./transaction/ChangeParams"; import { CreateShardActionJSON } from "./transaction/CreateShard"; -import { CustomActionJSON } from "./transaction/Custom"; +import { DelegateCCSActionJSON } from "./transaction/DelegateCCS"; import { PayActionJSON } from "./transaction/Pay"; +import { RedelegateActionJSON } from "./transaction/Redelegate"; import { RemoveActionJSON } from "./transaction/Remove"; +import { ReportDoubleVoteActionJSON } from "./transaction/ReportDoubleVote"; +import { RevokeActionJSON } from "./transaction/Revoke"; +import { SelfNominateActionJSON } from "./transaction/SelfNominate"; import { SetShardOwnersActionJSON } from "./transaction/SetShardOwners"; import { SetShardUsersActionJSON } from "./transaction/SetShardUsers"; import { StoreActionJSON } from "./transaction/Store"; +import { TransferCCSActionJSON } from "./transaction/TransferCCS"; import { NetworkId } from "./types"; type ActionJSON = @@ -19,7 +25,13 @@ type ActionJSON = | CreateShardActionJSON | StoreActionJSON | RemoveActionJSON - | CustomActionJSON; + | TransferCCSActionJSON + | DelegateCCSActionJSON + | RevokeActionJSON + | RedelegateActionJSON + | SelfNominateActionJSON + | ReportDoubleVoteActionJSON + | ChangeParamsActionJSON; export interface TransactionJSON { action: ActionJSON & { type: string }; diff --git a/test/src/sdk/core/index.ts b/test/src/sdk/core/index.ts index 9320ab950d..f1c2efac1a 100644 --- a/test/src/sdk/core/index.ts +++ b/test/src/sdk/core/index.ts @@ -15,13 +15,19 @@ import { Block } from "./Block"; import { Script } from "./Script"; import { SignedTransaction } from "./SignedTransaction"; import { Transaction } from "./Transaction"; +import { ChangeParams } from "./transaction/ChangeParams"; import { CreateShard } from "./transaction/CreateShard"; -import { Custom } from "./transaction/Custom"; +import { DelegateCCS } from "./transaction/DelegateCCS"; import { Pay } from "./transaction/Pay"; +import { Redelegate } from "./transaction/Redelegate"; import { Remove } from "./transaction/Remove"; +import { ReportDoubleVote } from "./transaction/ReportDoubleVote"; +import { Revoke } from "./transaction/Revoke"; +import { SelfNominate } from "./transaction/SelfNominate"; import { SetShardOwners } from "./transaction/SetShardOwners"; import { SetShardUsers } from "./transaction/SetShardUsers"; import { Store } from "./transaction/Store"; +import { TransferCCS } from "./transaction/TransferCCS"; import { NetworkId } from "./types"; export class Core { @@ -45,7 +51,12 @@ export class Core { SetShardUsers, Store, Remove, - Custom, + DelegateCCS, + TransferCCS, + Revoke, + Redelegate, + SelfNominate, + ReportDoubleVote, // Script Script, Address @@ -216,24 +227,100 @@ export class Core { return new Remove(removeParam, this.networkId); } - /** - * Creates Custom type that will be handled by a specified type handler - * @param params.handlerId An Id of an type handler which will handle a custom transaction - * @param params.bytes A custom transaction body - * @throws Given number for handlerId is invalid for converting it to U64 - */ - public createCustomTransaction(params: { - handlerId: number; - bytes: Buffer; - }): Custom { - const { handlerId, bytes } = params; - checkHandlerId(handlerId); - checkBytes(bytes); - const customParam = { - handlerId: U64.ensure(handlerId), - bytes - }; - return new Custom(customParam, this.networkId); + public createDelegateCCSTransaction(params: { + delegatee: AddressValue; + quantity: U64Value; + }): DelegateCCS { + const { delegatee, quantity } = params; + checkAddressRecipient(delegatee); + checkAmount(quantity); + return new DelegateCCS( + Address.ensure(delegatee), + U64.ensure(quantity), + this.networkId + ); + } + + public createTransferCCSTransaction(params: { + recipient: AddressValue; + quantity: U64Value; + }): TransferCCS { + const { recipient, quantity } = params; + checkAddressRecipient(recipient); + checkAmount(quantity); + return new TransferCCS( + Address.ensure(recipient), + U64.ensure(quantity), + this.networkId + ); + } + + public createRevokeTransaction(params: { + delegatee: AddressValue; + quantity: U64Value; + }): Revoke { + const { delegatee, quantity } = params; + checkAddressRecipient(delegatee); + checkAmount(quantity); + return new Revoke( + Address.ensure(delegatee), + U64.ensure(quantity), + this.networkId + ); + } + + public createRedelegateTransaction(params: { + prevDelegator: AddressValue; + nextDelegator: AddressValue; + quantity: U64Value; + }): Redelegate { + const { prevDelegator, nextDelegator, quantity } = params; + checkAddressRecipient(prevDelegator); + checkAddressRecipient(nextDelegator); + checkAmount(quantity); + return new Redelegate( + Address.ensure(prevDelegator), + Address.ensure(nextDelegator), + U64.ensure(quantity), + this.networkId + ); + } + + public createSelfNominateTransaction(params: { + deposit: U64Value; + metadata: Buffer | string; + }): SelfNominate { + const { deposit } = params; + const metadata = Buffer.from(params.metadata); + checkAmount(deposit); + checkBytes(metadata); + return new SelfNominate(U64.ensure(deposit), metadata, this.networkId); + } + + public createReportDoubleVoteTransaction(params: { + message1: Buffer | string; + message2: Buffer | string; + }): ReportDoubleVote { + const message1 = Buffer.from(params.message1); + const message2 = Buffer.from(params.message2); + checkBytes(message1); + checkBytes(message2); + return new ReportDoubleVote(message1, message2, this.networkId); + } + + public createChangeParamsTransaction(args: { + metadataSeq: U64Value; + params: (number | string)[]; + approvals: any[]; + }): ChangeParams { + const { metadataSeq, params, approvals } = args; + checkAmount(metadataSeq); + return new ChangeParams( + U64.ensure(metadataSeq), + params, + approvals, + this.networkId + ); } } diff --git a/test/src/sdk/core/transaction/ChangeParams.ts b/test/src/sdk/core/transaction/ChangeParams.ts new file mode 100644 index 0000000000..72d4c67267 --- /dev/null +++ b/test/src/sdk/core/transaction/ChangeParams.ts @@ -0,0 +1,48 @@ +import { U64 } from "../classes"; +import { Transaction } from "../Transaction"; +import { NetworkId } from "../types"; + +export interface ChangeParamsActionJSON { + metadataSeq: string; + params: (number | string)[]; + approvals: any[]; +} + +export class ChangeParams extends Transaction { + private readonly metadataSeq: U64; + private readonly params: (number | string)[]; + private readonly approvals: any[]; + + public constructor( + metadataSeq: U64, + params: (number | string)[], + approvals: any[], + networkId: NetworkId + ) { + super(networkId); + this.metadataSeq = metadataSeq; + this.approvals = approvals; + this.params = params; + } + + public type(): string { + return "changeParams"; + } + + protected actionToEncodeObject(): any[] { + return [ + 0xff, + this.metadataSeq.toEncodeObject(), + this.params, + ...this.approvals + ]; + } + + protected actionToJSON(): ChangeParamsActionJSON { + return { + metadataSeq: this.metadataSeq.toJSON(), + params: this.params, + approvals: this.approvals + }; + } +} diff --git a/test/src/sdk/core/transaction/Custom.ts b/test/src/sdk/core/transaction/Custom.ts deleted file mode 100644 index 2aa1283eb5..0000000000 --- a/test/src/sdk/core/transaction/Custom.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { U64 } from "foundry-primitives"; - -import { Transaction } from "../Transaction"; -import { NetworkId } from "../types"; - -export interface CustomActionJSON { - handlerId: string; - bytes: number[]; -} - -export class Custom extends Transaction { - private readonly handlerId: U64; - private readonly bytes: Buffer; - - constructor( - params: { handlerId: U64; bytes: Buffer }, - networkId: NetworkId - ) { - super(networkId); - - this.handlerId = params.handlerId; - this.bytes = params.bytes; - } - - public type(): string { - return "custom"; - } - - protected actionToEncodeObject(): any[] { - const { handlerId, bytes } = this; - return [0xff, handlerId.toEncodeObject(), bytes]; - } - - protected actionToJSON(): CustomActionJSON { - const { handlerId, bytes } = this; - return { - handlerId: handlerId.toJSON(), - bytes: [...bytes] - }; - } -} diff --git a/test/src/sdk/core/transaction/DelegateCCS.ts b/test/src/sdk/core/transaction/DelegateCCS.ts new file mode 100644 index 0000000000..bae7490619 --- /dev/null +++ b/test/src/sdk/core/transaction/DelegateCCS.ts @@ -0,0 +1,38 @@ +import { Address, U64 } from "../classes"; +import { Transaction } from "../Transaction"; +import { NetworkId } from "../types"; + +export interface DelegateCCSActionJSON { + address: string; + quantity: string; +} + +export class DelegateCCS extends Transaction { + private readonly address: Address; + private readonly quantity: U64; + + public constructor(address: Address, quantity: U64, networkId: NetworkId) { + super(networkId); + this.address = address; + this.quantity = quantity; + } + + public type(): string { + return "delegateCCS"; + } + + protected actionToEncodeObject(): any[] { + return [ + 0x22, + this.address.getAccountId().toEncodeObject(), + this.quantity.toEncodeObject() + ]; + } + + protected actionToJSON(): DelegateCCSActionJSON { + return { + address: this.address.value, + quantity: this.quantity.toJSON() + }; + } +} diff --git a/test/src/sdk/core/transaction/Redelegate.ts b/test/src/sdk/core/transaction/Redelegate.ts new file mode 100644 index 0000000000..d26d7d6ee6 --- /dev/null +++ b/test/src/sdk/core/transaction/Redelegate.ts @@ -0,0 +1,48 @@ +import { Address, U64 } from "../classes"; +import { Transaction } from "../Transaction"; +import { NetworkId } from "../types"; + +export interface RedelegateActionJSON { + prevDelegator: string; + nextDelegator: string; + quantity: string; +} + +export class Redelegate extends Transaction { + private readonly prevDelegator: Address; + private readonly nextDelegator: Address; + private readonly quantity: U64; + + public constructor( + prevDelegator: Address, + nextDelegator: Address, + quantity: U64, + networkId: NetworkId + ) { + super(networkId); + this.prevDelegator = prevDelegator; + this.nextDelegator = nextDelegator; + this.quantity = quantity; + } + + public type(): string { + return "redelegate"; + } + + protected actionToEncodeObject(): any[] { + return [ + 0x26, + this.prevDelegator.getAccountId().toEncodeObject(), + this.nextDelegator.getAccountId().toEncodeObject(), + this.quantity.toEncodeObject() + ]; + } + + protected actionToJSON(): RedelegateActionJSON { + return { + prevDelegator: this.prevDelegator.value, + nextDelegator: this.nextDelegator.value, + quantity: this.quantity.toJSON() + }; + } +} diff --git a/test/src/sdk/core/transaction/ReportDoubleVote.ts b/test/src/sdk/core/transaction/ReportDoubleVote.ts new file mode 100644 index 0000000000..c4f669b00c --- /dev/null +++ b/test/src/sdk/core/transaction/ReportDoubleVote.ts @@ -0,0 +1,37 @@ +import { Transaction } from "../Transaction"; +import { NetworkId } from "../types"; + +export interface ReportDoubleVoteActionJSON { + message1: number[]; + message2: number[]; +} + +export class ReportDoubleVote extends Transaction { + private readonly message1: Buffer; + private readonly message2: Buffer; + + public constructor( + message1: Buffer, + message2: Buffer, + networkId: NetworkId + ) { + super(networkId); + this.message1 = message1; + this.message2 = message2; + } + + public type(): string { + return "reportDoubleVote"; + } + + protected actionToEncodeObject(): any[] { + return [0x25, this.message1, this.message2]; + } + + protected actionToJSON(): ReportDoubleVoteActionJSON { + return { + message1: [...this.message1], + message2: [...this.message2] + }; + } +} diff --git a/test/src/sdk/core/transaction/Revoke.ts b/test/src/sdk/core/transaction/Revoke.ts new file mode 100644 index 0000000000..d4adc19602 --- /dev/null +++ b/test/src/sdk/core/transaction/Revoke.ts @@ -0,0 +1,38 @@ +import { Address, U64 } from "../classes"; +import { Transaction } from "../Transaction"; +import { NetworkId } from "../types"; + +export interface RevokeActionJSON { + address: string; + quantity: string; +} + +export class Revoke extends Transaction { + private readonly address: Address; + private readonly quantity: U64; + + public constructor(address: Address, quantity: U64, networkId: NetworkId) { + super(networkId); + this.address = address; + this.quantity = quantity; + } + + public type(): string { + return "revoke"; + } + + protected actionToEncodeObject(): any[] { + return [ + 0x23, + this.address.getAccountId().toEncodeObject(), + this.quantity.toEncodeObject() + ]; + } + + protected actionToJSON(): RevokeActionJSON { + return { + address: this.address.value, + quantity: this.quantity.toJSON() + }; + } +} diff --git a/test/src/sdk/core/transaction/SelfNominate.ts b/test/src/sdk/core/transaction/SelfNominate.ts new file mode 100644 index 0000000000..f572956505 --- /dev/null +++ b/test/src/sdk/core/transaction/SelfNominate.ts @@ -0,0 +1,34 @@ +import { U64 } from "../classes"; +import { Transaction } from "../Transaction"; +import { NetworkId } from "../types"; + +export interface SelfNominateActionJSON { + deposit: string; + metadata: number[]; +} + +export class SelfNominate extends Transaction { + private readonly deposit: U64; + private readonly metadata: Buffer; + + public constructor(deposit: U64, metadata: Buffer, networkId: NetworkId) { + super(networkId); + this.deposit = deposit; + this.metadata = metadata; + } + + public type(): string { + return "selfNominate"; + } + + protected actionToEncodeObject(): any[] { + return [0x24, this.deposit.toEncodeObject(), this.metadata]; + } + + protected actionToJSON(): SelfNominateActionJSON { + return { + deposit: this.deposit.toJSON(), + metadata: [...this.metadata] + }; + } +} diff --git a/test/src/sdk/core/transaction/TransferCCS.ts b/test/src/sdk/core/transaction/TransferCCS.ts new file mode 100644 index 0000000000..95cc680031 --- /dev/null +++ b/test/src/sdk/core/transaction/TransferCCS.ts @@ -0,0 +1,38 @@ +import { Address, U64 } from "../classes"; +import { Transaction } from "../Transaction"; +import { NetworkId } from "../types"; + +export interface TransferCCSActionJSON { + address: string; + quantity: string; +} + +export class TransferCCS extends Transaction { + private readonly address: Address; + private readonly quantity: U64; + + public constructor(address: Address, quantity: U64, networkId: NetworkId) { + super(networkId); + this.address = address; + this.quantity = quantity; + } + + public type(): string { + return "transferCCS"; + } + + protected actionToEncodeObject(): any[] { + return [ + 0x21, + this.address.getAccountId().toEncodeObject(), + this.quantity.toEncodeObject() + ]; + } + + protected actionToJSON(): TransferCCSActionJSON { + return { + address: this.address.value, + quantity: this.quantity.toJSON() + }; + } +} diff --git a/test/src/sdk/core/transaction/json.ts b/test/src/sdk/core/transaction/json.ts index d77dc21341..c5351b5526 100644 --- a/test/src/sdk/core/transaction/json.ts +++ b/test/src/sdk/core/transaction/json.ts @@ -8,13 +8,19 @@ import { U64 } from "../classes"; import { SignedTransactionJSON } from "../SignedTransaction"; +import { ChangeParams } from "./ChangeParams"; import { CreateShard } from "./CreateShard"; -import { Custom } from "./Custom"; +import { DelegateCCS } from "./DelegateCCS"; import { Pay } from "./Pay"; +import { Redelegate } from "./Redelegate"; import { Remove } from "./Remove"; +import { ReportDoubleVote } from "./ReportDoubleVote"; +import { Revoke } from "./Revoke"; +import { SelfNominate } from "./SelfNominate"; import { SetShardOwners } from "./SetShardOwners"; import { SetShardUsers } from "./SetShardUsers"; import { Store } from "./Store"; +import { TransferCCS } from "./TransferCCS"; export function fromJSONToTransaction(result: any): Transaction { const { seq, fee, networkId, action } = result; @@ -80,18 +86,55 @@ export function fromJSONToTransaction(result: any): Transaction { ); break; } - case "custom": { - const handlerId = U64.ensure(action.handlerId); - const bytes = Buffer.from(action.bytes); - tx = new Custom( - { - handlerId, - bytes - }, + case "delegateCCS": { + const address = Address.ensure(action.address); + const quantity = new U64(action.quantity); + tx = new DelegateCCS(address, quantity, networkId); + break; + } + case "transferCCS": { + const address = Address.ensure(action.address); + const quantity = new U64(action.quantity); + tx = new TransferCCS(address, quantity, networkId); + break; + } + case "revoke": { + const address = Address.ensure(action.address); + const quantity = new U64(action.quantity); + tx = new Revoke(address, quantity, networkId); + break; + } + case "redelegate": { + const prevDelegator = Address.ensure(action.prevDelegator); + const nextDelegator = Address.ensure(action.nextDelegator); + const quantity = new U64(action.quantity); + tx = new Redelegate( + prevDelegator, + nextDelegator, + quantity, networkId ); break; } + case "selfNominate": { + const deposit = new U64(action.deposit); + const metadata = Buffer.from(action.metadata); + tx = new SelfNominate(deposit, metadata, networkId); + break; + } + case "reportDoubleVote": { + const message1 = Buffer.from(action.message1); + const message2 = Buffer.from(action.message2); + tx = new ReportDoubleVote(message1, message2, networkId); + break; + } + case "changeParams": { + const metadataSeq = new U64(action.metadataSeq); + const params = action.params; + const approvals = action.approvals; + tx = new ChangeParams(metadataSeq, params, approvals, networkId); + break; + } default: throw Error(`Unexpected action: ${action}`); } diff --git a/test/src/stakeholder/index.ts b/test/src/stakeholder/index.ts index b5df05d305..8a2ad35d47 100644 --- a/test/src/stakeholder/index.ts +++ b/test/src/stakeholder/index.ts @@ -17,15 +17,4 @@ export { getBanned } from "./actionData"; -export { - createTransferCCSTransaction, - createDelegateCCSTransaction, - createRedelegateTransaction, - createReportDoubleVoteTransaction, - createRevokeTransaction, - createSelfNominateTransaction, - actionFromCustom, - actionFromRLP -} from "./transactions"; - export { TermMetadata, getTermMetadata, getPossibleAuthors } from "./rpc"; diff --git a/test/src/stakeholder/transactions.ts b/test/src/stakeholder/transactions.ts deleted file mode 100644 index f4a27fb6c7..0000000000 --- a/test/src/stakeholder/transactions.ts +++ /dev/null @@ -1,263 +0,0 @@ -// FIXME: The SDK doesn't export addressValue and U64Value. -// In the import statement below uses "foundry-primitives" which is installed by the SDK. -// We should use the SDK's addressValue when the SDK is updated. -import { AddressValue, U64Value } from "foundry-primitives/lib"; -import * as RLP from "rlp"; -import { SDK } from "../sdk"; -import { Address, U64 } from "../sdk/core/classes"; -import { Custom } from "../sdk/core/transaction/Custom"; - -import ReportDoubleVote from "./actions/reportDoubleVote"; -import { HANDLER_ID } from "./index"; -import { ConsensusMessage } from "./message"; -import { decodeaddress, decodeU64, decodeUInt } from "./util"; - -export const TRANSFER_CCS_ACTION_ID = 1; -export const DELEGATE_CCS_ACTION_ID = 2; -export const REVOKE_ACTION_ID = 3; -export const SELF_NOMINATE_ACTION_ID = 4; -export const REPORT_DOUBLE_VOTE_ACTION_ID = ReportDoubleVote.ACTION_ID; -export const REDELEGATE_ACTION_ID = 6; -export const CHANGE_PARAMS_ACTION_ID = 0xff; - -export function createTransferCCSTransaction( - sdk: SDK, - recipient: AddressValue, - quantity: U64Value -): Custom { - return sdk.core.createCustomTransaction({ - handlerId: HANDLER_ID, - bytes: RLP.encode([ - TRANSFER_CCS_ACTION_ID, - Address.ensure(recipient).accountId.toEncodeObject(), - U64.ensure(quantity).toEncodeObject() - ]) - }); -} - -export function createDelegateCCSTransaction( - sdk: SDK, - delegatee: AddressValue, - quantity: U64Value -): Custom { - return sdk.core.createCustomTransaction({ - handlerId: HANDLER_ID, - bytes: RLP.encode([ - DELEGATE_CCS_ACTION_ID, - Address.ensure(delegatee).accountId.toEncodeObject(), - U64.ensure(quantity).toEncodeObject() - ]) - }); -} - -export function createRevokeTransaction( - sdk: SDK, - delegatee: AddressValue, - quantity: U64Value -): Custom { - return sdk.core.createCustomTransaction({ - handlerId: HANDLER_ID, - bytes: RLP.encode([ - REVOKE_ACTION_ID, - Address.ensure(delegatee).accountId.toEncodeObject(), - U64.ensure(quantity).toEncodeObject() - ]) - }); -} - -export function createSelfNominateTransaction( - sdk: SDK, - deposit: U64Value, - metadata: Buffer | string -): Custom { - return sdk.core.createCustomTransaction({ - handlerId: HANDLER_ID, - bytes: RLP.encode([ - SELF_NOMINATE_ACTION_ID, - U64.ensure(deposit).toEncodeObject(), - metadata - ]) - }); -} - -export function createReportDoubleVoteTransaction( - sdk: SDK, - message1: ConsensusMessage, - message2: ConsensusMessage -): Custom { - const action = new ReportDoubleVote(message1, message2); - return sdk.core.createCustomTransaction({ - handlerId: HANDLER_ID, - bytes: action.toBytes() - }); -} - -export function createRedelegateTransaction( - sdk: SDK, - prevDelegatee: AddressValue, - nextDelegatee: AddressValue, - quantity: U64Value -): Custom { - return sdk.core.createCustomTransaction({ - handlerId: HANDLER_ID, - bytes: RLP.encode([ - REDELEGATE_ACTION_ID, - Address.ensure(prevDelegatee).accountId.toEncodeObject(), - Address.ensure(nextDelegatee).accountId.toEncodeObject(), - U64.ensure(quantity).toEncodeObject() - ]) - }); -} - -interface TransferCCS { - type: "transferCCS"; - recipient: Address; - quantity: U64; -} - -interface DelegateCCS { - type: "delegateCCS"; - delegatee: Address; - quantity: U64; -} - -interface Revoke { - type: "revoke"; - delegatee: Address; - quantity: U64; -} - -interface SelfNominate { - type: "selfNominate"; - deposit: U64; - metadata: Buffer; -} - -interface Redelegate { - type: "redelegate"; - prevDelegatee: Address; - nextDelegatee: Address; - quantity: U64; -} - -interface ChangeParams { - type: "changeParams"; - metadataSeq: U64; - // TODO: Use concrete type when it is needed. - params: any; - signatures: any[]; -} - -type Action = - | TransferCCS - | DelegateCCS - | Revoke - | SelfNominate - | ReportDoubleVote - | Redelegate - | ChangeParams; - -export function actionFromCustom(sdk: SDK, custom: Custom): Action | null { - const { handlerId, bytes } = custom as any; - if (!U64.ensure(handlerId).eq(HANDLER_ID)) { - return null; - } - if (!Buffer.isBuffer(bytes)) { - throw new Error("bytes should be a number"); - } - return actionFromRLP(sdk, bytes); -} - -export function actionFromRLP(sdk: SDK, rlp: Buffer): Action { - const decoded = RLP.decode(rlp); - if ( - !Array.isArray(decoded) || - decoded.length < 1 || - !Buffer.isBuffer(decoded[0]) - ) { - throw new Error( - "RLP of a stake action must be an array and it should have at least a tag as a first item" - ); - } - - switch (decodeUInt(decoded[0])) { - case TRANSFER_CCS_ACTION_ID: - if (decoded.length !== 3) { - throw new Error( - "A length of a RLP list of a transferCCS action must be 3" - ); - } - return { - type: "transferCCS", - recipient: decodeaddress(sdk, decoded[1]), - quantity: decodeU64(decoded[2]) - }; - case DELEGATE_CCS_ACTION_ID: - if (decoded.length !== 3) { - throw new Error( - "A length of a RLP list of a delegateCCS action must be 3" - ); - } - return { - type: "delegateCCS", - delegatee: decodeaddress(sdk, decoded[1]), - quantity: decodeU64(decoded[2]) - }; - case REVOKE_ACTION_ID: - if (decoded.length !== 3) { - throw new Error( - "A length of a RLP list of a revoke action must be 3" - ); - } - return { - type: "revoke", - delegatee: decodeaddress(sdk, decoded[1]), - quantity: decodeU64(decoded[2]) - }; - case SELF_NOMINATE_ACTION_ID: - if (decoded.length !== 3) { - throw new Error( - "A length of a RLP list of a selfNominate action must be 3" - ); - } - if (!Buffer.isBuffer(decoded[2])) { - throw new Error( - "The metadata field of a RLP encoded selfNominate action must be a string" - ); - } - return { - type: "selfNominate", - deposit: decodeU64(decoded[1]), - metadata: decoded[2] - }; - case REPORT_DOUBLE_VOTE_ACTION_ID: - return ReportDoubleVote.fromEncodeObject(decoded); - case REDELEGATE_ACTION_ID: - if (decoded.length !== 4) { - throw new Error( - "A length of a RLP list of a redelegate action must be 4" - ); - } - return { - type: "redelegate", - prevDelegatee: decodeaddress(sdk, decoded[1]), - nextDelegatee: decodeaddress(sdk, decoded[2]), - quantity: decodeU64(decoded[3]) - }; - case CHANGE_PARAMS_ACTION_ID: - if (decoded.length <= 3) { - throw new Error( - "A length of a RLP list of a changeParams action should be more than 3" - ); - } - const signatures: any = decoded.slice(3); - return { - type: "changeParams", - metadataSeq: decodeU64(decoded[1]), - params: decoded[2], - signatures - }; - default: - throw new Error("Invalid tag for a stake action"); - } -} diff --git a/types/src/common_params.rs b/types/src/common_params.rs index f264d8290d..604a97ee12 100644 --- a/types/src/common_params.rs +++ b/types/src/common_params.rs @@ -18,7 +18,7 @@ use cjson::scheme::Params; use ckey::NetworkId; use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream}; -#[derive(Copy, Clone, Debug, Default, PartialEq)] +#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] pub struct CommonParams { /// Maximum size of extra data. max_extra_data_size: usize, diff --git a/types/src/transaction/action.rs b/types/src/transaction/action.rs index 32f9a1d88f..e8584ece70 100644 --- a/types/src/transaction/action.rs +++ b/types/src/transaction/action.rs @@ -15,10 +15,10 @@ // along with this program. If not, see . use crate::errors::SyntaxError; -use crate::transaction::ShardTransaction; +use crate::transaction::{Approval, ShardTransaction}; use crate::{CommonParams, ShardId, Tracker}; use ccrypto::Blake; -use ckey::{Address, NetworkId}; +use ckey::{verify, Address, NetworkId}; use primitives::{Bytes, H256}; use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream}; @@ -30,7 +30,13 @@ enum ActionTag { SetShardOwners = 0x05, SetShardUsers = 0x06, ShardStore = 0x19, - Custom = 0xFF, + TransferCCS = 0x21, + DelegateCCS = 0x22, + Revoke = 0x23, + SelfNominate = 0x24, + ReportDoubleVote = 0x25, + Redelegate = 0x26, + ChangeParams = 0xFF, } impl Encodable for ActionTag { @@ -48,7 +54,13 @@ impl Decodable for ActionTag { 0x05 => Ok(Self::SetShardOwners), 0x06 => Ok(Self::SetShardUsers), 0x19 => Ok(Self::ShardStore), - 0xFF => Ok(Self::Custom), + 0x21 => Ok(Self::TransferCCS), + 0x22 => Ok(Self::DelegateCCS), + 0x23 => Ok(Self::Revoke), + 0x24 => Ok(Self::SelfNominate), + 0x25 => Ok(Self::ReportDoubleVote), + 0x26 => Ok(Self::Redelegate), + 0xFF => Ok(Self::ChangeParams), _ => Err(DecoderError::Custom("Unexpected action prefix")), } } @@ -72,15 +84,41 @@ pub enum Action { shard_id: ShardId, users: Vec
, }, - Custom { - handler_id: u64, - bytes: Bytes, - }, ShardStore { network_id: NetworkId, shard_id: ShardId, content: String, }, + TransferCCS { + address: Address, + quantity: u64, + }, + DelegateCCS { + address: Address, + quantity: u64, + }, + Revoke { + address: Address, + quantity: u64, + }, + Redelegate { + prev_delegatee: Address, + next_delegatee: Address, + quantity: u64, + }, + SelfNominate { + deposit: u64, + metadata: Bytes, + }, + ChangeParams { + metadata_seq: u64, + params: Box, + approvals: Vec, + }, + ReportDoubleVote { + message1: Bytes, + message2: Bytes, + }, } impl Action { @@ -114,6 +152,63 @@ impl Action { } } + match self { + Action::TransferCCS { + .. + } => {} + Action::DelegateCCS { + .. + } => {} + Action::Revoke { + .. + } => {} + Action::Redelegate { + .. + } => {} + Action::SelfNominate { + metadata, + .. + } => { + if metadata.len() > common_params.max_candidate_metadata_size() { + return Err(SyntaxError::InvalidCustomAction(format!( + "Too long candidate metadata: the size limit is {}", + common_params.max_candidate_metadata_size() + ))) + } + } + Action::ChangeParams { + metadata_seq, + params, + approvals, + } => { + params.verify_change(common_params).map_err(SyntaxError::InvalidCustomAction)?; + let action = Action::ChangeParams { + metadata_seq: *metadata_seq, + params: params.clone(), + approvals: vec![], + }; + let encoded_action = H256::blake(rlp::encode(&action)); + for approval in approvals { + if !verify(approval.signature(), &encoded_action, approval.signer_public()) { + return Err(SyntaxError::InvalidCustomAction(format!( + "Cannot decode the signature {:?} with public {:?} and the message {:?}", + approval.signature(), + approval.signer_public(), + &encoded_action, + ))) + } + } + } + Action::ReportDoubleVote { + message1, + message2, + } => { + if message1 == message2 { + return Err(SyntaxError::InvalidCustomAction(String::from("Messages are duplicated"))) + } + } + _ => {} + } Ok(()) } @@ -182,15 +277,6 @@ impl Encodable for Action { s.append(shard_id); s.append_list(users); } - Action::Custom { - handler_id, - bytes, - } => { - s.begin_list(3); - s.append(&ActionTag::Custom); - s.append(handler_id); - s.append(bytes); - } Action::ShardStore { shard_id, content, @@ -202,6 +288,60 @@ impl Encodable for Action { s.append(shard_id); s.append(content); } + Action::TransferCCS { + address, + quantity, + } => { + s.begin_list(3).append(&ActionTag::TransferCCS).append(address).append(quantity); + } + Action::DelegateCCS { + address, + quantity, + } => { + s.begin_list(3).append(&ActionTag::DelegateCCS).append(address).append(quantity); + } + Action::Revoke { + address, + quantity, + } => { + s.begin_list(3).append(&ActionTag::Revoke).append(address).append(quantity); + } + Action::Redelegate { + prev_delegatee, + next_delegatee, + quantity, + } => { + s.begin_list(4) + .append(&ActionTag::Redelegate) + .append(prev_delegatee) + .append(next_delegatee) + .append(quantity); + } + Action::SelfNominate { + deposit, + metadata, + } => { + s.begin_list(3).append(&ActionTag::SelfNominate).append(deposit).append(metadata); + } + Action::ChangeParams { + metadata_seq, + params, + approvals, + } => { + s.begin_list(3 + approvals.len()) + .append(&ActionTag::ChangeParams) + .append(metadata_seq) + .append(&**params); + for approval in approvals { + s.append(approval); + } + } + Action::ReportDoubleVote { + message1, + message2, + } => { + s.begin_list(3).append(&ActionTag::ReportDoubleVote).append(message1).append(message2); + } } } } @@ -260,31 +400,116 @@ impl Decodable for Action { users: rlp.list_at(2)?, }) } - ActionTag::Custom => { + ActionTag::ShardStore => { let item_count = rlp.item_count()?; - if item_count != 3 { + if item_count != 4 { return Err(DecoderError::RlpIncorrectListLen { got: item_count, + expected: 4, + }) + } + Ok(Action::ShardStore { + network_id: rlp.val_at(1)?, + shard_id: rlp.val_at(2)?, + content: rlp.val_at(3)?, + }) + } + ActionTag::TransferCCS => { + let item_count = rlp.item_count()?; + if item_count != 3 { + return Err(DecoderError::RlpInvalidLength { + expected: 3, + got: item_count, + }) + } + Ok(Action::TransferCCS { + address: rlp.val_at(1)?, + quantity: rlp.val_at(2)?, + }) + } + ActionTag::DelegateCCS => { + let item_count = rlp.item_count()?; + if item_count != 3 { + return Err(DecoderError::RlpInvalidLength { expected: 3, + got: item_count, }) } - Ok(Action::Custom { - handler_id: rlp.val_at(1)?, - bytes: rlp.val_at(2)?, + Ok(Action::DelegateCCS { + address: rlp.val_at(1)?, + quantity: rlp.val_at(2)?, }) } - ActionTag::ShardStore => { + ActionTag::Revoke => { + let item_count = rlp.item_count()?; + if item_count != 3 { + return Err(DecoderError::RlpInvalidLength { + expected: 3, + got: item_count, + }) + } + Ok(Action::Revoke { + address: rlp.val_at(1)?, + quantity: rlp.val_at(2)?, + }) + } + ActionTag::Redelegate => { let item_count = rlp.item_count()?; if item_count != 4 { - return Err(DecoderError::RlpIncorrectListLen { + return Err(DecoderError::RlpInvalidLength { + expected: 4, + got: item_count, + }) + } + Ok(Action::Redelegate { + prev_delegatee: rlp.val_at(1)?, + next_delegatee: rlp.val_at(2)?, + quantity: rlp.val_at(3)?, + }) + } + ActionTag::SelfNominate => { + let item_count = rlp.item_count()?; + if item_count != 3 { + return Err(DecoderError::RlpInvalidLength { + expected: 3, got: item_count, + }) + } + Ok(Action::SelfNominate { + deposit: rlp.val_at(1)?, + metadata: rlp.val_at(2)?, + }) + } + ActionTag::ChangeParams => { + let item_count = rlp.item_count()?; + if item_count < 4 { + return Err(DecoderError::RlpIncorrectListLen { expected: 4, + got: item_count, }) } - Ok(Action::ShardStore { - network_id: rlp.val_at(1)?, - shard_id: rlp.val_at(2)?, - content: rlp.val_at(3)?, + let metadata_seq = rlp.val_at(1)?; + let params = Box::new(rlp.val_at(2)?); + let approvals = (3..item_count).map(|i| rlp.val_at(i)).collect::>()?; + Ok(Action::ChangeParams { + metadata_seq, + params, + approvals, + }) + } + ActionTag::ReportDoubleVote => { + let item_count = rlp.item_count()?; + if item_count != 3 { + return Err(DecoderError::RlpIncorrectListLen { + expected: 3, + got: item_count, + }) + } + let message1 = rlp.val_at(1)?; + let message2 = rlp.val_at(2)?; + Ok(Action::ReportDoubleVote { + message1, + message2, }) } } @@ -293,9 +518,9 @@ impl Decodable for Action { #[cfg(test)] mod tests { - use rlp::rlp_encode_and_decode_test; - use super::*; + use ckey::{Ed25519Public as Public, Signature}; + use rlp::rlp_encode_and_decode_test; #[test] fn encode_and_decode_pay_action() { @@ -320,4 +545,32 @@ mod tests { users: vec![Address::random(), Address::random()], }); } + + #[test] + fn rlp_of_change_params() { + rlp_encode_and_decode_test!(Action::ChangeParams { + metadata_seq: 3, + params: CommonParams::default_for_test().into(), + approvals: vec![ + Approval::new(Signature::random(), Public::random()), + Approval::new(Signature::random(), Public::random()), + ], + }); + } + + #[test] + fn decode_fail_if_change_params_have_no_signatures() { + let action = Action::ChangeParams { + metadata_seq: 3, + params: CommonParams::default_for_test().into(), + approvals: vec![], + }; + assert_eq!( + Err(DecoderError::RlpIncorrectListLen { + expected: 4, + got: 3, + }), + Rlp::new(&rlp::encode(&action)).as_val::() + ); + } } diff --git a/types/src/transaction/approval.rs b/types/src/transaction/approval.rs new file mode 100644 index 0000000000..9069bdbf61 --- /dev/null +++ b/types/src/transaction/approval.rs @@ -0,0 +1,39 @@ +// Copyright 2018-2020 Kodebox, Inc. +// This file is part of CodeChain. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +use ckey::{Ed25519Public as Public, Signature}; + +#[derive(Clone, Debug, Eq, PartialEq, RlpEncodable, RlpDecodable, Serialize, Deserialize)] +pub struct Approval { + signature: Signature, + signer_public: Public, +} + +impl Approval { + pub fn new(signature: Signature, signer_public: Public) -> Self { + Self { + signature, + signer_public, + } + } + pub fn signature(&self) -> &Signature { + &self.signature + } + + pub fn signer_public(&self) -> &Public { + &self.signer_public + } +} diff --git a/types/src/transaction/mod.rs b/types/src/transaction/mod.rs index 7c84767764..3d2e59ee43 100644 --- a/types/src/transaction/mod.rs +++ b/types/src/transaction/mod.rs @@ -15,18 +15,18 @@ // along with this program. If not, see . mod action; +mod approval; mod incomplete_transaction; mod partial_hashing; mod shard; -mod stake; mod timelock; #[cfg_attr(feature = "cargo-clippy", allow(clippy::module_inception))] mod transaction; pub use self::action::Action; +pub use self::approval::Approval; pub use self::incomplete_transaction::IncompleteTransaction; pub use self::partial_hashing::{HashingError, PartialHashing}; pub use self::shard::ShardTransaction; -pub use self::stake::{Approval, StakeAction}; pub use self::timelock::Timelock; pub use self::transaction::Transaction; diff --git a/types/src/transaction/stake.rs b/types/src/transaction/stake.rs deleted file mode 100644 index cd403692a4..0000000000 --- a/types/src/transaction/stake.rs +++ /dev/null @@ -1,375 +0,0 @@ -// Copyright 2018-2020 Kodebox, Inc. -// This file is part of CodeChain. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -use crate::errors::SyntaxError; -use crate::CommonParams; -use ccrypto::Blake; -use ckey::{verify, Address, Ed25519Public as Public, Signature}; -use primitives::{Bytes, H256}; -use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream}; - -#[derive(Clone, Copy)] -#[repr(u8)] -enum StakeActionTag { - TransferCCS = 1, - DelegateCCS = 2, - Revoke = 3, - SelfNominate = 4, - ReportDoubleVote = 5, - Redelegate = 6, - ChangeParams = 0xFF, -} - -impl Encodable for StakeActionTag { - fn rlp_append(&self, s: &mut RlpStream) { - s.append_single_value(&(*self as u8)); - } -} - -impl Decodable for StakeActionTag { - fn decode(rlp: &Rlp) -> Result { - let tag = rlp.as_val()?; - match tag { - 1u8 => Ok(StakeActionTag::TransferCCS), - 2 => Ok(StakeActionTag::DelegateCCS), - 3 => Ok(StakeActionTag::Revoke), - 4 => Ok(StakeActionTag::SelfNominate), - 5 => Ok(StakeActionTag::ReportDoubleVote), - 6 => Ok(StakeActionTag::Redelegate), - 0xFF => Ok(StakeActionTag::ChangeParams), - _ => Err(DecoderError::Custom("Unexpected ActionTag Value")), - } - } -} - -#[derive(Debug, PartialEq, RlpEncodable, RlpDecodable)] -pub struct Approval { - signature: Signature, - signer_public: Public, -} - -impl Approval { - pub fn signature(&self) -> &Signature { - &self.signature - } - - pub fn signer_public(&self) -> &Public { - &self.signer_public - } -} - -#[derive(Debug, PartialEq)] -pub enum StakeAction { - TransferCCS { - address: Address, - quantity: u64, - }, - DelegateCCS { - address: Address, - quantity: u64, - }, - Revoke { - address: Address, - quantity: u64, - }, - Redelegate { - prev_delegatee: Address, - next_delegatee: Address, - quantity: u64, - }, - SelfNominate { - deposit: u64, - metadata: Bytes, - }, - ChangeParams { - metadata_seq: u64, - params: Box, - approvals: Vec, - }, - ReportDoubleVote { - message1: Bytes, - message2: Bytes, - }, -} - -impl StakeAction { - pub fn verify(&self, current_params: &CommonParams) -> Result<(), SyntaxError> { - match self { - StakeAction::TransferCCS { - .. - } => {} - StakeAction::DelegateCCS { - .. - } => {} - StakeAction::Revoke { - .. - } => {} - StakeAction::Redelegate { - .. - } => {} - StakeAction::SelfNominate { - metadata, - .. - } => { - if metadata.len() > current_params.max_candidate_metadata_size() { - return Err(SyntaxError::InvalidCustomAction(format!( - "Too long candidate metadata: the size limit is {}", - current_params.max_candidate_metadata_size() - ))) - } - } - StakeAction::ChangeParams { - metadata_seq, - params, - approvals, - } => { - params.verify_change(current_params).map_err(SyntaxError::InvalidCustomAction)?; - let action = StakeAction::ChangeParams { - metadata_seq: *metadata_seq, - params: params.clone(), - approvals: vec![], - }; - let encoded_action = H256::blake(rlp::encode(&action)); - for approval in approvals { - if !verify(approval.signature(), &encoded_action, approval.signer_public()) { - return Err(SyntaxError::InvalidCustomAction(format!( - "Cannot decode the signature {:?} with public {:?} and the message {:?}", - approval.signature(), - approval.signer_public(), - &encoded_action, - ))) - } - } - } - StakeAction::ReportDoubleVote { - message1, - message2, - } => { - if message1 == message2 { - return Err(SyntaxError::InvalidCustomAction(String::from("Messages are duplicated"))) - } - } - } - Ok(()) - } -} - -impl Encodable for StakeAction { - fn rlp_append(&self, s: &mut RlpStream) { - match self { - StakeAction::TransferCCS { - address, - quantity, - } => { - s.begin_list(3).append(&StakeActionTag::TransferCCS).append(address).append(quantity); - } - StakeAction::DelegateCCS { - address, - quantity, - } => { - s.begin_list(3).append(&StakeActionTag::DelegateCCS).append(address).append(quantity); - } - StakeAction::Revoke { - address, - quantity, - } => { - s.begin_list(3).append(&StakeActionTag::Revoke).append(address).append(quantity); - } - StakeAction::Redelegate { - prev_delegatee, - next_delegatee, - quantity, - } => { - s.begin_list(4) - .append(&StakeActionTag::Redelegate) - .append(prev_delegatee) - .append(next_delegatee) - .append(quantity); - } - StakeAction::SelfNominate { - deposit, - metadata, - } => { - s.begin_list(3).append(&StakeActionTag::SelfNominate).append(deposit).append(metadata); - } - StakeAction::ChangeParams { - metadata_seq, - params, - approvals, - } => { - s.begin_list(3 + approvals.len()) - .append(&StakeActionTag::ChangeParams) - .append(metadata_seq) - .append(&**params); - for approval in approvals { - s.append(approval); - } - } - StakeAction::ReportDoubleVote { - message1, - message2, - } => { - s.begin_list(3).append(&StakeActionTag::ReportDoubleVote).append(message1).append(message2); - } - }; - } -} - -impl Decodable for StakeAction { - fn decode(rlp: &Rlp<'_>) -> Result { - let tag = rlp.val_at(0)?; - match tag { - StakeActionTag::TransferCCS => { - let item_count = rlp.item_count()?; - if item_count != 3 { - return Err(DecoderError::RlpInvalidLength { - expected: 3, - got: item_count, - }) - } - Ok(StakeAction::TransferCCS { - address: rlp.val_at(1)?, - quantity: rlp.val_at(2)?, - }) - } - StakeActionTag::DelegateCCS => { - let item_count = rlp.item_count()?; - if item_count != 3 { - return Err(DecoderError::RlpInvalidLength { - expected: 3, - got: item_count, - }) - } - Ok(StakeAction::DelegateCCS { - address: rlp.val_at(1)?, - quantity: rlp.val_at(2)?, - }) - } - StakeActionTag::Revoke => { - let item_count = rlp.item_count()?; - if item_count != 3 { - return Err(DecoderError::RlpInvalidLength { - expected: 3, - got: item_count, - }) - } - Ok(StakeAction::Revoke { - address: rlp.val_at(1)?, - quantity: rlp.val_at(2)?, - }) - } - StakeActionTag::Redelegate => { - let item_count = rlp.item_count()?; - if item_count != 4 { - return Err(DecoderError::RlpInvalidLength { - expected: 4, - got: item_count, - }) - } - Ok(StakeAction::Redelegate { - prev_delegatee: rlp.val_at(1)?, - next_delegatee: rlp.val_at(2)?, - quantity: rlp.val_at(3)?, - }) - } - StakeActionTag::SelfNominate => { - let item_count = rlp.item_count()?; - if item_count != 3 { - return Err(DecoderError::RlpInvalidLength { - expected: 3, - got: item_count, - }) - } - Ok(StakeAction::SelfNominate { - deposit: rlp.val_at(1)?, - metadata: rlp.val_at(2)?, - }) - } - StakeActionTag::ChangeParams => { - let item_count = rlp.item_count()?; - if item_count < 4 { - return Err(DecoderError::RlpIncorrectListLen { - expected: 4, - got: item_count, - }) - } - let metadata_seq = rlp.val_at(1)?; - let params = Box::new(rlp.val_at(2)?); - let approvals = (3..item_count).map(|i| rlp.val_at(i)).collect::>()?; - Ok(StakeAction::ChangeParams { - metadata_seq, - params, - approvals, - }) - } - StakeActionTag::ReportDoubleVote => { - let item_count = rlp.item_count()?; - if item_count != 3 { - return Err(DecoderError::RlpIncorrectListLen { - expected: 3, - got: item_count, - }) - } - let message1 = rlp.val_at(1)?; - let message2 = rlp.val_at(2)?; - Ok(StakeAction::ReportDoubleVote { - message1, - message2, - }) - } - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use rlp::rlp_encode_and_decode_test; - - #[test] - fn rlp_of_change_params() { - rlp_encode_and_decode_test!(StakeAction::ChangeParams { - metadata_seq: 3, - params: CommonParams::default_for_test().into(), - approvals: vec![ - Approval { - signature: Signature::random(), - signer_public: Public::random(), - }, - Approval { - signature: Signature::random(), - signer_public: Public::random(), - } - ], - }); - } - - #[test] - fn decode_fail_if_change_params_have_no_signatures() { - let action = StakeAction::ChangeParams { - metadata_seq: 3, - params: CommonParams::default_for_test().into(), - approvals: vec![], - }; - assert_eq!( - Err(DecoderError::RlpIncorrectListLen { - expected: 4, - got: 3, - }), - Rlp::new(&rlp::encode(&action)).as_val::() - ); - } -}