-
Notifications
You must be signed in to change notification settings - Fork 235
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
Problem: no integration test for EIP-1559 feature #249
Changes from all commits
ba38dd0
f3358ed
6e59feb
592c851
24a3a69
c7f4ba5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
from .utils import ADDRS, KEYS, send_transaction, w3_wait_for_block | ||
|
||
|
||
def adjust_base_fee(parent_fee, gas_limit, gas_used): | ||
"spec: https://eips.ethereum.org/EIPS/eip-1559#specification" | ||
change_denominator = 8 | ||
elasticity_multiplier = 2 | ||
gas_target = gas_limit // elasticity_multiplier | ||
|
||
delta = parent_fee * (gas_target - gas_used) // gas_target // change_denominator | ||
return parent_fee - delta | ||
|
||
|
||
def test_dynamic_fee_tx(cluster): | ||
""" | ||
test basic eip-1559 tx works: | ||
- tx fee calculation is compliant to go-ethereum | ||
- base fee adjustment is compliant to go-ethereum | ||
""" | ||
w3 = cluster.w3 | ||
amount = 10000 | ||
before = w3.eth.get_balance(ADDRS["community"]) | ||
tip_price = 1 | ||
max_price = 1000000000000 + tip_price | ||
tx = { | ||
"to": "0x0000000000000000000000000000000000000000", | ||
"value": amount, | ||
"gas": 21000, | ||
"maxFeePerGas": max_price, | ||
"maxPriorityFeePerGas": tip_price, | ||
} | ||
txreceipt = send_transaction(w3, tx, KEYS["community"]) | ||
assert txreceipt.status == 1 | ||
blk = w3.eth.get_block(txreceipt.blockNumber) | ||
assert txreceipt.effectiveGasPrice == blk.baseFeePerGas + tip_price | ||
|
||
fee_expected = txreceipt.gasUsed * txreceipt.effectiveGasPrice | ||
after = w3.eth.get_balance(ADDRS["community"]) | ||
fee_deducted = before - after - amount | ||
assert fee_deducted == fee_expected | ||
|
||
assert blk.gasUsed == txreceipt.gasUsed # we are the only tx in the block | ||
|
||
# check the next block's base fee is adjusted accordingly | ||
w3_wait_for_block(w3, txreceipt.blockNumber + 1) | ||
next_base_price = w3.eth.get_block(txreceipt.blockNumber + 1).baseFeePerGas | ||
|
||
assert next_base_price == adjust_base_fee( | ||
blk.baseFeePerGas, blk.gasLimit, blk.gasUsed | ||
) | ||
|
||
|
||
def test_base_fee_adjustment(cluster): | ||
""" | ||
verify base fee adjustment of three continuous empty blocks | ||
""" | ||
w3 = cluster.w3 | ||
begin = w3.eth.block_number | ||
w3_wait_for_block(w3, begin + 3) | ||
|
||
blk = w3.eth.get_block(begin) | ||
parent_fee = blk.baseFeePerGas | ||
|
||
for i in range(3): | ||
fee = w3.eth.get_block(begin + 1 + i).baseFeePerGas | ||
assert fee == adjust_base_fee(parent_fee, blk.gasLimit, 0) | ||
parent_fee = fee |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -131,6 +131,30 @@ def wait_for_ipc(path, timeout=40.0): | |
) | ||
|
||
|
||
def w3_wait_for_block(w3, height, timeout=240): | ||
for i in range(timeout * 2): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why multiply with 2? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. because it sleep |
||
try: | ||
current_height = w3.eth.block_number | ||
except AssertionError as e: | ||
print(f"get current block number failed: {e}", file=sys.stderr) | ||
else: | ||
if current_height >= height: | ||
break | ||
print("current block height", current_height) | ||
time.sleep(0.5) | ||
else: | ||
raise TimeoutError(f"wait for block {height} timeout") | ||
|
||
|
||
def w3_wait_for_new_blocks(w3, n): | ||
begin_height = w3.eth.block_number | ||
while True: | ||
time.sleep(0.5) | ||
cur_height = w3.eth.block_number | ||
if cur_height - begin_height >= n: | ||
break | ||
|
||
|
||
def get_ledger(): | ||
return ledger.Ledger() | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,13 @@ in | |
import sources.nixpkgs { | ||
overlays = [ | ||
(_: pkgs: dapptools) # use released version to hit the binary cache | ||
(_: pkgs: { | ||
go-ethereum = pkgs.callPackage ./go-ethereum.nix { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. to replace to a newer version to test eip-1559 logic. |
||
inherit (pkgs.darwin) libobjc; | ||
inherit (pkgs.darwin.apple_sdk.frameworks) IOKit; | ||
buildGoModule = pkgs.buildGo117Module; | ||
}; | ||
}) # update to a version that supports eip-1559 | ||
(_: pkgs: rec { | ||
buildGoApplication = pkgs.callPackage (import (sources.gomod2nix + "/builder")) { | ||
go = pkgs.go_1_17; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
{ lib, stdenv, buildGoModule, fetchFromGitHub, libobjc, IOKit }: | ||
|
||
let | ||
# A list of binaries to put into separate outputs | ||
bins = [ | ||
"geth" | ||
"clef" | ||
]; | ||
|
||
in | ||
buildGoModule rec { | ||
pname = "go-ethereum"; | ||
version = "1.10.15"; | ||
|
||
src = fetchFromGitHub { | ||
owner = "ethereum"; | ||
repo = pname; | ||
rev = "v${version}"; | ||
sha256 = "0f6n9rg42ph47mvykc9f0lf99yzwqy4jm7mlzyks4l6i6fl1g3q1"; | ||
}; | ||
|
||
vendorSha256 = "1s5yfpk2yn7f3zwjl2fdrh6c63ki2b8rlmnlss27yxibsidaj0yd"; | ||
|
||
doCheck = false; | ||
|
||
outputs = [ "out" ] ++ bins; | ||
|
||
# Move binaries to separate outputs and symlink them back to $out | ||
postInstall = lib.concatStringsSep "\n" ( | ||
builtins.map (bin: "mkdir -p \$${bin}/bin && mv $out/bin/${bin} \$${bin}/bin/ && ln -s \$${bin}/bin/${bin} $out/bin/") bins | ||
); | ||
|
||
subPackages = [ | ||
"cmd/abidump" | ||
"cmd/abigen" | ||
"cmd/bootnode" | ||
"cmd/checkpoint-admin" | ||
"cmd/clef" | ||
"cmd/devp2p" | ||
"cmd/ethkey" | ||
"cmd/evm" | ||
"cmd/faucet" | ||
"cmd/geth" | ||
"cmd/p2psim" | ||
"cmd/puppeth" | ||
"cmd/rlpdump" | ||
"cmd/utils" | ||
]; | ||
|
||
# Fix for usb-related segmentation faults on darwin | ||
propagatedBuildInputs = | ||
lib.optionals stdenv.isDarwin [ libobjc IOKit ]; | ||
|
||
meta = with lib; { | ||
homepage = "https://geth.ethereum.org/"; | ||
description = "Official golang implementation of the Ethereum protocol"; | ||
license = with licenses; [ lgpl3Plus gpl3Plus ]; | ||
maintainers = with maintainers; [ adisbladis lionello RaghavSood ]; | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some explanation for parent_fee?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I linked the eip-1559 spec, it's basically the same code as the spec.