Skip to content

Commit

Permalink
Various fixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mixa84 committed Aug 28, 2023
1 parent a33080a commit e18d3de
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 38 deletions.
5 changes: 0 additions & 5 deletions lib/ain-rs-exports/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -722,11 +722,6 @@ pub fn evm_try_get_dst20_total_supply(
},
};

debug!(
"[evm_try_get_dst20_total_supply] State root {:#?}",
state_root
);

match SERVICES.evm.get_dst20_total_supply(token_id, state_root) {
Ok(total_supply) => {
let Ok(total_supply) = u64::try_from(WeiAmount(total_supply).to_satoshi()) else {
Expand Down
4 changes: 4 additions & 0 deletions src/masternodes/errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,10 @@ class DeFiErrors {
return Res::Err("Accounting mistmatch on EVM side for DST20 token #%s: Old: %lld New: %lld Current: %lld", token, oldBalance, newBalance, currentBalance);
}

static Res InvalidEVMAddressBalance() {
return Res::Err("Unable to read EVM address balance");
}

static Res SettingEVMAttributeFailure() {
return Res::Err("Failed to set EVM attribute");
}
Expand Down
90 changes: 59 additions & 31 deletions src/masternodes/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2413,29 +2413,44 @@ CTransferDomainMessage DecodeTransferDomainMessage(const CTransactionRef& tx, co
return CTransferDomainMessage{};
}

CAmount GetEvmDST20TotalSupply(const DCT_ID& id, const std::string &stateRoot = std::string()) {
ResVal<uint64_t> GetEVMBlockCount() {
auto result = XResultValue(evm_try_get_block_count(result));
if (!result) {
return result;
}

return {static_cast<uint64_t>(*result), Res::Ok()};
}

ResVal<CAmount> GetEvmDST20TotalSupply(const DCT_ID& id, const std::string &stateRoot = std::string()) {
auto result = XResultValue(evm_try_get_dst20_total_supply(result, id.v, stateRoot));
if (result)
if (auto balance = *result)
return static_cast<CAmount>(balance);
if (!result) {
return result;
}

return -1;
return {static_cast<CAmount>(*result), Res::Ok()};
}

CAmount GetEvmDFIBalance(const CScript& address, const std::string &stateRoot = std::string()) {
ResVal<CAmount> GetEvmDFIBalance(const CScript& address, const std::string &stateRoot = std::string()) {
CTxDestination dest;
if (ExtractDestination(address, dest) && dest.index() == WitV16KeyEthHashType) {
const auto keyID = std::get<WitnessV16EthHash>(dest);
auto result = XResultValue(stateRoot.empty() ? evm_try_get_balance(result, keyID.ToHexString()) : evm_try_get_balance_at_state_root(result, keyID.ToHexString(), stateRoot));
if (result)
if (auto balance = *result)
return static_cast<CAmount>(balance);
if (!result) {
return result;
}

return {static_cast<CAmount>(*result), Res::Ok()};
}

return -1;
return DeFiErrors::InvalidEVMAddressBalance();
}

void ProcessAccountingStateBeforeBlock(const CBlock &block, const CBlockIndex* pindex, CCustomCSView &mnview, const CChainParams& chainparams, CEVMInitialState& evmInitialState) {
Res ProcessAccountingStateBeforeBlock(const CBlock &block, const CBlockIndex* pindex, CCustomCSView &mnview, const CChainParams& chainparams, CEVMInitialState& evmInitialState) {
auto evmBlockCount = GetEVMBlockCount();
if (!evmBlockCount || !*evmBlockCount)
return Res::Ok();

std::map<CScript, CStatsTokenBalances> &evmBalances = evmInitialState.evmBalances;
CStatsTokenBalances& dst20EvmTotalSupply = evmInitialState.dst20EvmTotalSupply;

Expand All @@ -2444,33 +2459,40 @@ void ProcessAccountingStateBeforeBlock(const CBlock &block, const CBlockIndex* p
auto txMessage = DecodeTransferDomainMessage(tx, pindex, chainparams);
for (auto const &[src, dst]: txMessage.transfers){
if (src.amount.nTokenId == DCT_ID{0}) {
std::vector<std::tuple<const uint8_t, VMDomain, const CScript&, const CTokenAmount&, bool>> balanceList{
{ src.domain, VMDomain::EVM, src.address, src.amount, evmBalances.find(src.address) == evmBalances.end() },
{ dst.domain, VMDomain::EVM, dst.address, src.amount, evmBalances.find(dst.address) == evmBalances.end() },
};
for (auto [domain, domainTarget, address, amount, condition]: balanceList) {
if (domain == static_cast<uint8_t>(domainTarget) && condition) {
if (amount.nTokenId == DCT_ID{0}) {
auto balance = GetEvmDFIBalance(address);
if (balance > -1) evmBalances[address].Add({amount.nTokenId, balance});
}
}
auto condition = evmBalances.find(src.address) == evmBalances.end();
if ((src.domain == static_cast<uint8_t>(VMDomain::EVM) || dst.domain == static_cast<uint8_t>(VMDomain::EVM)) && condition) {
auto address = src.domain == static_cast<uint8_t>(VMDomain::EVM) ? src.address : dst.address;
auto balance = GetEvmDFIBalance(address);
if (!balance)
return balance;

evmBalances[address].Add({DCT_ID{0}, *balance});
}
}
}
}

auto res = Res::Ok();
// Storing inital EVM DST20 total supply
mnview.ForEachToken([&](DCT_ID const& id, CTokenImplementation token) {
auto supply = GetEvmDST20TotalSupply(id);
if (supply != -1)
dst20EvmTotalSupply.Add({id, supply});
if (!supply) {
res = supply;
return false;
}
dst20EvmTotalSupply.Add({id, *supply});

return true;
});

return res;
}

static Res ProcessAccountingConsensusChecks(const CBlock &block, const CBlockIndex* pindex, CCustomCSView& cache, const CChainParams& chainparams, CEVMInitialState& evmInitialState, const CEvmBlockStatsLive& evmStats, const std::string &stateRoot) {
auto evmBlockCount = GetEVMBlockCount();
if (!evmBlockCount || !*evmBlockCount)
return Res::Ok();

auto attributes = cache.GetAttributes();
assert(attributes);

Expand Down Expand Up @@ -2554,22 +2576,28 @@ static Res ProcessAccountingConsensusChecks(const CBlock &block, const CBlockInd
auto oldBalance = (evmInitialState.evmBalances.find(address) != evmInitialState.evmBalances.end()) ? evmInitialState.evmBalances[address] : CStatsTokenBalances{};
auto newBalance = oldBalance;
auto balance = GetEvmDFIBalance(address,stateRoot);
if (!balance)
return balance;

newBalance.AddBalances(delta.balances);
if (balance > -1 && newBalance.balances[DFIToken] != balance)
return DeFiErrors::AccountingMissmatchEVM(ScriptToString(address), oldBalance.balances[DFIToken], newBalance.balances[DFIToken], balance);
if (newBalance.balances[DFIToken] != *balance)
return DeFiErrors::AccountingMissmatchEVM(ScriptToString(address), oldBalance.balances[DFIToken], newBalance.balances[DFIToken], *balance);
}

// DST20 token EVM totaly supply tally
deltaDST20EvmTotalSupply.AddBalances(evmInitialState.dst20EvmTotalSupply.balances);
auto res = Res::Ok();
cache.ForEachToken([&](DCT_ID const& id, CTokenImplementation token) {
auto supply = GetEvmDST20TotalSupply(id, stateRoot);
if (supply != -1)
if (deltaDST20EvmTotalSupply.balances[id] != supply || deltaDST20EvmTotalSupply.balances[id] < 0) {
res = DeFiErrors::AccountingMissmatchEVMDST20(id.ToString(), evmInitialState.dst20EvmTotalSupply.balances[id], deltaDST20EvmTotalSupply.balances[id], supply);
return false;
}
if (!supply) {
res = supply;
return false;
}

if (deltaDST20EvmTotalSupply.balances[id] != *supply || deltaDST20EvmTotalSupply.balances[id] < 0) {
res = DeFiErrors::AccountingMissmatchEVMDST20(id.ToString(), evmInitialState.dst20EvmTotalSupply.balances[id], deltaDST20EvmTotalSupply.balances[id], *supply);
return false;
}

return true;
});
Expand Down
2 changes: 1 addition & 1 deletion src/masternodes/validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ using CreationTxs = std::map<uint32_t, std::pair<uint256, std::vector<std::pair<

void ProcessDeFiEvent(const CBlock &block, const CBlockIndex* pindex, CCustomCSView& mnview, const CCoinsViewCache& view, const CChainParams& chainparams, const CreationTxs &creationTxs, const uint64_t evmQueueId);

void ProcessAccountingStateBeforeBlock(const CBlock &block, const CBlockIndex* pindex, CCustomCSView &mnview, const CChainParams& chainparams, CEVMInitialState& evmInitialState);
Res ProcessAccountingStateBeforeBlock(const CBlock &block, const CBlockIndex* pindex, CCustomCSView &mnview, const CChainParams& chainparams, CEVMInitialState& evmInitialState);

Res ProcessDeFiEventFallible(const CBlock &block, const CBlockIndex *pindex, CCustomCSView &mnview, const CChainParams& chainparams, const uint64_t evmQueueId, const bool isEvmEnabledForBlock, CEVMInitialState& evmInitialState);

Expand Down
4 changes: 3 additions & 1 deletion src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2619,7 +2619,9 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl

if (isEvmEnabledForBlock) {
evmInitialState.transferDomainState = attributes->GetValue(CTransferDomainStatsLive::Key, CTransferDomainStatsLive{});
ProcessAccountingStateBeforeBlock(block, pindex, mnview, chainparams, evmInitialState);
auto res = ProcessAccountingStateBeforeBlock(block, pindex, mnview, chainparams, evmInitialState);
if (!res.ok)
return state.Invalid(ValidationInvalidReason::CONSENSUS, error("%s: %s", __func__, res.msg), REJECT_INVALID, res.dbgMsg);
}

// Execute TXs
Expand Down

0 comments on commit e18d3de

Please sign in to comment.