@ -33,6 +33,7 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/trie"
"github.com/holiman/uint256"
"golang.org/x/crypto/sha3"
)
@ -45,19 +46,23 @@ func u64(val uint64) *uint64 { return &val }
func TestStateProcessorErrors ( t * testing . T ) {
var (
config = & params . ChainConfig {
ChainID : big . NewInt ( 1 ) ,
HomesteadBlock : big . NewInt ( 0 ) ,
EIP150Block : big . NewInt ( 0 ) ,
EIP155Block : big . NewInt ( 0 ) ,
EIP158Block : big . NewInt ( 0 ) ,
ByzantiumBlock : big . NewInt ( 0 ) ,
ConstantinopleBlock : big . NewInt ( 0 ) ,
PetersburgBlock : big . NewInt ( 0 ) ,
IstanbulBlock : big . NewInt ( 0 ) ,
MuirGlacierBlock : big . NewInt ( 0 ) ,
BerlinBlock : big . NewInt ( 0 ) ,
LondonBlock : big . NewInt ( 0 ) ,
Ethash : new ( params . EthashConfig ) ,
ChainID : big . NewInt ( 1 ) ,
HomesteadBlock : big . NewInt ( 0 ) ,
EIP150Block : big . NewInt ( 0 ) ,
EIP155Block : big . NewInt ( 0 ) ,
EIP158Block : big . NewInt ( 0 ) ,
ByzantiumBlock : big . NewInt ( 0 ) ,
ConstantinopleBlock : big . NewInt ( 0 ) ,
PetersburgBlock : big . NewInt ( 0 ) ,
IstanbulBlock : big . NewInt ( 0 ) ,
MuirGlacierBlock : big . NewInt ( 0 ) ,
BerlinBlock : big . NewInt ( 0 ) ,
LondonBlock : big . NewInt ( 0 ) ,
Ethash : new ( params . EthashConfig ) ,
TerminalTotalDifficulty : big . NewInt ( 0 ) ,
TerminalTotalDifficultyPassed : true ,
ShanghaiTime : new ( uint64 ) ,
CancunTime : new ( uint64 ) ,
}
signer = types . LatestSigner ( config )
key1 , _ = crypto . HexToECDSA ( "b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291" )
@ -89,6 +94,22 @@ func TestStateProcessorErrors(t *testing.T) {
} ) , signer , key1 )
return tx
}
var mkBlobTx = func ( nonce uint64 , to common . Address , gasLimit uint64 , gasTipCap , gasFeeCap * big . Int , hashes [ ] common . Hash ) * types . Transaction {
tx , err := types . SignTx ( types . NewTx ( & types . BlobTx {
Nonce : nonce ,
GasTipCap : uint256 . MustFromBig ( gasTipCap ) ,
GasFeeCap : uint256 . MustFromBig ( gasFeeCap ) ,
Gas : gasLimit ,
To : to ,
BlobHashes : hashes ,
Value : new ( uint256 . Int ) ,
} ) , signer , key1 )
if err != nil {
t . Fatal ( err )
}
return tx
}
{ // Tests against a 'recent' chain definition
var (
db = rawdb . NewMemoryDatabase ( )
@ -105,8 +126,10 @@ func TestStateProcessorErrors(t *testing.T) {
} ,
} ,
}
blockchain , _ = NewBlockChain ( db , nil , gspec , nil , ethash . NewFaker ( ) , vm . Config { } , nil , nil )
blockchain , _ = NewBlockChain ( db , nil , gspec , nil , beacon . New ( ethash . NewFaker ( ) ) , vm . Config { } , nil , nil )
tooBigInitCode = [ params . MaxInitCodeSize + 1 ] byte { }
)
defer blockchain . Stop ( )
bigNumber := new ( big . Int ) . SetBytes ( common . FromHex ( "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" ) )
tooBigNumber := new ( big . Int ) . Set ( bigNumber )
@ -209,8 +232,26 @@ func TestStateProcessorErrors(t *testing.T) {
} ,
want : "could not apply tx 0 [0xd82a0c2519acfeac9a948258c47e784acd20651d9d80f9a1c67b4137651c3a24]: insufficient funds for gas * price + value: address 0x71562b71999873DB5b286dF957af199Ec94617F7 have 1000000000000000000 want 2431633873983640103894990685182446064918669677978451844828609264166175722438635000" ,
} ,
{ // ErrMaxInitCodeSizeExceeded
txs : [ ] * types . Transaction {
mkDynamicCreationTx ( 0 , 500000 , common . Big0 , big . NewInt ( params . InitialBaseFee ) , tooBigInitCode [ : ] ) ,
} ,
want : "could not apply tx 0 [0xd491405f06c92d118dd3208376fcee18a57c54bc52063ee4a26b1cf296857c25]: max initcode size exceeded: code size 49153 limit 49152" ,
} ,
{ // ErrIntrinsicGas: Not enough gas to cover init code
txs : [ ] * types . Transaction {
mkDynamicCreationTx ( 0 , 54299 , common . Big0 , big . NewInt ( params . InitialBaseFee ) , make ( [ ] byte , 320 ) ) ,
} ,
want : "could not apply tx 0 [0xfd49536a9b323769d8472fcb3ebb3689b707a349379baee3e2ee3fe7baae06a1]: intrinsic gas too low: have 54299, want 54300" ,
} ,
{ // ErrBlobFeeCapTooLow
txs : [ ] * types . Transaction {
mkBlobTx ( 0 , common . Address { } , params . TxGas , big . NewInt ( 1 ) , big . NewInt ( 1 ) , [ ] common . Hash { ( common . Hash { 1 } ) } ) ,
} ,
want : "could not apply tx 0 [0x6c11015985ce82db691d7b2d017acda296db88b811c3c60dc71449c76256c716]: max fee per gas less than block base fee: address 0x71562b71999873DB5b286dF957af199Ec94617F7, maxFeePerGas: 1 baseFee: 875000000" ,
} ,
} {
block := GenerateBadBlock ( gspec . ToBlock ( ) , ethash . NewFaker ( ) , tt . txs , gspec . Config )
block := GenerateBadBlock ( gspec . ToBlock ( ) , beacon . New ( ethash . NewFaker ( ) ) , tt . txs , gspec . Config )
_ , err := blockchain . InsertChain ( types . Blocks { block } )
if err == nil {
t . Fatal ( "block imported without errors" )
@ -284,7 +325,7 @@ func TestStateProcessorErrors(t *testing.T) {
} ,
} ,
}
blockchain , _ = NewBlockChain ( db , nil , gspec , nil , ethash . NewFaker ( ) , vm . Config { } , nil , nil )
blockchain , _ = NewBlockChain ( db , nil , gspec , nil , beacon . New ( ethash . NewFaker ( ) ) , vm . Config { } , nil , nil )
)
defer blockchain . Stop ( )
for i , tt := range [ ] struct {
@ -298,73 +339,7 @@ func TestStateProcessorErrors(t *testing.T) {
want : "could not apply tx 0 [0x88626ac0d53cb65308f2416103c62bb1f18b805573d4f96a3640bbbfff13c14f]: sender not an eoa: address 0x71562b71999873DB5b286dF957af199Ec94617F7, codehash: 0x9280914443471259d4570a8661015ae4a5b80186dbc619658fb494bebc3da3d1" ,
} ,
} {
block := GenerateBadBlock ( gspec . ToBlock ( ) , ethash . NewFaker ( ) , tt . txs , gspec . Config )
_ , err := blockchain . InsertChain ( types . Blocks { block } )
if err == nil {
t . Fatal ( "block imported without errors" )
}
if have , want := err . Error ( ) , tt . want ; have != want {
t . Errorf ( "test %d:\nhave \"%v\"\nwant \"%v\"\n" , i , have , want )
}
}
}
// ErrMaxInitCodeSizeExceeded, for this we need extra Shanghai (EIP-3860) enabled.
{
var (
db = rawdb . NewMemoryDatabase ( )
gspec = & Genesis {
Config : & params . ChainConfig {
ChainID : big . NewInt ( 1 ) ,
HomesteadBlock : big . NewInt ( 0 ) ,
EIP150Block : big . NewInt ( 0 ) ,
EIP155Block : big . NewInt ( 0 ) ,
EIP158Block : big . NewInt ( 0 ) ,
ByzantiumBlock : big . NewInt ( 0 ) ,
ConstantinopleBlock : big . NewInt ( 0 ) ,
PetersburgBlock : big . NewInt ( 0 ) ,
IstanbulBlock : big . NewInt ( 0 ) ,
MuirGlacierBlock : big . NewInt ( 0 ) ,
BerlinBlock : big . NewInt ( 0 ) ,
LondonBlock : big . NewInt ( 0 ) ,
ArrowGlacierBlock : big . NewInt ( 0 ) ,
GrayGlacierBlock : big . NewInt ( 0 ) ,
MergeNetsplitBlock : big . NewInt ( 0 ) ,
TerminalTotalDifficulty : big . NewInt ( 0 ) ,
TerminalTotalDifficultyPassed : true ,
ShanghaiTime : u64 ( 0 ) ,
} ,
Alloc : GenesisAlloc {
common . HexToAddress ( "0x71562b71999873DB5b286dF957af199Ec94617F7" ) : GenesisAccount {
Balance : big . NewInt ( 1000000000000000000 ) , // 1 ether
Nonce : 0 ,
} ,
} ,
}
genesis = gspec . MustCommit ( db )
blockchain , _ = NewBlockChain ( db , nil , gspec , nil , beacon . New ( ethash . NewFaker ( ) ) , vm . Config { } , nil , nil )
tooBigInitCode = [ params . MaxInitCodeSize + 1 ] byte { }
smallInitCode = [ 320 ] byte { }
)
defer blockchain . Stop ( )
for i , tt := range [ ] struct {
txs [ ] * types . Transaction
want string
} {
{ // ErrMaxInitCodeSizeExceeded
txs : [ ] * types . Transaction {
mkDynamicCreationTx ( 0 , 500000 , common . Big0 , misc . CalcBaseFee ( config , genesis . Header ( ) ) , tooBigInitCode [ : ] ) ,
} ,
want : "could not apply tx 0 [0x832b54a6c3359474a9f504b1003b2cc1b6fcaa18e4ef369eb45b5d40dad6378f]: max initcode size exceeded: code size 49153 limit 49152" ,
} ,
{ // ErrIntrinsicGas: Not enough gas to cover init code
txs : [ ] * types . Transaction {
mkDynamicCreationTx ( 0 , 54299 , common . Big0 , misc . CalcBaseFee ( config , genesis . Header ( ) ) , smallInitCode [ : ] ) ,
} ,
want : "could not apply tx 0 [0x39b7436cb432d3662a25626474282c5c4c1a213326fd87e4e18a91477bae98b2]: intrinsic gas too low: have 54299, want 54300" ,
} ,
} {
block := GenerateBadBlock ( genesis , beacon . New ( ethash . NewFaker ( ) ) , tt . txs , gspec . Config )
block := GenerateBadBlock ( gspec . ToBlock ( ) , beacon . New ( ethash . NewFaker ( ) ) , tt . txs , gspec . Config )
_ , err := blockchain . InsertChain ( types . Blocks { block } )
if err == nil {
t . Fatal ( "block imported without errors" )
@ -412,6 +387,7 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr
hasher := sha3 . NewLegacyKeccak256 ( )
hasher . Write ( header . Number . Bytes ( ) )
var cumulativeGas uint64
var nBlobs int
for _ , tx := range txs {
txh := tx . Hash ( )
hasher . Write ( txh [ : ] )
@ -420,8 +396,20 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr
receipt . GasUsed = tx . Gas ( )
receipts = append ( receipts , receipt )
cumulativeGas += tx . Gas ( )
nBlobs += len ( tx . BlobHashes ( ) )
}
header . Root = common . BytesToHash ( hasher . Sum ( nil ) )
if config . IsCancun ( header . Number , header . Time ) {
var pExcess , pUsed = uint64 ( 0 ) , uint64 ( 0 )
if parent . ExcessDataGas ( ) != nil {
pExcess = * parent . ExcessDataGas ( )
pUsed = * parent . DataGasUsed ( )
}
excess := misc . CalcExcessDataGas ( pExcess , pUsed )
used := uint64 ( nBlobs * params . BlobTxDataGasPerBlob )
header . ExcessDataGas = & excess
header . DataGasUsed = & used
}
// Assemble and return the final block for sealing
if config . IsShanghai ( header . Number , header . Time ) {
return types . NewBlockWithWithdrawals ( header , txs , nil , receipts , [ ] * types . Withdrawal { } , trie . NewStackTrie ( nil ) )