Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: vmmap blocknumber hashlookup #2350

Closed
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions lib/ain-rs-exports/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,27 @@ pub fn evm_try_get_block_number_by_hash(result: &mut ffi::CrossBoundaryResult, h
}
}

pub fn evm_try_get_dvm_block_number_by_number(
result: &mut ffi::CrossBoundaryResult,
number: u64,
) -> u64 {
match SERVICES.evm.storage.get_block_by_number(&U256::from(number)) {
Ok(Some(block)) => {
let extra_data = block.header.extra_data;
let data = String::from_utf8(extra_data.to_vec()).unwrap();
let Some(data) = data.split_whitespace().nth(1) else {
return cross_boundary_error_return(result, format!("Expected `DFI: <n>`, actual: {:?}", data));
canonbrother marked this conversation as resolved.
Show resolved Hide resolved
};
let Ok(dvm_block_number) = data.parse::<u64>() else {
return cross_boundary_error_return(result, "Parse integer error");
};
cross_boundary_success_return(result, dvm_block_number)
}
Ok(None) => cross_boundary_error_return(result, "Invalid block number"),
Err(e) => cross_boundary_error_return(result, e.to_string()),
}
}

pub fn evm_try_get_block_header_by_hash(
result: &mut ffi::CrossBoundaryResult,
hash: &str,
Expand Down
4 changes: 4 additions & 0 deletions lib/ain-rs-exports/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ pub mod ffi {
result: &mut CrossBoundaryResult,
hash: &str,
) -> EVMBlockHeader;
fn evm_try_get_dvm_block_number_by_number(
result: &mut CrossBoundaryResult,
height: u64,
) -> u64;
fn evm_try_get_block_count(result: &mut CrossBoundaryResult) -> u64;
fn evm_try_get_tx_by_hash(
result: &mut CrossBoundaryResult,
Expand Down
8 changes: 8 additions & 0 deletions src/masternodes/errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,14 @@ class DeFiErrors {
static Res InvalidBlockNumberString(const std::string &number) {
return Res::Err("Invalid block number: %s", number);
}

static Res VmmapScriptPubKeyNotFound() {
return Res::Err("ScriptPubKey not found");
}

static Res VmmapScriptPubKeyInvalid() {
return Res::Err("ScriptPubKey is invalid");
}
};

#endif // DEFI_MASTERNODES_ERRORS_H
Expand Down
46 changes: 22 additions & 24 deletions src/masternodes/rpc_evm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <ain_rs_exports.h>
#include <key_io.h>
#include <masternodes/errors.h>
#include <masternodes/mn_checks.h>
#include <rpc/blockchain.h>
#include <util/strencodings.h>

enum class VMDomainRPCMapType {
Expand Down Expand Up @@ -234,13 +236,13 @@ UniValue vmmap(const JSONRPCRequest &request) {

return VMDomainRPCMapType::Unknown;
};
/*

auto crossBoundaryOkOrThrow = [&throwInvalidParam](CrossBoundaryResult &result) {
if (!result.ok) {
throwInvalidParam(result.reason.c_str());
}
};

/*
auto tryResolveBlockNumberType =
[&throwUnsupportedAuto, &crossBoundaryOkOrThrow](const std::string input) {
uint64_t height;
Expand Down Expand Up @@ -296,7 +298,7 @@ UniValue vmmap(const JSONRPCRequest &request) {
return ret;
}
};
/*

auto finalizeBlockNumberResult = [&](uint64_t &number, const VMDomainRPCMapType type, const uint64_t input) {
UniValue ret(UniValue::VOBJ);
ret.pushKV("input", input);
Expand All @@ -314,15 +316,8 @@ UniValue vmmap(const JSONRPCRequest &request) {
throwInvalidParam(DeFiErrors::InvalidBlockNumberString(input).msg.c_str());
}
CrossBoundaryResult result;
auto evmHash = evm_try_get_block_hash_by_number(result, height);
auto evmBlockHash = std::string(evmHash.data(), evmHash.length());
uint64_t blockNumber = evm_try_get_dvm_block_number_by_number(result, height);
crossBoundaryOkOrThrow(result);
ResVal<uint256> dvm_block = pcustomcsview->GetVMDomainBlockEdge(VMDomainEdge::EVMToDVM, evmBlockHash);
if (!dvm_block) {
throwInvalidParam(dvm_block.msg);
}
CBlockIndex *pindex = LookupBlockIndex(*dvm_block.val);
uint64_t blockNumber = pindex->GetBlockHeader().deprecatedHeight;
return finalizeBlockNumberResult(blockNumber, VMDomainRPCMapType::BlockNumberEVMToDVM, height);
};

Expand All @@ -336,17 +331,21 @@ UniValue vmmap(const JSONRPCRequest &request) {
throwInvalidParam(DeFiErrors::InvalidBlockNumberString(input).msg);
}
CBlockIndex *pindex = ::ChainActive()[height];
auto evmBlockHash =
pcustomcsview->GetVMDomainBlockEdge(VMDomainEdge::DVMToEVM, pindex->GetBlockHash().GetHex());
if (!evmBlockHash.val.has_value()) {
throwInvalidParam(evmBlockHash.msg);
const CBlock block = GetBlockChecked(pindex);
CScript scriptPubKey = block.vtx[0]->vout[1].scriptPubKey;
if (scriptPubKey.size() == 0) {
throwInvalidParam(DeFiErrors::VmmapScriptPubKeyNotFound());
}
auto xvm = XVM::TryFrom(scriptPubKey);
if (!xvm) {
throwInvalidParam(DeFiErrors::VmmapScriptPubKeyInvalid());
}
CrossBoundaryResult result;
uint64_t blockNumber = evm_try_get_block_number_by_hash(result, *evmBlockHash.val);
uint64_t blockNumber = evm_try_get_block_number_by_hash(result, xvm->evm.blockHash);
crossBoundaryOkOrThrow(result);
return finalizeBlockNumberResult(blockNumber, VMDomainRPCMapType::BlockNumberDVMToEVM, height);
};
*/

LOCK(cs_main);

if (type == VMDomainRPCMapType::Auto) {
Expand Down Expand Up @@ -374,13 +373,12 @@ UniValue vmmap(const JSONRPCRequest &request) {
res = pcustomcsview->GetVMDomainBlockEdge(VMDomainEdge::EVMToDVM, input);
break;
}
// TODO(canonbrother): disable for release, more investigation needed
// case VMDomainRPCMapType::BlockNumberDVMToEVM: {
// return handleMapBlockNumberDVMToEVMRequest(input);
// }
// case VMDomainRPCMapType::BlockNumberEVMToDVM: {
// return handleMapBlockNumberEVMToDVMRequest(input);
// }
case VMDomainRPCMapType::BlockNumberDVMToEVM: {
return handleMapBlockNumberDVMToEVMRequest(input);
}
case VMDomainRPCMapType::BlockNumberEVMToDVM: {
return handleMapBlockNumberEVMToDVMRequest(input);
}
default: {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Unknown map type");
}
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1024,7 +1024,7 @@ static UniValue getblockheader(const JSONRPCRequest& request)
return blockheaderToJSON(tip, pblockindex);
}

static CBlock GetBlockChecked(const CBlockIndex* pblockindex)
CBlock GetBlockChecked(const CBlockIndex* pblockindex)
{
CBlock block;
if (IsBlockPruned(pblockindex)) {
Expand Down
4 changes: 4 additions & 0 deletions src/rpc/blockchain.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include <stdint.h>
#include <vector>

#include <primitives/block.h>

extern RecursiveMutex cs_main;

class CBlock;
Expand Down Expand Up @@ -50,4 +52,6 @@ UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex
/** Used by getblockstats to get feerates at different percentiles by weight */
void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES], std::vector<std::pair<CAmount, int64_t>>& scores, int64_t total_weight);

CBlock GetBlockChecked(const CBlockIndex* pblockindex);

#endif
Loading