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(E2E): Enable e2e tests to run in different networks based on chain spec #2403

Open
wants to merge 58 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
3808991
configure the chain spec and chain ID in e2e
nidhi-singh02 Jan 6, 2025
15bfac1
linter
nidhi-singh02 Jan 6, 2025
643ffae
readme updated
nidhi-singh02 Jan 6, 2025
4ba3644
using variables
nidhi-singh02 Jan 6, 2025
d2def49
lint fix
nidhi-singh02 Jan 6, 2025
8bfed47
trying to prep skeleton
nidhi-singh02 Jan 7, 2025
254d89d
network not coming up
nidhi-singh02 Jan 7, 2025
677b51f
why direct destroy
nidhi-singh02 Jan 7, 2025
1f9adde
reverting all change in test
nidhi-singh02 Jan 7, 2025
9feafa5
proposed structure of testing/e2e
calbera Jan 7, 2025
2b6134e
network is spinning, test not running
nidhi-singh02 Jan 8, 2025
d005c9b
rpc node is not ready
nidhi-singh02 Jan 8, 2025
eb07614
json rpc working - required geth node
nidhi-singh02 Jan 8, 2025
4a4a418
two tests runs on devnet directly
nidhi-singh02 Jan 8, 2025
1ffbefb
as test runs by default, change name convention
nidhi-singh02 Jan 8, 2025
1476986
now atleast basic and inflation test run
nidhi-singh02 Jan 9, 2025
d1a874b
beaconAPI test works
nidhi-singh02 Jan 9, 2025
b73614d
blob test working
nidhi-singh02 Jan 9, 2025
707e861
deposit not working with 500, why?
nidhi-singh02 Jan 9, 2025
f0f9fdc
use chainID in fundAccount so other network acc gets funded
nidhi-singh02 Jan 9, 2025
a5a0c1d
removed test chain which was unused
nidhi-singh02 Jan 9, 2025
b5dea33
removal of duplicate cleanup
nidhi-singh02 Jan 9, 2025
a25bf87
Merge branch 'main' into e2e-configure
nidhi-singh02 Jan 23, 2025
d101890
nilaway fix
nidhi-singh02 Jan 23, 2025
4d87fe3
Merge branch 'main' into e2e-configure
nidhi-singh02 Jan 24, 2025
08c0477
remove teardown from startup
nidhi-singh02 Jan 24, 2025
77c28f6
Merge branch 'main' into e2e-configure
nidhi-singh02 Jan 27, 2025
cf72d88
teardownsuite has to be there else failure
nidhi-singh02 Jan 27, 2025
a555d92
cleanup
nidhi-singh02 Jan 27, 2025
d565753
nits - comments
nidhi-singh02 Jan 27, 2025
6cb00a4
increase amount for test accounts for deposit
nidhi-singh02 Jan 27, 2025
66efca7
linting fixing
nidhi-singh02 Jan 27, 2025
eeb6568
more linter
nidhi-singh02 Jan 27, 2025
1449a87
initializeNetwork complexity removed - refactor
nidhi-singh02 Jan 27, 2025
c3090f5
made CleanupNetwork more modular to remove gocognit
nidhi-singh02 Jan 27, 2025
e3f44dc
moved functions to setup and removed redundant func
nidhi-singh02 Jan 27, 2025
24f4e76
remove changes from account and lint
nidhi-singh02 Jan 27, 2025
2a864a4
is lb nil check really needed?
nidhi-singh02 Jan 27, 2025
4cb5fa5
changed default to dev and readme
nidhi-singh02 Jan 27, 2025
e494d75
Merge branch 'main' into e2e-configure
nidhi-singh02 Jan 28, 2025
3237b69
increased gas for deposists and running everything on devnet
nidhi-singh02 Jan 28, 2025
98a95e4
better structure and remove unecessary code
nidhi-singh02 Jan 28, 2025
750123f
Merge branch 'main' into e2e-configure
nidhi-singh02 Jan 29, 2025
b7f3471
linter fix
nidhi-singh02 Jan 29, 2025
4c32ee5
nilawayyyy
nidhi-singh02 Jan 29, 2025
5440398
teardownsuite not needed as cleanup happening already
nidhi-singh02 Jan 29, 2025
cf12e3d
remove consensusClient redundancy
nidhi-singh02 Jan 29, 2025
c505cbf
genesis account in suite
nidhi-singh02 Jan 29, 2025
2de566c
have genesis and test accounts in network instance only
nidhi-singh02 Jan 29, 2025
a6c36a2
load balancer in network instance
nidhi-singh02 Jan 29, 2025
8c68d2a
nilawayyy
nidhi-singh02 Jan 29, 2025
9c610cb
linting are you happy
nidhi-singh02 Jan 29, 2025
07cff99
readme enhanced for adding tests
nidhi-singh02 Jan 29, 2025
4c0dbf6
Merge branch 'main' into e2e-configure
nidhi-singh02 Jan 30, 2025
c6d8cd2
Merge branch 'main' into e2e-configure
nidhi-singh02 Jan 31, 2025
147785d
Merge branch 'main' into e2e-configure
rezbera Feb 1, 2025
560e1c5
Merge branch 'main' into e2e-configure
nidhi-singh02 Feb 3, 2025
aa5514f
Merge branch 'main' into e2e-configure
nidhi-singh02 Feb 4, 2025
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
20 changes: 18 additions & 2 deletions testing/e2e/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,31 @@ This will automatically build your beacond docker image from the local source
code, and spin up a Kurtosis network based on the config file in
`testing/e2e/config/defaults.go`.

Currently, the e2e tests runs in different kurtosis enclaves. Check the default configuration in `TestBeaconKitE2ESuite()`.
Play around with the configuration to see how it works. You need to pass the chain ID and chain spec name to the `suite.WithChain()` function. Ensure that the chain ID and chain spec name are valid.


## Configuration
In case you want to configure(change) the validator set, consider doing changes in `defaultValidators`.
The user can specify the number of replicas they want per type.

All the default configuration are listed in `testing/e2e/config/defaults.go`

Note: Currently the chainID for this local network is 80087, which is our dev network configuration (this is fixed in the kurtosis env setup and will be made configurable in a future version). To make changes to the 80087 chain spec used, modify parameters [here](https://github.com/berachain/beacon-kit/blob/main/config/spec/devnet.go#L40).
Note: The default chainID for this local network is 80087, which is our dev network configuration. To make changes to the 80087 chain spec used, modify parameters [here](https://github.com/berachain/beacon-kit/blob/main/config/spec/devnet.go#L40).

## Configure the default network configuration
To change the chainID, modify the `ChainID` field in the `NetworkConfiguration` struct in `defaultNetworkConfiguration`
function in `testing/e2e/config/defaults.go`.

To change the chainSpec, modify the `ChainSpec` field in the `NetworkConfiguration` struct in `defaultNetworkConfiguration`
function in `testing/e2e/config/defaults.go`.

## Add your tests
Add your tests in here like how it is done in `TestBasicStartup()`
To add your tests, you need to do the following:
1. Create a new file in the `testing/e2e/` directory.
2. Add your tests in here like how it is done in `runBasicStartup()`
3. Register your tests in `TestRunE2E()`.
4. Then specify the chainID and chainSpec in `SetupSuiteWithOptions()` in `e2e_test.go`.



4 changes: 4 additions & 0 deletions testing/e2e/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ type E2ETestConfig struct {
}

type NetworkConfiguration struct {
// ChainID specifies the chain ID for the network.
ChainID int `json:"chain_id"`
// ChainSpec specifies the chain spec for the network.
ChainSpec string `json:"chain_spec"`
// Validators lists the configurations for each validator in the test.
Validators NodeSet `json:"validators"`
// FullNodes specifies the number of full nodes to include in the test.
Expand Down
12 changes: 12 additions & 0 deletions testing/e2e/config/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ const (
ClientValidator4 = "cl-validator-beaconkit-4"
)

// default network configuration.
//
//nolint:gochecknoglobals // it's a default value
var (
// defaultChainID is the default chain ID for the network.
defaultChainID = 80087
// defaultChainSpec is the default chain spec for the network.
defaultChainSpec = "devnet"
)

// DefaultE2ETestConfig provides a default configuration for end-to-end tests,
// pre-populating with a standard set of validators and no additional
// services.
Expand All @@ -50,6 +60,8 @@ func DefaultE2ETestConfig() *E2ETestConfig {

func defaultNetworkConfiguration() NetworkConfiguration {
return NetworkConfiguration{
ChainID: defaultChainID,
ChainSpec: defaultChainSpec,
Validators: defaultValidators(),
FullNodes: defaultFullNodes(),
SeedNodes: defaultSeedNodes(),
Expand Down
11 changes: 8 additions & 3 deletions testing/e2e/e2e_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,18 @@ import (

// TestBeaconAPISuite tests that the api test suite is setup correctly with a
// working beacon node-api client.
func (s *BeaconKitE2ESuite) TestBeaconAPIStartup() {
func (s *BeaconKitE2ESuite) runBeaconAPIStartup() {
s.Logger().Info("Running BeaconAPIStartup")
// Get the current network instance
network := s.GetCurrentNetwork()
s.Require().NotNil(network, "Network instance is nil")

// Wait for execution block 5.
err := s.WaitForFinalizedBlockNumber(5)
err := s.WaitForFinalizedBlockNumber(network, 5)
s.Require().NoError(err)

// Get the consensus client.
client := s.ConsensusClients()[config.ClientValidator0]
client := network.ConsensusClients()[config.ClientValidator0]
s.Require().NotNil(client)

// Ensure the state root is not nil.
Expand Down
33 changes: 21 additions & 12 deletions testing/e2e/e2e_blob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,26 +48,35 @@ const (

// Test4844Live tests sending a large number of blob carrying txs over the
// network.
func (s *BeaconKitE2ESuite) Test4844Live() {
func (s *BeaconKitE2ESuite) run4844Live() {
s.Logger().Info("Running 4844 Live")
ctx, cancel := context.WithTimeout(s.Ctx(), suite.DefaultE2ETestTimeout)
defer cancel()

// Get the current network
network := s.GetCurrentNetwork()
s.Require().NotNil(network, "Network instance is nil")

// Connect the consensus client node-api
client0 := s.ConsensusClients()[config.ClientValidator0]
client0 := network.ConsensusClients()[config.ClientValidator0]
s.Require().NotNil(client0)
s.Require().NoError(client0.Connect(ctx))

// Grab values to plug into txs
sender := s.TestAccounts()[0]
chainID, err := s.JSONRPCBalancer().ChainID(ctx)
accounts := s.GetAccounts()
s.Require().NotNil(accounts, "Test accounts are nil")
s.Require().NotEmpty(accounts, "No test accounts available")

sender := accounts[0]
chainID, err := network.JSONRPCBalancer().ChainID(ctx)
s.Require().NoError(err)
tip, err := s.JSONRPCBalancer().SuggestGasTipCap(ctx)
tip, err := network.JSONRPCBalancer().SuggestGasTipCap(ctx)
s.Require().NoError(err)
gasFee, err := s.JSONRPCBalancer().SuggestGasPrice(ctx)
gasFee, err := network.JSONRPCBalancer().SuggestGasPrice(ctx)
s.Require().NoError(err)
blkNum, err := s.JSONRPCBalancer().BlockNumber(s.Ctx())
blkNum, err := network.JSONRPCBalancer().BlockNumber(s.Ctx())
s.Require().NoError(err)
nonce, err := s.JSONRPCBalancer().NonceAt(
nonce, err := network.JSONRPCBalancer().NonceAt(
s.Ctx(), sender.Address(), new(big.Int).SetUint64(blkNum),
)
s.Require().NoError(err)
Expand Down Expand Up @@ -99,7 +108,7 @@ func (s *BeaconKitE2ESuite) Test4844Live() {
s.Logger().Info("submitting blob transaction", "blobTx", blobTx.Hash().Hex())
blobTxs = append(blobTxs, blobTx)

err = s.JSONRPCBalancer().SendTransaction(ctx, blobTx)
err = network.JSONRPCBalancer().SendTransaction(ctx, blobTx)
// TODO: Figure out what is causing this to happen.
// Also, `errors.Is(err, txpool.ErrAlreadyKnown)` doesn't catch it.
if err != nil && err.Error() == txpool.ErrAlreadyKnown.Error() {
Expand All @@ -119,7 +128,7 @@ func (s *BeaconKitE2ESuite) Test4844Live() {
// Wait for the blob transaction to be mined before making request.
s.Logger().
Info("waiting for blob transaction to be mined", "blobTx", blobTx.Hash().Hex())
receipt, errWait := bind.WaitMined(ctx, s.JSONRPCBalancer(), blobTx)
receipt, errWait := bind.WaitMined(ctx, network.JSONRPCBalancer(), blobTx)
s.Require().NoError(errWait)
s.Require().Equal(coretypes.ReceiptStatusSuccessful, receipt.Status)

Expand All @@ -130,7 +139,7 @@ func (s *BeaconKitE2ESuite) Test4844Live() {
// just wait 1 block.
//
//nolint:contextcheck // uses the service context.
s.Require().NoError(s.WaitForNBlockNumbers(1))
s.Require().NoError(s.WaitForNBlockNumbers(network, 1))

// Fetch blobs from node-api.
response, errAPI := client0.BlobSidecars(ctx, &api.BlobSidecarsOpts{Block: receipt.BlockNumber.String()})
Expand All @@ -156,6 +165,6 @@ func (s *BeaconKitE2ESuite) Test4844Live() {
wg.Wait()

// Ensure Blob Tx doesn't cause liveliness issues.
err = s.WaitForNBlockNumbers(BlocksToWait4844)
err = s.WaitForNBlockNumbers(network, BlocksToWait4844)
s.Require().NoError(err)
}
21 changes: 13 additions & 8 deletions testing/e2e/e2e_inflation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,14 @@ import (
"github.com/ethereum/go-ethereum/params"
)

// TestEVMInflation checks that the EVM inflation address receives the correct
// runEVMInflation checks that the EVM inflation address receives the correct
// amount of EVM inflation per block.
func (s *BeaconKitE2ESuite) TestEVMInflation() {
func (s *BeaconKitE2ESuite) runEVMInflation() {
s.Logger().Info("Running TestEVMInflation")

// Get the current network
network := s.GetCurrentNetwork()
s.Require().NotNil(network, "Network instance is nil")
// TODO: make test use configurable chain spec.
chainspec, err := spec.DevnetChainSpec()
s.Require().NoError(err)
Expand All @@ -43,7 +48,7 @@ func (s *BeaconKitE2ESuite) TestEVMInflation() {
preForkInflation := chainspec.EVMInflationPerBlock(math.Slot(0))
preForkAddress := chainspec.EVMInflationAddress(math.Slot(0))
for blkNum := range int64(deneb1ForkSlot) {
err = s.WaitForFinalizedBlockNumber(uint64(blkNum))
err = s.WaitForFinalizedBlockNumber(network, uint64(blkNum))
s.Require().NoError(err)

expectedBalance := new(big.Int).Mul(
Expand All @@ -52,7 +57,7 @@ func (s *BeaconKitE2ESuite) TestEVMInflation() {
)

var balance *big.Int
balance, err = s.JSONRPCBalancer().BalanceAt(
balance, err = network.JSONRPCBalancer().BalanceAt(
s.Ctx(),
gethcommon.Address(preForkAddress),
big.NewInt(blkNum),
Expand All @@ -75,13 +80,13 @@ func (s *BeaconKitE2ESuite) TestEVMInflation() {

// take the snapshot of balance right before the fork and check it won't change anymore
var preForkAddressFinalBalance *big.Int
preForkAddressFinalBalance, err = s.JSONRPCBalancer().BalanceAt(
preForkAddressFinalBalance, err = network.JSONRPCBalancer().BalanceAt(
s.Ctx(), gethcommon.Address(preForkAddress), big.NewInt(int64(deneb1ForkSlot-1)),
)
s.Require().NoError(err)

for blkNum := deneb1ForkSlot; blkNum < deneb1ForkSlot+chainspec.SlotsPerEpoch(); blkNum++ {
err = s.WaitForFinalizedBlockNumber(blkNum)
err = s.WaitForFinalizedBlockNumber(network, blkNum)
s.Require().NoError(err)

expectedBalance := new(big.Int).Mul(
Expand All @@ -90,7 +95,7 @@ func (s *BeaconKitE2ESuite) TestEVMInflation() {
)

var balance *big.Int
balance, err = s.JSONRPCBalancer().BalanceAt(
balance, err = network.JSONRPCBalancer().BalanceAt(
s.Ctx(),
gethcommon.Address(postForkAddress),
big.NewInt(int64(blkNum)),
Expand All @@ -105,7 +110,7 @@ func (s *BeaconKitE2ESuite) TestEVMInflation() {
// Enforce that the balance of the EVM inflation address
// prior to the hardfork is the same as it is now.
var preForkLatestBalance *big.Int
preForkLatestBalance, err = s.JSONRPCBalancer().BalanceAt(
preForkLatestBalance, err = network.JSONRPCBalancer().BalanceAt(
s.Ctx(), gethcommon.Address(preForkAddress), nil, // at the current block
)
s.Require().NoError(err)
Expand Down
37 changes: 22 additions & 15 deletions testing/e2e/e2e_staking_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,11 @@ type ValidatorTestStruct struct {
// TODO:
// 1) Add staking tests for adding a new validator to the network.
// 2) Add staking tests for hitting the validator set cap and eviction.
func (s *BeaconKitE2ESuite) TestDepositRobustness() {
func (s *BeaconKitE2ESuite) runDepositRobustness() {
s.Logger().Info("Running Deposit Robustness")
// Get the current network
network := s.GetCurrentNetwork()
s.Require().NotNil(network, "Network instance is nil")
// TODO: make test use configurable chain spec.
chainspec, err := spec.DevnetChainSpec()
s.Require().NoError(err)
Expand All @@ -80,7 +84,7 @@ func (s *BeaconKitE2ESuite) TestDepositRobustness() {
)

// Get the chain ID.
chainID, err := s.JSONRPCBalancer().ChainID(s.Ctx())
chainID, err := network.JSONRPCBalancer().ChainID(s.Ctx())
s.Require().NoError(err)

// Get the chain spec used by the e2e nodes. TODO: make configurable.
Expand All @@ -90,7 +94,7 @@ func (s *BeaconKitE2ESuite) TestDepositRobustness() {
// Bind the deposit contract.
depositContractAddress := gethcommon.Address(chainSpec.DepositContractAddress())

dc, err := deposit.NewDepositContract(depositContractAddress, s.JSONRPCBalancer())
dc, err := deposit.NewDepositContract(depositContractAddress, network.JSONRPCBalancer())
s.Require().NoError(err)

// Enforce the deposit count at genesis is equal to the number of validators.
Expand Down Expand Up @@ -139,7 +143,7 @@ func (s *BeaconKitE2ESuite) TestDepositRobustness() {
s.Require().NotNil(val.Validator)
creds := [32]byte(val.Validator.WithdrawalCredentials)
withdrawalAddress := gethcommon.Address(creds[12:])
withdrawalBalance, jErr := s.JSONRPCBalancer().BalanceAt(s.Ctx(), withdrawalAddress, nil)
withdrawalBalance, jErr := network.JSONRPCBalancer().BalanceAt(s.Ctx(), withdrawalAddress, nil)
s.Require().NoError(jErr)

// Populate the validators testing struct so we can keep track of the pre-state.
Expand All @@ -155,24 +159,27 @@ func (s *BeaconKitE2ESuite) TestDepositRobustness() {
}

// Sender account
sender := s.TestAccounts()[0]
accounts := s.GetAccounts()
s.Require().NotNil(accounts, "Test accounts are nil")
s.Require().NotEmpty(accounts, "No test accounts available")

sender := accounts[0]

// Get the block num
blkNum, err := s.JSONRPCBalancer().BlockNumber(s.Ctx())
blkNum, err := network.JSONRPCBalancer().BlockNumber(s.Ctx())
s.Require().NoError(err)

// Get original evm balance
balance, err := s.JSONRPCBalancer().BalanceAt(
balance, err := network.JSONRPCBalancer().BalanceAt(
s.Ctx(), sender.Address(), new(big.Int).SetUint64(blkNum),
)
s.Require().NoError(err)

// Get the nonce.
nonce, err := s.JSONRPCBalancer().NonceAt(
nonce, err := network.JSONRPCBalancer().NonceAt(
s.Ctx(), sender.Address(), new(big.Int).SetUint64(blkNum),
)
s.Require().NoError(err)

var (
tx *coretypes.Transaction
clientPubkey []byte
Expand Down Expand Up @@ -214,13 +221,13 @@ func (s *BeaconKitE2ESuite) TestDepositRobustness() {
"Waiting for the final deposit tx to be mined",
"num", NumDepositsLoad, "hash", tx.Hash().Hex(),
)
receipt, err := bind.WaitMined(s.Ctx(), s.JSONRPCBalancer(), tx)
receipt, err := bind.WaitMined(s.Ctx(), network.JSONRPCBalancer(), tx)
s.Require().NoError(err)
s.Require().Equal(coretypes.ReceiptStatusSuccessful, receipt.Status)
s.Logger().Info("Final deposit tx mined successfully", "hash", receipt.TxHash.Hex())

// Give time for the nodes to catch up.
err = s.WaitForNBlockNumbers(NumDepositsLoad / chainspec.MaxDepositsPerBlock())
err = s.WaitForNBlockNumbers(network, NumDepositsLoad/chainspec.MaxDepositsPerBlock())
s.Require().NoError(err)

// Compare height of nodes 0 and 1
Expand All @@ -231,7 +238,7 @@ func (s *BeaconKitE2ESuite) TestDepositRobustness() {
s.Require().InDelta(height.Response.LastBlockHeight, height2.Response.LastBlockHeight, 1)

// Check to see if evm balance decreased.
postDepositBalance, err := s.JSONRPCBalancer().BalanceAt(s.Ctx(), sender.Address(), nil)
postDepositBalance, err := network.JSONRPCBalancer().BalanceAt(s.Ctx(), sender.Address(), nil)
s.Require().NoError(err)

// Check that the eth spent is somewhere~ (gas) between
Expand All @@ -246,11 +253,11 @@ func (s *BeaconKitE2ESuite) TestDepositRobustness() {
// Check that all validators' voting power have increased by
// (NumDepositsLoad / NumValidators) * depositAmountWei
// after the end of the epoch (next multiple of SlotsPerEpoch after receipt.BlockNumber).
blkNum, err = s.JSONRPCBalancer().BlockNumber(s.Ctx())
blkNum, err = network.JSONRPCBalancer().BlockNumber(s.Ctx())
s.Require().NoError(err)
nextEpoch := chainspec.SlotToEpoch(math.Slot(blkNum)) + 1
nextEpochBlockNum := nextEpoch.Unwrap() * chainspec.SlotsPerEpoch()
err = s.WaitForFinalizedBlockNumber(nextEpochBlockNum + 1)
err = s.WaitForFinalizedBlockNumber(network, nextEpochBlockNum+1)
s.Require().NoError(err)

increaseAmt := new(big.Int).Mul(depositAmountGwei, big.NewInt(int64(NumDepositsLoad/config.NumValidators)))
Expand All @@ -264,7 +271,7 @@ func (s *BeaconKitE2ESuite) TestDepositRobustness() {

// withdrawal balance is in Wei, so we'll convert it to Gwei.
withdrawalAddress := gethcommon.Address(val.WithdrawalCredentials[12:])
withdrawalBalanceAfter, jErr := s.JSONRPCBalancer().BalanceAt(s.Ctx(), withdrawalAddress, nil)
withdrawalBalanceAfter, jErr := network.JSONRPCBalancer().BalanceAt(s.Ctx(), withdrawalAddress, nil)
s.Require().NoError(jErr)
withdrawalDiff := new(big.Int).Sub(withdrawalBalanceAfter, val.WithdrawalBalance)
withdrawalDiff.Div(withdrawalDiff, weiPerGwei)
Expand Down
Loading
Loading