Skip to content

Commit

Permalink
Merge pull request #214 from eosnetworkfoundation/elmato/use-base-gas…
Browse files Browse the repository at this point in the history
…-per-fee

Use base_fee_per_gas from when generating EVM blocks
  • Loading branch information
elmato authored Apr 30, 2024
2 parents 97a0dfd + ff602c5 commit 987a473
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 36 deletions.
25 changes: 22 additions & 3 deletions src/block_conversion_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,12 @@ class block_conversion_plugin_impl : std::enable_shared_from_this<block_conversi
} else {
eos_evm_version = eosevm::nonce_to_version(last_evm_block.header.nonce);
}
eosevm::prepare_block_header(new_block.header, bm.value(), evm_contract_name, last_evm_block.header.number+1, eos_evm_version);

std::optional<uint64_t> base_fee_per_gas;
if(last_evm_block.header.base_fee_per_gas.has_value()) {
base_fee_per_gas = static_cast<uint64_t>(last_evm_block.header.base_fee_per_gas.value());
}
eosevm::prepare_block_header(new_block.header, bm.value(), evm_contract_name, last_evm_block.header.number+1, eos_evm_version, base_fee_per_gas);

new_block.header.parent_hash = last_evm_block.header.hash();
new_block.header.transactions_root = silkworm::kEmptyRoot;
Expand Down Expand Up @@ -299,7 +304,7 @@ class block_conversion_plugin_impl : std::enable_shared_from_this<block_conversi

silkworm::ByteView bv = {(const uint8_t*)rlpx_ref.data(), rlpx_ref.size()};
silkworm::Transaction evm_tx;
if (!silkworm::rlp::decode(bv, evm_tx)) {
if (!silkworm::rlp::decode_transaction(bv, evm_tx, silkworm::rlp::Eip2718Wrapping::kBoth, silkworm::rlp::Leftover::kProhibit)) {
SILK_CRIT << "Failed to decode transaction in block: " << curr.header.number;
throw std::runtime_error("Failed to decode transaction");
}
Expand All @@ -318,6 +323,20 @@ class block_conversion_plugin_impl : std::enable_shared_from_this<block_conversi
}
}

if(block_version >= 1) {
auto tx_base_fee = std::visit([](auto&& arg) -> auto { return arg.base_fee_per_gas; }, dtx);
if(!curr.header.base_fee_per_gas.has_value()) {
curr.header.base_fee_per_gas = tx_base_fee;
} else if (curr.header.base_fee_per_gas.value() != tx_base_fee) {
if(curr.transactions.empty()) {
curr.header.base_fee_per_gas = tx_base_fee;
} else {
SILK_CRIT << "curr.base_fee_per_gas != tx_base_fee";
throw std::runtime_error("curr.base_fee_per_gas != tx_base_fee");
}
}
}

curr.transactions.emplace_back(std::move(evm_tx));
});
set_upper_bound(curr, *new_block);
Expand Down Expand Up @@ -358,7 +377,7 @@ class block_conversion_plugin_impl : std::enable_shared_from_this<block_conversi
if( na.name == pushtx_n ) {
pushtx tx;
eosio::convert_from_bin(tx, na.data);
return evmtx_type{evmtx_v0{0, std::move(tx.rlpx)}};
return evmtx_type{evmtx_v0{0, std::move(tx.rlpx), 0}};
}
evmtx_type evmtx;
eosio::convert_from_bin(evmtx, na.data);
Expand Down
3 changes: 2 additions & 1 deletion src/block_conversion_plugin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ EOSIO_REFLECT(pushtx, miner, rlpx)
struct evmtx_v0 {
uint64_t eos_evm_version;
std::vector<uint8_t> rlpx;
uint64_t base_fee_per_gas;
};
using evmtx_type = std::variant<evmtx_v0>;
EOSIO_REFLECT(evmtx_v0, eos_evm_version, rlpx)
EOSIO_REFLECT(evmtx_v0, eos_evm_version, rlpx, base_fee_per_gas)

struct gas_parameter_type {
uint64_t gas_txnewaccount = 0;
Expand Down
49 changes: 27 additions & 22 deletions tests/nodeos_eos_evm_gasparam_fork_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ def makeReservedEvmAddress(account):

specificExtraNodeosArgs[2]="--plugin eosio::test_control_api_plugin"

extraNodeosArgs="--contracts-console"
extraNodeosArgs="--contracts-console --resource-monitor-not-shutdown-on-threshold-exceeded"

Print("Stand up cluster")
if cluster.launch(prodCount=2, pnodes=2, topo="bridge", totalNodes=3, extraNodeosArgs=extraNodeosArgs, totalProducers=3, specificExtraNodeosArgs=specificExtraNodeosArgs,delay=5) is False:
Expand Down Expand Up @@ -711,11 +711,12 @@ def makeReservedEvmAddress(account):
prodNode.waitForTransBlockIfNeeded(trans[1], True)
row4=prodNode.getTableRow(evmAcc.name, evmAcc.name, "account", 4) # 4th balance of this integration test
Utils.Print("\taccount row4: ", row4)

assert(row4["eth_address"] == "9e126c57330fa71556628e0aabd6b6b6783d99fa")
assert(row4["balance"] == "0000000000000000000000000000000000000000000000024c923bc3177b4c00")
# diff = 3,173,650,000,000,000 = 3,173,650 (Gwei) = (100,000 + (183910 + 21000) * 15) (Gwei)
assert(row4["balance"] == "0000000000000000000000000000000000000000000000024c9336a8ead00600")
# diff = 2,897,785,000,000,000 = 2,897,785 (Gwei) = (100,000 + (165519 + 21000) * 15) (Gwei)
# {"ram_price_mb":"5.0000 EOS","gas_price":10000000000}
# {'consensusParameter': AttributeDict({'gasFeeParameters': AttributeDict({'gasCodedeposit': 530, 'gasNewaccount': 183910, 'gasSset': 186280, 'gasTxcreate': 321180, 'gasTxnewaccount': 183910}
# {'consensusParameter': AttributeDict({'gasFeeParameters': AttributeDict({'gasCodedeposit': 477, 'gasNewaccount': 165519, 'gasSset': 167942, 'gasTxcreate': 289062, 'gasTxnewaccount': 165519}

# Launch eos-evm-node
dataDir = Utils.DataDir + "eos_evm"
Expand Down Expand Up @@ -753,11 +754,11 @@ def makeReservedEvmAddress(account):
Utils.Print("before fork, the latest evm block is:" + str(evm_block))
assert(evm_block["nonce"].hex() == "0x0000000000000001")
assert("consensusParameter" in evm_block)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasCodedeposit"] == 530)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasNewaccount"] == 183910)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasSset"] == 186280)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasTxcreate"] == 321180)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasTxnewaccount"] == 183910)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasCodedeposit"] == 477)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasNewaccount"] == 165519)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasSset"] == 167942)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasTxcreate"] == 289062)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasTxnewaccount"] == 165519)

# Validate all balances are the same on both sides
rows=prodNode.getTable(evmAcc.name, evmAcc.name, "account")
Expand Down Expand Up @@ -918,8 +919,9 @@ def makeReservedEvmAddress(account):
prodNode.waitForTransBlockIfNeeded(trans[1], True)
row4=prodNode.getTableRow(evmAcc.name, evmAcc.name, "account", 4)
Utils.Print("\taccount row4 in node0: ", row4)

assert(row4["eth_address"] == "9e126c57330fa71556628e0aabd6b6b6783d99fa")
assert(row4["balance"] == "0000000000000000000000000000000000000000000000024c84ff8c77eda400")
assert(row4["balance"] == "0000000000000000000000000000000000000000000000024c8724aef459cc00")

# push the same transaction to node1's minor fork (prodc)
trans = node1.pushMessage(evmAcc.name, "pushtx", json.dumps(actData), '-p {0}'.format(minerAcc.name), silentErrors=False)
Expand All @@ -928,19 +930,20 @@ def makeReservedEvmAddress(account):
row4_node1=node1.getTableRow(evmAcc.name, evmAcc.name, "account", 4)
Utils.Print("\taccount row4 in node1: ", row4_node1)
assert(row4_node1["eth_address"] == "9e126c57330fa71556628e0aabd6b6b6783d99fa")
assert(row4_node1["balance"] == "0000000000000000000000000000000000000000000000024c86f5581e971800")
assert(row4_node1["balance"] == "0000000000000000000000000000000000000000000000024c88eb23c5408c00")
assert(row4["balance"] != row4_node1["balance"])

# verify eos-evm-node get the new gas parameter from the minor fork
evm_block = w3.eth.get_block('latest')
Utils.Print("in minor fork, the latest evm block is:" + str(evm_block))
assert(evm_block["nonce"].hex() == "0x0000000000000001")
assert("consensusParameter" in evm_block)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasCodedeposit"] == 636)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasNewaccount"] == 220692)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasSset"] == 222956)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasTxcreate"] == 385416)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasTxnewaccount"] == 220692)

assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasCodedeposit"] == 573)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasNewaccount"] == 198831)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasSset"] == 201158)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasTxcreate"] == 347238)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasTxnewaccount"] == 198831)

# Validate all balances are the same between node0(prodNode) and eos-evm-node
Utils.Print("Validate all balances are the same between node0(minor-fork) and eos-evm-node")
Expand Down Expand Up @@ -1030,19 +1033,21 @@ def makeReservedEvmAddress(account):

row4=prodNode.getTableRow(evmAcc.name, evmAcc.name, "account", 4)
Utils.Print("\taccount row4 in node0: ", row4)

assert(row4["eth_address"] == "9e126c57330fa71556628e0aabd6b6b6783d99fa")
assert(row4["balance"] == "0000000000000000000000000000000000000000000000024c86f5581e971800")
assert(row4["balance"] == "0000000000000000000000000000000000000000000000024c88eb23c5408c00")
assert(row4["balance"] == row4_node1["balance"])

evm_block = w3.eth.get_block('latest')
Utils.Print("after fork resolved, the latest evm block is:" + str(evm_block))
assert(evm_block["nonce"].hex() == "0x0000000000000001")
assert("consensusParameter" in evm_block)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasCodedeposit"] == 530)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasNewaccount"] == 183910)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasSset"] == 186280)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasTxcreate"] == 321180)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasTxnewaccount"] == 183910)

assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasCodedeposit"] == 477)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasNewaccount"] == 165519)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasSset"] == 167942)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasTxcreate"] == 289062)
assert(evm_block["consensusParameter"]["gasFeeParameters"]["gasTxnewaccount"] == 165519)

# Validate all balances are the same between node0(prodNode) and eos-evm-node
Utils.Print("Validate all balances are the same between node0 and eos-evm-node after fork resolved")
Expand Down
37 changes: 28 additions & 9 deletions tests/nodeos_eos_evm_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -860,10 +860,13 @@ def get_block(num):
nonProdNode.transferFunds(cluster.eosioAccount, evmAcc, "111.0000 EOS", "0xB106D2C286183FFC3D1F0C4A6f0753bB20B407c2", waitForTransBlock=True)
time.sleep(2)

Utils.Print("Verify evm_version==1")
Utils.Print("Verify evm_version==1 and base_fe_per_gas")
# Verify header.nonce == 1 (evmversion=1)
# Verify header.baseFeePerGas == 10GWei (0x2540be400)
b = get_block("latest")

assert(b["nonce"] == "0x0000000000000001")
assert(b["baseFeePerGas"] == "0x2540be400")

Utils.Print("Transfer funds to trigger evmtx event on contract")
# Transfer funds (now using version=1)
Expand All @@ -883,14 +886,18 @@ def get_block(num):

b = get_block("latest")
Utils.Print("get_block_latest: " + json.dumps(b))
# 'consensusParameter': {'gasFeeParameters': {'gasCodedeposit': 118, 'gasNewaccount': 40946, 'gasSset': 43728, 'gasTxcreate': 71508, 'gasTxnewaccount': 40946}}
# "consensusParameter": {"gasFeeParameters": {"gasCodedeposit": 106, "gasNewaccount": 36782, "gasSset": 39576, "gasTxcreate": 64236, "gasTxnewaccount": 36782}

assert("consensusParameter" in b)
assert(b["consensusParameter"]["gasFeeParameters"]["gasCodedeposit"] == 118)
assert(b["consensusParameter"]["gasFeeParameters"]["gasNewaccount"] == 40946)
assert(b["consensusParameter"]["gasFeeParameters"]["gasSset"] == 43728)
assert(b["consensusParameter"]["gasFeeParameters"]["gasTxcreate"] == 71508)
assert(b["consensusParameter"]["gasFeeParameters"]["gasTxnewaccount"] == 40946)
assert(b["consensusParameter"]["gasFeeParameters"]["gasCodedeposit"] == 106)
assert(b["consensusParameter"]["gasFeeParameters"]["gasNewaccount"] == 36782)
assert(b["consensusParameter"]["gasFeeParameters"]["gasSset"] == 39576)
assert(b["consensusParameter"]["gasFeeParameters"]["gasTxcreate"] == 64236)
assert(b["consensusParameter"]["gasFeeParameters"]["gasTxnewaccount"] == 36782)

# Verify header.baseFeePerGas still 10GWei (0x2540be400) it will change in 3mins
b = get_block("latest")
assert(b["baseFeePerGas"] == "0x2540be400")

# EVM -> EOS
# 0x9E126C57330FA71556628e0aabd6B6B6783d99fA private key: 0xba8c9ff38e4179748925335a9891b969214b37dc3723a1754b8b849d3eea9ac0
Expand All @@ -917,8 +924,20 @@ def get_block(num):
Utils.Print("\taccount row4: ", row4)
bal2 = w3.eth.get_balance(Web3.to_checksum_address("0x9E126C57330FA71556628e0aabd6B6B6783d99fA"))

# balance different = 1.0 EOS (val) + 900(Gwei) (21000(base gas) + 40946 (gas for non-exist account) )
assert(bal1 == bal2 + 1000000000000000000 + 900000000000 * (21000 + 40946))
# balance different = 1.0 EOS (val) + 900(Gwei) (21000(base gas) + 36782 (gas for non-exist account) )
assert(bal1 == bal2 + 1000000000000000000 + 900000000000 * (21000 + 36782))

# Wait 3 mins
Utils.Print("Wait 3 mins")
time.sleep(180)

# Trigger change in base_fee_per_gas
nonProdNode.transferFunds(cluster.eosioAccount, evmAcc, "1.0000 EOS", "0xB106D2C286183FFC3D1F0C4A6f0753bB20B407c2", waitForTransBlock=True)
time.sleep(2)

# Verify header.baseFeePerGas is now 900GWei (0xd18c2e2800)
b = get_block("latest")
assert(b["baseFeePerGas"] == "0xd18c2e2800")

Utils.Print("Validate all balances (check evmtx event processing)")
# Validate all balances (check evmtx event)
Expand Down

0 comments on commit 987a473

Please sign in to comment.