Skip to content

Commit

Permalink
estimateGas and gasPrice RPC implementations (#1940)
Browse files Browse the repository at this point in the history
* estimateGas and gasPrice rpc and ffi

* Remove protoc lib includes

* Resolve depends build issues

* Consolidate persistent state to BlockchainDataHandler struct (#1944)

* Consolidate persistent state to BlockchainDataHandler struct

* Update cache after cache miss

* Get receipts root before creating block

* Update deps, add protobuf-src into runtime deps

* Fix protobuf-src compilation

* Use self contained rust toolchain

* CI workflow for EVM RPC testing (#1821)

* Add workflow for testing evm rpc

* Add test workflow for EVM RPCs

* Rename EVM RPC Test

* Rename tests

* Rename workflow job

* Fix typo on environment var on CI

* Rename tag 'test/rpc_evm' to 'evm'

* Set NODE_URL to point devnet

---------

Co-authored-by: Prasanna Loganathar <[email protected]>
Co-authored-by: Jouzo <[email protected]>
Co-authored-by: dCorral <[email protected]>
Co-authored-by: canonbrother <[email protected]>
  • Loading branch information
5 people authored May 3, 2023
1 parent 069442c commit 8222cc2
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 9 deletions.
2 changes: 2 additions & 0 deletions lib/ain-cpp-imports/src/bridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,7 @@ pub mod ffi {
fn getDifficulty(_block_hash: [u8; 32]) -> u32;
fn getChainWork(_block_hash: [u8; 32]) -> [u8; 32];
fn getPoolTransactions() -> Vec<String>;
fn getNativeTxSize(data: Vec<u8>) -> u64;
fn getMinRelayTxFee() -> u64;
}
}
16 changes: 16 additions & 0 deletions lib/ain-cpp-imports/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ mod ffi {
pub fn getPoolTransactions() -> Vec<String> {
unimplemented!("{}", UNIMPL_MSG)
}
pub fn getNativeTxSize(_data: Vec<u8>) -> u64 {
unimplemented!("{}", UNIMPL_MSG)
}
pub fn getMinRelayTxFee() -> u64 {
unimplemented!("{}", UNIMPL_MSG)
}
}

pub fn get_chain_id() -> Result<u64, Box<dyn Error>> {
Expand Down Expand Up @@ -76,5 +82,15 @@ pub fn get_pool_transactions() -> Result<Vec<String>, Box<dyn Error>> {
Ok(transactions)
}

pub fn get_native_tx_size(data: Vec<u8>) -> Result<u64, Box<dyn Error>> {
let tx_size = ffi::getNativeTxSize(data);
Ok(tx_size)
}

pub fn get_min_relay_tx_fee() -> Result<u64, Box<dyn Error>> {
let tx_fee = ffi::getMinRelayTxFee();
Ok(tx_fee)
}

#[cfg(test)]
mod tests {}
12 changes: 8 additions & 4 deletions lib/ain-evm/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ impl EVMHandler {
data: &[u8],
gas_limit: u64,
access_list: AccessList,
) -> (ExitReason, Vec<u8>) {
) -> (ExitReason, Vec<u8>, u64) {
// TODO Add actual gas, chain_id, block_number from header
let vicinity = get_vicinity(caller, None);

Expand All @@ -76,7 +76,11 @@ impl EVMHandler {
},
false,
);
(tx_response.exit_reason, tx_response.data)
(
tx_response.exit_reason,
tx_response.data,
tx_response.used_gas,
)
}

// TODO wrap in EVM transaction and dryrun with evm_call
Expand Down Expand Up @@ -120,8 +124,8 @@ impl EVMHandler {
signed_tx.gas_limit().as_u64(),
signed_tx.access_list(),
) {
(exit_reason, _) if exit_reason.is_succeed() => Ok(signed_tx),
(exit_reason, _) => Err(anyhow!("Error calling EVM {:?}", exit_reason).into()),
(exit_reason, _, _) if exit_reason.is_succeed() => Ok(signed_tx),
(exit_reason, _, _) => Err(anyhow!("Error calling EVM {:?}", exit_reason).into()),
}
}

Expand Down
34 changes: 29 additions & 5 deletions lib/ain-grpc/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ pub trait MetachainRPC {
fn get_transaction_count(&self, address: H160) -> RpcResult<String>;

#[method(name = "eth_estimateGas")]
fn estimate_gas(&self) -> RpcResult<String>;
fn estimate_gas(&self, input: CallRequest) -> RpcResult<String>;

#[method(name = "mc_getState")]
fn get_state(&self) -> RpcResult<EVMState>;
Expand Down Expand Up @@ -131,7 +131,7 @@ impl MetachainRPCServer for MetachainRPCModule {
data,
..
} = input;
let (_, data) = self.handler.evm.call(
let (_, data, ..) = self.handler.evm.call(
from,
to,
value.unwrap_or_default(),
Expand Down Expand Up @@ -357,16 +357,40 @@ impl MetachainRPCServer for MetachainRPCModule {
Ok(format!("{:#x}", nonce))
}

fn estimate_gas(&self) -> RpcResult<String> {
Ok(format!("{:#x}", 21000))
fn estimate_gas(&self, input: CallRequest) -> RpcResult<String> {
let CallRequest {
from,
to,
gas,
value,
data,
..
} = input;

let (_, data, used_gas) = self.handler.evm.call(
from,
to,
value.unwrap_or_default(),
&data.unwrap_or_default(),
gas.unwrap_or_default().as_u64(),
vec![],
);
let native_size = ain_cpp_imports::get_native_tx_size(data).unwrap_or(0);
debug!("estimateGas: {:#?} + {:#?}", native_size, used_gas);
Ok(format!(
"{:#x}",
native_size + std::cmp::max(21000, used_gas)
))
}

fn get_state(&self) -> RpcResult<EVMState> {
Ok(self.handler.evm.state.read().unwrap().clone())
}

fn gas_price(&self) -> RpcResult<String> {
Ok(format!("{:#x}", 0))
let gas_price = ain_cpp_imports::get_min_relay_tx_fee().unwrap_or(10);
debug!("gasPrice: {:#?}", gas_price);
Ok(format!("{:#x}", gas_price))
}

fn get_receipt(&self, hash: H256) -> RpcResult<Option<ReceiptResult>> {
Expand Down
34 changes: 34 additions & 0 deletions src/ffi/ffiexports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,37 @@ rust::vec<rust::string> getPoolTransactions() {

return poolTransactions;
}

uint64_t getNativeTxSize(rust::Vec<uint8_t> rawTransaction) {
std::vector<uint8_t> evmTx(rawTransaction.size());
std::copy(rawTransaction.begin(), rawTransaction.end(), evmTx.begin());
CDataStream metadata(DfTxMarker, SER_NETWORK, PROTOCOL_VERSION);
metadata << static_cast<unsigned char>(CustomTxType::EvmTx)
<< CEvmTxMessage{evmTx};

CScript scriptMeta;
scriptMeta << OP_RETURN << ToByteVector(metadata);

int targetHeight;
{
LOCK(cs_main);
targetHeight = ::ChainActive().Height() + 1;
}

const auto txVersion = GetTransactionVersion(targetHeight);
CMutableTransaction rawTx(txVersion);

rawTx.vin.resize(2);
rawTx.vin[0].scriptSig = CScript() << OP_0;
rawTx.vin[1].scriptSig = CScript() << OP_0;

rawTx.vout.emplace_back(0, scriptMeta);

CTransaction tx(rawTx);

return tx.GetTotalSize();
}

uint64_t getMinRelayTxFee() {
return ::minRelayTxFee.GetFeePerK() * 10000000;
}
2 changes: 2 additions & 0 deletions src/ffi/ffiexports.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,7 @@ rust::string getDatadir();
uint32_t getDifficulty(std::array<uint8_t, 32> blockHash);
std::array<uint8_t, 32> getChainWork(std::array<uint8_t, 32> blockHash);
rust::vec<rust::string> getPoolTransactions();
uint64_t getNativeTxSize(rust::Vec<uint8_t> rawTransaction);
uint64_t getMinRelayTxFee();

#endif // DEFI_EVM_FFI_H

0 comments on commit 8222cc2

Please sign in to comment.