diff --git a/src/components/abciapp/src/abci/server/callback/mod.rs b/src/components/abciapp/src/abci/server/callback/mod.rs index 1067897d2..9145bf823 100644 --- a/src/components/abciapp/src/abci/server/callback/mod.rs +++ b/src/components/abciapp/src/abci/server/callback/mod.rs @@ -501,7 +501,32 @@ pub fn end_block( panic!() }; } + let evm_resp = if td_height <= CFG.checkpoint.disable_evm_block_height + || td_height >= CFG.checkpoint.enable_frc20_height + { + let mut sum = 0; + let ledger = la.get_committed_state().read(); + let mut addrs = FF_ADDR_LIST.to_vec(); + addrs.push(FF_ADDR_EXTRA_120_0000); + for fra_addr in addrs.iter() { + for (_, (utxo, _)) in pnk!(wallet::public_key_from_bech32(fra_addr) + .and_then(|pub_key| ledger.get_owned_utxos(&pub_key))) + { + if AssetRecordType::NonConfidentialAmount_NonConfidentialAssetType + == utxo.0.record.get_record_type() + && Some(ASSET_TYPE_FRA) == utxo.0.record.asset_type.get_asset_type() + { + if let Some(v) = utxo.0.record.amount.get_amount() { + sum += v; + }; + } + } + } + s.account_base_app.write().end_block(req, sum) + } else { + Default::default() + }; // mint coinbase, cache system transactions to ledger { let laa = la.get_committed_state().read(); @@ -533,33 +558,6 @@ pub fn end_block( ); } - let evm_resp = if td_height <= CFG.checkpoint.disable_evm_block_height - || td_height >= CFG.checkpoint.enable_frc20_height - { - let mut sum = 0; - let ledger = la.get_committed_state().read(); - let mut addrs = FF_ADDR_LIST.to_vec(); - addrs.push(FF_ADDR_EXTRA_120_0000); - for fra_addr in addrs.iter() { - for (_, (utxo, _)) in pnk!(wallet::public_key_from_bech32(fra_addr) - .and_then(|pub_key| ledger.get_owned_utxos(&pub_key))) - { - if AssetRecordType::NonConfidentialAmount_NonConfidentialAssetType - == utxo.0.record.get_record_type() - && Some(ASSET_TYPE_FRA) == utxo.0.record.asset_type.get_asset_type() - { - if let Some(v) = utxo.0.record.amount.get_amount() { - sum += v; - }; - } - } - } - - s.account_base_app.write().end_block(req, sum) - } else { - Default::default() - }; - if td_height > CFG.checkpoint.evm_staking_inital_height && 0 == TENDERMINT_BLOCK_HEIGHT.load(Ordering::Relaxed) % VALIDATOR_UPDATE_BLOCK_ITV diff --git a/src/components/abciapp/src/abci/staking/mod.rs b/src/components/abciapp/src/abci/staking/mod.rs index d65de6ae3..45f83544b 100644 --- a/src/components/abciapp/src/abci/staking/mod.rs +++ b/src/components/abciapp/src/abci/staking/mod.rs @@ -4,8 +4,6 @@ //! Business logic based on [**Ledger Staking**](ledger::staking). //! -use ledger::staking::evm::EVM_STAKING_MINTS; - mod whoami; #[cfg(test)] @@ -18,6 +16,7 @@ use { config::abci::global_cfg::CFG, fp_types::actions::xhub::NonConfidentialOutput, lazy_static::lazy_static, + ledger::staking::evm::EVM_STAKING_MINTS, ledger::{ data_model::{ AssetType, AssetTypeCode, IssuerPublicKey, Operation, Transaction, diff --git a/src/components/config/src/abci/mod.rs b/src/components/config/src/abci/mod.rs index 66b6ec98b..a55985ddc 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: "0x84db796A3F8F02396f82219e3197933d15960771".to_owned(), + evm_staking_address: "0x321DF28026D01858906D322533900aD3435eE964".to_owned(), }; } diff --git a/src/components/contracts/baseapp/src/app.rs b/src/components/contracts/baseapp/src/app.rs index 035a76a2e..e23241926 100644 --- a/src/components/contracts/baseapp/src/app.rs +++ b/src/components/contracts/baseapp/src/app.rs @@ -1,4 +1,4 @@ -use crate::{extensions::SignedExtra, BaseApp}; +use crate::extensions::SignedExtra; use abci::*; use config::abci::global_cfg::CFG; use enterprise_web3::{ @@ -7,25 +7,14 @@ use enterprise_web3::{ }; use fp_core::context::RunTxMode; use fp_evm::BlockId; -use fp_traits::account::AccountAsset; use fp_types::{ actions::xhub::NonConfidentialOutput, assemble::convert_unchecked_transaction, - crypto::Address, }; use fp_utils::tx::EvmRawTxWrapper; -use ledger::data_model::ASSET_TYPE_FRA; -use module_evm::{ - get_claim_on_contract_address, - system_contracts::SYSTEM_ADDR, - utils::{ - coinbase_mint_event, coinbase_mint_event_topic_str, - deposit_asset_event_topic_str, parse_deposit_asset_event, - parse_evm_staking_coinbase_mint_event, - }, -}; -use primitive_types::{H160, H256, U256}; +use module_evm::utils::{deposit_asset_event_topic_str, parse_deposit_asset_event}; +use primitive_types::U256; use ruc::*; -use std::{mem::take, ops::DerefMut, str::FromStr}; +use std::{mem::take, ops::DerefMut}; use tracing::{debug, error, info}; impl crate::BaseApp { /// info implements the ABCI interface. @@ -294,40 +283,12 @@ impl crate::BaseApp { if td_height > CFG.checkpoint.prismxx_inital_height && 0 == resp.code { let deposit_asset_topic = deposit_asset_event_topic_str(); - let coinbase_mint_event_topic = coinbase_mint_event_topic_str(); for evt in resp.events.iter() { if evt.field_type == *"ethereum_ContractLog" { let mut bridge_contract_found = false; let mut deposit_asset_foud = false; - let mut staking_contract_found = false; - let mut coinbase_mint_foud = false; - let mut validator = H256::zero(); - let mut delegator = H256::zero(); - - let claim_on_contract_address = if td_height - > CFG.checkpoint.evm_staking_inital_height - { - match H160::from_str(SYSTEM_ADDR).c(d!()).and_then( - |from| { - get_claim_on_contract_address::( - &self.modules.evm_module.contracts, - &self.deliver_state, - from, - ) - }, - ) { - Ok(v) => v, - Err(e) => { - resp.code = 1; - resp.log = e.to_string(); - return (resp, vec![]); - } - } - } else { - Default::default() - }; for pair in evt.attributes.iter() { let key = String::from_utf8(pair.key.clone()) .unwrap_or_default(); @@ -341,11 +302,6 @@ impl crate::BaseApp { .to_lowercase() { bridge_contract_found = true - } else if addr - == format!("{:?}", claim_on_contract_address) - .to_lowercase() - { - staking_contract_found = true; } } if key == *"topics" { @@ -354,130 +310,28 @@ impl crate::BaseApp { .unwrap_or_default(); if topic == deposit_asset_topic { deposit_asset_foud = true; - } else if td_height - > CFG.checkpoint.evm_staking_inital_height - && topic.starts_with( - &coinbase_mint_event_topic[0 - ..coinbase_mint_event_topic.len() - - 1], - ) - { - let hashes = topic - .strip_prefix('[') - .and_then(|v| v.strip_suffix(']')) - .unwrap_or(&topic) - .split(", ") - .collect::>(); - - let mut validator_flag = false; - if let Some(v) = hashes.get(1) { - validator_flag = true; - - let s = v - .strip_prefix(' ') - .and_then(|v| v.strip_suffix(' ')) - .unwrap_or(v); - validator = match H256::from_str(s) { - Ok(v) => v, - Err(e) => { - resp.code = 1; - resp.log = e.to_string(); - return (resp, vec![]); - } - }; - }; - let mut delegator_flag = false; - if let Some(v) = hashes.get(2) { - delegator_flag = true; - - let s = v - .strip_prefix(' ') - .and_then(|v| v.strip_suffix(' ')) - .unwrap_or(v); - delegator = match H256::from_str(s) { - Ok(v) => v, - Err(e) => { - resp.code = 1; - resp.log = e.to_string(); - return (resp, vec![]); - } - }; - }; - coinbase_mint_foud = - validator_flag && delegator_flag; } } - if key == *"data" { - if bridge_contract_found && deposit_asset_foud { - let data = - String::from_utf8(pair.value.clone()) - .unwrap_or_default(); - - let data_vec = - serde_json::from_str(&data).unwrap(); - - let deposit_asset = - parse_deposit_asset_event(data_vec); - - match deposit_asset { - Ok(deposit) => non_confidential_outputs - .push(deposit), - Err(e) => { - resp.code = 1; - resp.log = e.to_string(); - } + if key == *"data" + && bridge_contract_found + && deposit_asset_foud + { + let data = String::from_utf8(pair.value.clone()) + .unwrap_or_default(); + + let data_vec = + serde_json::from_str(&data).unwrap(); + + let deposit_asset = + parse_deposit_asset_event(data_vec); + + match deposit_asset { + Ok(deposit) => { + non_confidential_outputs.push(deposit) } - } else if td_height - > CFG.checkpoint.evm_staking_inital_height - && staking_contract_found - && coinbase_mint_foud - { - let data = - String::from_utf8(pair.value.clone()) - .unwrap_or_default(); - - let data_vec: Vec = - serde_json::from_str(&data).unwrap(); - - let event = coinbase_mint_event(); - let ret = - parse_evm_staking_coinbase_mint_event( - &event, - vec![ - event.signature(), - validator, - delegator, - ], - data_vec, - ); - - match ret { - Ok((addr, pub_key, amount)) => { - if let Some(pk) = pub_key { - non_confidential_outputs.push( - NonConfidentialOutput { - asset: ASSET_TYPE_FRA, - amount, - target: pk, - decimal: 0, - max_supply: 0, - }, - ); - } else if let Err(e) = module_account::App::< - BaseApp, - >::mint( - &self.deliver_state, - &Address::from(addr), - U256::from(amount), - ) { - resp.code = 2; - resp.log = e.to_string(); - } - } - Err(e) => { - resp.code = 1; - resp.log = e.to_string(); - } + Err(e) => { + resp.code = 1; + resp.log = e.to_string(); } } } diff --git a/src/components/contracts/baseapp/src/modules.rs b/src/components/contracts/baseapp/src/modules.rs index 42d91dfdc..6db8cd39e 100644 --- a/src/components/contracts/baseapp/src/modules.rs +++ b/src/components/contracts/baseapp/src/modules.rs @@ -83,17 +83,11 @@ impl ModuleManager { let mut resp: ResponseEndBlock = Default::default(); // Note: adding new modules need to be updated. self.account_module.end_block(ctx, req, ff_addr_balance); - let (mresp, burn_amount) = self.evm_module.end_block(ctx, req, 0); + let mresp = self.evm_module.end_block(ctx, req, 0); if !mresp.validator_updates.is_empty() { resp.validator_updates = mresp.validator_updates; } - if let Err(e) = module_account::App::::burn( - ctx, - &Address::from(self.evm_module.contracts.staking_address), - burn_amount, - ) { - tracing::warn!("module_account::App::::burn error: {:?}", e) - } + self.ethereum_module.end_block(ctx, req, 0); self.xhub_module.end_block(ctx, req, 0); self.template_module.end_block(ctx, req, 0); diff --git a/src/components/contracts/baseapp/src/staking.rs b/src/components/contracts/baseapp/src/staking.rs index a99f360f2..b15150a3a 100644 --- a/src/components/contracts/baseapp/src/staking.rs +++ b/src/components/contracts/baseapp/src/staking.rs @@ -10,9 +10,10 @@ use ledger::staking::{ evm::EVMStaking, Delegation, DelegationState, Validator, BLOCK_HEIGHT_MAX, }; use module_evm::{ - system_contracts::SYSTEM_ADDR, DelegatorParam, UndelegationInfos, ValidatorParam, + get_claim_on_contract_address, system_contracts::SYSTEM_ADDR, DelegatorParam, + UndelegationInfos, ValidatorParam, }; -use ruc::{d, Result, RucResult}; +use ruc::{d, eg, Result, RucResult}; use sha3::{Digest, Keccak256}; use std::{collections::BTreeMap, str::FromStr}; use zei::xfr::sig::XfrPublicKey; @@ -26,6 +27,7 @@ impl EVMStaking for BaseApp { ) -> Result<()> { let from = H160::from_str(SYSTEM_ADDR).c(d!())?; + let mut amount = U256::zero(); let mut vs = vec![]; { for v in validators.iter() { @@ -33,7 +35,10 @@ impl EVMStaking for BaseApp { .get(&v.id) .map(|d| d.start_height) .unwrap_or(self.deliver_state.header.height as u64); - + let power = + EthereumDecimalsMapping::from_native_token(U256::from(v.td_power)) + .c(d!())?; + amount = amount.checked_add(power).c(d!())?; vs.push(ValidatorParam { td_addr: H160::from_slice(&v.td_addr), td_pubkey: v.td_pubkey.clone(), @@ -42,18 +47,13 @@ impl EVMStaking for BaseApp { rate: mapping_rate(v.commission_rate), staker: mapping_address(&v.id), staker_pk: v.id.as_bytes().to_vec(), - power: U256::from(v.td_power), + power, begin_block: U256::from(begin_block), }); } } - let power = vs.iter().map(|v| v.power.as_u128()).sum::(); - let amount = - EthereumDecimalsMapping::from_native_token(U256::from(power)).c(d!())?; - 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), @@ -77,7 +77,9 @@ impl EVMStaking for BaseApp { let public_key = delegation.receiver_pk.unwrap_or(delegation.id); for (validator, amount) in delegation.delegations.iter() { - let amount = U256::from(*amount); + let amount = + EthereumDecimalsMapping::from_native_token(U256::from(*amount)) + .c(d!())?; ds.entry((public_key, mapping_address(validator))) .and_modify(|am| { am.push((delegation.end_height, amount)); @@ -117,6 +119,7 @@ impl EVMStaking for BaseApp { }); } } + undelegation_infos.sort_by(|a, b| a.height.cmp(&b.height)); if let Err(e) = self.modules.evm_module.import_delegators( &self.deliver_state, @@ -145,7 +148,8 @@ impl EVMStaking for BaseApp { .map(|d| { ( mapping_address(&d.receiver_pk.unwrap_or(d.id)), - d.rwd_amount, + EthereumDecimalsMapping::from_native_token(U256::from(d.rwd_amount)) + .unwrap(), ) }) .collect::>(); @@ -159,16 +163,19 @@ impl EVMStaking for BaseApp { tracing::error!(target: "evm staking", "import_reward error:{:?}", e); return Err(e); } - if let Err(e) = self.modules.evm_module.import_coinbase_balance( + + let claim_on_contract_address = get_claim_on_contract_address::( + &self.modules.evm_module.contracts, &self.deliver_state, from, - coinbase_balance, - ) { - self.deliver_state.state.write().discard_session(); - self.deliver_state.db.write().discard_session(); - tracing::error!(target: "evm staking", "import_coinbase_balance error:{:?}", e); - return Err(e); - } + )?; + module_account::App::::mint( + &self.deliver_state, + &Address::from(claim_on_contract_address), + EthereumDecimalsMapping::from_native_token(U256::from(coinbase_balance)) + .c(d!())?, + )?; + self.deliver_state.state.write().commit_session(); self.deliver_state.db.write().commit_session(); Ok(()) @@ -319,32 +326,10 @@ impl EVMStaking for BaseApp { Ok(()) } - fn replace_delegator( - &self, - validator: &[u8], - staker: &XfrPublicKey, - new_staker_address: H160, - ) -> Result<()> { - let validator = H160::from_slice(validator); - let staker_address = mapping_address(staker); - - if let Err(e) = self.modules.evm_module.replace_delegator( - &self.deliver_state, - validator, - staker_address, - new_staker_address, - ) { - self.deliver_state.state.write().discard_session(); - self.deliver_state.db.write().discard_session(); - tracing::error!(target: "evm staking", "replace_delegator error:{:?}", e); - return Err(e); - } - - self.deliver_state.state.write().commit_session(); - self.deliver_state.db.write().commit_session(); - Ok(()) - } fn claim(&self, td_addr: &[u8], delegator_pk: &XfrPublicKey) -> Result<()> { + if td_addr.len() != 20 { + return Err(eg!("td_addr length error")); + } let validator = H160::from_slice(td_addr); let delegator = mapping_address(delegator_pk); let from = H160::from_str(SYSTEM_ADDR).c(d!())?; @@ -353,7 +338,6 @@ impl EVMStaking for BaseApp { from, validator, delegator, - delegator_pk, ) { self.deliver_state.state.write().discard_session(); self.deliver_state.db.write().discard_session(); diff --git a/src/components/contracts/modules/ethereum/src/lib.rs b/src/components/contracts/modules/ethereum/src/lib.rs index 02ff0eafc..2af77f31d 100644 --- a/src/components/contracts/modules/ethereum/src/lib.rs +++ b/src/components/contracts/modules/ethereum/src/lib.rs @@ -135,7 +135,7 @@ impl AppModule for App { ctx: &mut Context, req: &RequestEndBlock, _ff_addr_balance: u64, - ) -> (ResponseEndBlock, U256) { + ) -> ResponseEndBlock { let _ = ruc::info!(self.store_block(ctx, U256::from(req.height))); Default::default() } diff --git a/src/components/contracts/modules/evm/contracts/EVMStaking.abi.json b/src/components/contracts/modules/evm/contracts/EVMStaking.abi.json index 586c15f28..aff466ea4 100644 --- a/src/components/contracts/modules/evm/contracts/EVMStaking.abi.json +++ b/src/components/contracts/modules/evm/contracts/EVMStaking.abi.json @@ -1,35 +1,4 @@ [ - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "validator", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "delegator", - "type": "address" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "public_key", - "type": "bytes" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "CoinbaseMint", - "type": "event" - }, { "anonymous": false, "inputs": [ @@ -43,25 +12,6 @@ "name": "Initialized", "type": "event" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bytes", - "name": "public_key", - "type": "bytes" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "MintOps", - "type": "event" - }, { "anonymous": false, "inputs": [ @@ -94,6 +44,19 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "config", + "outputs": [ + { + "internalType": "contract IConfig", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -222,19 +185,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "importCoinBase", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { @@ -396,7 +346,13 @@ "type": "function" }, { - "inputs": [], + "inputs": [ + { + "internalType": "address", + "name": "_config", + "type": "address" + } + ], "name": "initialize", "outputs": [], "stateMutability": "nonpayable", @@ -440,54 +396,15 @@ "stateMutability": "nonpayable", "type": "function" }, - { - "inputs": [], - "name": "rewardAddr", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "addr", - "type": "address" - } - ], - "name": "setRewardAddr", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { "internalType": "address", - "name": "addr", + "name": "_newConfig", "type": "address" } ], - "name": "setStakingAddr", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "addr", - "type": "address" - } - ], - "name": "setSystemAddr", + "name": "setConfig", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -520,32 +437,6 @@ "stateMutability": "payable", "type": "function" }, - { - "inputs": [], - "name": "stakingAddr", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "systemAddr", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -554,7 +445,7 @@ "type": "address" }, { - "internalType": "address", + "internalType": "address payable", "name": "delegator", "type": "address" } @@ -578,7 +469,7 @@ }, { "internalType": "bytes", - "name": "delegator_pk", + "name": "delegatorPk", "type": "bytes" } ], @@ -603,6 +494,11 @@ "internalType": "address", "name": "newDelegator", "type": "address" + }, + { + "internalType": "bytes", + "name": "delegatorPk", + "type": "bytes" } ], "name": "systemReplaceDelegator", @@ -619,7 +515,7 @@ }, { "internalType": "bytes", - "name": "public_key", + "name": "publicKey", "type": "bytes" }, { @@ -629,7 +525,7 @@ }, { "internalType": "bytes", - "name": "staker_pk", + "name": "stakerPk", "type": "bytes" }, { diff --git a/src/components/contracts/modules/evm/src/lib.rs b/src/components/contracts/modules/evm/src/lib.rs index 60d6400d2..89a1d10bf 100644 --- a/src/components/contracts/modules/evm/src/lib.rs +++ b/src/components/contracts/modules/evm/src/lib.rs @@ -28,7 +28,6 @@ use fp_core::{ }; use fp_evm::TransactionStatus; use fp_storage::BorrowMut; -use fp_traits::evm::EthereumDecimalsMapping; use fp_traits::{ account::AccountAsset, evm::{AddressMapping, BlockHashMapping, DecimalsMapping, FeeCalculator}, @@ -49,10 +48,9 @@ pub use runtime::*; use std::marker::PhantomData; use std::str::FromStr; use system_contracts::{SystemContracts, SYSTEM_ADDR}; -use utils::parse_evm_staking_coinbase_mint_event; use zei::xfr::sig::XfrPublicKey; -use crate::utils::parse_evm_staking_mint_event; +use crate::utils::{deposit_asset_event, parse_deposit_asset_event}; pub const MODULE_NAME: &str = "evm"; @@ -306,7 +304,7 @@ impl App { ctx: &Context, req: &abci::RequestBeginBlock, ff_addr_balance: u64, - ) -> Result { + ) -> Result<()> { let pre_issue_amount = FRA_PRE_ISSUE_AMOUNT - ff_addr_balance; let input = utils::build_evm_staking_input(&self.contracts, req, pre_issue_amount)?; @@ -324,8 +322,6 @@ impl App { self.contracts.staking_address, hex::encode(&input) ); - let trigger_on_contract_address = - get_trigger_on_contract_address::(&self.contracts, ctx, from)?; let (_, logs, used_gas) = ActionRunner::::execute_systemc_contract( ctx, @@ -345,33 +341,30 @@ impl App { &logs, used_gas, )?; - let mut mints = vec![]; - - for log in logs.into_iter() { - if log.address != trigger_on_contract_address { + let addr = H160::from_str(&CFG.checkpoint.prism_bridge_address).c(d!())?; + let signature = deposit_asset_event().signature(); + for log in logs.iter() { + if log.address != addr { continue; } - match parse_evm_staking_mint_event(&self.contracts.staking, log) { - Ok((pk, am)) => { - if am != 0 { - mints.push((pk, am)); + match log.topics.get(0).cloned() { + Some(v) => { + if v != signature { + continue; } } - Err(e) => { - tracing::warn!("Parse evm staking mint error: {}", e); - } + None => continue, + } + if let Ok(output) = parse_deposit_asset_event(log.data.to_vec()) { + mints.push((output.target, output.amount)); } } - - let amount = mints.iter().map(|v| v.1).sum::(); - let amount = - EthereumDecimalsMapping::from_native_token(U256::from(amount)).c(d!())?; if !mints.is_empty() { EVM_STAKING_MINTS.lock().extend(mints); } - Ok(amount) + Ok(()) } pub fn import_validators( @@ -605,7 +598,7 @@ impl App { &self, ctx: &Context, from: H160, - rewards: &[(H160, u64)], + rewards: &[(H160, U256)], ) -> Result<()> { let function = self.contracts.staking.function("importReward").c(d!())?; let mut reward_tokens = vec![]; @@ -613,10 +606,7 @@ impl App { let tokens = rewards .iter() .map(|(addr, amount)| { - Token::Tuple(vec![ - Token::Address(*addr), - Token::Uint(U256::from(*amount)), - ]) + Token::Tuple(vec![Token::Address(*addr), Token::Uint(*amount)]) }) .collect::>(); let mut tmp = vec![]; @@ -667,48 +657,7 @@ impl App { } Ok(()) } - pub fn import_coinbase_balance( - &self, - ctx: &Context, - from: H160, - coinbase_balance: u64, - ) -> Result<()> { - let function = self.contracts.staking.function("importCoinBase").c(d!())?; - let input = function - .encode_input(&[Token::Uint(U256::from(coinbase_balance))]) - .c(d!())?; - let gas_limit = u64::MAX; - let value = U256::zero(); - tracing::info!( - target: "evm staking", - "importCoinBase from:{:?} gas_limit:{} value:{} contracts_address:{:?} input:{}", - from, - gas_limit, - value, - self.contracts.staking_address, - hex::encode(&input) - ); - let (_, logs, used_gas) = ActionRunner::::execute_systemc_contract( - ctx, - input.clone(), - from, - gas_limit, - self.contracts.staking_address, - value, - )?; - Self::store_transaction( - ctx, - U256::from(gas_limit), - from, - self.contracts.staking_address, - value, - input, - &logs, - used_gas, - )?; - Ok(()) - } #[allow(clippy::too_many_arguments)] pub fn stake( &self, @@ -882,7 +831,6 @@ impl App { from: H160, validator: H160, delegator: H160, - delegator_pk: &XfrPublicKey, ) -> Result<()> { let function = self.contracts.staking.function("systemClaim").c(d!())?; let input = function @@ -901,8 +849,6 @@ impl App { self.contracts.staking_address, hex::encode(&input) ); - let claim_on_contract_address = - get_claim_on_contract_address::(&self.contracts, ctx, from)?; let (_, logs, used_gas) = ActionRunner::::execute_systemc_contract( ctx, @@ -923,37 +869,29 @@ impl App { &logs, used_gas, )?; - - let mut mints = Vec::new(); - - for log in logs.into_iter() { - if log.address != claim_on_contract_address { + let mut mints = vec![]; + let addr = H160::from_str(&CFG.checkpoint.prism_bridge_address).c(d!())?; + let signature = deposit_asset_event().signature(); + for log in logs.iter() { + if log.address != addr { continue; } - let event = self - .contracts - .staking - .event("CoinbaseMint") - .map_err(|e| eg!(e))?; - match parse_evm_staking_coinbase_mint_event(event, log.topics, log.data) { - Ok((_delegator, _, am)) => { - if delegator != _delegator { - return Err(eg!("Invalid delegator.")); - } - if am != 0 { - mints.push((*delegator_pk, am)); + match log.topics.get(0).cloned() { + Some(v) => { + if v != signature { + continue; } } - Err(e) => { - tracing::warn!("Parse claim mint error: {}", e); - } + None => continue, } - } + if let Ok(output) = parse_deposit_asset_event(log.data.to_vec()) { + mints.push((output.target, output.amount)); + } + } if !mints.is_empty() { EVM_STAKING_MINTS.lock().extend(mints); } - Ok(()) } @@ -1017,64 +955,6 @@ impl App { Ok(()) } - pub fn replace_delegator( - &self, - ctx: &Context, - validator: H160, - staker: H160, - new_staker: H160, - ) -> Result<()> { - let func = self - .contracts - .staking - .function("systemReplaceDelegator") - .c(d!())?; - - let validator = Token::Array(vec![Token::Address(validator)]); - let staker = Token::Address(staker); - let new_staker = Token::Address(new_staker); - - let input = func - .encode_input(&[validator, staker, new_staker]) - .c(d!())?; - - let gas_limit = u64::MAX; - let value = U256::zero(); - let from = H160::from_str(SYSTEM_ADDR).c(d!())?; - - tracing::info!( - target: "evm staking", - "systemReplaceStaker from:{:?} gas_limit:{} value:{} contracts_address:{:?} input:{}", - from, - gas_limit, - value, - self.contracts.staking_address, - hex::encode(&input) - ); - - let (_, logs, used_gas) = ActionRunner::::execute_systemc_contract( - ctx, - input.clone(), - from, - gas_limit, - self.contracts.staking_address, - value, - )?; - - Self::store_transaction( - ctx, - U256::from(gas_limit), - from, - self.contracts.staking_address, - value, - input, - &logs, - used_gas, - )?; - - Ok(()) - } - #[allow(clippy::too_many_arguments)] fn store_transaction( ctx: &Context, @@ -1199,11 +1079,11 @@ impl AppModule for App { ctx: &mut Context, _req: &abci::RequestEndBlock, ff_addr_balance: u64, - ) -> (abci::ResponseEndBlock, U256) { + ) -> abci::ResponseEndBlock { let mut resp = abci::ResponseEndBlock::default(); - let mut burn_amount = Default::default(); + if ctx.header.height > CFG.checkpoint.evm_staking_inital_height { - burn_amount = match self.execute_staking_contract( + match self.execute_staking_contract( ctx, &self.abci_begin_block, ff_addr_balance, @@ -1224,48 +1104,7 @@ impl AppModule for App { } } - (resp, burn_amount) - } -} - -fn get_trigger_on_contract_address( - contract: &SystemContracts, - ctx: &Context, - from: H160, -) -> Result { - let function = contract - .staking - .function("getTriggerOnContractAddress") - .c(d!())?; - let input = function.encode_input(&[]).c(d!())?; - - let gas_limit = u64::MAX; - let value = U256::zero(); - - tracing::info!( - target: "evm staking", - "getTriggerOnContractAddress from:{:?} gas_limit:{} value:{} contracts_address:{:?} input:{}", - from, - gas_limit, - value, - contract.staking_address, - hex::encode(&input) - ); - - let (data, _, _) = ActionRunner::::execute_systemc_contract( - ctx, - input, - from, - gas_limit, - contract.staking_address, - value, - )?; - let ret = function.decode_output(&data).c(d!())?; - - if let Some(Token::Address(addr)) = ret.get(0) { - Ok(*addr) - } else { - Err(eg!("address not found")) + resp } } diff --git a/src/components/contracts/modules/evm/src/runtime/runner.rs b/src/components/contracts/modules/evm/src/runtime/runner.rs index a91e6e06a..f05863e05 100644 --- a/src/components/contracts/modules/evm/src/runtime/runner.rs +++ b/src/components/contracts/modules/evm/src/runtime/runner.rs @@ -203,9 +203,10 @@ impl ActionRunner { } else { // TODO: store error execution on pending tx later. Err(eg!( - "Execute system error: {:?}, data is: {}", + "Execute system error: {:?}, data is: {}, info:{}", result, - hex::encode(data) + hex::encode(&data), + String::from_utf8_lossy(&data) )) } } diff --git a/src/components/contracts/modules/evm/src/utils.rs b/src/components/contracts/modules/evm/src/utils.rs index a10e5a9c8..c7185c945 100644 --- a/src/components/contracts/modules/evm/src/utils.rs +++ b/src/components/contracts/modules/evm/src/utils.rs @@ -1,7 +1,6 @@ use crate::system_contracts::SystemContracts; -use ethabi::{Contract, Event, EventParam, ParamType, RawLog, Token}; -use ethereum::Log; -use ethereum_types::{H160, H256, U256}; +use ethabi::{Event, EventParam, ParamType, RawLog, Token}; +use ethereum_types::{H160, U256}; use fp_traits::evm::{DecimalsMapping, EthereumDecimalsMapping}; use fp_types::actions::xhub::NonConfidentialOutput; use ledger::data_model::ASSET_TYPE_FRA; @@ -146,7 +145,9 @@ pub fn build_evm_staking_input( } let func = sc.staking.function("trigger").c(d!())?; - + let issue_amount = + EthereumDecimalsMapping::from_native_token(U256::from(pre_issue_amount)) + .c(d!())?; let input = func .encode_input(&[ proposer, @@ -154,7 +155,7 @@ pub fn build_evm_staking_input( Token::Array(unsigned), Token::Array(byzantines), Token::Array(behaviors), - Token::Uint(U256::from(pre_issue_amount)), + Token::Uint(issue_amount), ]) .c(d!())?; @@ -186,7 +187,8 @@ fn build_update_info(tk: &Token) -> Result { } if let Token::Uint(p) = v.get(3).ok_or(eg!("update info 3 must int"))? { - update.set_power(p.as_u64() as i64); + let power = EthereumDecimalsMapping::convert_to_native_token(*p).as_u64(); + update.set_power(power as i64); } else { return Err(eg!("Error type of public key type")); } @@ -222,81 +224,6 @@ pub fn build_validator_updates( } } -pub fn parse_evm_staking_mint_event( - staking_contracts: &Contract, - log: Log, -) -> Result<(XfrPublicKey, u64)> { - let event = staking_contracts.event("MintOps").map_err(|e| eg!(e))?; - let log = RawLog { - topics: log.topics, - data: log.data, - }; - - let result = event.parse_log(log).map_err(|e| eg!(e))?; - let public_key_bytes = result.params[0].value.clone().into_bytes().c(d!())?; - - let public_key = XfrPublicKey::zei_from_bytes(public_key_bytes.as_slice())?; - - let amount = result.params[1].value.clone().into_uint().c(d!())?.as_u64(); - - Ok((public_key, amount)) -} - -pub fn coinbase_mint_event() -> Event { - Event { - name: "CoinbaseMint".to_owned(), - inputs: vec![ - EventParam { - name: "validator".to_owned(), - kind: ParamType::Address, - indexed: true, - }, - EventParam { - name: "delegator".to_owned(), - kind: ParamType::Address, - indexed: true, - }, - EventParam { - name: "public_key".to_owned(), - kind: ParamType::Bytes, - indexed: false, - }, - EventParam { - name: "amount".to_owned(), - kind: ParamType::Uint(256), - indexed: false, - }, - ], - anonymous: false, - } -} - -pub fn coinbase_mint_event_topic_str() -> String { - let topic = coinbase_mint_event().signature(); - let temp = hex::encode(topic.as_bytes()); - "[0x".to_owned() + &*temp + &*"]".to_owned() -} - -pub fn parse_evm_staking_coinbase_mint_event( - event: &Event, - topics: Vec, - data: Vec, -) -> Result<(H160, Option, u64)> { - let log = RawLog { topics, data }; - let result = event.parse_log(log).map_err(|e| eg!(e))?; - let delegator = result.params[1].value.clone().into_address().c(d!())?; - - let public_key_bytes = result.params[2].value.clone().into_bytes().c(d!())?; - let amount = result.params[3].value.clone().into_uint().c(d!())?.as_u64(); - - if public_key_bytes.is_empty() { - return Ok((delegator, None, amount)); - } - let public_key = XfrPublicKey::zei_from_bytes(public_key_bytes.as_slice())?; - - Ok((delegator, Some(public_key), amount)) -} - fn build_claim_info(tk: &Token) -> Result<(H160, U256)> { if let Token::Tuple(v) = tk { let addr = if let Token::Address(addr) = diff --git a/src/components/contracts/primitives/core/src/module.rs b/src/components/contracts/primitives/core/src/module.rs index 7a7e843a4..6dd5f2345 100644 --- a/src/components/contracts/primitives/core/src/module.rs +++ b/src/components/contracts/primitives/core/src/module.rs @@ -1,6 +1,5 @@ use crate::context::Context; use abci::*; -use primitive_types::U256; use ruc::Result; /// AppModuleBasic is the standard form for basic non-dependant elements of an application module. @@ -42,7 +41,7 @@ pub trait AppModule: AppModuleBasic { _ctx: &mut Context, _req: &RequestEndBlock, _ff_addr_balance: u64, - ) -> (ResponseEndBlock, U256) { + ) -> ResponseEndBlock { Default::default() } } diff --git a/src/components/finutils/src/common/mod.rs b/src/components/finutils/src/common/mod.rs index 534364f6c..ab00ab060 100644 --- a/src/components/finutils/src/common/mod.rs +++ b/src/components/finutils/src/common/mod.rs @@ -847,7 +847,7 @@ pub fn replace_staker(target_addr: fp_types::H160, td_addr: &str) -> Result<()> builder.add_operation(op); })?; - builder.add_operation_replace_staker(&keypair, target_addr, td_addr)?; + builder.add_operation_replace_staker(&keypair, target_addr, None, td_addr)?; let mut tx = builder.take_transaction(); tx.sign_to_map(&keypair); diff --git a/src/components/finutils/src/txn_builder/mod.rs b/src/components/finutils/src/txn_builder/mod.rs index dc4e37c45..c4ef9a1a0 100644 --- a/src/components/finutils/src/txn_builder/mod.rs +++ b/src/components/finutils/src/txn_builder/mod.rs @@ -623,12 +623,14 @@ impl TransactionBuilder { pub fn add_operation_replace_staker( &mut self, keypair: &XfrKeyPair, - new_staker_address: H160, + new_delegator: H160, + new_delegator_pk: Option>, td_addr: Vec, ) -> Result<&mut Self> { let ops = ReplaceStakerOps::new( keypair, - new_staker_address, + new_delegator, + new_delegator_pk, td_addr, self.txn.body.no_replay_token, ); diff --git a/src/ledger/src/staking/evm.rs b/src/ledger/src/staking/evm.rs index dd048d4fa..3fb1fa1c2 100644 --- a/src/ledger/src/staking/evm.rs +++ b/src/ledger/src/staking/evm.rs @@ -1,7 +1,6 @@ //! For interact with BaseApp (EVM) use super::{Delegation, Validator}; -use fp_types::H160; use once_cell::sync::{Lazy, OnceCell}; use parking_lot::{Mutex, RwLock}; use ruc::Result; @@ -47,13 +46,7 @@ pub trait EVMStaking: Sync + Send + 'static { memo: String, rate: [u64; 2], ) -> Result<()>; - /// - fn replace_delegator( - &self, - validator: &[u8], - staker: &XfrPublicKey, - new_staker_address: H160, - ) -> Result<()>; + /// claim call fn claim(&self, td_addr: &[u8], delegator_pk: &XfrPublicKey) -> Result<()>; } diff --git a/src/ledger/src/staking/ops/replace_staker.rs b/src/ledger/src/staking/ops/replace_staker.rs index b88b3b44b..90aec6371 100644 --- a/src/ledger/src/staking/ops/replace_staker.rs +++ b/src/ledger/src/staking/ops/replace_staker.rs @@ -6,7 +6,7 @@ use { crate::{ data_model::{NoReplayToken, Transaction}, - staking::{evm::EVM_STAKING, Staking}, + staking::Staking, }, config::abci::global_cfg::CFG, fp_types::H160, @@ -27,14 +27,16 @@ impl ReplaceStakerOps { ///create a new replace operation. pub fn new( keypair: &XfrKeyPair, - new_staker_address: H160, + new_delegator: H160, + new_delegator_pk: Option>, td_addr: Vec, nonce: NoReplayToken, ) -> Self { let body = Data { new_public_key: XfrPublicKey::default(), new_tendermint_params: None, - new_staker_address: Some(new_staker_address), + new_delegator: Some(new_delegator), + new_delegator_pk, td_addr: Some(td_addr), nonce, }; @@ -73,22 +75,7 @@ impl ReplaceStakerOps { self.verify()?; let cur_height = staking_simulator.cur_height() as i64; if cur_height > CFG.checkpoint.evm_staking_inital_height { - let validator = self - .body - .td_addr - .clone() - .ok_or(eg!("replace staker validator not found"))?; - - let new_staker_address = self - .body - .new_staker_address - .ok_or(eg!("replace staker new_staker_address not found"))?; - - EVM_STAKING.get().c(d!())?.write().replace_delegator( - &validator, - &self.pubkey, - new_staker_address, - ) + Err(eg!("replace_delegator not support")) } else { dbg!(staking_simulator.check_and_replace_staker( &self.pubkey, @@ -126,7 +113,9 @@ pub struct Data { pub new_public_key: XfrPublicKey, pub new_tendermint_params: Option, #[serde(skip_serializing_if = "Option::is_none")] - pub new_staker_address: Option, + pub new_delegator: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub new_delegator_pk: Option>, #[serde(skip_serializing_if = "Option::is_none")] pub td_addr: Option>, nonce: NoReplayToken,