EVM: Support EIP-1559 tx encoding & decoding
Context
Previous MR !9555 (merged)
Support EIP-1559 https://eips.ethereum.org/EIPS/eip-1559
For now it doesn't introduce elastic blocks and fee market but just encodes & decodes transactions of the eip-1550 format.
Manually testing the MR
Launch cluster of 4 tezos nodes with this script:
#!/bin/sh
## The goal of this script is to start a tezos cluster
## The script should be started from this folder
SETTINGS_PATH="/Users/pva701/tezos_evm/src/proto_alpha/parameters/sandbox-parameters.json"
TEZOS_PATH="/Users/pva701/tezos_evm"
# Set the block time to 10s
cat $SETTINGS_PATH | jq '.minimal_block_delay = "10"' > /tmp/test.json
SETTINGS_PATH=/tmp/test.json
function init(){
BOOTSTRAP1_IDENTITY="tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"
BOOTSTRAP1_PUBLIC="edpkuBknW28nW72KG6RoHtYW7p12T6GKc7nAbwYX5m8Wd9sDVC9yav"
BOOTSTRAP1_SECRET="unencrypted:edsk3gUfUPyBSfrS9CCgmCiQsTCHGkviBDusMxDJstFtojtc1zcpsh"
BOOTSTRAP2_IDENTITY="tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN"
BOOTSTRAP2_PUBLIC="edpktzNbDAUjUk697W7gYg2CRuBQjyPxbEg8dLccYYwKSKvkPvjtV9"
BOOTSTRAP2_SECRET="unencrypted:edsk39qAm1fiMjgmPkw1EgQYkMzkJezLNewd7PLNHTkr6w9XA2zdfo"
BOOTSTRAP3_IDENTITY="tz1faswCTDciRzE4oJ9jn2Vm2dvjeyA9fUzU"
BOOTSTRAP3_PUBLIC="edpkuTXkJDGcFd5nh6VvMz8phXxU3Bi7h6hqgywNFi1vZTfQNnS1RV"
BOOTSTRAP3_SECRET="unencrypted:edsk4ArLQgBTLWG5FJmnGnT689VKoqhXwmDPBuGx3z4cvwU9MmrPZZ"
BOOTSTRAP4_IDENTITY="tz1b7tUupMgCNw2cCLpKTkSD1NZzB5TkP2sv"
BOOTSTRAP4_PUBLIC="edpkuFrRoDSEbJYgxRtLx2ps82UdaYc1WwfS9sE11yhauZt5DgCHbU"
BOOTSTRAP4_SECRET="unencrypted:edsk2uqQB9AY4FvioK2YMdfmyMrer5R8mGFyuaLLFfSRo8EoyNdht3"
BOOTSTRAP5_IDENTITY="tz1ddb9NMYHZi5UzPdzTZMYQQZoMub195zgv"
BOOTSTRAP5_PUBLIC="edpkv8EUUH68jmo3f7Um5PezmfGrRF24gnfLpH3sVNwJnV5bVCxL2n"
BOOTSTRAP5_SECRET="unencrypted:edsk4QLrcijEffxV31gGdN2HU7UpyJjA8drFoNcmnB28n89YjPNRFm"
ACTIVATOR_SECRET="unencrypted:edsk31vznjHSSpGExDMHYASz45VZqXN4DPxvsa4hAyY8dHM28cZzp6"
./octez-client -E http://localhost:18731 import secret key bootstrap1 ${BOOTSTRAP1_SECRET} --force
./octez-client -E http://localhost:18731 import secret key bootstrap2 ${BOOTSTRAP2_SECRET} --force
./octez-client -E http://localhost:18731 import secret key bootstrap3 ${BOOTSTRAP3_SECRET} --force
./octez-client -E http://localhost:18731 import secret key bootstrap4 ${BOOTSTRAP4_SECRET} --force
./octez-client -E http://localhost:18731 import secret key bootstrap5 ${BOOTSTRAP5_SECRET} --force
# This key is my key that does everything, everywhere, it's also the:
# ACTIVATOR
./octez-client -E http://localhost:18731 import secret key activator ${ACTIVATOR_SECRET} --force
}
function activate_alpha() {
./octez-client \
-E http://localhost:18731 \
-block genesis \
activate protocol ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK \
with fitness 1 \
and key activator \
and parameters "${SETTINGS_PATH}"
}
# Creates the node folder
rm -rf sandbox
mkdir -p ./sandbox/1
mkdir -p ./sandbox/2
# Start the node 1
DATA_DIR=./sandbox/1 ${TEZOS_PATH}/src/bin_node/octez-sandboxed-node.sh 1 --connections 1 &
# Start the node 2
DATA_DIR=./sandbox/2 ${TEZOS_PATH}/src/bin_node/octez-sandboxed-node.sh 2 &
# Let the nodes start
sleep 3
# Init the client
init
# Let the nodes start
sleep 3;
eval `${TEZOS_PATH}/src/bin_client/octez-init-sandboxed-client.sh 1`
activate_alpha
octez-baker-alpha run with local node ./sandbox/1 --liquidity-baking-toggle-vote pass
Originate EVM rollup and launch rollup node with this script:
#!/bin/sh
set -e
# compile the kernel
make build-kernels || exit 1
# reset the rollup
rm -rf $HOME/evm-rollup
mkdir -p $HOME/evm-rollup
# Copy paste the kernel
cp $HOME/tezos_evm/evm_kernel.wasm $HOME/evm-rollup/
# Wasm strip
wasm-strip $HOME/evm-rollup/evm_kernel.wasm
cp $HOME/tezos_evm/src/kernel_evm/config/dev.yaml $HOME/evm-rollup/evm-local.yaml
# Put it in hex
smart-rollup-installer get-reveal-installer \
--upgrade-to $HOME/evm-rollup/evm_kernel.wasm \
--output $HOME/evm-rollup/kernel.hex \
--preimages-dir $HOME/evm-rollup/wasm_2_0_0 \
--setup-file $HOME/evm-rollup/evm-local.yaml
./octez-client -E http://localhost:18731 \
originate smart rollup "evm-rollup" \
from tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx \
of kind wasm_2_0_0 \
of type unit \
with kernel "file:$HOME/evm-rollup/kernel.hex" \
--burn-cap 999 \
--force
./octez-smart-rollup-node-alpha -E http://localhost:18731 \
run operator \
for "evm-rollup" \
with operators tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx \
--data-dir "$HOME/evm-rollup" \
--log-kernel-debug
Then run EVM rollup:
./octez-evm-proxy-server run with endpoint http://localhost:8932
Run this JS script (by node send_tx.js, web3 is required
// First step: initialize `web3` instance
const { Web3 } = require('web3');
const RPC = "http://127.0.0.1:8545";
const web3 = new Web3(RPC);
// Second step: add an account to wallet
const privateKeyString = '0x9722f6cc9ff938e63f8ccb74c3daa6b45837e5c5e3835ac08c44c50ab5f39dc0';
const account = web3.eth.accounts.wallet.add(privateKeyString);
const my_address = '6ce4d79d4e77402e1ef3417fdda433aa744c6e1c';
// Make sure the account has enough eth on balance to send the transaction
web3.eth.getBalance(my_address)
.then(r => console.log("My balance: " + r));
// Third step: sign and send the transaction
// Magic happens behind sendTransaction.
// If a transaction is sent from an account that exists in a wallet, it will be automatically signed.
const to_address = 'b53dc01974176e5dff2298c5a94343c2585e3c54';
web3.eth.getBalance(to_address)
.then(r => console.log("Their balance: " + r));
const main = async () => {
try {
console.log("Sending a legacy tx");
const legacy_receipt = await web3.eth.sendTransaction({
from: "0x" + my_address,
to: "0x" + to_address,
value: 1000000000,
gas: 300000,
nonce: 0,
data: "",
});
console.log("Legacy tx has been successfully sent");
console.log(legacy_receipt);
console.log("Sending a EIP-2930 tx");
const eip2930_receipt = await web3.eth.sendTransaction({
type: '0x01',
customChain: {
networkId: 1337,
chainId: 1337
},
from: "0x" + my_address,
to: "0x" + to_address,
value: 1000000000,
gas: 300000,
nonce: 1,
accessList: [
{
"address": "0x00f5f5f3a25f142fafd0af24a754fafa340f32c7",
"storageKeys": [
"0x0000000000000000000000000000000000000000000000000000000000000000"
]
}
]
});
console.log("EIP-2930 tx has been successfully sent");
console.log(eip2930_receipt);
console.log("Sending a EIP-1559 tx");
const eip1559_receipt = await web3.eth.sendTransaction({
type: '0x02',
customChain: {
networkId: 1337,
chainId: 1337
},
from: "0x" + my_address,
to: "0x" + to_address,
value: 1000000000,
gas: 300000,
nonce: 2,
maxFeePerGas: 21000 * 2 + 200,
maxPriorityFeePerGas: 100,
});
console.log("EIP-1559 tx has been successfully sent");
console.log(eip1559_receipt);
} catch (error) {
// catch transaction error
console.error(error);
}
}
main()
You should get as output:
NOTE: web3.js is running without provider. You need to pass a provider in order to interact with the network!
Sending a legacy tx
My balance: 9999000000000000000000
Their balance: 9999000000000000000000
Legacy tx has been successfully sent
{
transactionHash: '0x884b05362dd8f0a1de29f4e9f79ca1d1e7ef937a8c0d2ad0b0f2b2e5dca45975',
transactionIndex: 0n,
blockHash: '0x0000000000000000000000000000000000000000000000000000000000000004',
blockNumber: 4n,
from: '0x6ce4d79d4e77402e1ef3417fdda433aa744c6e1c',
to: '0xb53dc01974176e5dff2298c5a94343c2585e3c54',
cumulativeGasUsed: 21000n,
effectiveGasPrice: 1n,
gasUsed: 21000n,
logs: [],
logsBloom: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
type: 0n,
status: 1n
}
Sending a EIP-2930 tx
EIP-2930 tx has been successfully sent
{
transactionHash: '0x99e765b020209518880526c9ac9752183f6cd3aec3d169f0459896220926fc93',
transactionIndex: 0n,
blockHash: '0x0000000000000000000000000000000000000000000000000000000000000006',
blockNumber: 6n,
from: '0x6ce4d79d4e77402e1ef3417fdda433aa744c6e1c',
to: '0xb53dc01974176e5dff2298c5a94343c2585e3c54',
cumulativeGasUsed: 21000n,
effectiveGasPrice: 1n,
gasUsed: 21000n,
logs: [],
logsBloom: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
type: 0n,
status: 1n
}
Sending a EIP-1559 tx
EIP-1559 tx has been successfully sent
{
transactionHash: '0x3d7aa57b1b5d800c56c51df13b523d0afa8ba901f7db62fd366af0e0ccd69c66',
transactionIndex: 0n,
blockHash: '0x0000000000000000000000000000000000000000000000000000000000000008',
blockNumber: 8n,
from: '0x6ce4d79d4e77402e1ef3417fdda433aa744c6e1c',
to: '0xb53dc01974176e5dff2298c5a94343c2585e3c54',
cumulativeGasUsed: 21000n,
effectiveGasPrice: 1n,
gasUsed: 21000n,
logs: [],
logsBloom: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
type: 0n,
status: 1n
}
The only issue here is that type of tx is 0 in receipts, because this function https://gitlab.com/tezos/tezos/-/blob/master/src/kernel_evm/kernel/src/block_in_progress.rs?ref_type=heads#L240 doesn't set type to correct one but to legacy. I will address this in a separate issue.
Additionally, you can check that nonce actually has been updated to 3
Should return
"0300000000000000000000000000000000000000000000000000000000000000"
Checklist
-
Document the interface of any function added or modified (see the coding guidelines) -
Document any change to the user interface, including configuration parameters (see node configuration) -
Provide automatic testing (see the testing guide). -
For new features and bug fixes, add an item in the appropriate changelog ( docs/protocols/alpha.rstfor the protocol and the environment,CHANGES.rstat the root of the repository for everything else). -
Select suitable reviewers using the Reviewersfield below. -
Select as Assigneethe next person who should take action on that MR