From ca02d1cb7c6a4089f07ef1a59e396e82fc7ca643 Mon Sep 17 00:00:00 2001 From: Bushstar Date: Mon, 24 Apr 2023 08:39:01 +0100 Subject: [PATCH 1/3] FFI: Get block difficulty and chain work of block --- lib/ain-cpp-imports/src/bridge.rs | 2 ++ lib/ain-cpp-imports/src/lib.rs | 16 ++++++++++++ lib/ain-grpc/src/rpc.rs | 23 +++++++++++++++-- src/ffi/ffiexports.cpp | 41 +++++++++++++++++++++++++++++++ src/ffi/ffiexports.h | 2 ++ 5 files changed, 82 insertions(+), 2 deletions(-) diff --git a/lib/ain-cpp-imports/src/bridge.rs b/lib/ain-cpp-imports/src/bridge.rs index b2a3f40387..ac4b8dec11 100644 --- a/lib/ain-cpp-imports/src/bridge.rs +++ b/lib/ain-cpp-imports/src/bridge.rs @@ -8,5 +8,7 @@ pub mod ffi { fn publishEthTransaction(data: Vec) -> bool; fn getAccounts() -> Vec; fn getDatadir() -> String; + fn getDifficulty(_block_hash: [u8; 32]) -> u32; + fn getChainWork(_block_hash: [u8; 32]) -> [u8; 32]; } } diff --git a/lib/ain-cpp-imports/src/lib.rs b/lib/ain-cpp-imports/src/lib.rs index 0bc3213233..925cc8d0f0 100644 --- a/lib/ain-cpp-imports/src/lib.rs +++ b/lib/ain-cpp-imports/src/lib.rs @@ -25,6 +25,12 @@ mod ffi { pub fn getDatadir() -> String { unimplemented!("{}", UNIMPL_MSG) } + pub fn getDifficulty(_block_hash: [u8; 32]) -> u32 { + unimplemented!("{}", UNIMPL_MSG) + } + pub fn getChainWork(_block_hash: [u8; 32]) -> [u8; 32] { + unimplemented!("{}", UNIMPL_MSG) + } } pub fn get_chain_id() -> Result> { @@ -52,5 +58,15 @@ pub fn get_datadir() -> Result> { Ok(datadir) } +pub fn get_difficulty(block_hash: [u8; 32]) -> Result> { + let bits = ffi::getDifficulty(block_hash); + Ok(bits) +} + +pub fn get_chainwork(block_hash: [u8; 32]) -> Result<[u8; 32], Box> { + let chainwork = ffi::getChainWork(block_hash); + Ok(chainwork) +} + #[cfg(test)] mod tests {} diff --git a/lib/ain-grpc/src/rpc.rs b/lib/ain-grpc/src/rpc.rs index 071257e407..2222febb0e 100644 --- a/lib/ain-grpc/src/rpc.rs +++ b/lib/ain-grpc/src/rpc.rs @@ -154,11 +154,30 @@ impl MetachainRPCServer for MetachainRPCModule { let hash: H256 = hash.parse().expect("Invalid hash"); - Ok(self + let block: Option = self .handler .storage .get_block_by_hash(&hash) - .map(Into::into)) + .map(Into::into); + + match block { + None => Ok(None), + Some(mut block) => { + let hash_array = hash.to_fixed_bytes(); + let difficulty = ain_cpp_imports::get_difficulty(hash_array); + let chainwork = ain_cpp_imports::get_chainwork(hash_array); + + if let Ok(difficulty) = difficulty { + block.difficulty = U256::from(difficulty); + } + + if let Ok(chainwork) = chainwork { + block.total_difficulty = Some(U256::from(chainwork)); + } + + Ok(Some(block)) + } + } } fn chain_id(&self) -> Result { diff --git a/src/ffi/ffiexports.cpp b/src/ffi/ffiexports.cpp index 39851bbcc2..e5ee01eb2e 100644 --- a/src/ffi/ffiexports.cpp +++ b/src/ffi/ffiexports.cpp @@ -66,3 +66,44 @@ rust::vec getAccounts() { rust::string getDatadir() { return GetDataDir().c_str(); } + +uint32_t getDifficulty(std::array blockHash) { + uint256 hash{}; + std::copy(blockHash.begin(), blockHash.end(), hash.begin()); + + const CBlockIndex* pblockindex; + uint32_t difficulty{}; + { + LOCK(cs_main); + pblockindex = LookupBlockIndex(hash); + + if (!pblockindex) { + return difficulty; + } + + difficulty = pblockindex->nBits; + } + + return difficulty; +} + +std::array getChainWork(std::array blockHash) { + uint256 hash{}; + std::copy(blockHash.begin(), blockHash.end(), hash.begin()); + + const CBlockIndex* pblockindex; + std::array chainWork{}; + { + LOCK(cs_main); + pblockindex = LookupBlockIndex(hash); + + if (!pblockindex) { + return chainWork; + } + + const auto sourceWork = ArithToUint256(pblockindex->nChainWork); + std::copy(sourceWork.begin(), sourceWork.end(), chainWork.begin()); + } + + return chainWork; +} diff --git a/src/ffi/ffiexports.h b/src/ffi/ffiexports.h index 4e3843a2c1..6c518593f7 100644 --- a/src/ffi/ffiexports.h +++ b/src/ffi/ffiexports.h @@ -9,5 +9,7 @@ bool isMining(); bool publishEthTransaction(rust::Vec rawTransaction); rust::vec getAccounts(); rust::string getDatadir(); +uint32_t getDifficulty(std::array blockHash); +std::array getChainWork(std::array blockHash); #endif // DEFI_EVM_FFI_H From 4873c09c842c6c595517256aada722fbc7e68f6c Mon Sep 17 00:00:00 2001 From: Bushstar Date: Mon, 24 Apr 2023 09:40:55 +0100 Subject: [PATCH 2/3] Pass difficulty to finalise_block --- lib/ain-evm/src/handler.rs | 3 ++- lib/ain-evm/tests/block.rs | 8 ++++---- lib/ain-grpc/src/rpc.rs | 5 ----- lib/ain-grpc/src/tests.rs | 2 +- lib/ain-rs-exports/src/lib.rs | 4 +++- src/miner.cpp | 2 +- src/validation.cpp | 6 +++--- 7 files changed, 14 insertions(+), 16 deletions(-) diff --git a/lib/ain-evm/src/handler.rs b/lib/ain-evm/src/handler.rs index d674422a73..5fe0149244 100644 --- a/lib/ain-evm/src/handler.rs +++ b/lib/ain-evm/src/handler.rs @@ -34,6 +34,7 @@ impl Handlers { &self, context: u64, update_state: bool, + difficulty: u32, _miner_address: Option, ) -> Result<(BlockAny, Vec), Box> { let mut successful_transactions = Vec::with_capacity(self.evm.tx_queues.len(context)); @@ -71,7 +72,7 @@ impl Handlers { state_root: Default::default(), receipts_root: Default::default(), logs_bloom: Default::default(), - difficulty: Default::default(), + difficulty: U256::from(difficulty), number, gas_limit: Default::default(), gas_used: Default::default(), diff --git a/lib/ain-evm/tests/block.rs b/lib/ain-evm/tests/block.rs index 397c60d64d..60c6fa203b 100644 --- a/lib/ain-evm/tests/block.rs +++ b/lib/ain-evm/tests/block.rs @@ -23,7 +23,7 @@ fn test_finalize_block_and_do_not_update_state() { handler.evm.tx_queues.add_signed_tx(context, tx1); let old_state = handler.evm.state.read().unwrap(); - let _ = handler.finalize_block(context, false, None).unwrap(); + let _ = handler.finalize_block(context, false, 0, None).unwrap(); let new_state = handler.evm.state.read().unwrap(); assert_eq!(*new_state, *old_state); @@ -60,7 +60,7 @@ fn test_finalize_block_and_update_state() { assert_eq!(handler.evm.tx_queues.len(context), 3); assert_eq!(handler.evm.tx_queues.len(handler.evm.get_context()), 0); - let (block, failed_txs) = handler.finalize_block(context, true, None).unwrap(); + let (block, failed_txs) = handler.finalize_block(context, true, 0, None).unwrap(); assert_eq!( block.transactions, vec![tx1, tx2, tx3.clone()] @@ -133,7 +133,7 @@ fn test_deploy_and_call_smart_contract() { .tx_queues .add_signed_tx(context, create_smart_contract_tx); - handler.finalize_block(context, true, None).unwrap(); + handler.finalize_block(context, true, 0, None).unwrap(); // Fund caller address handler.evm.add_balance( @@ -152,7 +152,7 @@ fn test_deploy_and_call_smart_contract() { .tx_queues .add_signed_tx(context, call_smart_contract_tx); - handler.finalize_block(context, true, None).unwrap(); + handler.finalize_block(context, true, 0, None).unwrap(); let smart_contract_storage = handler.evm.get_storage(smart_contract_address); assert_eq!( diff --git a/lib/ain-grpc/src/rpc.rs b/lib/ain-grpc/src/rpc.rs index 2222febb0e..6bfc90b317 100644 --- a/lib/ain-grpc/src/rpc.rs +++ b/lib/ain-grpc/src/rpc.rs @@ -164,13 +164,8 @@ impl MetachainRPCServer for MetachainRPCModule { None => Ok(None), Some(mut block) => { let hash_array = hash.to_fixed_bytes(); - let difficulty = ain_cpp_imports::get_difficulty(hash_array); let chainwork = ain_cpp_imports::get_chainwork(hash_array); - if let Ok(difficulty) = difficulty { - block.difficulty = U256::from(difficulty); - } - if let Ok(chainwork) = chainwork { block.total_difficulty = Some(U256::from(chainwork)); } diff --git a/lib/ain-grpc/src/tests.rs b/lib/ain-grpc/src/tests.rs index ece6f989c0..afb2976d9a 100644 --- a/lib/ain-grpc/src/tests.rs +++ b/lib/ain-grpc/src/tests.rs @@ -50,7 +50,7 @@ fn should_get_balance() { .evm .add_balance(ctx, H160::from_str(ALICE).unwrap(), U256::from(1337)); - let _ = handler.finalize_block(ctx, true, None); + let _ = handler.finalize_block(ctx, true, 0, None); let res2 = EthService::Eth_GetBalance(handler, input.into()); assert_eq!(res2.unwrap().balance, "1337"); diff --git a/lib/ain-rs-exports/src/lib.rs b/lib/ain-rs-exports/src/lib.rs index 4e65ea6936..e47c2d5f89 100644 --- a/lib/ain-rs-exports/src/lib.rs +++ b/lib/ain-rs-exports/src/lib.rs @@ -24,6 +24,7 @@ mod ffi { fn evm_finalize( context: u64, update_state: bool, + difficulty: u32, miner_address: [u8; 20], ) -> Result>; @@ -111,12 +112,13 @@ use rlp::Encodable; fn evm_finalize( context: u64, update_state: bool, + difficulty: u32, miner_address: [u8; 20], ) -> Result, Box> { let eth_address = H160::from(miner_address); let (block, _failed_tx) = RUNTIME .handlers - .finalize_block(context, update_state, Some(eth_address))?; + .finalize_block(context, update_state, difficulty, Some(eth_address))?; Ok(block.header.rlp_bytes().into()) } diff --git a/src/miner.cpp b/src/miner.cpp index 7e96033a31..4966382019 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -245,7 +245,7 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc // TODO Get failed TXs and try to restore to mempool std::array dummyAddress{}; - const auto rustHeader = evm_finalize(evmContext, false, dummyAddress); + const auto rustHeader = evm_finalize(evmContext, false, pos::GetNextWorkRequired(pindexPrev, pblock->nTime, consensus), dummyAddress); std::vector evmHeader{}; evmHeader.resize(rustHeader.size()); diff --git a/src/validation.cpp b/src/validation.cpp index 88e3b4029d..c320771c69 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2853,11 +2853,11 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl height = idHeight->blockHeight - GetMnResignDelay(std::numeric_limits::max()); mnID = node->collateralTx; } - + const auto blockindex = ::ChainActive()[height]; assert(blockindex); - + CTransactionRef tx; uint256 hash_block; assert(GetTransaction(mnID, tx, Params().GetConsensus(), hash_block, blockindex)); @@ -2873,7 +2873,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl std::copy(minter.begin(), minter.end(), minerAddress.begin()); } - evm_finalize(evmContext, true, minerAddress); + evm_finalize(evmContext, true, block.nBits, minerAddress); } auto &checkpoints = chainparams.Checkpoints().mapCheckpoints; From d73fff0717f45f6963a7f6f30b9f581070eb52df Mon Sep 17 00:00:00 2001 From: Bushstar Date: Mon, 24 Apr 2023 09:47:42 +0100 Subject: [PATCH 3/3] Do not store total_difficulty --- lib/ain-grpc/src/rpc.rs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/lib/ain-grpc/src/rpc.rs b/lib/ain-grpc/src/rpc.rs index 6bfc90b317..d66787dd66 100644 --- a/lib/ain-grpc/src/rpc.rs +++ b/lib/ain-grpc/src/rpc.rs @@ -160,19 +160,7 @@ impl MetachainRPCServer for MetachainRPCModule { .get_block_by_hash(&hash) .map(Into::into); - match block { - None => Ok(None), - Some(mut block) => { - let hash_array = hash.to_fixed_bytes(); - let chainwork = ain_cpp_imports::get_chainwork(hash_array); - - if let Ok(chainwork) = chainwork { - block.total_difficulty = Some(U256::from(chainwork)); - } - - Ok(Some(block)) - } - } + Ok(block) } fn chain_id(&self) -> Result {