From 2af1fe5052eaec5ab0628aa7b38236a46a5d2c83 Mon Sep 17 00:00:00 2001 From: shaorongqiang Date: Mon, 26 Jun 2023 10:25:54 +0800 Subject: [PATCH] update import --- .../abciapp/src/abci/server/callback/mod.rs | 9 +- src/components/config/src/abci/mod.rs | 2 +- .../contracts/baseapp/src/staking.rs | 101 +++--- .../modules/evm/contracts/EVMStaking.abi.json | 168 ++++------ .../contracts/modules/evm/src/lib.rs | 310 +++++++++++++----- 5 files changed, 368 insertions(+), 222 deletions(-) diff --git a/src/components/abciapp/src/abci/server/callback/mod.rs b/src/components/abciapp/src/abci/server/callback/mod.rs index c85f4d6d9..efc255ec6 100644 --- a/src/components/abciapp/src/abci/server/callback/mod.rs +++ b/src/components/abciapp/src/abci/server/callback/mod.rs @@ -261,9 +261,12 @@ pub fn begin_block( .map(|v| (v.id, v.clone())) .collect(); - EVM_STAKING - .get() - .map(|staking| staking.write().import_validators(&validators, &delegations)); + if let Err(e) = EVM_STAKING.get().c(d!()).and_then(|staking| { + staking.write().import_validators(&validators, &delegations) + }) { + println!("import_validators error {:?}", e); + panic!() + }; } if CFG.checkpoint.disable_evm_block_height < header.height && header.height < CFG.checkpoint.enable_frc20_height diff --git a/src/components/config/src/abci/mod.rs b/src/components/config/src/abci/mod.rs index 0f3dec3dd..66b6ec98b 100644 --- a/src/components/config/src/abci/mod.rs +++ b/src/components/config/src/abci/mod.rs @@ -270,7 +270,7 @@ lazy_static! { validator_whitelist_v3: vec![], max_gas_price_limit: 0, evm_staking_inital_height: 128, - evm_staking_address: "0x34d4F6946Ceb1014BF13603fA7e7fC943952e8a4".to_owned(), + evm_staking_address: "0x84db796A3F8F02396f82219e3197933d15960771".to_owned(), }; } diff --git a/src/components/contracts/baseapp/src/staking.rs b/src/components/contracts/baseapp/src/staking.rs index e970441a5..c9ef55ec2 100644 --- a/src/components/contracts/baseapp/src/staking.rs +++ b/src/components/contracts/baseapp/src/staking.rs @@ -1,4 +1,5 @@ use crate::BaseApp; +use config::abci::global_cfg::CFG; use ethereum_types::{H160, U256}; use fp_traits::{ account::AccountAsset, @@ -43,76 +44,92 @@ impl EVMStaking for BaseApp { }); } } - let mut ds: BTreeMap>> = - BTreeMap::new(); + let power = vs.iter().map(|v| v.power.as_u128()).sum::(); + + let evm_staking_address = + H160::from_str(CFG.checkpoint.evm_staking_address.as_str()).c(d!())?; + + module_account::App::::mint( + &self.deliver_state, + &Address::from(evm_staking_address), + U256::from(power), + )?; + + if let Err(e) = + self.modules + .evm_module + .import_validators(&self.deliver_state, from, &vs) { - for delegation in delegations.values() { - let d = delegation - .delegations - .iter() - .map(|(validator_addr, amount)| { - (mapping_address(validator_addr), U256::from(*amount)) - }) - .collect::>(); - let mut v = BTreeMap::new(); - v.insert(delegation.end_height, d.clone()); + self.deliver_state.state.write().discard_session(); + self.deliver_state.db.write().discard_session(); + return Err(e); + } + let mut ds: BTreeMap<(XfrPublicKey, H160), Vec<(u64, U256)>> = BTreeMap::new(); + { + for delegation in delegations.values() { let public_key = delegation.receiver_pk.unwrap_or(delegation.id); - ds.entry(public_key) - .and_modify(|rem| { - rem.entry(delegation.end_height) - .and_modify(|rem1| rem1.extend(d.clone().into_iter())) - .or_insert(d); - }) - .or_insert(v); + + for (validator, amount) in delegation.delegations.iter() { + let amount = U256::from(*amount); + ds.entry((public_key, mapping_address(validator))) + .and_modify(|am| { + am.push((delegation.end_height, amount)); + }) + .or_insert(vec![(delegation.end_height, amount)]); + } } } let mut delegators = vec![]; let mut undelegation_infos = vec![]; { - for (public_key, delegations) in ds.iter() { - let mut bound_amount = vec![]; - let mut unbound_amount = vec![]; - let address = mapping_address(public_key); - for (end_height, values) in delegations.iter() { - let v = values.to_vec(); + for ((public_key, validator_address), value) in ds.iter() { + let mut bound_amount = U256::zero(); + let mut unbound_amount = U256::zero(); + + let delegator_address = mapping_address(public_key); + + for (end_height, amount) in value.iter() { if BLOCK_HEIGHT_MAX == *end_height { - bound_amount.extend(v); + bound_amount = bound_amount.checked_add(*amount).c(d!())?; } else { - unbound_amount.extend(v); - let v = values - .iter() - .map(|(validator_addr, amount)| UndelegationInfos { - validator: *validator_addr, - delegator: address, - amount: *amount, - height: U256::from(*end_height), - }) - .collect::>(); - undelegation_infos.extend(v); + unbound_amount = unbound_amount.checked_add(*amount).c(d!())?; + undelegation_infos.push(UndelegationInfos { + validator: *validator_address, + delegator: delegator_address, + amount: *amount, + height: U256::from(*end_height), + }); } } - delegators.push(DelegatorParam { - delegator: address, + validator: *validator_address, + delegator: delegator_address, delegator_pk: public_key.as_bytes().to_vec(), bound_amount, unbound_amount, }); } } - if let Err(e) = self.modules.evm_module.import_validators( + + if let Err(e) = self.modules.evm_module.import_delegators( &self.deliver_state, from, - &vs, &delegators, + ) { + self.deliver_state.state.write().discard_session(); + self.deliver_state.db.write().discard_session(); + return Err(e); + } + if let Err(e) = self.modules.evm_module.import_undelegations( + &self.deliver_state, + from, &undelegation_infos, ) { self.deliver_state.state.write().discard_session(); self.deliver_state.db.write().discard_session(); return Err(e); } - self.deliver_state.state.write().commit_session(); self.deliver_state.db.write().commit_session(); Ok(()) diff --git a/src/components/contracts/modules/evm/contracts/EVMStaking.abi.json b/src/components/contracts/modules/evm/contracts/EVMStaking.abi.json index 34a4e2c2a..e5a42a517 100644 --- a/src/components/contracts/modules/evm/contracts/EVMStaking.abi.json +++ b/src/components/contracts/modules/evm/contracts/EVMStaking.abi.json @@ -104,16 +104,6 @@ "internalType": "address", "name": "validator", "type": "address" - }, - { - "internalType": "address", - "name": "delegator", - "type": "address" - }, - { - "internalType": "bytes", - "name": "delegator_pk", - "type": "bytes" } ], "name": "delegate", @@ -162,130 +152,127 @@ "components": [ { "internalType": "address", - "name": "td_addr", + "name": "validator", "type": "address" }, { - "internalType": "bytes", - "name": "public_key", - "type": "bytes" + "internalType": "address", + "name": "delegator", + "type": "address" }, { - "internalType": "enum IBaseEnum.PublicKeyType", - "name": "ty", - "type": "uint8" + "internalType": "bytes", + "name": "delegator_pk", + "type": "bytes" }, { - "internalType": "string", - "name": "memo", - "type": "string" + "internalType": "uint256", + "name": "boundAmount", + "type": "uint256" }, { "internalType": "uint256", - "name": "rate", + "name": "unboundAmount", "type": "uint256" - }, + } + ], + "internalType": "struct ISystemImporter.DelegatorParam[]", + "name": "dp", + "type": "tuple[]" + } + ], + "name": "importDelegators", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ { "internalType": "address", - "name": "staker", + "name": "validator", "type": "address" }, { - "internalType": "bytes", - "name": "staker_pk", - "type": "bytes" + "internalType": "address payable", + "name": "delegator", + "type": "address" }, { "internalType": "uint256", - "name": "power", + "name": "amount", "type": "uint256" }, { "internalType": "uint256", - "name": "beginBlock", + "name": "height", "type": "uint256" } ], - "internalType": "struct ISystemImporter.ValidatorParam[]", - "name": "vs", + "internalType": "struct ISystemImporter.UndelegationParam[]", + "name": "udp", "type": "tuple[]" - }, + } + ], + "name": "importUndelegations", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ { "components": [ { "internalType": "address", - "name": "delegator", + "name": "td_addr", "type": "address" }, { "internalType": "bytes", - "name": "delegator_pk", + "name": "public_key", "type": "bytes" }, { - "components": [ - { - "internalType": "address", - "name": "validator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "internalType": "struct ISystemImporter.DelegatorAmount[]", - "name": "boundAmount", - "type": "tuple[]" + "internalType": "enum IBaseEnum.PublicKeyType", + "name": "ty", + "type": "uint8" }, { - "components": [ - { - "internalType": "address", - "name": "validator", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "internalType": "struct ISystemImporter.DelegatorAmount[]", - "name": "unboundAmount", - "type": "tuple[]" - } - ], - "internalType": "struct ISystemImporter.DelegatorParam[]", - "name": "ds", - "type": "tuple[]" - }, - { - "components": [ + "internalType": "string", + "name": "memo", + "type": "string" + }, + { + "internalType": "uint256", + "name": "rate", + "type": "uint256" + }, { "internalType": "address", - "name": "validator", + "name": "staker", "type": "address" }, { - "internalType": "address payable", - "name": "delegator", - "type": "address" + "internalType": "bytes", + "name": "staker_pk", + "type": "bytes" }, { "internalType": "uint256", - "name": "amount", + "name": "power", "type": "uint256" }, { "internalType": "uint256", - "name": "height", + "name": "beginBlock", "type": "uint256" } ], - "internalType": "struct ISystemImporter.UndelegationInfo[]", - "name": "uis", + "internalType": "struct ISystemImporter.ValidatorParam[]", + "name": "vp", "type": "tuple[]" } ], @@ -295,13 +282,7 @@ "type": "function" }, { - "inputs": [ - { - "internalType": "address", - "name": "systemAddr_", - "type": "address" - } - ], + "inputs": [], "name": "initialize", "outputs": [], "stateMutability": "nonpayable", @@ -378,16 +359,6 @@ "name": "public_key", "type": "bytes" }, - { - "internalType": "address", - "name": "staker", - "type": "address" - }, - { - "internalType": "bytes", - "name": "staker_pk", - "type": "bytes" - }, { "internalType": "string", "name": "memo", @@ -605,11 +576,6 @@ "name": "validator", "type": "address" }, - { - "internalType": "address", - "name": "delegator", - "type": "address" - }, { "internalType": "uint256", "name": "amount", diff --git a/src/components/contracts/modules/evm/src/lib.rs b/src/components/contracts/modules/evm/src/lib.rs index ba62f8ba9..261c13468 100644 --- a/src/components/contracts/modules/evm/src/lib.rs +++ b/src/components/contracts/modules/evm/src/lib.rs @@ -93,10 +93,11 @@ pub struct ValidatorParam { pub begin_block: U256, } pub struct DelegatorParam { + pub validator: H160, pub delegator: H160, pub delegator_pk: Vec, - pub bound_amount: Vec<(H160, U256)>, - pub unbound_amount: Vec<(H160, U256)>, + pub bound_amount: U256, + pub unbound_amount: U256, } pub struct UndelegationInfos { @@ -305,6 +306,15 @@ impl App { let value = U256::zero(); let from = H160::from_str(SYSTEM_ADDR).c(d!())?; + tracing::info!( + target: "evm staking", + "trigger from:{:?} gas_limit:{} value:{} contracts_address:{:?} input:{}", + from, + gas_limit, + value, + self.contracts.staking_address, + hex::encode(&input) + ); let (_, logs, _) = ActionRunner::::execute_systemc_contract( ctx, input, @@ -340,86 +350,194 @@ impl App { ctx: &Context, from: H160, validators: &[ValidatorParam], - delegators: &[DelegatorParam], - undelegationinfos: &[UndelegationInfos], ) -> Result<()> { let function = self .contracts .staking .function("importValidators") .c(d!())?; - - let vs = validators - .iter() - .map(|v| { - Token::Tuple(vec![ - Token::Address(v.td_addr), - Token::Bytes(v.td_pubkey.clone()), - Token::Uint(v.keytype), - Token::String(v.memo.clone()), - Token::Uint(v.rate), - Token::Address(v.staker), - Token::Bytes(v.staker_pk.clone()), - Token::Uint(v.power), - Token::Uint(v.begin_block), - ]) - }) - .collect::>(); - let mut ds = vec![]; - for delegator in delegators.iter() { - let mut bound_amounts = vec![]; - let mut unbound_amounts = vec![]; - for (addr, amount) in delegator.bound_amount.iter() { - bound_amounts.push(Token::Tuple(vec![ - Token::Address(*addr), - Token::Uint(*amount), - ])); + let mut vss = vec![]; + { + let vs = validators + .iter() + .map(|v| { + Token::Tuple(vec![ + Token::Address(v.td_addr), + Token::Bytes(v.td_pubkey.clone()), + Token::Uint(v.keytype), + Token::String(v.memo.clone()), + Token::Uint(v.rate), + Token::Address(v.staker), + Token::Bytes(v.staker_pk.clone()), + Token::Uint(v.power), + Token::Uint(v.begin_block), + ]) + }) + .collect::>(); + let mut tmp = vec![]; + for (index, v) in vs.iter().enumerate() { + tmp.push(v.clone()); + if index > 0 && 0 == index % 60 { + vss.push(tmp.clone()); + tmp.clear(); + } + } + if !tmp.is_empty() { + vss.push(tmp); } + } + for vs in vss.iter() { + let input = function + .encode_input(&[Token::Array(vs.to_vec())]) + .c(d!())?; + let gas_limit = 99999999999; + let value = U256::zero(); + tracing::info!( + target: "evm staking", + "importValidators from:{:?} gas_limit:{} value:{} contracts_address:{:?} input:{}", + from, + gas_limit, + value, + self.contracts.staking_address, + hex::encode(&input) + ); + let (_, _, _) = ActionRunner::::execute_systemc_contract( + ctx, + input, + from, + gas_limit, + self.contracts.staking_address, + value, + )?; + } + + Ok(()) + } - for (addr, amount) in delegator.unbound_amount.iter() { - unbound_amounts.push(Token::Tuple(vec![ - Token::Address(*addr), - Token::Uint(*amount), + pub fn import_delegators( + &self, + ctx: &Context, + from: H160, + delegators: &[DelegatorParam], + ) -> Result<()> { + let function = self + .contracts + .staking + .function("importDelegators") + .c(d!())?; + + let mut dss = vec![]; + { + let mut ds = vec![]; + for delegator in delegators.iter() { + ds.push(Token::Tuple(vec![ + Token::Address(delegator.validator), + Token::Address(delegator.delegator), + Token::Bytes(delegator.delegator_pk.clone()), + Token::Uint(delegator.bound_amount), + Token::Uint(delegator.unbound_amount), ])); } - - ds.push(Token::Tuple(vec![ - Token::Address(delegator.delegator), - Token::Bytes(delegator.delegator_pk.clone()), - Token::Array(bound_amounts), - Token::Array(unbound_amounts), - ])); + let mut tmp = vec![]; + for (index, v) in ds.iter().enumerate() { + tmp.push(v.clone()); + if index > 0 && 0 == index % 60 { + dss.push(tmp.clone()); + tmp.clear(); + } + } + if !tmp.is_empty() { + dss.push(tmp); + } + } + for ds in dss.iter() { + let input = function + .encode_input(&[Token::Array(ds.to_vec())]) + .c(d!())?; + let gas_limit = 99999999999; + let value = U256::zero(); + tracing::info!( + target: "evm staking", + "importDelegators from:{:?} gas_limit:{} value:{} contracts_address:{:?} input:{}", + from, + gas_limit, + value, + self.contracts.staking_address, + hex::encode(&input) + ); + let (_, _, _) = ActionRunner::::execute_systemc_contract( + ctx, + input, + from, + gas_limit, + self.contracts.staking_address, + value, + )?; } - let undelegation_infos = undelegationinfos - .iter() - .map(|v| { - Token::Tuple(vec![ - Token::Address(v.validator), - Token::Address(v.delegator), - Token::Uint(v.amount), - Token::Uint(v.height), - ]) - }) - .collect::>(); - let input = function - .encode_input(&[ - Token::Array(vs), - Token::Array(ds), - Token::Array(undelegation_infos), - ]) - .c(d!())?; + Ok(()) + } - let gas_limit = 99999999999; - let value = U256::zero(); - let (_, _, _) = ActionRunner::::execute_systemc_contract( - ctx, - input, - from, - gas_limit, - self.contracts.staking_address, - value, - )?; + pub fn import_undelegations( + &self, + ctx: &Context, + from: H160, + undelegationinfos: &[UndelegationInfos], + ) -> Result<()> { + let function = self + .contracts + .staking + .function("importUndelegations") + .c(d!())?; + let mut infos = vec![]; + { + let undelegation_infos = undelegationinfos + .iter() + .map(|v| { + Token::Tuple(vec![ + Token::Address(v.validator), + Token::Address(v.delegator), + Token::Uint(v.amount), + Token::Uint(v.height), + ]) + }) + .collect::>(); + let mut tmp = vec![]; + for (index, v) in undelegation_infos.iter().enumerate() { + tmp.push(v.clone()); + if index > 0 && 0 == index % 60 { + infos.push(tmp.clone()); + tmp.clear(); + } + } + if !tmp.is_empty() { + infos.push(tmp); + } + } + for info in infos.iter() { + let input = function + .encode_input(&[Token::Array(info.to_vec())]) + .c(d!())?; + let gas_limit = 99999999999; + let value = U256::zero(); + tracing::info!( + target: "evm staking", + "importUndelegations from:{:?} gas_limit:{} value:{} contracts_address:{:?} input:{}", + from, + gas_limit, + value, + self.contracts.staking_address, + hex::encode(&input) + ); + let (_, _, _) = ActionRunner::::execute_systemc_contract( + ctx, + input, + from, + gas_limit, + self.contracts.staking_address, + value, + )?; + } Ok(()) } @@ -436,11 +554,6 @@ impl App { memo: String, rate: U256, ) -> Result<()> { - println!( - "Stake: from {:x} to {:x}, amount: {}", - &staker, &validator, &value - ); - let function = self.contracts.staking.function("systemStake").c(d!())?; let validator = Token::Address(validator); @@ -456,6 +569,15 @@ impl App { let gas_limit = 99999999999; + tracing::info!( + target: "evm staking", + "systemStake from:{:?} gas_limit:{} value:{} contracts_address:{:?} input:{}", + from, + gas_limit, + value, + self.contracts.staking_address, + hex::encode(&input) + ); let (_, _, _) = ActionRunner::::execute_systemc_contract( ctx, input, @@ -491,7 +613,15 @@ impl App { .c(d!())?; let gas_limit = 99999999999; - + tracing::info!( + target: "evm staking", + "systemDelegate from:{:?} gas_limit:{} value:{} contracts_address:{:?} input:{}", + from, + gas_limit, + amount, + self.contracts.staking_address, + hex::encode(&input) + ); let (_, _, _) = ActionRunner::::execute_systemc_contract( ctx, input, @@ -527,6 +657,16 @@ impl App { let gas_limit = 99999999999; let value = U256::zero(); + tracing::info!( + target: "evm staking", + "systemUndelegate from:{:?} gas_limit:{} value:{} contracts_address:{:?} input:{}", + from, + gas_limit, + value, + self.contracts.staking_address, + hex::encode(&input) + ); + let (_, _, _) = ActionRunner::::execute_systemc_contract( ctx, input, @@ -560,6 +700,16 @@ impl App { let gas_limit = 99999999999; let value = U256::zero(); + tracing::info!( + target: "evm staking", + "systemClaim from:{:?} gas_limit:{} value:{} contracts_address:{:?} input:{}", + from, + gas_limit, + value, + self.contracts.staking_address, + hex::encode(&input) + ); + let (_, logs, _) = ActionRunner::::execute_systemc_contract( ctx, input, @@ -620,6 +770,16 @@ impl App { let value = U256::zero(); let from = H160::from_str(SYSTEM_ADDR).c(d!())?; + tracing::info!( + target: "evm staking", + "systemUpdateValidator from:{:?} gas_limit:{} value:{} contracts_address:{:?} input:{}", + from, + gas_limit, + value, + self.contracts.staking_address, + hex::encode(&input) + ); + let (_, _, _) = ActionRunner::::execute_systemc_contract( ctx, input,