Skip to content

Commit

Permalink
Move EVM state changes to outside Connect/DisconnectBlock (#2032)
Browse files Browse the repository at this point in the history
* Demo work in progress code

* Add iter method to keep transaction in queue instead of draining

* Remove print from test

* Rename iter to get_cloned_vec

* Use get_cloned_vec

* Update code after merge

---------

Co-authored-by: jouzo <jdesclercs@gmail.com>
  • Loading branch information
Bushstar and Jouzo authored Jun 7, 2023
1 parent bba09e5 commit 9cc4f21
Show file tree
Hide file tree
Showing 9 changed files with 37 additions and 21 deletions.
6 changes: 4 additions & 2 deletions lib/ain-evm/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ impl Handlers {

let mut executor = AinExecutor::new(&mut backend);

for (queue_tx, hash) in self.evm.tx_queues.drain_all(context) {
for (queue_tx, hash) in self.evm.tx_queues.get_cloned_vec(context) {
match queue_tx {
QueueTx::SignedTx(signed_tx) => {
let TxResponse {
Expand Down Expand Up @@ -133,7 +133,9 @@ impl Handlers {
}
}

self.evm.tx_queues.remove(context);
if update_state {
self.evm.tx_queues.remove(context);
}

let block = Block::new(
PartialHeader {
Expand Down
4 changes: 2 additions & 2 deletions lib/ain-evm/src/transaction/bridge.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use primitive_types::{H160, U256};

#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct BalanceUpdate {
pub address: H160,
pub amount: U256,
}

#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum BridgeTx {
EvmIn(BalanceUpdate),
EvmOut(BalanceUpdate),
Expand Down
14 changes: 13 additions & 1 deletion lib/ain-evm/src/tx_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ impl TransactionQueueMap {
.map_or(Vec::new(), TransactionQueue::drain_all)
}

pub fn get_cloned_vec(&self, context_id: u64) -> Vec<QueueTxWithNativeHash> {
self.queues
.read()
.unwrap()
.get(&context_id)
.map_or(Vec::new(), TransactionQueue::get_cloned_vec)
}

pub fn len(&self, context_id: u64) -> usize {
self.queues
.read()
Expand All @@ -84,7 +92,7 @@ impl TransactionQueueMap {
}
}

#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum QueueTx {
SignedTx(Box<SignedTx>),
BridgeTx(BridgeTx),
Expand Down Expand Up @@ -116,6 +124,10 @@ impl TransactionQueue {
.collect::<Vec<QueueTxWithNativeHash>>()
}

pub fn get_cloned_vec(&self) -> Vec<QueueTxWithNativeHash> {
self.transactions.lock().unwrap().clone()
}

pub fn queue_tx(&self, tx: QueueTxWithNativeHash) {
self.transactions.lock().unwrap().push(tx);
}
Expand Down
9 changes: 4 additions & 5 deletions src/masternodes/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2386,12 +2386,11 @@ static void RevertFailedTransferDomainTxs(const std::vector<std::string> &failed
}
}

static void ProcessEVMQueue(const CBlock &block, const CBlockIndex *pindex, CCustomCSView &cache, const CChainParams& chainparams, const uint64_t evmContext) {
static void ProcessEVMQueue(const CBlock &block, const CBlockIndex *pindex, CCustomCSView &cache, const CChainParams& chainparams, const uint64_t evmContext, std::array<uint8_t, 20>& beneficiary) {

if (IsEVMEnabled(pindex->nHeight, cache)) {
CKeyID minter;
assert(block.ExtractMinterKey(minter));
std::array<uint8_t, 20> beneficiary{};
CScript minerAddress;

if (!fMockNetwork) {
Expand Down Expand Up @@ -2430,7 +2429,7 @@ static void ProcessEVMQueue(const CBlock &block, const CBlockIndex *pindex, CCus
minerAddress = GetScriptForDestination(dest);
}

const auto blockResult = evm_finalize(evmContext, true, block.nBits, beneficiary, block.GetBlockTime());
const auto blockResult = evm_finalize(evmContext, false, block.nBits, beneficiary, block.GetBlockTime());

if (!blockResult.failed_transactions.empty()) {
std::vector<std::string> failedTransactions;
Expand All @@ -2445,7 +2444,7 @@ static void ProcessEVMQueue(const CBlock &block, const CBlockIndex *pindex, CCus
}
}

void ProcessDeFiEvent(const CBlock &block, const CBlockIndex* pindex, CCustomCSView& mnview, const CCoinsViewCache& view, const CChainParams& chainparams, const CreationTxs &creationTxs, const uint64_t evmContext) {
void ProcessDeFiEvent(const CBlock &block, const CBlockIndex* pindex, CCustomCSView& mnview, const CCoinsViewCache& view, const CChainParams& chainparams, const CreationTxs &creationTxs, const uint64_t evmContext, std::array<uint8_t, 20>& beneficiary) {
CCustomCSView cache(mnview);

// calculate rewards to current block
Expand Down Expand Up @@ -2500,7 +2499,7 @@ void ProcessDeFiEvent(const CBlock &block, const CBlockIndex* pindex, CCustomCSV
ProcessGrandCentralEvents(pindex, cache, chainparams);

// Execute EVM Queue
ProcessEVMQueue(block, pindex, cache, chainparams, evmContext);
ProcessEVMQueue(block, pindex, cache, chainparams, evmContext, beneficiary);

// construct undo
auto& flushable = cache.GetStorage();
Expand Down
2 changes: 1 addition & 1 deletion src/masternodes/validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class CCustomCSView;

using CreationTxs = std::map<uint32_t, std::pair<uint256, std::vector<std::pair<DCT_ID, uint256>>>>;

void ProcessDeFiEvent(const CBlock &block, const CBlockIndex* pindex, CCustomCSView& mnview, const CCoinsViewCache& view, const CChainParams& chainparams, const CreationTxs &creationTxs, const uint64_t evmContext);
void ProcessDeFiEvent(const CBlock &block, const CBlockIndex* pindex, CCustomCSView& mnview, const CCoinsViewCache& view, const CChainParams& chainparams, const CreationTxs &creationTxs, const uint64_t evmContext, std::array<uint8_t, 20>& beneficiary);
std::vector<CAuctionBatch> CollectAuctionBatches(const CVaultAssets& vaultAssets, const TAmounts& collBalances, const TAmounts& loanBalances);


Expand Down
1 change: 1 addition & 0 deletions src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
std::array<uint8_t, 20> beneficiary{};
std::copy(nodePtr->ownerAuthAddress.begin(), nodePtr->ownerAuthAddress.end(), beneficiary.begin());
auto blockResult = evm_finalize(evmContext, false, pos::GetNextWorkRequired(pindexPrev, pblock->nTime, consensus), beneficiary, blockTime);
evm_discard_context(evmContext);

const auto blockHash = std::vector<uint8_t>(blockResult.block_hash.begin(), blockResult.block_hash.end());

Expand Down
18 changes: 10 additions & 8 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1858,11 +1858,8 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI
}
}

evm_disconnect_latest_block();

mnview.SetLastHeight(pindex->pprev->nHeight);


return fClean ? DISCONNECT_OK : DISCONNECT_UNCLEAN;
}

Expand Down Expand Up @@ -2294,7 +2291,7 @@ static void LogApplyCustomTx(const CTransaction &tx, const int64_t start) {
* Validity checks that depend on the UTXO set are also done; ConnectBlock ()
* can fail if those validity checks fail (among other reasons). */
bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex,
CCoinsViewCache& view, CCustomCSView& mnview, const CChainParams& chainparams, bool & rewardedAnchors, bool fJustCheck, const int64_t evmContext)
CCoinsViewCache& view, CCustomCSView& mnview, const CChainParams& chainparams, bool & rewardedAnchors, std::array<uint8_t, 20>& beneficiary, bool fJustCheck, const int64_t evmContext)
{
AssertLockHeld(cs_main);
assert(pindex);
Expand Down Expand Up @@ -2818,7 +2815,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
// add this block to the view's block chain
view.SetBestBlock(pindex->GetBlockHash());

ProcessDeFiEvent(block, pindex, mnview, view, chainparams, creationTxs, evmContext);
ProcessDeFiEvent(block, pindex, mnview, view, chainparams, creationTxs, evmContext, beneficiary);

// Write any UTXO burns
for (const auto& [key, value] : writeBurnEntries)
Expand Down Expand Up @@ -3139,6 +3136,7 @@ bool CChainState::DisconnectTip(CValidationState& state, const CChainParams& cha
mnview.GetHistoryWriters().DiscardDB();
return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
}
evm_disconnect_latest_block();
bool flushed = view.Flush() && mnview.Flush();
assert(flushed);
mnview.GetHistoryWriters().FlushDB();
Expand Down Expand Up @@ -3280,8 +3278,9 @@ bool CChainState::ConnectTip(CValidationState& state, const CChainParams& chainp
CCoinsViewCache view(&CoinsTip());
CCustomCSView mnview(*pcustomcsview, paccountHistoryDB.get(), pburnHistoryDB.get(), pvaultHistoryDB.get());
bool rewardedAnchors{};
std::array<uint8_t, 20> beneficiary{};
const auto evmContext = evm_get_context();
bool rv = ConnectBlock(blockConnecting, state, pindexNew, view, mnview, chainparams, rewardedAnchors, false, evmContext);
bool rv = ConnectBlock(blockConnecting, state, pindexNew, view, mnview, chainparams, rewardedAnchors, beneficiary, false, evmContext);
GetMainSignals().BlockChecked(blockConnecting, state);
if (!rv) {
evm_discard_context(evmContext);
Expand All @@ -3293,6 +3292,7 @@ bool CChainState::ConnectTip(CValidationState& state, const CChainParams& chainp
}
nTime3 = GetTimeMicros(); nTimeConnectTotal += nTime3 - nTime2;
LogPrint(BCLog::BENCH, " - Connect total: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime3 - nTime2) * MILLI, nTimeConnectTotal * MICRO, nTimeConnectTotal * MILLI / nBlocksTotal);
evm_finalize(evmContext, true, blockConnecting.nBits, beneficiary, blockConnecting.GetBlockTime());
bool flushed = view.Flush() && mnview.Flush();
assert(flushed);
mnview.GetHistoryWriters().FlushDB();
Expand Down Expand Up @@ -4809,6 +4809,7 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams,
assert(pindexPrev && pindexPrev == ::ChainActive().Tip());
CCoinsViewCache viewNew(&::ChainstateActive().CoinsTip());
bool dummyRewardedAnchors{};
std::array<uint8_t, 20> dummyBeneficiary{};
CCustomCSView mnview(*pcustomcsview);
uint256 block_hash(block.GetHash());
CBlockIndex indexDummy(block);
Expand All @@ -4824,7 +4825,7 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams,
return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state));
if (!ContextualCheckBlock(block, state, chainparams.GetConsensus(), pindexPrev))
return error("%s: Consensus::ContextualCheckBlock: %s", __func__, FormatStateMessage(state));
if (!::ChainstateActive().ConnectBlock(block, state, &indexDummy, viewNew, mnview, chainparams, dummyRewardedAnchors, true))
if (!::ChainstateActive().ConnectBlock(block, state, &indexDummy, viewNew, mnview, chainparams, dummyRewardedAnchors, dummyBeneficiary, true))
return false;
assert(state.IsValid());

Expand Down Expand Up @@ -5287,7 +5288,8 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview,
if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus()))
return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
bool dummyRewardedAnchors{};
if (!::ChainstateActive().ConnectBlock(block, state, pindex, coins, mnview, chainparams, dummyRewardedAnchors))
std::array<uint8_t, 20> dummyBeneficiary{};
if (!::ChainstateActive().ConnectBlock(block, state, pindex, coins, mnview, chainparams, dummyRewardedAnchors, dummyBeneficiary))
return error("VerifyDB(): *** found unconnectable block at %d, hash=%s (%s)", pindex->nHeight, pindex->GetBlockHash().ToString(), FormatStateMessage(state));
if (ShutdownRequested()) return true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,7 @@ class CChainState {
// Block (dis)connection on a given view:
DisconnectResult DisconnectBlock(const CBlock& block, const CBlockIndex* pindex, CCoinsViewCache& view, CCustomCSView& cache, std::vector<CAnchorConfirmMessage> & disconnectedAnchorConfirms);
bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex,
CCoinsViewCache& view, CCustomCSView& cache, const CChainParams& chainparams, bool & rewardedAnchors, bool fJustCheck = false, const int64_t evmContext = 0) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
CCoinsViewCache& view, CCustomCSView& cache, const CChainParams& chainparams, bool & rewardedAnchors, std::array<uint8_t, 20>& beneficiary, bool fJustCheck = false, const int64_t evmContext = 0) EXCLUSIVE_LOCKS_REQUIRED(cs_main);

// Apply the effects of a block disconnection on the UTXO set.
bool DisconnectTip(CValidationState& state, const CChainParams& chainparams, DisconnectedBlockTransactions* disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, ::mempool.cs);
Expand Down
2 changes: 1 addition & 1 deletion test/functional/feature_evm.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def run_test(self):
self.nodes[0].generate(1)
self.sync_blocks()

# Check that EVM balance shows in gettokenabalances
# Check that EVM balance shows in gettokenbalances
assert_equal(self.nodes[0].gettokenbalances({}, False, False, True), ['101.00000000@0'])

newDFIbalance = self.nodes[0].getaccount(address, {}, True)['0']
Expand Down

0 comments on commit 9cc4f21

Please sign in to comment.