From a3c3433413761bd5a373c8b0caa57bfab3f9afd8 Mon Sep 17 00:00:00 2001 From: Eason Gao Date: Wed, 24 Jun 2020 16:12:42 +0800 Subject: [PATCH] feat(service)!: add authorization service for mempool (#320) * feat: add authorization service * feat: mempool check authorization by service * add set admin function * tmp * feat: verify signature when new authorization * feat: register multi_signature * encode json twice * fix * refactor executor * test: update muta sdk version for checking multi sig with mempool changes * fix unit test * cargo fmt * fix decode may panic * cargo clippy * change verify signature api * test(e2e): add multi signature testcase Co-authored-by: homura Co-authored-by: zero.qn --- Cargo.toml | 6 +- built-in-services/asset/Cargo.toml | 2 +- built-in-services/asset/src/lib.rs | 4 +- built-in-services/authorization/Cargo.toml | 25 +++ built-in-services/authorization/src/lib.rs | 127 +++++++++++ built-in-services/authorization/src/types.rs | 29 +++ built-in-services/multi-signature/src/lib.rs | 204 ++++++++++-------- .../multi-signature/src/tests/mod.rs | 1 + .../src/tests/recursion_test.rs | 7 +- .../multi-signature/src/types.rs | 3 +- core/mempool/Cargo.toml | 2 + core/mempool/src/adapter/mod.rs | 118 ++++++---- core/mempool/src/lib.rs | 13 +- core/mempool/src/tests/mempool.rs | 4 +- core/mempool/src/tests/mod.rs | 6 +- examples/muta-chain.rs | 12 +- framework/src/executor/mod.rs | 3 +- protocol/src/traits/mempool.rs | 2 +- protocol/src/types/transaction.rs | 7 +- src/default_start.rs | 31 +-- tests/e2e/multisig.ts | 29 +++ tests/e2e/package.json | 7 +- tests/e2e/sdk.test.ts | 66 +++++- tests/e2e/yarn.lock | 122 +++++------ tests/trust_metric_all/common.rs | 7 +- tests/trust_metric_all/node/full_node.rs | 11 +- .../node/full_node/default_start.rs | 15 +- 27 files changed, 622 insertions(+), 241 deletions(-) create mode 100644 built-in-services/authorization/Cargo.toml create mode 100644 built-in-services/authorization/src/lib.rs create mode 100644 built-in-services/authorization/src/types.rs create mode 100644 tests/e2e/multisig.ts diff --git a/Cargo.toml b/Cargo.toml index 2b3799b7c..faddb8280 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,9 +39,10 @@ futures-timer="3.0" [dev-dependencies] asset = { path = "built-in-services/asset" } -metadata = { path = "built-in-services/metadata" } -util = { path = "built-in-services/util" } multi-signature = { path = "built-in-services/multi-signature" } +authorization = { path = "built-in-services/authorization" } +metadata = { path = "built-in-services/metadata"} +util = { path = "built-in-services/util"} rand = "0.7" cita_trie = "2.0" core-network = { path = "./core/network", features = ["diagnostic"] } @@ -68,6 +69,7 @@ members = [ "built-in-services/asset", "built-in-services/metadata", "built-in-services/multi-signature", + "built-in-services/authorization", "protocol", ] diff --git a/built-in-services/asset/Cargo.toml b/built-in-services/asset/Cargo.toml index c446e3491..cc33aa217 100644 --- a/built-in-services/asset/Cargo.toml +++ b/built-in-services/asset/Cargo.toml @@ -15,7 +15,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" rlp = "0.4" bytes = "0.5" -derive_more = "0.15" +derive_more = "0.99" byteorder = "1.3" muta-codec-derive = "0.2" diff --git a/built-in-services/asset/src/lib.rs b/built-in-services/asset/src/lib.rs index 3355d3319..abe4e95c8 100644 --- a/built-in-services/asset/src/lib.rs +++ b/built-in-services/asset/src/lib.rs @@ -4,11 +4,9 @@ pub mod types; use std::collections::BTreeMap; -use bytes::Bytes; - use binding_macro::{cycles, genesis, service}; use protocol::traits::{ExecutorParams, ServiceResponse, ServiceSDK, StoreMap}; -use protocol::types::{Address, Hash, ServiceContext}; +use protocol::types::{Address, Bytes, Hash, ServiceContext}; use crate::types::{ ApproveEvent, ApprovePayload, Asset, AssetBalance, CreateAssetPayload, GetAllowancePayload, diff --git a/built-in-services/authorization/Cargo.toml b/built-in-services/authorization/Cargo.toml new file mode 100644 index 000000000..cdb5d605b --- /dev/null +++ b/built-in-services/authorization/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "authorization" +version = "0.1.0" +authors = ["Muta Dev "] +edition = "2018" +repository = "https://github.com/nervosnetwork/muta" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +binding-macro = { path = "../../binding-macro" } +protocol = { path = "../../protocol", package = "muta-protocol" } + +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +rlp = "0.4" +bytes = "0.5" +derive_more = "0.99" +byteorder = "1.3" +muta-codec-derive = "0.2" + +[dev-dependencies] +cita_trie = "2.0" +async-trait = "0.1" +framework = { path = "../../framework" } diff --git a/built-in-services/authorization/src/lib.rs b/built-in-services/authorization/src/lib.rs new file mode 100644 index 000000000..7f7ae815a --- /dev/null +++ b/built-in-services/authorization/src/lib.rs @@ -0,0 +1,127 @@ +mod types; + +use binding_macro::{cycles, genesis, service}; +use protocol::traits::{ExecutorParams, ServiceResponse, ServiceSDK, StoreMap}; +use protocol::types::{Address, ServiceContext}; + +use crate::types::{ + AddVerifiedItemPayload, InitGenesisPayload, RemoveVerifiedItemPayload, SetAdminPayload, +}; + +const AUTHORIZATION_ADMIN_KEY: &str = "authotization_admin"; +const MULTI_SIG_SERVICE: &str = "multi_signature"; +const MULTI_SIG_METHOD: &str = "verify_signature"; + +pub struct AuthorizationService { + sdk: SDK, + verified_map: Box>, +} + +#[service] +impl AuthorizationService { + pub fn new(mut sdk: SDK) -> Self { + let mut verified_map: Box> = + sdk.alloc_or_recover_map("authotization"); + + verified_map.insert(MULTI_SIG_SERVICE.to_owned(), MULTI_SIG_METHOD.to_owned()); + + Self { sdk, verified_map } + } + + #[genesis] + fn init_genesis(&mut self, payload: InitGenesisPayload) { + let service_names = payload.register_service_names; + let function_names = payload.verified_method_names; + assert!(service_names.len() == function_names.len()); + + self.sdk + .set_value(AUTHORIZATION_ADMIN_KEY.to_string(), payload.admin); + + for item in service_names.into_iter().zip(function_names.into_iter()) { + self.verified_map.insert(item.0, item.1); + } + } + + #[cycles(210_00)] + #[read] + fn check_authorization(&self, ctx: ServiceContext, payload: String) -> ServiceResponse<()> { + for (service_name, mathod_name) in self.verified_map.iter() { + let resp = self._do_verify(&ctx, &service_name, &mathod_name, &payload); + if resp.is_error() { + return ServiceResponse::<()>::from_error( + 102, + format!( + "verify transaction {:?} error {:?}", + mathod_name, resp.error_message + ), + ); + } + } + + ServiceResponse::from_succeed(()) + } + + #[cycles(210_00)] + #[write] + fn add_verified_item( + &mut self, + ctx: ServiceContext, + payload: AddVerifiedItemPayload, + ) -> ServiceResponse<()> { + if !self._is_admin(&ctx) { + return ServiceResponse::<()>::from_error(103, "Invalid caller".to_owned()); + } + + self.verified_map + .insert(payload.service_name, payload.method_name); + ServiceResponse::from_succeed(()) + } + + #[cycles(210_00)] + #[write] + fn remove_verified_item( + &mut self, + ctx: ServiceContext, + payload: RemoveVerifiedItemPayload, + ) -> ServiceResponse<()> { + if !self._is_admin(&ctx) { + return ServiceResponse::<()>::from_error(103, "Invalid caller".to_owned()); + } + + self.verified_map.remove(&payload.service_name); + ServiceResponse::from_succeed(()) + } + + #[cycles(210_00)] + #[write] + fn set_admin(&mut self, ctx: ServiceContext, payload: SetAdminPayload) -> ServiceResponse<()> { + if !self._is_admin(&ctx) { + return ServiceResponse::<()>::from_error(103, "Invalid caller".to_owned()); + } + + self.sdk + .set_value(AUTHORIZATION_ADMIN_KEY.to_string(), payload.new_admin); + + ServiceResponse::from_succeed(()) + } + + fn _do_verify( + &self, + ctx: &ServiceContext, + service_name: &str, + method_name: &str, + payload_json: &str, + ) -> ServiceResponse { + self.sdk + .read(&ctx, None, service_name, method_name, &payload_json) + } + + fn _is_admin(&self, ctx: &ServiceContext) -> bool { + let admin: Address = self + .sdk + .get_value(&AUTHORIZATION_ADMIN_KEY.to_string()) + .expect("must have an admin"); + + ctx.get_caller() == admin + } +} diff --git a/built-in-services/authorization/src/types.rs b/built-in-services/authorization/src/types.rs new file mode 100644 index 000000000..385228ebe --- /dev/null +++ b/built-in-services/authorization/src/types.rs @@ -0,0 +1,29 @@ +use muta_codec_derive::RlpFixedCodec; +use serde::{Deserialize, Serialize}; + +use protocol::fixed_codec::{FixedCodec, FixedCodecError}; +use protocol::types::{Address, Bytes}; +use protocol::ProtocolResult; + +#[derive(RlpFixedCodec, Deserialize, Serialize, Clone, Debug)] +pub struct InitGenesisPayload { + pub admin: Address, + pub register_service_names: Vec, + pub verified_method_names: Vec, +} + +#[derive(RlpFixedCodec, Deserialize, Serialize, Clone, Debug)] +pub struct AddVerifiedItemPayload { + pub service_name: String, + pub method_name: String, +} + +#[derive(RlpFixedCodec, Deserialize, Serialize, Clone, Debug)] +pub struct RemoveVerifiedItemPayload { + pub service_name: String, +} + +#[derive(RlpFixedCodec, Deserialize, Serialize, Clone, Debug)] +pub struct SetAdminPayload { + pub new_admin: Address, +} diff --git a/built-in-services/multi-signature/src/lib.rs b/built-in-services/multi-signature/src/lib.rs index 189657a79..3454edc52 100644 --- a/built-in-services/multi-signature/src/lib.rs +++ b/built-in-services/multi-signature/src/lib.rs @@ -5,12 +5,13 @@ mod tests; pub mod types; use std::collections::HashMap; +use std::panic::catch_unwind; use binding_macro::{cycles, genesis, service}; use common_crypto::{Crypto, Secp256k1}; use protocol::traits::{ExecutorParams, ServiceResponse, ServiceSDK}; -use protocol::types::{Address, Bytes, Hash, ServiceContext}; +use protocol::types::{Address, Bytes, Hash, ServiceContext, SignedTransaction}; use crate::types::{ Account, AddAccountPayload, ChangeMemoPayload, ChangeOwnerPayload, @@ -175,91 +176,30 @@ impl MultiSignatureService { fn verify_signature( &self, ctx: ServiceContext, - payload: VerifySignaturePayload, + payload: SignedTransaction, ) -> ServiceResponse<()> { - let pubkeys = payload.pubkeys.clone(); - let signatures = payload.signatures.clone(); - - if pubkeys.len() != signatures.len() { - return ServiceResponse::<()>::from_error( - 114, - "pubkkeys len is not equal to signatures len".to_owned(), - ); - } - - if pubkeys.len() > MAX_PERMISSION_ACCOUNTS as usize { - return ServiceResponse::<()>::from_error( - 115, - "len of signatures must be [1,16]".to_owned(), - ); - } - - if pubkeys.len() == 1 { - if let Ok(addr) = Address::from_pubkey_bytes(pubkeys[0].clone()) { - if addr == payload.sender { - return self._verify_single_signature( - &ctx.get_tx_hash().unwrap(), - &signatures[0], - &pubkeys[0], - ); - } - } else { - return ServiceResponse::<()>::from_error(123, "invalid public key".to_owned()); - } - } - - let mut recursion_depth = 0u8; - self._verify_multi_signature( - &ctx.get_tx_hash().unwrap(), - &Witness::new(pubkeys, signatures).to_addr_map(), - &payload.sender, - &mut recursion_depth, - ) - } - - fn _verify_multi_signature( - &self, - tx_hash: &Hash, - wit_map: &HashMap, - sender: &Address, - recursion_depth: &mut u8, - ) -> ServiceResponse<()> { - // check recursion depth - *recursion_depth += 1; - if *recursion_depth >= MAX_MULTI_SIGNATURE_RECURSION_DEPTH { - return ServiceResponse::<()>::from_error(116, "above max recursion depth".to_owned()); - } - - let mut weight_acc = 0u32; - - let permission = self - .sdk - .get_account_value::<_, MultiSigPermission>(sender, &0u8); - if permission.is_none() { - return ServiceResponse::<()>::from_error(113, "account not existed".to_owned()); - } - let permission = permission.unwrap(); - - for account in permission.accounts.iter() { - if !account.is_multiple { - if let Some((pk, sig)) = wit_map.get(&account.address) { - if !self._verify_single_signature(tx_hash, sig, pk).is_error() { - weight_acc += account.weight as u32; - } - } - } else if !self - ._verify_multi_signature(tx_hash, wit_map, &account.address, recursion_depth) - .is_error() - { - weight_acc += account.weight as u32; - } + let pubkeys = if let Ok(pubkeys_bytes) = + catch_unwind(|| rlp::decode_list::>(&payload.pubkey.to_vec())) + { + pubkeys_bytes + } else { + return ServiceResponse::<()>::from_error(122, "decode pubkey failed".to_owned()); + }; - if weight_acc >= permission.threshold { - return ServiceResponse::<()>::from_succeed(()); - } - } + let sigs = if let Ok(sigs_bytes) = + catch_unwind(|| rlp::decode_list::>(&payload.signature.to_vec())) + { + sigs_bytes + } else { + return ServiceResponse::<()>::from_error(122, "decode signatures failed".to_owned()); + }; - ServiceResponse::<()>::from_error(117, "multi signature not verified".to_owned()) + self._inner_verify_signature(VerifySignaturePayload { + tx_hash: payload.tx_hash, + pubkeys: pubkeys.into_iter().map(Bytes::from).collect::>(), + signatures: sigs.into_iter().map(Bytes::from).collect::>(), + sender: payload.raw.sender, + }) } #[cycles(210_00)] @@ -279,7 +219,7 @@ impl MultiSignatureService { } // check owner signature - if self.verify_signature(ctx, payload.witness).is_error() { + if self._inner_verify_signature(payload.witness).is_error() { return ServiceResponse::<()>::from_error( 120, "owner signature verified failed".to_owned(), @@ -320,7 +260,7 @@ impl MultiSignatureService { } // check owner signature - if self.verify_signature(ctx, payload.witness).is_error() { + if self._inner_verify_signature(payload.witness).is_error() { return ServiceResponse::<()>::from_error( 120, "owner signature verified failed".to_owned(), @@ -361,7 +301,7 @@ impl MultiSignatureService { } // check owner signature - if self.verify_signature(ctx, payload.witness).is_error() { + if self._inner_verify_signature(payload.witness).is_error() { return ServiceResponse::<()>::from_error( 120, "owner signature verified failed".to_owned(), @@ -405,7 +345,7 @@ impl MultiSignatureService { } // check owner signature - if self.verify_signature(ctx, payload.witness).is_error() { + if self._inner_verify_signature(payload.witness).is_error() { return ServiceResponse::::from_error( 120, "owner signature verified failed".to_owned(), @@ -447,7 +387,7 @@ impl MultiSignatureService { } // check owner signature - if self.verify_signature(ctx, payload.witness).is_error() { + if self._inner_verify_signature(payload.witness).is_error() { return ServiceResponse::<()>::from_error( 120, "owner signature verified failed".to_owned(), @@ -503,7 +443,7 @@ impl MultiSignatureService { } // check owner signature - if self.verify_signature(ctx, payload.witness).is_error() { + if self._inner_verify_signature(payload.witness).is_error() { return ServiceResponse::<()>::from_error( 120, "owner signature verified failed".to_owned(), @@ -519,6 +459,92 @@ impl MultiSignatureService { } } + fn _inner_verify_signature(&self, payload: VerifySignaturePayload) -> ServiceResponse<()> { + let pubkeys = payload.pubkeys.clone(); + let signatures = payload.signatures.clone(); + + if pubkeys.len() != signatures.len() { + return ServiceResponse::<()>::from_error( + 114, + "pubkkeys len is not equal to signatures len".to_owned(), + ); + } + + if pubkeys.len() > MAX_PERMISSION_ACCOUNTS as usize { + return ServiceResponse::<()>::from_error( + 115, + "len of signatures must be [1,16]".to_owned(), + ); + } + + if pubkeys.len() == 1 { + if let Ok(addr) = Address::from_pubkey_bytes(pubkeys[0].clone()) { + if addr == payload.sender { + return self._verify_single_signature( + &payload.tx_hash, + &signatures[0], + &pubkeys[0], + ); + } + } else { + return ServiceResponse::<()>::from_error(123, "invalid public key".to_owned()); + } + } + + let mut recursion_depth = 0u8; + self._verify_multi_signature( + &payload.tx_hash, + &Witness::new(pubkeys, signatures).to_addr_map(), + &payload.sender, + &mut recursion_depth, + ) + } + + fn _verify_multi_signature( + &self, + tx_hash: &Hash, + wit_map: &HashMap, + sender: &Address, + recursion_depth: &mut u8, + ) -> ServiceResponse<()> { + // check recursion depth + *recursion_depth += 1; + if *recursion_depth >= MAX_MULTI_SIGNATURE_RECURSION_DEPTH { + return ServiceResponse::<()>::from_error(116, "above max recursion depth".to_owned()); + } + + let mut weight_acc = 0u32; + + let permission = self + .sdk + .get_account_value::<_, MultiSigPermission>(sender, &0u8); + if permission.is_none() { + return ServiceResponse::<()>::from_error(113, "account not existed".to_owned()); + } + let permission = permission.unwrap(); + + for account in permission.accounts.iter() { + if !account.is_multiple { + if let Some((pk, sig)) = wit_map.get(&account.address) { + if !self._verify_single_signature(tx_hash, sig, pk).is_error() { + weight_acc += account.weight as u32; + } + } + } else if !self + ._verify_multi_signature(tx_hash, wit_map, &account.address, recursion_depth) + .is_error() + { + weight_acc += account.weight as u32; + } + + if weight_acc >= permission.threshold { + return ServiceResponse::<()>::from_succeed(()); + } + } + + ServiceResponse::<()>::from_error(117, "multi signature not verified".to_owned()) + } + fn _verify_single_signature( &self, tx_hash: &Hash, diff --git a/built-in-services/multi-signature/src/tests/mod.rs b/built-in-services/multi-signature/src/tests/mod.rs index 0ca84b132..c3b809719 100644 --- a/built-in-services/multi-signature/src/tests/mod.rs +++ b/built-in-services/multi-signature/src/tests/mod.rs @@ -184,6 +184,7 @@ fn gen_single_witness(privkey: &Bytes, hash: &Hash) -> VerifySignaturePayload { pubkeys: vec![pk.clone()], signatures: vec![sig], sender: Address::from_pubkey_bytes(pk).unwrap(), + tx_hash: hash.clone(), } } diff --git a/built-in-services/multi-signature/src/tests/recursion_test.rs b/built-in-services/multi-signature/src/tests/recursion_test.rs index f94542e67..89953cdea 100644 --- a/built-in-services/multi-signature/src/tests/recursion_test.rs +++ b/built-in-services/multi-signature/src/tests/recursion_test.rs @@ -65,10 +65,11 @@ fn test_recursion_verify_signature() { assert_eq!(pks.len(), sigs.len()); - let res = service.verify_signature(ctx, VerifySignaturePayload { - pubkeys: pks, + let res = service._inner_verify_signature(VerifySignaturePayload { + pubkeys: pks, signatures: sigs, - sender: sender_new, + sender: sender_new, + tx_hash, }); assert_eq!(res.is_error(), false); diff --git a/built-in-services/multi-signature/src/types.rs b/built-in-services/multi-signature/src/types.rs index 28a2aa25f..9560dbec6 100644 --- a/built-in-services/multi-signature/src/types.rs +++ b/built-in-services/multi-signature/src/types.rs @@ -4,7 +4,7 @@ use muta_codec_derive::RlpFixedCodec; use serde::{Deserialize, Serialize}; use protocol::fixed_codec::{FixedCodec, FixedCodecError}; -use protocol::types::{Address, Bytes}; +use protocol::types::{Address, Bytes, Hash}; use protocol::ProtocolResult; #[derive(Clone, Debug)] @@ -45,6 +45,7 @@ pub struct GenerateMultiSigAccountResponse { #[derive(RlpFixedCodec, Deserialize, Serialize, Clone, Debug)] pub struct VerifySignaturePayload { + pub tx_hash: Hash, pub pubkeys: Vec, pub signatures: Vec, pub sender: Address, diff --git a/core/mempool/Cargo.toml b/core/mempool/Cargo.toml index d976d0ab5..df704a523 100644 --- a/core/mempool/Cargo.toml +++ b/core/mempool/Cargo.toml @@ -23,11 +23,13 @@ bytes = "0.5" rand = "0.7" hex = "0.4" serde_derive = "1.0" +serde_json = "1.0" serde = "1.0" futures-timer = "3.0" log = "0.4" tokio = { version = "0.2", features = ["macros", "rt-core", "sync", "blocking"]} muta-apm = "0.1.0-alpha.7" +cita_trie = "2.0" [dev-dependencies] chashmap = "2.2" diff --git a/core/mempool/src/adapter/mod.rs b/core/mempool/src/adapter/mod.rs index 9eb2f703b..3274eeaac 100644 --- a/core/mempool/src/adapter/mod.rs +++ b/core/mempool/src/adapter/mod.rs @@ -26,8 +26,11 @@ use log::{debug, error}; use common_crypto::Crypto; use protocol::{ fixed_codec::FixedCodec, - traits::{Context, Gossip, MemPoolAdapter, PeerTrust, Priority, Rpc, Storage, TrustFeedback}, - types::{Hash, SignedTransaction}, + traits::{ + Context, ExecutorFactory, ExecutorParams, Gossip, MemPoolAdapter, PeerTrust, Priority, Rpc, + ServiceMapping, Storage, TrustFeedback, + }, + types::{Address, Hash, SignedTransaction, TransactionRequest}, ProtocolError, ProtocolErrorKind, ProtocolResult, }; @@ -132,9 +135,11 @@ impl IntervalTxsBroadcaster { } } -pub struct DefaultMemPoolAdapter { - network: N, - storage: Arc, +pub struct DefaultMemPoolAdapter { + network: N, + storage: Arc, + trie_db: Arc, + service_mapping: Arc, timeout_gap: AtomicU64, cycles_limit: AtomicU64, @@ -143,18 +148,24 @@ pub struct DefaultMemPoolAdapter { stx_tx: UnboundedSender, err_rx: Mutex>, - pin_c: PhantomData, + pin_c: PhantomData, + pin_ef: PhantomData, } -impl DefaultMemPoolAdapter +impl DefaultMemPoolAdapter where + EF: ExecutorFactory, C: Crypto, N: Rpc + PeerTrust + Gossip + Clone + Unpin + 'static, S: Storage, + DB: cita_trie::DB + 'static, + Mapping: ServiceMapping + 'static, { pub fn new( network: N, storage: Arc, + trie_db: Arc, + service_mapping: Arc, broadcast_txs_size: usize, broadcast_txs_interval: u64, ) -> Self { @@ -178,6 +189,8 @@ where DefaultMemPoolAdapter { network, storage, + trie_db, + service_mapping, timeout_gap: AtomicU64::new(0), cycles_limit: AtomicU64::new(0), @@ -187,16 +200,20 @@ where err_rx: Mutex::new(err_rx), pin_c: PhantomData, + pin_ef: PhantomData, } } } #[async_trait] -impl MemPoolAdapter for DefaultMemPoolAdapter +impl MemPoolAdapter for DefaultMemPoolAdapter where + EF: ExecutorFactory, C: Crypto + Send + Sync + 'static, N: Rpc + PeerTrust + Gossip + Clone + Unpin + 'static, S: Storage + 'static, + DB: cita_trie::DB + 'static, + Mapping: ServiceMapping + 'static, { #[muta_apm::derive::tracing_span( kind = "mempool.adapter", @@ -237,10 +254,13 @@ where Ok(()) } - async fn check_signature(&self, ctx: Context, tx: SignedTransaction) -> ProtocolResult<()> { + async fn check_authorization(&self, ctx: Context, tx: SignedTransaction) -> ProtocolResult<()> { let network = self.network.clone(); + let network_clone = network.clone(); + let ctx_clone = ctx.clone(); + let tx_clone = tx.clone(); - let blocking_res = tokio::task::spawn_blocking(move || { + let blocking_res: Result, _> = tokio::task::spawn_blocking(move || { // Verify transaction hash let fixed_bytes = tx.raw.encode_fixed()?; let tx_hash = Hash::digest(fixed_bytes); @@ -263,37 +283,63 @@ where return Err(wrong_hash.into()); } - - let hash = tx.tx_hash.as_bytes(); - let pub_key = tx.pubkey.as_ref(); - let sig = tx.signature.as_ref(); - - C::verify_signature(hash.as_ref(), sig, pub_key).map_err(|_| { - if ctx.is_network_origin_txs() { - network.report( - ctx, - TrustFeedback::Worse(format!( - "Mempool wrong signature of tx {:?}", - tx.tx_hash - )), - ); - } - - MemPoolError::CheckSig { - tx_hash: tx.tx_hash, - } - .into() - }) + Ok(()) }) .await; - match blocking_res { - Ok(res) => res, - Err(_) => { - log::error!("[mempool] check_signature failed"); - Err(AdapterError::Internal.into()) + if blocking_res.is_err() || blocking_res.unwrap().is_err() { + return Err(AdapterError::Internal.into()); + } + + let stx_json = serde_json::to_string(&tx_clone).map_err(|_| { + network_clone.report( + ctx_clone.clone(), + TrustFeedback::Worse(format!("Mempool encode json error {:?}", tx_clone.tx_hash)), + ); + MemPoolError::EncodeJson + })?; + let payload_json = + serde_json::to_string(&stx_json).map_err(|_| MemPoolError::EncodeJson)?; + + let block = self.storage.get_latest_block(ctx_clone.clone()).await?; + let caller = Address::from_hex("0x0000000000000000000000000000000000000000")?; + let executor = EF::from_root( + block.header.state_root.clone(), + Arc::clone(&self.trie_db), + Arc::clone(&self.storage), + Arc::clone(&self.service_mapping), + )?; + let params = ExecutorParams { + state_root: block.header.state_root, + height: block.header.height, + timestamp: block.header.timestamp, + cycles_limit: 99999, + proposer: block.header.proposer, + }; + let check_resp = executor.read(¶ms, &caller, 1, &TransactionRequest { + service_name: "authorization".to_string(), + method: "check_authorization".to_string(), + payload: payload_json, + })?; + + if check_resp.is_error() { + if ctx_clone.is_network_origin_txs() { + network_clone.report( + ctx_clone, + TrustFeedback::Worse(format!( + "Mempool check authorization failed tx hash {:?}", + tx_clone.tx_hash.clone() + )), + ) } + + return Err(MemPoolError::CheckSig { + tx_hash: tx_clone.tx_hash, + } + .into()); } + + Ok(()) } async fn check_transaction(&self, ctx: Context, stx: SignedTransaction) -> ProtocolResult<()> { diff --git a/core/mempool/src/lib.rs b/core/mempool/src/lib.rs index d4ea3de15..e1f53f16b 100644 --- a/core/mempool/src/lib.rs +++ b/core/mempool/src/lib.rs @@ -102,7 +102,7 @@ where self.tx_cache.check_reach_limit(self.pool_size).await?; self.tx_cache.check_exist(tx_hash).await?; self.adapter - .check_signature(ctx.clone(), tx.clone()) + .check_authorization(ctx.clone(), tx.clone()) .await?; self.adapter .check_transaction(ctx.clone(), tx.clone()) @@ -125,11 +125,7 @@ where Ok(()) } - #[muta_apm::derive::tracing_span( - kind = "mempool", - logs = "{'txs': - 'txs.len()'}" - )] + #[muta_apm::derive::tracing_span(kind = "mempool", logs = "{'txs': 'txs.len()'}")] async fn verify_tx_in_parallel( &self, ctx: Context, @@ -146,7 +142,7 @@ where tokio::spawn(async move { adapter - .check_signature(ctx.clone(), signed_tx.clone()) + .check_authorization(ctx.clone(), signed_tx.clone()) .await?; adapter .check_transaction(ctx.clone(), signed_tx.clone()) @@ -442,6 +438,9 @@ pub enum MemPoolError { #[display(fmt = "Batch transaction validation failed")] VerifyBatchTransactions, + + #[display(fmt = "Encode transaction to JSON failed")] + EncodeJson, } impl Error for MemPoolError {} diff --git a/core/mempool/src/tests/mempool.rs b/core/mempool/src/tests/mempool.rs index 0da3afa2e..e6ca90662 100644 --- a/core/mempool/src/tests/mempool.rs +++ b/core/mempool/src/tests/mempool.rs @@ -379,7 +379,7 @@ async fn bench_sign_with_spawn_list() { let adapter = Arc::clone(&adapter); tokio::spawn(async move { adapter - .check_signature(Context::new(), tx.clone()) + .check_authorization(Context::new(), tx.clone()) .await .unwrap(); }) @@ -402,7 +402,7 @@ async fn bench_sign() { for tx in txs.iter() { adapter - .check_signature(Context::new(), tx.clone()) + .check_authorization(Context::new(), tx.clone()) .await .unwrap(); } diff --git a/core/mempool/src/tests/mod.rs b/core/mempool/src/tests/mod.rs index f78d2d4dd..8347310f2 100644 --- a/core/mempool/src/tests/mod.rs +++ b/core/mempool/src/tests/mod.rs @@ -65,7 +65,11 @@ impl MemPoolAdapter for HashMemPoolAdapter { Ok(()) } - async fn check_signature(&self, _ctx: Context, tx: SignedTransaction) -> ProtocolResult<()> { + async fn check_authorization( + &self, + _ctx: Context, + tx: SignedTransaction, + ) -> ProtocolResult<()> { check_hash(tx.clone()).await?; check_sig(&tx) } diff --git a/examples/muta-chain.rs b/examples/muta-chain.rs index f8f448f8a..7486fbbc2 100644 --- a/examples/muta-chain.rs +++ b/examples/muta-chain.rs @@ -1,6 +1,8 @@ use asset::AssetService; +use authorization::AuthorizationService; use derive_more::{Display, From}; use metadata::MetadataService; +use multi_signature::MultiSignatureService; use muta::MutaBuilder; use protocol::traits::{Service, ServiceMapping, ServiceSDK}; use protocol::{ProtocolError, ProtocolErrorKind, ProtocolResult}; @@ -16,7 +18,9 @@ impl ServiceMapping for DefaultServiceMapping { ) -> ProtocolResult> { let service = match name { "asset" => Box::new(AssetService::new(sdk)) as Box, + "authorization" => Box::new(AuthorizationService::new(sdk)) as Box, "metadata" => Box::new(MetadataService::new(sdk)) as Box, + "multi_signature" => Box::new(MultiSignatureService::new(sdk)) as Box, "util" => Box::new(UtilService::new(sdk)) as Box, _ => { return Err(MappingError::NotFoundService { @@ -30,7 +34,13 @@ impl ServiceMapping for DefaultServiceMapping { } fn list_service_name(&self) -> Vec { - vec!["asset".to_owned(), "metadata".to_owned(), "util".to_owned()] + vec![ + "asset".to_owned(), + "authorization".to_owned(), + "metadata".to_owned(), + "multi_signature".to_owned(), + "util".to_owned(), + ] } } diff --git a/framework/src/executor/mod.rs b/framework/src/executor/mod.rs index 94b10b85b..acf1d70cb 100644 --- a/framework/src/executor/mod.rs +++ b/framework/src/executor/mod.rs @@ -325,11 +325,10 @@ impl ProtocolResult<()>; - async fn check_signature(&self, ctx: Context, tx: SignedTransaction) -> ProtocolResult<()>; + async fn check_authorization(&self, ctx: Context, tx: SignedTransaction) -> ProtocolResult<()>; async fn check_transaction(&self, ctx: Context, tx: SignedTransaction) -> ProtocolResult<()>; diff --git a/protocol/src/types/transaction.rs b/protocol/src/types/transaction.rs index 6693d8121..8a52bebc0 100644 --- a/protocol/src/types/transaction.rs +++ b/protocol/src/types/transaction.rs @@ -1,11 +1,12 @@ use bytes::Bytes; use muta_codec_derive::RlpFixedCodec; +use serde::{Deserialize, Serialize}; use crate::fixed_codec::{FixedCodec, FixedCodecError}; use crate::types::primitive::{Address, Hash, JsonString}; use crate::ProtocolResult; -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub struct RawTransaction { pub chain_id: Hash, pub cycles_price: u64, @@ -16,14 +17,14 @@ pub struct RawTransaction { pub sender: Address, } -#[derive(RlpFixedCodec, Clone, Debug, PartialEq, Eq)] +#[derive(RlpFixedCodec, Deserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub struct TransactionRequest { pub method: String, pub service_name: String, pub payload: JsonString, } -#[derive(RlpFixedCodec, Clone, Debug, PartialEq, Eq)] +#[derive(RlpFixedCodec, Deserialize, Serialize, Clone, Debug, PartialEq, Eq)] pub struct SignedTransaction { pub raw: RawTransaction, pub tx_hash: Hash, diff --git a/src/default_start.rs b/src/default_start.rs index 9dad3ab70..1281ba84b 100644 --- a/src/default_start.rs +++ b/src/default_start.rs @@ -199,14 +199,25 @@ pub async fn start( .listen(config.network.listening_address) .await?; + // Init trie db + let path_state = config.data_path_for_state(); + let trie_db = Arc::new(RocksTrieDB::new( + path_state, + config.executor.light, + config.rocksdb.max_open_files, + )?); + // Init mempool let current_block = storage.get_latest_block(Context::new()).await?; - let mempool_adapter = DefaultMemPoolAdapter::::new( - network_service.handle(), - Arc::clone(&storage), - config.mempool.broadcast_txs_size, - config.mempool.broadcast_txs_interval, - ); + let mempool_adapter = + DefaultMemPoolAdapter::::new( + network_service.handle(), + Arc::clone(&storage), + Arc::clone(&trie_db), + Arc::clone(&service_mapping), + config.mempool.broadcast_txs_size, + config.mempool.broadcast_txs_interval, + ); let mempool = Arc::new(HashMemPool::new( config.mempool.pool_size as usize, mempool_adapter, @@ -222,14 +233,6 @@ pub async fn start( } }); - // Init trie db - let path_state = config.data_path_for_state(); - let trie_db = Arc::new(RocksTrieDB::new( - path_state, - config.executor.light, - config.rocksdb.max_open_files, - )?); - // self private key let hex_privkey = hex::decode(config.privkey.as_string_trim0x()).map_err(MainError::FromHex)?; let my_privkey = diff --git a/tests/e2e/multisig.ts b/tests/e2e/multisig.ts new file mode 100644 index 000000000..cb82905fa --- /dev/null +++ b/tests/e2e/multisig.ts @@ -0,0 +1,29 @@ +import { Address } from '@mutajs/types'; +import { createBindingClass, write, Write } from '@mutajs/service'; + +type u8 = number; +type u32 = number; + +interface AddressWithWeight { + address: Address, + weight: u8, // u8 +} + +interface GenerateMultiSigAccountPayload { + owner: Address, + addr_with_weight: Array, + threshold: u32, + memo: string, +} + +interface GenerateMultiSigAccountResponse { + address: Address, +} + +export interface MultiSigServiceModel { + generate_account: Write; +} + +export const MultiSigService = createBindingClass('multi_signature', { + generate_account: write(), +}); diff --git a/tests/e2e/package.json b/tests/e2e/package.json index 2c1a97a12..b5057995f 100644 --- a/tests/e2e/package.json +++ b/tests/e2e/package.json @@ -10,12 +10,15 @@ "prettier": "prettier --write **/*.{js,ts,graphql}" }, "dependencies": { - "@mutajs/service": "^0.11.0-next.feature.1816be9", + "@mutajs/service": "^0.11.2-dev.0", + "@mutajs/account": "^0.11.2-dev.0", + "@mutajs/utils": "^0.11.2-dev.0", + "@mutajs/client": "^0.11.2-dev.0", "@types/node": "^12.12.8", "apollo-boost": "^0.4.4", "graphql": "^14.5.8", "graphql-tag": "^2.10.1", - "muta-sdk": "^0.11.0-dev.0", + "muta-sdk": "^0.11.2-dev.0", "node-fetch": "^2.6.0", "toml": "^3.0.0", "ts-node": "^8.3.0", diff --git a/tests/e2e/sdk.test.ts b/tests/e2e/sdk.test.ts index 0489d930b..ab9063161 100644 --- a/tests/e2e/sdk.test.ts +++ b/tests/e2e/sdk.test.ts @@ -1,6 +1,10 @@ -import { AssetService } from "@mutajs/service" -import * as sdk from "muta-sdk"; -import { mutaClient } from "./utils"; +import { Account } from '@mutajs/account'; +import { AssetService } from '@mutajs/service' +import { toHex } from '@mutajs/utils'; +import { retry } from '@mutajs/client'; +import * as sdk from 'muta-sdk'; +import { mutaClient } from './utils'; +import { MultiSigService } from './multisig'; describe("API test via muta-sdk-js", () => { test("getLatestBlock", async () => { @@ -53,4 +57,60 @@ describe("API test via muta-sdk-js", () => { const c2 = to_balance_before.succeedData.balance as number; expect(to_balance_after.succeedData.balance).toBe(c2 + 1); }); + + test('multisig', async () => { + const wangYe = Account.fromPrivateKey( + '0x1000000000000000000000000000000000000000000000000000000000000000', + ); + const qing = Account.fromPrivateKey( + '0x2000000000000000000000000000000000000000000000000000000000000000', + ); + + const multiSigService = new MultiSigService(mutaClient, wangYe.address, wangYe); + + const GenerateMultiSigAccountPayload = { + owner: wangYe.address, + addr_with_weight: [{ address: wangYe.address, weight: 1 }, { address: qing.address, weight: 1 }], + threshold: 2, + memo: 'welcome to BiYouCun' + }; + const generated = await multiSigService.generate_account(GenerateMultiSigAccountPayload); + expect(Number(generated.response.response.code)).toBe(0); + + const multiSigAddress = generated.response.response.succeedData.address; + const createAssetTx = await mutaClient.composeTransaction({ + method: 'create_asset', + payload: { + name: 'miao', + supply: 2077, + symbol: '😺', + }, + serviceName: 'asset', + sender: multiSigAddress, + }); + + const signedCreateAssetTx = wangYe.signTransaction(createAssetTx); + try { + await mutaClient.sendTransaction(signedCreateAssetTx); + throw 'should failed'; + } catch(e) { + expect(String(e)).toContain('CheckSig'); + } + + const bothSignedCreateAssetTx = qing.signMultiSigTransaction(signedCreateAssetTx); + const txHash = await mutaClient.sendTransaction(bothSignedCreateAssetTx); + const receipt = await retry(() => mutaClient.getReceipt(toHex(txHash))); + expect(Number(receipt.response.response.code)).toBe(0); + + // MultiSig address balance + const asset = JSON.parse(receipt.response.response.succeedData); + const assetService = new AssetService(mutaClient, wangYe.address, wangYe); + const balance = await assetService.get_balance({ + asset_id: asset.id, + user: multiSigAddress, + }); + + expect(Number(balance.code)).toBe(0); + expect(Number(balance.succeedData.balance)).toBe(2077); + }); }); diff --git a/tests/e2e/yarn.lock b/tests/e2e/yarn.lock index feb5d8be1..698881e26 100644 --- a/tests/e2e/yarn.lock +++ b/tests/e2e/yarn.lock @@ -286,88 +286,88 @@ "@types/istanbul-reports" "^1.1.1" "@types/yargs" "^13.0.0" -"@mutajs/account@^0.11.0-next.feature.1816be9": - version "0.11.0-next.feature.1816be9" - resolved "https://registry.npmjs.org/@mutajs/account/-/account-0.11.0-next.feature.1816be9.tgz#8a13ce2c796af9a5085b9b3da32cfd5f2ab4b202" - integrity sha512-koB+JXQXqDIwFHhTdv2GHOhLhEx6ysOB+wruQdmagBkk6C27EMCic47o98JEl1mxT+8g261L1Vye2+3YgB9fQQ== +"@mutajs/account@^0.11.2-dev.0": + version "0.11.2-dev.0" + resolved "https://registry.npmjs.org/@mutajs/account/-/account-0.11.2-dev.0.tgz#34d046817e7bad79188ebc0b03a9fe3125a22580" + integrity sha512-80/f97hbIqnaN1+inN6N3fJRfJkvxfzdl3ma2JDFAtMoghI5r6WmoPjX5t67f3yip6nl/FsJstay5C9Q4qJQTA== dependencies: - "@mutajs/utils" "^0.11.0-next.feature.1816be9" + "@mutajs/utils" "^0.11.2-dev.0" -"@mutajs/client-raw@^0.11.0-next.feature.1816be9": - version "0.11.0-next.feature.1816be9" - resolved "https://registry.npmjs.org/@mutajs/client-raw/-/client-raw-0.11.0-next.feature.1816be9.tgz#49b132559b1dfa549fb078bd1370e10116e5e5e9" - integrity sha512-srA5392yc5NRBBpM0F3wqhA673a1lNpFAZ/3yyMNU4MYVBcJLQtADlC3+6Yn7SZp4trGaeA0EUbW/HCVSrl32g== +"@mutajs/client-raw@^0.11.2-dev.0": + version "0.11.2-dev.0" + resolved "https://registry.npmjs.org/@mutajs/client-raw/-/client-raw-0.11.2-dev.0.tgz#8aa820ab85fd8a4e639723ec0418e4e94a4ce6d6" + integrity sha512-M5bWbVMRcr89+GivV6MkrM4gJP96nifUXbu5RFMkk2THiezA/ESnsWnovQZAUs0nCT0Hx0RtcKhHW3dCNp8m4A== dependencies: graphql-request "^1.8.2" graphql-tag "^2.10.1" -"@mutajs/client@^0.11.0-next.feature.1816be9": - version "0.11.0-next.feature.1816be9" - resolved "https://registry.npmjs.org/@mutajs/client/-/client-0.11.0-next.feature.1816be9.tgz#1f72a66e7772ce9a2fdb3595a88d5371a808e6c7" - integrity sha512-BlavCauoW5XJpLSP9YQ0muG9Hqm4fUNj0AiplnzoheTL8429Xob/ZMe8DaIBH0o2BZImNC+BEydk9lGD/+3tcQ== +"@mutajs/client@^0.11.2-dev.0": + version "0.11.2-dev.0" + resolved "https://registry.npmjs.org/@mutajs/client/-/client-0.11.2-dev.0.tgz#83f87ef8e95bcdabead64431cf05f8bb3c183573" + integrity sha512-czCq35wbpNY/WTeogzwJAxSVk7H3gdKoF9JFB0LtS/WPgkchNgRy/hjQafrFb0HolD/UMAtWjOVmIqrd6DAGoA== dependencies: - "@mutajs/client-raw" "^0.11.0-next.feature.1816be9" - "@mutajs/defaults" "^0.11.0-next.feature.1816be9" - "@mutajs/shared" "^0.11.0-next.feature.1816be9" - "@mutajs/types" "^0.11.0-next.feature.1816be9" - "@mutajs/utils" "^0.11.0-next.feature.1816be9" + "@mutajs/client-raw" "^0.11.2-dev.0" + "@mutajs/defaults" "^0.11.2-dev.0" + "@mutajs/shared" "^0.11.2-dev.0" + "@mutajs/types" "^0.11.2-dev.0" + "@mutajs/utils" "^0.11.2-dev.0" "@types/lodash" "^4.14.149" invariant "^2.2.4" lodash "^4.17.15" p-limit "^2.3.0" utility-types "^3.10.0" -"@mutajs/defaults@^0.11.0-next.feature.1816be9": - version "0.11.0-next.feature.1816be9" - resolved "https://registry.npmjs.org/@mutajs/defaults/-/defaults-0.11.0-next.feature.1816be9.tgz#8b55fbc36aeebe73fee3950af1fbb4c85630fa82" - integrity sha512-JCj7NujnlLgN45wb5BQw3ppEtUl+kI9aTKTJ+Wv8dEqH0bxI7/WosuDNrH6XY8tQC7yTTsXiLZxcHDls1x2rNg== +"@mutajs/defaults@^0.11.2-dev.0": + version "0.11.2-dev.0" + resolved "https://registry.npmjs.org/@mutajs/defaults/-/defaults-0.11.2-dev.0.tgz#03b7f76b236e08992d09c7a32cb37598ac05a191" + integrity sha512-0YS1doMN7Ofr/13omaz7ykeRk4X5ey1GDyeJUbAC+qedT3sQkViTn+/2b9eO/tZ+R2IB4GJYXY5ryZBqZDD87A== -"@mutajs/service@^0.11.0-next.feature.1816be9": - version "0.11.0-next.feature.1816be9" - resolved "https://registry.npmjs.org/@mutajs/service/-/service-0.11.0-next.feature.1816be9.tgz#26b9a59cac5d79055eb411b5ec576488b3160802" - integrity sha512-1jp2mWU5CmGqaSSKrkBTLEzyRkslFM+HJbhKNDrv1+fm1IuAHg0uD+NxpaiV87QqcmHFjZ53hAnsTlPXC3IiXQ== +"@mutajs/service@^0.11.2-dev.0": + version "0.11.2-dev.0" + resolved "https://registry.npmjs.org/@mutajs/service/-/service-0.11.2-dev.0.tgz#425cae8ddb31b55d42974ff6ff447c4650064bd3" + integrity sha512-FbHcLtZtdslTbvB35XoJkuwel/D5iikB1nAgel75nCD6JZ54aB5YZIaO6p4GEqbMuxdJt/auttB6gH2lhFmIbw== dependencies: - "@mutajs/account" "^0.11.0-next.feature.1816be9" - "@mutajs/client" "^0.11.0-next.feature.1816be9" - "@mutajs/shared" "^0.11.0-next.feature.1816be9" - "@mutajs/types" "^0.11.0-next.feature.1816be9" - "@mutajs/utils" "^0.11.0-next.feature.1816be9" + "@mutajs/account" "^0.11.2-dev.0" + "@mutajs/client" "^0.11.2-dev.0" + "@mutajs/shared" "^0.11.2-dev.0" + "@mutajs/types" "^0.11.2-dev.0" + "@mutajs/utils" "^0.11.2-dev.0" -"@mutajs/shared@^0.11.0-next.feature.1816be9": - version "0.11.0-next.feature.1816be9" - resolved "https://registry.npmjs.org/@mutajs/shared/-/shared-0.11.0-next.feature.1816be9.tgz#f29ec8342a144bf18b88230cdaccb1fc8d70299e" - integrity sha512-wEVHSjck0au+dTOJPTQyl7N7jA8Lft2kzI4ibHHs1N7veWXzLHl90IB7hhVbhkUvY/T4WPZ/OnEwnCMluATZmg== +"@mutajs/shared@^0.11.2-dev.0": + version "0.11.2-dev.0" + resolved "https://registry.npmjs.org/@mutajs/shared/-/shared-0.11.2-dev.0.tgz#448fcf7476f1f616516b4fccf9d2fa316917a9f8" + integrity sha512-ltxkJFwexloR4vEfOwfPCwgJLn+kPMXP5S7MaYfsi3nfbzsz78HrpgTIBfGoe1zukRQOjH/PUp+m/wEX4orUTg== dependencies: "@types/invariant" "^2.2.4" bignumber.js "^9.0.0" invariant "^2.2.4" -"@mutajs/types@^0.11.0-next.feature.1816be9": - version "0.11.0-next.feature.1816be9" - resolved "https://registry.npmjs.org/@mutajs/types/-/types-0.11.0-next.feature.1816be9.tgz#78ce0b512e6dccb2b846f7e2de7f7e85c0fecbb5" - integrity sha512-SO9Lksa2EW7tKGdojh050sP54G5WoensFVGSPavHAYZdztLKF7e8fOYPDsKHQtuyn9oUon8lBU52g+M9vVbUsw== +"@mutajs/types@^0.11.2-dev.0": + version "0.11.2-dev.0" + resolved "https://registry.npmjs.org/@mutajs/types/-/types-0.11.2-dev.0.tgz#bdffdf501b12b2ced2743d0fe3405e25a23c1209" + integrity sha512-g6g9grPy7jPhF6Ouu+th3wYJDtL6XVKm8iAHtDwSfBJIkJSzHJPGgSB9pv0cAGrKMWPsa/2owQsfsiOwQoLlwA== dependencies: bignumber.js "^9.0.0" -"@mutajs/utils@^0.11.0-next.feature.1816be9": - version "0.11.0-next.feature.1816be9" - resolved "https://registry.npmjs.org/@mutajs/utils/-/utils-0.11.0-next.feature.1816be9.tgz#20fbd18d510ac3694e0a5962a29b1bff02616b92" - integrity sha512-azFzHw2+60r4+5QiTpd1sCd7D31gaSd8ZJyyRYqVqAqJr+TxDwKBmepsV0T/HUsqlaHdBzrAZ1wLhbsh9iCSJQ== +"@mutajs/utils@^0.11.2-dev.0": + version "0.11.2-dev.0" + resolved "https://registry.npmjs.org/@mutajs/utils/-/utils-0.11.2-dev.0.tgz#a72715fb29f0063987f0bde83342963236e42e9a" + integrity sha512-jgrJVuVAtoEA+kVXAytIH+lCRWjE4FRh/IeINJ9BpIqhF+eycHmgHjVVk8iVaZQVYGzJXPYoyxy7bqg1rsjwMQ== dependencies: - "@mutajs/types" "^0.11.0-next.feature.1816be9" + "@mutajs/types" "^0.11.2-dev.0" json-bigint "^0.3.0" keccak "^3.0.0" randombytes "^2.1.0" rlp "^2.2.5" secp256k1 "^4.0.0" -"@mutajs/wallet@^0.11.0-next.feature.1816be9": - version "0.11.0-next.feature.1816be9" - resolved "https://registry.npmjs.org/@mutajs/wallet/-/wallet-0.11.0-next.feature.1816be9.tgz#bb8efc89bcd1056f0c848397dd8d03fdaff8afd5" - integrity sha512-55HdWjZCvulJxG1+EvHc/gVgmRr6e51jv79p8/mxVnf+Aqwx82CPkKsLSvIO1j5/TbeiTuA3s4z4MrfmprSxoA== +"@mutajs/wallet@^0.11.2-dev.0": + version "0.11.2-dev.0" + resolved "https://registry.npmjs.org/@mutajs/wallet/-/wallet-0.11.2-dev.0.tgz#281b7dbd720a76df265ee5615afb5239f7895a52" + integrity sha512-6JTdkafqUKXBw0wEfHGYdIR+oDAZNTVGOpdi2Y8xd0C7tT5Z7sOVHGD69JcGUkE3QvCvFWpqOdSqt2CtB7P5pQ== dependencies: - "@mutajs/account" "^0.11.0-next.feature.1816be9" - "@mutajs/utils" "^0.11.0-next.feature.1816be9" + "@mutajs/account" "^0.11.2-dev.0" + "@mutajs/utils" "^0.11.2-dev.0" bip39 "^3.0.2" hdkey "^1.1.1" @@ -2812,17 +2812,17 @@ ms@^2.1.1: resolved "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk= -muta-sdk@^0.11.0-dev.0: - version "0.11.0-next.feature.1816be9" - resolved "https://registry.npmjs.org/muta-sdk/-/muta-sdk-0.11.0-next.feature.1816be9.tgz#b91b85653cf8884c03d88a9b2d97017b8a202f61" - integrity sha512-NwMB0iGkpox9HX5nCq2PIBCJrM3L9FeCgXJ93uaWER2Ik7NpsEyQIsujPNL0HpHS8xgyw0dLU7aeSOn/6enPhw== - dependencies: - "@mutajs/account" "^0.11.0-next.feature.1816be9" - "@mutajs/client" "^0.11.0-next.feature.1816be9" - "@mutajs/defaults" "^0.11.0-next.feature.1816be9" - "@mutajs/shared" "^0.11.0-next.feature.1816be9" - "@mutajs/types" "^0.11.0-next.feature.1816be9" - "@mutajs/wallet" "^0.11.0-next.feature.1816be9" +muta-sdk@^0.11.2-dev.0: + version "0.11.2-dev.0" + resolved "https://registry.npmjs.org/muta-sdk/-/muta-sdk-0.11.2-dev.0.tgz#7f0dc8f721984685966c17e7c71bbe24e876d554" + integrity sha512-94NVoH2UEaOcXMvkALEnB2RCirvNBMGau5KkocfCrMCE0rAP9hq0WVyZAAgullWLH/+L3fjMcaKNGjtt3/pG9A== + dependencies: + "@mutajs/account" "^0.11.2-dev.0" + "@mutajs/client" "^0.11.2-dev.0" + "@mutajs/defaults" "^0.11.2-dev.0" + "@mutajs/shared" "^0.11.2-dev.0" + "@mutajs/types" "^0.11.2-dev.0" + "@mutajs/wallet" "^0.11.2-dev.0" utility-types "^3.10.0" nan@^2.12.1, nan@^2.14.0: diff --git a/tests/trust_metric_all/common.rs b/tests/trust_metric_all/common.rs index 4b06a1100..885e1a268 100644 --- a/tests/trust_metric_all/common.rs +++ b/tests/trust_metric_all/common.rs @@ -105,8 +105,11 @@ impl SignedTransactionBuilder { SignedTransaction { raw, tx_hash, - pubkey: pk.pub_key().to_bytes(), - signature: sig.to_bytes(), + pubkey: Bytes::from(rlp::encode_list::, _>(&[pk + .pub_key() + .to_bytes() + .to_vec()])), + signature: Bytes::from(rlp::encode_list::, _>(&[sig.to_bytes().to_vec()])), } } } diff --git a/tests/trust_metric_all/node/full_node.rs b/tests/trust_metric_all/node/full_node.rs index ff6533d95..8893e463a 100644 --- a/tests/trust_metric_all/node/full_node.rs +++ b/tests/trust_metric_all/node/full_node.rs @@ -7,8 +7,10 @@ use super::{common, config, consts, diagnostic}; use builder::MutaBuilder; use asset::AssetService; +use authorization::AuthorizationService; use derive_more::{Display, From}; use metadata::MetadataService; +use multi_signature::MultiSignatureService; use protocol::traits::{Service, ServiceMapping, ServiceSDK}; use protocol::{ProtocolError, ProtocolErrorKind, ProtocolResult}; @@ -22,7 +24,9 @@ impl ServiceMapping for DefaultServiceMapping { ) -> ProtocolResult> { let service = match name { "asset" => Box::new(AssetService::new(sdk)) as Box, + "authorization" => Box::new(AuthorizationService::new(sdk)) as Box, "metadata" => Box::new(MetadataService::new(sdk)) as Box, + "multi_signature" => Box::new(MultiSignatureService::new(sdk)) as Box, _ => { return Err(MappingError::NotFoundService { service: name.to_owned(), @@ -35,7 +39,12 @@ impl ServiceMapping for DefaultServiceMapping { } fn list_service_name(&self) -> Vec { - vec!["asset".to_owned(), "metadata".to_owned()] + vec![ + "asset".to_owned(), + "authorization".to_owned(), + "metadata".to_owned(), + "multi_signature".to_owned(), + ] } } diff --git a/tests/trust_metric_all/node/full_node/default_start.rs b/tests/trust_metric_all/node/full_node/default_start.rs index 98ea95dfc..c2b6ac9a3 100644 --- a/tests/trust_metric_all/node/full_node/default_start.rs +++ b/tests/trust_metric_all/node/full_node/default_start.rs @@ -194,12 +194,15 @@ pub async fn start( // Init mempool let current_block = storage.get_latest_block(Context::new()).await?; - let mempool_adapter = DefaultMemPoolAdapter::::new( - network_service.handle(), - Arc::clone(&storage), - config.mempool.broadcast_txs_size, - config.mempool.broadcast_txs_interval, - ); + let mempool_adapter = + DefaultMemPoolAdapter::::new( + network_service.handle(), + Arc::clone(&storage), + Arc::new(db.clone()), + Arc::clone(&service_mapping), + config.mempool.broadcast_txs_size, + config.mempool.broadcast_txs_interval, + ); let mempool = Arc::new(HashMemPool::new(consts::MEMPOOL_POOL_SIZE, mempool_adapter)); // self private key