Compare commits
3 Commits
5cf160177b
...
4731c8a793
Author | SHA1 | Date |
---|---|---|
|
4731c8a793 | |
|
dab746b3ef | |
|
6139430ed7 |
|
@ -255,7 +255,8 @@ func TestStateProcessorErrors(t *testing.T) {
|
|||
},
|
||||
want: "could not apply tx 0 [0xc18d10f4c809dbdfa1a074c3300de9bc4b7f16a20f0ec667f6f67312b71b956a]: EIP-7702 transaction with empty auth list (sender 0x71562b71999873DB5b286dF957af199Ec94617F7)",
|
||||
},
|
||||
// ErrSetCodeTxCreate cannot be tested: it is impossible to create a SetCode-tx with nil `to`.
|
||||
// ErrSetCodeTxCreate cannot be tested here: it is impossible to create a SetCode-tx with nil `to`.
|
||||
// The EstimateGas API tests test this case.
|
||||
} {
|
||||
block := GenerateBadBlock(gspec.ToBlock(), beacon.New(ethash.NewFaker()), tt.txs, gspec.Config, false)
|
||||
_, err := blockchain.InsertChain(types.Blocks{block})
|
||||
|
|
|
@ -2280,7 +2280,7 @@ func TestSetCodeTransactions(t *testing.T) {
|
|||
t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err)
|
||||
}
|
||||
if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), keyC)); err != nil {
|
||||
t.Fatalf("%s: failed to add with pending delegatio: %v", name, err)
|
||||
t.Fatalf("%s: failed to add with pending delegation: %v", name, err)
|
||||
}
|
||||
// Also check gapped transaction is rejected.
|
||||
if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyC)); !errors.Is(err, txpool.ErrAccountLimitExceeded) {
|
||||
|
|
|
@ -81,6 +81,11 @@ type ErrInvalidOpCode struct {
|
|||
|
||||
func (e *ErrInvalidOpCode) Error() string { return fmt.Sprintf("invalid opcode: %s", e.opcode) }
|
||||
|
||||
// NewErrInvalidOpCode is only used in tests to generate an exact ErrInvalidOpCode error.
|
||||
func NewErrInvalidOpCode(opcode OpCode) *ErrInvalidOpCode {
|
||||
return &ErrInvalidOpCode{opcode: opcode}
|
||||
}
|
||||
|
||||
// rpcError is the same interface as the one defined in rpc/errors.go
|
||||
// but we do not want to depend on rpc package here so we redefine it.
|
||||
//
|
||||
|
|
|
@ -33,6 +33,8 @@ import (
|
|||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/params/forks"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
)
|
||||
|
||||
|
@ -95,6 +97,16 @@ type SimulatedBeacon struct {
|
|||
lastBlockTime uint64
|
||||
}
|
||||
|
||||
func payloadVersion(config *params.ChainConfig, time uint64) engine.PayloadVersion {
|
||||
switch config.LatestFork(time) {
|
||||
case forks.Prague, forks.Cancun:
|
||||
return engine.PayloadV3
|
||||
case forks.Paris, forks.Shanghai:
|
||||
return engine.PayloadV2
|
||||
}
|
||||
panic("invalid fork, simulated beacon needs to be started post-merge")
|
||||
}
|
||||
|
||||
// NewSimulatedBeacon constructs a new simulated beacon chain.
|
||||
func NewSimulatedBeacon(period uint64, eth *eth.Ethereum) (*SimulatedBeacon, error) {
|
||||
block := eth.BlockChain().CurrentBlock()
|
||||
|
@ -107,7 +119,8 @@ func NewSimulatedBeacon(period uint64, eth *eth.Ethereum) (*SimulatedBeacon, err
|
|||
|
||||
// if genesis block, send forkchoiceUpdated to trigger transition to PoS
|
||||
if block.Number.Sign() == 0 {
|
||||
if _, err := engineAPI.ForkchoiceUpdatedV3(current, nil); err != nil {
|
||||
version := payloadVersion(eth.BlockChain().Config(), block.Time)
|
||||
if _, err := engineAPI.forkchoiceUpdated(current, nil, version, false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
@ -171,6 +184,8 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u
|
|||
return fmt.Errorf("failed to sync txpool: %w", err)
|
||||
}
|
||||
|
||||
version := payloadVersion(c.eth.BlockChain().Config(), timestamp)
|
||||
|
||||
var random [32]byte
|
||||
rand.Read(random[:])
|
||||
fcResponse, err := c.engineAPI.forkchoiceUpdated(c.curForkchoiceState, &engine.PayloadAttributes{
|
||||
|
@ -179,7 +194,7 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u
|
|||
Withdrawals: withdrawals,
|
||||
Random: random,
|
||||
BeaconRoot: &common.Hash{},
|
||||
}, engine.PayloadV3, false)
|
||||
}, version, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -204,28 +219,39 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u
|
|||
}
|
||||
}
|
||||
|
||||
// Independently calculate the blob hashes from sidecars.
|
||||
blobHashes := make([]common.Hash, 0)
|
||||
if envelope.BlobsBundle != nil {
|
||||
hasher := sha256.New()
|
||||
for _, commit := range envelope.BlobsBundle.Commitments {
|
||||
var c kzg4844.Commitment
|
||||
if len(commit) != len(c) {
|
||||
return errors.New("invalid commitment length")
|
||||
var (
|
||||
blobHashes []common.Hash
|
||||
beaconRoot *common.Hash
|
||||
requests [][]byte
|
||||
)
|
||||
// Compute post-shanghai fields
|
||||
if version > engine.PayloadV2 {
|
||||
// Independently calculate the blob hashes from sidecars.
|
||||
blobHashes = make([]common.Hash, 0)
|
||||
if envelope.BlobsBundle != nil {
|
||||
hasher := sha256.New()
|
||||
for _, commit := range envelope.BlobsBundle.Commitments {
|
||||
var c kzg4844.Commitment
|
||||
if len(commit) != len(c) {
|
||||
return errors.New("invalid commitment length")
|
||||
}
|
||||
copy(c[:], commit)
|
||||
blobHashes = append(blobHashes, kzg4844.CalcBlobHashV1(hasher, &c))
|
||||
}
|
||||
copy(c[:], commit)
|
||||
blobHashes = append(blobHashes, kzg4844.CalcBlobHashV1(hasher, &c))
|
||||
}
|
||||
beaconRoot = &common.Hash{}
|
||||
requests = envelope.Requests
|
||||
}
|
||||
|
||||
// Mark the payload as canon
|
||||
_, err = c.engineAPI.newPayload(*payload, blobHashes, &common.Hash{}, envelope.Requests, false)
|
||||
_, err = c.engineAPI.newPayload(*payload, blobHashes, beaconRoot, requests, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.setCurrentState(payload.BlockHash, finalizedHash)
|
||||
|
||||
// Mark the block containing the payload as canonical
|
||||
if _, err = c.engineAPI.ForkchoiceUpdatedV3(c.curForkchoiceState, nil); err != nil {
|
||||
if _, err = c.engineAPI.forkchoiceUpdated(c.curForkchoiceState, nil, version, false); err != nil {
|
||||
return err
|
||||
}
|
||||
c.lastBlockTime = payload.Timestamp
|
||||
|
|
|
@ -719,6 +719,9 @@ func toCallArg(msg ethereum.CallMsg) interface{} {
|
|||
if msg.BlobHashes != nil {
|
||||
arg["blobVersionedHashes"] = msg.BlobHashes
|
||||
}
|
||||
if msg.AuthList != nil {
|
||||
arg["authorizationList"] = msg.AuthList
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
|
|
|
@ -251,6 +251,9 @@ func toCallArg(msg ethereum.CallMsg) interface{} {
|
|||
if msg.BlobHashes != nil {
|
||||
arg["blobVersionedHashes"] = msg.BlobHashes
|
||||
}
|
||||
if msg.AuthList != nil {
|
||||
arg["authorizationList"] = msg.AuthList
|
||||
}
|
||||
return arg
|
||||
}
|
||||
|
||||
|
|
|
@ -156,6 +156,9 @@ type CallMsg struct {
|
|||
// For BlobTxType
|
||||
BlobGasFeeCap *big.Int
|
||||
BlobHashes []common.Hash
|
||||
|
||||
// For SetCodeTxType
|
||||
AuthList []types.SetCodeAuthorization
|
||||
}
|
||||
|
||||
// A ContractCaller provides contract calls, essentially transactions that are executed by
|
||||
|
|
|
@ -656,6 +656,11 @@ func TestEstimateGas(t *testing.T) {
|
|||
b.SetPoS()
|
||||
}))
|
||||
|
||||
setCodeAuthorization, _ := types.SignSetCode(accounts[0].key, types.SetCodeAuthorization{
|
||||
Address: accounts[0].addr,
|
||||
Nonce: uint64(genBlocks + 1),
|
||||
})
|
||||
|
||||
var testSuite = []struct {
|
||||
blockNumber rpc.BlockNumber
|
||||
call TransactionArgs
|
||||
|
@ -834,6 +839,50 @@ func TestEstimateGas(t *testing.T) {
|
|||
},
|
||||
want: 21000,
|
||||
},
|
||||
// Should be able to estimate SetCodeTx.
|
||||
{
|
||||
blockNumber: rpc.LatestBlockNumber,
|
||||
call: TransactionArgs{
|
||||
From: &accounts[0].addr,
|
||||
To: &accounts[1].addr,
|
||||
Value: (*hexutil.Big)(big.NewInt(0)),
|
||||
AuthorizationList: []types.SetCodeAuthorization{setCodeAuthorization},
|
||||
},
|
||||
want: 46000,
|
||||
},
|
||||
// Should retrieve the code of 0xef0001 || accounts[0].addr and return an invalid opcode error.
|
||||
{
|
||||
blockNumber: rpc.LatestBlockNumber,
|
||||
call: TransactionArgs{
|
||||
From: &accounts[0].addr,
|
||||
To: &accounts[0].addr,
|
||||
Value: (*hexutil.Big)(big.NewInt(0)),
|
||||
AuthorizationList: []types.SetCodeAuthorization{setCodeAuthorization},
|
||||
},
|
||||
expectErr: vm.NewErrInvalidOpCode(0xef),
|
||||
},
|
||||
// SetCodeTx with empty authorization list should fail.
|
||||
{
|
||||
blockNumber: rpc.LatestBlockNumber,
|
||||
call: TransactionArgs{
|
||||
From: &accounts[0].addr,
|
||||
To: &common.Address{},
|
||||
Value: (*hexutil.Big)(big.NewInt(0)),
|
||||
AuthorizationList: []types.SetCodeAuthorization{},
|
||||
},
|
||||
expectErr: core.ErrEmptyAuthList,
|
||||
},
|
||||
// SetCodeTx with nil `to` should fail.
|
||||
{
|
||||
blockNumber: rpc.LatestBlockNumber,
|
||||
call: TransactionArgs{
|
||||
From: &accounts[0].addr,
|
||||
To: nil,
|
||||
Value: (*hexutil.Big)(big.NewInt(0)),
|
||||
AuthorizationList: []types.SetCodeAuthorization{setCodeAuthorization},
|
||||
},
|
||||
expectErr: core.ErrSetCodeTxCreate,
|
||||
},
|
||||
}
|
||||
for i, tc := range testSuite {
|
||||
result, err := api.EstimateGas(context.Background(), tc.call, &rpc.BlockNumberOrHash{BlockNumber: &tc.blockNumber}, &tc.overrides, &tc.blockOverrides)
|
||||
|
|
Loading…
Reference in New Issue