From 7f737cdfc9353148b945ad52dd5ab3fd46e2c4db Mon Sep 17 00:00:00 2001 From: Wenchao Hu Date: Fri, 25 Oct 2019 19:21:06 +0800 Subject: [PATCH] feat: change rlp in executor to fixed-codec (#29) * change rlp in executor to fixed-codec * change ContractSer to ProtocolFixedCodec * fix cigst * impl schema for bytes --- Cargo.lock | 1 - core/executor/Cargo.toml | 1 - core/executor/src/adapter/contract.rs | 16 +- core/executor/src/fixed_types/mod.rs | 425 +----------------- core/executor/src/native_contract/account.rs | 32 +- core/executor/src/native_contract/bank.rs | 18 +- .../src/tests/general_state_adapter.rs | 64 +-- protocol/src/fixed_codec/primitive.rs | 10 + protocol/src/traits/executor/mod.rs | 13 +- 9 files changed, 75 insertions(+), 505 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 60612b353..e33bfe047 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -476,7 +476,6 @@ dependencies = [ "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "protocol 0.1.0", - "rlp 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rocksdb 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/core/executor/Cargo.toml b/core/executor/Cargo.toml index a340d49a8..82cb415dc 100644 --- a/core/executor/Cargo.toml +++ b/core/executor/Cargo.toml @@ -14,6 +14,5 @@ cita_trie = "2.0" bytes = "0.4" lazy_static = "1.4" derive_more = "0.15" -rlp = "0.4" rocksdb = "0.12" hex = "0.3" diff --git a/core/executor/src/adapter/contract.rs b/core/executor/src/adapter/contract.rs index 10dcbbe35..215944e05 100644 --- a/core/executor/src/adapter/contract.rs +++ b/core/executor/src/adapter/contract.rs @@ -6,8 +6,9 @@ use std::rc::Rc; use bytes::Bytes; use derive_more::{Display, From}; +use protocol::fixed_codec::ProtocolFixedCodec; use protocol::traits::executor::contract::ContractStateAdapter; -use protocol::traits::executor::{ContractSchema, ContractSer, TrieDB}; +use protocol::traits::executor::{ContractSchema, TrieDB}; use protocol::types::MerkleRoot; use protocol::{ProtocolError, ProtocolErrorKind, ProtocolResult}; @@ -40,20 +41,20 @@ impl ContractStateAdapter for GeneralContractStateAdapter { &self, key: &::Key, ) -> ProtocolResult::Value>> { - let encoded_key = key.encode()?; + let encoded_key = key.encode_fixed()?; if let Some(value_bytes) = self.cache_map.get(&encoded_key) { - let inst = <_>::decode(value_bytes.clone())?; + let inst = <_>::decode_fixed(value_bytes.clone())?; return Ok(Some(inst)); } if let Some(value_bytes) = self.stash_map.get(&encoded_key) { - let inst = <_>::decode(value_bytes.clone())?; + let inst = <_>::decode_fixed(value_bytes.clone())?; return Ok(Some(inst)); } if let Some(value_bytes) = self.trie.get(&encoded_key)? { - return Ok(Some(Schema::Value::decode(value_bytes)?)); + return Ok(Some(Schema::Value::decode_fixed(value_bytes)?)); } Ok(None) @@ -63,7 +64,7 @@ impl ContractStateAdapter for GeneralContractStateAdapter { &self, key: &::Key, ) -> ProtocolResult { - let encoded_key = key.encode()?; + let encoded_key = key.encode_fixed()?; if self.cache_map.contains_key(&encoded_key) { return Ok(true); @@ -81,7 +82,8 @@ impl ContractStateAdapter for GeneralContractStateAdapter { key: ::Key, value: ::Value, ) -> ProtocolResult<()> { - self.cache_map.insert(key.encode()?, value.encode()?); + self.cache_map + .insert(key.encode_fixed()?, value.encode_fixed()?); Ok(()) } diff --git a/core/executor/src/fixed_types/mod.rs b/core/executor/src/fixed_types/mod.rs index a0502d68e..a13ec0cee 100644 --- a/core/executor/src/fixed_types/mod.rs +++ b/core/executor/src/fixed_types/mod.rs @@ -1,422 +1,23 @@ -use std::collections::BTreeMap; -use std::error::Error; - use bytes::Bytes; -use derive_more::{Display, From}; - -use protocol::traits::executor::{ContractSchema, ContractSer}; -use protocol::types::{ - Account, Address, ApprovedInfo, Asset, AssetID, AssetInfo, Balance, ContractAccount, - ContractAddress, Hash, MerkleRoot, UserAccount, -}; -use protocol::{ProtocolError, ProtocolErrorKind, ProtocolResult}; - -pub struct FixedAssetSchema; -impl ContractSchema for FixedAssetSchema { - type Key = FixedAssetID; - type Value = FixedAsset; -} - -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -pub struct FixedAssetID { - inner: AssetID, -} - -impl FixedAssetID { - pub fn new(inner: AssetID) -> Self { - Self { inner } - } -} - -impl ContractSer for FixedAssetID { - fn encode(&self) -> ProtocolResult { - Ok(self.inner.as_bytes()) - } - - fn decode(bytes: Bytes) -> ProtocolResult { - let id = AssetID::from_bytes(bytes)?; - Ok(FixedAssetID { inner: id }) - } -} - -/// the `FixedAsset` is a wrapper type of asset just to provide a consistent -/// serialization algorithm `rlp`. -#[derive(Clone, Debug)] -pub struct FixedAsset { - pub inner: Asset, -} - -impl FixedAsset { - pub fn new(inner: Asset) -> Self { - Self { inner } - } -} - -impl ContractSer for FixedAsset { - fn encode(&self) -> ProtocolResult { - Ok(Bytes::from(rlp::encode(self))) - } - fn decode(bytes: Bytes) -> ProtocolResult { - Ok(rlp::decode(bytes.as_ref()).map_err(FixedTypesError::from)?) - } -} - -/// FixedAsset encodable to RLP -impl rlp::Encodable for FixedAsset { - /// Append a value to the stream - fn rlp_append(&self, s: &mut rlp::RlpStream) { - let inner = &self.inner; +use protocol::traits::executor::ContractSchema; +use protocol::types::{Account, Address, Asset, AssetID}; - s.begin_list(6); - s.append(&inner.id.as_bytes().to_vec()); - s.append(&inner.manage_contract.as_bytes().to_vec()); - s.append(&inner.name.as_bytes()); - s.append(&inner.storage_root.as_bytes().to_vec()); - s.append(&inner.supply.to_bytes_be()); - s.append(&inner.symbol.as_bytes()); - } +#[allow(dead_code)] +pub struct FixedBytesSchema; +impl ContractSchema for FixedBytesSchema { + type Key = Bytes; + type Value = Bytes; } -/// RLP decodable trait -impl rlp::Decodable for FixedAsset { - /// Decode a value from RLP bytes - fn decode(r: &rlp::Rlp) -> Result { - if !r.is_list() && r.size() != 6 { - return Err(rlp::DecoderError::RlpInvalidLength); - } - - let mut values = Vec::with_capacity(6); - - for val in r { - let data = val.data()?; - values.push(data) - } - - let id = Hash::from_bytes(Bytes::from(values[0])) - .map_err(|_| rlp::DecoderError::RlpInvalidLength)?; - let manage_contract = ContractAddress::from_bytes(Bytes::from(values[1])) - .map_err(|_| rlp::DecoderError::RlpInvalidLength)?; - let name = String::from_utf8(values[2].to_vec()) - .map_err(|_| rlp::DecoderError::RlpInvalidLength)?; - let storage_root = Hash::from_bytes(Bytes::from(values[3])) - .map_err(|_| rlp::DecoderError::RlpInvalidLength)?; - let supply = Balance::from_bytes_be(values[4]); - let symbol = String::from_utf8(values[5].to_vec()) - .map_err(|_| rlp::DecoderError::RlpInvalidLength)?; - - let asset = Asset { - id, - manage_contract, - name, - storage_root, - supply, - symbol, - }; - - Ok(FixedAsset { inner: asset }) - } +pub struct FixedAssetSchema; +impl ContractSchema for FixedAssetSchema { + type Key = AssetID; + type Value = Asset; } pub struct FixedAccountSchema; impl ContractSchema for FixedAccountSchema { - type Key = FixedAddress; - type Value = FixedAccount; -} - -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -pub struct FixedAddress { - inner: Address, -} - -impl FixedAddress { - pub fn new(inner: Address) -> Self { - Self { inner } - } -} - -impl ContractSer for FixedAddress { - fn encode(&self) -> ProtocolResult { - match &self.inner { - Address::User(user) => Ok(user.as_bytes()), - Address::Contract(contract) => Ok(contract.as_bytes()), - } - } - - fn decode(bytes: Bytes) -> ProtocolResult { - let address = Address::from_bytes(bytes)?; - Ok(FixedAddress { inner: address }) - } -} - -const USER_ACCOUNT_FLAG: u8 = 0; -const CONTRACT_ACCOUNT_FLAG: u8 = 1; - -/// the `FixedAccount` is a wrapper type of asset just to provide a consistent -/// serialization algorithm `rlp`. -#[derive(Clone, Debug)] -pub struct FixedAccount { - pub inner: Account, -} - -impl FixedAccount { - pub fn new(inner: Account) -> Self { - Self { inner } - } -} - -impl ContractSer for FixedAccount { - fn encode(&self) -> ProtocolResult { - Ok(Bytes::from(rlp::encode(self))) - } - - fn decode(bytes: Bytes) -> ProtocolResult { - Ok(rlp::decode(bytes.as_ref()).map_err(FixedTypesError::from)?) - } -} - -/// FixedAsset encodable to RLP -impl rlp::Encodable for FixedAccount { - /// Append a value to the stream - fn rlp_append(&self, s: &mut rlp::RlpStream) { - let inner = &self.inner; - - match inner { - Account::User(user) => { - s.begin_list(3); - s.append(&USER_ACCOUNT_FLAG); - s.append(&user.nonce.to_be_bytes().to_vec()); - - let mut asset_list = Vec::with_capacity(user.assets.len()); - - for (id, asset_info) in user.assets.iter() { - let asset_info = FixedUserAssetInfo { - id: id.clone(), - balance: asset_info.balance.clone(), - approved: asset_info.approved.clone(), - }; - - asset_list.push(asset_info); - } - - s.append_list(&asset_list); - } - Account::Contract(contract) => { - s.begin_list(4); - s.append(&CONTRACT_ACCOUNT_FLAG); - s.append(&contract.nonce.to_be_bytes().to_vec()); - s.append(&contract.storage_root.as_bytes().to_vec()); - - let mut asset_list = Vec::with_capacity(contract.assets.len()); - - for (id, balance) in contract.assets.iter() { - let asset = FixedContractAsset { - id: id.clone(), - balance: balance.clone(), - }; - - asset_list.push(asset); - } - - s.append_list(&asset_list); - } - } - } -} - -/// RLP decodable trait -impl rlp::Decodable for FixedAccount { - /// Decode a value from RLP bytes - fn decode(r: &rlp::Rlp) -> Result { - let flag: u8 = r.at(0)?.as_val()?; - - match flag { - USER_ACCOUNT_FLAG => { - let nonce = bytes_to_u64(r.at(1)?.data()?); - let asset_list: Vec = rlp::decode_list(r.at(2)?.as_raw()); - - let mut assets = BTreeMap::new(); - - for v in asset_list.into_iter() { - assets.insert(v.id, AssetInfo { - balance: v.balance, - approved: v.approved, - }); - } - - Ok(FixedAccount { - inner: Account::User(UserAccount { nonce, assets }), - }) - } - CONTRACT_ACCOUNT_FLAG => { - let nonce = bytes_to_u64(r.at(1)?.data()?); - let storage_root_bytes = r.at(2)?.data()?; - let asset_list: Vec = rlp::decode_list(r.at(3)?.as_raw()); - - let mut assets = BTreeMap::new(); - - for v in asset_list { - assets.insert(v.id, v.balance); - } - - let storage_root = MerkleRoot::from_bytes(Bytes::from(storage_root_bytes)) - .map_err(|_| rlp::DecoderError::RlpInvalidLength)?; - - Ok(FixedAccount { - inner: Account::Contract(ContractAccount { - nonce, - assets, - storage_root, - }), - }) - } - _ => Err(rlp::DecoderError::RlpListLenWithZeroPrefix), - } - } -} - -/// the `FixedUserAssetInfo` is a wrapper type of asset just to provide a -/// consistent serialization algorithm `rlp`. -#[derive(Clone, Debug)] -pub struct FixedUserAssetInfo { - pub id: AssetID, - pub balance: Balance, - pub approved: BTreeMap, -} - -/// FixedAsset encodable to RLP -impl rlp::Encodable for FixedUserAssetInfo { - /// Append a value to the stream - fn rlp_append(&self, s: &mut rlp::RlpStream) { - s.begin_list(3); - s.append(&self.id.as_bytes().to_vec()); - s.append(&self.balance.to_bytes_be()); - - let mut info_list = Vec::with_capacity(self.approved.len()); - - for (address, info) in self.approved.iter() { - let fixed_info = FixedUserAssetApproved { - contract_address: address.clone(), - max: info.max.clone(), - used: info.used.clone(), - }; - info_list.push(fixed_info); - } - - s.append_list(&info_list); - } -} - -/// RLP decodable trait -impl rlp::Decodable for FixedUserAssetInfo { - /// Decode a value from RLP bytes - fn decode(r: &rlp::Rlp) -> Result { - let id_bytes = r.at(0)?.data()?; - let balance_bytes = r.at(1)?.data()?; - let approved_list: Vec = rlp::decode_list(r.at(2)?.as_raw()); - - let mut approved_map = BTreeMap::new(); - for v in approved_list { - approved_map.insert(v.contract_address, ApprovedInfo { - max: v.max, - used: v.used, - }); - } - - Ok(FixedUserAssetInfo { - id: AssetID::from_bytes(Bytes::from(id_bytes)) - .map_err(|_| rlp::DecoderError::RlpInvalidLength)?, - balance: Balance::from_bytes_be(balance_bytes), - approved: approved_map, - }) - } -} - -/// the `FixedUserAssetApproved` is a wrapper type of asset just to provide a -/// consistent serialization algorithm `rlp`. -#[derive(Clone, Debug)] -pub struct FixedUserAssetApproved { - pub contract_address: ContractAddress, - pub max: Balance, - pub used: Balance, -} - -/// FixedAsset encodable to RLP -impl rlp::Encodable for FixedUserAssetApproved { - /// Append a value to the stream - fn rlp_append(&self, s: &mut rlp::RlpStream) { - s.begin_list(3); - s.append(&self.contract_address.as_bytes().to_vec()); - s.append(&self.max.to_bytes_be()); - s.append(&self.used.to_bytes_be()); - } -} - -/// RLP decodable trait -impl rlp::Decodable for FixedUserAssetApproved { - /// Decode a value from RLP bytes - fn decode(r: &rlp::Rlp) -> Result { - let address_bytes = r.at(0)?.data()?; - let max_bytes = r.at(1)?.data()?; - let used_bytes = r.at(2)?.data()?; - - Ok(FixedUserAssetApproved { - contract_address: ContractAddress::from_bytes(Bytes::from(address_bytes)) - .map_err(|_| rlp::DecoderError::RlpInvalidLength)?, - max: Balance::from_bytes_be(max_bytes), - used: Balance::from_bytes_be(used_bytes), - }) - } -} - -/// the `FixedUserAssetApproved` is a wrapper type of asset just to provide a -/// consistent serialization algorithm `rlp`. -#[derive(Clone, Debug)] -pub struct FixedContractAsset { - pub id: AssetID, - pub balance: Balance, -} - -/// FixedAsset encodable to RLP -impl rlp::Encodable for FixedContractAsset { - /// Append a value to the stream - fn rlp_append(&self, s: &mut rlp::RlpStream) { - s.begin_list(2); - s.append(&self.id.as_bytes().to_vec()); - s.append(&self.balance.to_bytes_be()); - } -} - -/// RLP decodable trait -impl rlp::Decodable for FixedContractAsset { - /// Decode a value from RLP bytes - fn decode(r: &rlp::Rlp) -> Result { - let id_bytes = r.at(0)?.data()?; - let balance_bytes = r.at(1)?.data()?; - - Ok(FixedContractAsset { - id: Hash::from_bytes(Bytes::from(id_bytes)) - .map_err(|_| rlp::DecoderError::RlpInvalidLength)?, - balance: Balance::from_bytes_be(balance_bytes), - }) - } -} - -#[derive(Debug, Display, From)] -pub enum FixedTypesError { - Decoder(rlp::DecoderError), -} - -impl Error for FixedTypesError {} - -impl From for ProtocolError { - fn from(err: FixedTypesError) -> ProtocolError { - ProtocolError::new(ProtocolErrorKind::Executor, Box::new(err)) - } -} - -fn bytes_to_u64(bytes: &[u8]) -> u64 { - let mut nonce_bytes = [0u8; 8]; - nonce_bytes.copy_from_slice(bytes); - u64::from_be_bytes(nonce_bytes) + type Key = Address; + type Value = Account; } diff --git a/core/executor/src/native_contract/account.rs b/core/executor/src/native_contract/account.rs index 01738da7d..8de79bf05 100644 --- a/core/executor/src/native_contract/account.rs +++ b/core/executor/src/native_contract/account.rs @@ -13,7 +13,7 @@ use protocol::types::{ use protocol::{ProtocolError, ProtocolErrorKind, ProtocolResult}; use crate::cycles::{consume_cycles, CyclesAction}; -use crate::fixed_types::{FixedAccount, FixedAccountSchema, FixedAddress}; +use crate::fixed_types::FixedAccountSchema; pub struct NativeAccountContract { state_adapter: Rc>, @@ -79,10 +79,7 @@ impl AccountContract self.state_adapter .borrow_mut() - .insert_cache::( - FixedAddress::new(address.clone()), - FixedAccount::new(modified_account), - )?; + .insert_cache::(address.clone(), modified_account)?; Ok(()) } @@ -107,10 +104,7 @@ impl AccountContract self.state_adapter .borrow_mut() - .insert_cache::( - FixedAddress::new(address.clone()), - FixedAccount::new(modified_account), - )?; + .insert_cache::(address.clone(), modified_account)?; Ok(()) } @@ -132,10 +126,7 @@ impl AccountContract self.state_adapter .borrow_mut() - .insert_cache::( - FixedAddress::new(caller.clone()), - FixedAccount::new(modified_account), - )?; + .insert_cache::(caller.clone(), modified_account)?; Ok(()) } @@ -143,12 +134,12 @@ impl AccountContract let fixed_account = self .state_adapter .borrow() - .get::(&FixedAddress::new(address.clone()))? + .get::(&address.clone())? .ok_or(NativeAccountContractError::AccountNotFound { address: address.clone(), })?; - match fixed_account.inner { + match fixed_account { Account::User(user) => self.get_balance_with_user(id, &user), Account::Contract(contract) => self.get_balance_with_contract(id, &contract), } @@ -158,11 +149,11 @@ impl AccountContract let fixed_accoount = self .state_adapter .borrow() - .get::(&FixedAddress::new(address.clone()))? + .get::(&address.clone())? .ok_or(NativeAccountContractError::AccountNotFound { address: address.clone(), })?; - Ok(fixed_accoount.inner) + Ok(fixed_accoount) } fn get_nonce(&self, address: &Address) -> ProtocolResult { @@ -180,9 +171,9 @@ impl NativeAccountContract { if let Some(fixed_account) = self .state_adapter .borrow() - .get::(&FixedAddress::new(address.clone()))? + .get::(&address.clone())? { - return Ok(fixed_account.inner); + return Ok(fixed_account); } let account = match address { @@ -297,9 +288,6 @@ pub enum NativeAccountContractError { #[display(fmt = "invalid address")] InvalidAddress, - - #[display(fmt = "fixed codec {:?}", _0)] - FixedCodec(rlp::DecoderError), } impl Error for NativeAccountContractError {} diff --git a/core/executor/src/native_contract/bank.rs b/core/executor/src/native_contract/bank.rs index c0aab2c66..7bb135ea2 100644 --- a/core/executor/src/native_contract/bank.rs +++ b/core/executor/src/native_contract/bank.rs @@ -11,7 +11,7 @@ use protocol::types::{Asset, AssetID, Balance, ContractAddress, ContractType, Ha use protocol::{ProtocolError, ProtocolErrorKind, ProtocolResult}; use crate::cycles::{consume_cycles, CyclesAction}; -use crate::fixed_types::{FixedAsset, FixedAssetID, FixedAssetSchema}; +use crate::fixed_types::FixedAssetSchema; /// Bank is the registration and query center for asset. /// @@ -62,7 +62,7 @@ impl BankContract if self .state_adapter .borrow() - .contains::(&FixedAssetID::new(asset_id.clone()))? + .contains::(&asset_id)? { return Err(NativeBankContractError::AssetExists { id: asset_id }.into()); } @@ -79,10 +79,7 @@ impl BankContract self.state_adapter .borrow_mut() - .insert_cache::( - FixedAssetID::new(asset_id.clone()), - FixedAsset::new(asset.clone()), - )?; + .insert_cache::(asset_id.clone(), asset.clone())?; let cycles_used = consume_cycles( CyclesAction::BankRegister, @@ -94,12 +91,12 @@ impl BankContract } fn get_asset(&self, _ictx: RcInvokeContext, id: &AssetID) -> ProtocolResult { - let fixed_asset: FixedAsset = self + let fixed_asset: Asset = self .state_adapter .borrow() - .get::(&FixedAssetID::new(id.clone()))? + .get::(&id)? .ok_or(NativeBankContractError::NotFound { id: id.clone() })?; - Ok(fixed_asset.inner) + Ok(fixed_asset) } } @@ -113,9 +110,6 @@ pub enum NativeBankContractError { #[display(fmt = "invalid address")] InvalidAddress, - - #[display(fmt = "fixed codec {:?}", _0)] - FixedCodec(rlp::DecoderError), } impl Error for NativeBankContractError {} diff --git a/core/executor/src/tests/general_state_adapter.rs b/core/executor/src/tests/general_state_adapter.rs index a533e31f0..085a76f3e 100644 --- a/core/executor/src/tests/general_state_adapter.rs +++ b/core/executor/src/tests/general_state_adapter.rs @@ -3,60 +3,41 @@ use std::sync::Arc; use bytes::Bytes; use protocol::traits::executor::contract::ContractStateAdapter; -use protocol::traits::executor::{ContractSchema, ContractSer}; -use protocol::ProtocolResult; use crate::adapter::GeneralContractStateAdapter; +use crate::fixed_types::FixedBytesSchema; use crate::tests; -struct FixedTestSchema; -impl ContractSchema for FixedTestSchema { - type Key = FixedTestBytes; - type Value = FixedTestBytes; -} - -#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -pub struct FixedTestBytes { - inner: Bytes, -} - -impl FixedTestBytes { - pub fn new(inner: Bytes) -> Self { - Self { inner } - } -} - -impl ContractSer for FixedTestBytes { - fn encode(&self) -> ProtocolResult { - Ok(self.inner.clone()) - } - - fn decode(bytes: Bytes) -> ProtocolResult { - Ok(FixedTestBytes { inner: bytes }) - } -} - #[test] fn insert() { let memdb = tests::create_empty_memdb(); let trie = tests::create_empty_trie(Arc::clone(&memdb)); let mut state_adapter = GeneralContractStateAdapter::new(trie); - let key = FixedTestBytes::new(Bytes::from(b"test-key".to_vec())); - let value = FixedTestBytes::new(Bytes::from(b"test-value".to_vec())); + let key = Bytes::from(b"test-key".to_vec()); + let value = Bytes::from(b"test-value".to_vec()); state_adapter - .insert_cache::(key.clone(), value.clone()) + .insert_cache::(key.clone(), value.clone()) .unwrap(); - let get_value = state_adapter.get::(&key).unwrap().unwrap(); + let get_value = state_adapter + .get::(&key) + .unwrap() + .unwrap(); assert_eq!(get_value, value.clone()); state_adapter.stash().unwrap(); - let get_value = state_adapter.get::(&key).unwrap().unwrap(); + let get_value = state_adapter + .get::(&key) + .unwrap() + .unwrap(); assert_eq!(get_value, value.clone()); state_adapter.commit().unwrap(); - let get_value = state_adapter.get::(&key).unwrap().unwrap(); + let get_value = state_adapter + .get::(&key) + .unwrap() + .unwrap(); assert_eq!(get_value, value.clone()); } @@ -66,16 +47,19 @@ fn revert() { let trie = tests::create_empty_trie(Arc::clone(&memdb)); let mut state_adapter = GeneralContractStateAdapter::new(trie); - let key = FixedTestBytes::new(Bytes::from(b"test-key".to_vec())); - let value = FixedTestBytes::new(Bytes::from(b"test-value".to_vec())); + let key = Bytes::from(b"test-key".to_vec()); + let value = Bytes::from(b"test-value".to_vec()); state_adapter - .insert_cache::(key.clone(), value.clone()) + .insert_cache::(key.clone(), value.clone()) .unwrap(); - let get_value = state_adapter.get::(&key).unwrap().unwrap(); + let get_value = state_adapter + .get::(&key) + .unwrap() + .unwrap(); assert_eq!(get_value, value.clone()); state_adapter.revert_cache().unwrap(); - let get_value = state_adapter.get::(&key).unwrap(); + let get_value = state_adapter.get::(&key).unwrap(); assert_eq!(get_value, None); } diff --git a/protocol/src/fixed_codec/primitive.rs b/protocol/src/fixed_codec/primitive.rs index 6e7b496cf..320b4562f 100644 --- a/protocol/src/fixed_codec/primitive.rs +++ b/protocol/src/fixed_codec/primitive.rs @@ -20,6 +20,16 @@ impl_default_fixed_codec_for!(primitive, [ Account ]); +impl ProtocolFixedCodec for Bytes { + fn encode_fixed(&self) -> ProtocolResult { + Ok(self.clone()) + } + + fn decode_fixed(bytes: Bytes) -> ProtocolResult { + Ok(bytes) + } +} + // AssetID, MerkleRoot are alias of Hash type impl rlp::Encodable for Hash { fn rlp_append(&self, s: &mut rlp::RlpStream) { diff --git a/protocol/src/traits/executor/mod.rs b/protocol/src/traits/executor/mod.rs index 7946b37a9..91feb1c8e 100644 --- a/protocol/src/traits/executor/mod.rs +++ b/protocol/src/traits/executor/mod.rs @@ -6,6 +6,7 @@ use std::sync::Arc; use bytes::Bytes; +use crate::fixed_codec::ProtocolFixedCodec; use crate::types::{ Address, AssetID, Balance, Bloom, CarryingAsset, ContractAddress, Fee, Genesis, Hash, MerkleRoot, Receipt, SignedTransaction, @@ -67,14 +68,6 @@ pub trait Dispatcher { } pub trait ContractSchema { - type Key: ContractSer + Clone + std::hash::Hash + PartialEq + Eq + PartialOrd + Ord; - type Value: ContractSer + Clone; -} - -pub trait ContractSer { - fn encode(&self) -> ProtocolResult; - - fn decode(bytes: Bytes) -> ProtocolResult - where - Self: Sized; + type Key: ProtocolFixedCodec + Clone + std::hash::Hash + PartialEq + Eq + PartialOrd + Ord; + type Value: ProtocolFixedCodec + Clone; }