Skip to content

Commit

Permalink
eupgrade/cancun: verify no blobs in header (ava-labs#611)
Browse files Browse the repository at this point in the history
* eupgrade/cancun: verify no blobs in header

* Update consensus/dummy/consensus.go

Signed-off-by: Darioush Jalali <darioush.jalali@avalabs.org>

* fix ut

* review comments

* add UT

* use require

* fix ut

* update UT to make a blob TX

---------

Signed-off-by: Darioush Jalali <darioush.jalali@avalabs.org>
  • Loading branch information
darioush authored and oxbee committed Nov 6, 2024
1 parent 08d0f7b commit f2d2d1e
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 7 deletions.
3 changes: 3 additions & 0 deletions consensus/dummy/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,9 @@ func (self *DummyEngine) verifyHeader(chain consensus.ChainHeaderReader, header
if err := eip4844.VerifyEIP4844Header(parent, header); err != nil {
return err
}
if *header.BlobGasUsed > 0 { // VerifyEIP4844Header ensures BlobGasUsed is non-nil
return fmt.Errorf("blobs not enabled on avalanche networks: used %d blob gas, expected 0", *header.BlobGasUsed)
}
}
return nil
}
Expand Down
6 changes: 4 additions & 2 deletions core/state_processor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ func TestStateProcessorErrors(t *testing.T) {
},
GasLimit: params.CortinaGasLimit,
}
blockchain, _ = NewBlockChain(db, DefaultCacheConfig, gspec, dummy.NewCoinbaseFaker(), vm.Config{}, common.Hash{}, false)
// FullFaker used to skip header verification that enforces no blobs.
blockchain, _ = NewBlockChain(db, DefaultCacheConfig, gspec, dummy.NewFullFaker(), vm.Config{}, common.Hash{}, false)
tooBigInitCode = [params.MaxInitCodeSize + 1]byte{}
)

Expand Down Expand Up @@ -236,7 +237,8 @@ func TestStateProcessorErrors(t *testing.T) {
want: "could not apply tx 0 [0x6c11015985ce82db691d7b2d017acda296db88b811c3c60dc71449c76256c716]: max fee per gas less than block base fee: address 0x71562b71999873DB5b286dF957af199Ec94617F7, maxFeePerGas: 1, baseFee: 225000000000",
},
} {
block := GenerateBadBlock(gspec.ToBlock(), dummy.NewCoinbaseFaker(), tt.txs, gspec.Config)
// FullFaker used to skip header verification that enforces no blobs.
block := GenerateBadBlock(gspec.ToBlock(), dummy.NewFullFaker(), tt.txs, gspec.Config)
_, err := blockchain.InsertChain(types.Blocks{block})
if err == nil {
t.Fatal("block imported without errors")
Expand Down
3 changes: 2 additions & 1 deletion internal/ethapi/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1436,7 +1436,8 @@ func setupReceiptBackend(t *testing.T, genBlocks int) (*testBackend, []common.Ha
// Set the terminal total difficulty in the config
// genesis.Config.TerminalTotalDifficulty = big.NewInt(0)
// genesis.Config.TerminalTotalDifficultyPassed = true
backend := newTestBackend(t, genBlocks, genesis, dummy.NewCoinbaseFaker(), func(i int, b *core.BlockGen) {
// FullFaker used to skip header verification that enforces no blobs.
backend := newTestBackend(t, genBlocks, genesis, dummy.NewFullFaker(), func(i int, b *core.BlockGen) {
var (
tx *types.Transaction
err error
Expand Down
5 changes: 5 additions & 0 deletions plugin/evm/block_verification.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,11 @@ func (v blockValidator) SyntacticVerify(b *Block, rules params.Rules) error {
case *ethHeader.ParentBeaconRoot != (common.Hash{}):
return fmt.Errorf("invalid parentBeaconRoot: have %x, expected empty hash", ethHeader.ParentBeaconRoot)
}
if ethHeader.BlobGasUsed == nil {
return fmt.Errorf("blob gas used must not be nil in Cancun")
} else if *ethHeader.BlobGasUsed > 0 {
return fmt.Errorf("blobs not enabled on avalanche networks: used %d blob gas, expected 0", *ethHeader.BlobGasUsed)
}
}
return nil
}
54 changes: 50 additions & 4 deletions plugin/evm/vm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rlp"
"github.com/holiman/uint256"

"github.com/ava-labs/coreth/constants"
"github.com/ava-labs/coreth/eth/filters"
"github.com/ava-labs/coreth/internal/ethapi"
"github.com/ava-labs/coreth/metrics"
Expand All @@ -41,7 +43,6 @@ import (
"github.com/ava-labs/avalanchego/snow"
"github.com/ava-labs/avalanchego/snow/validators"
"github.com/ava-labs/avalanchego/utils/cb58"
"github.com/ava-labs/avalanchego/utils/constants"
"github.com/ava-labs/avalanchego/utils/crypto/bls"
"github.com/ava-labs/avalanchego/utils/crypto/secp256k1"
"github.com/ava-labs/avalanchego/utils/formatting"
Expand All @@ -55,6 +56,7 @@ import (
"github.com/ava-labs/avalanchego/vms/secp256k1fx"

commonEng "github.com/ava-labs/avalanchego/snow/engine/common"
constantsEng "github.com/ava-labs/avalanchego/utils/constants"

"github.com/ava-labs/coreth/consensus/dummy"
"github.com/ava-labs/coreth/core"
Expand Down Expand Up @@ -217,9 +219,9 @@ func NewContext() *snow.Context {
ctx.ValidatorState = &validators.TestState{
GetSubnetIDF: func(_ context.Context, chainID ids.ID) (ids.ID, error) {
subnetID, ok := map[ids.ID]ids.ID{
constants.PlatformChainID: constants.PrimaryNetworkID,
testXChainID: constants.PrimaryNetworkID,
testCChainID: constants.PrimaryNetworkID,
constantsEng.PlatformChainID: constantsEng.PrimaryNetworkID,
testXChainID: constantsEng.PrimaryNetworkID,
testCChainID: constantsEng.PrimaryNetworkID,
}[chainID]
if !ok {
return ids.Empty, errors.New("unknown chain")
Expand Down Expand Up @@ -4090,6 +4092,50 @@ func TestParentBeaconRootBlock(t *testing.T) {
}
}

func TestNoBlobsAllowed(t *testing.T) {
ctx := context.Background()
require := require.New(t)

gspec := new(core.Genesis)
err := json.Unmarshal([]byte(genesisJSONCancun), gspec)
require.NoError(err)

// Make one block with a single blob tx
signer := types.NewCancunSigner(gspec.Config.ChainID)
blockGen := func(_ int, b *core.BlockGen) {
b.SetCoinbase(constants.BlackholeAddr)
fee := big.NewInt(500)
fee.Add(fee, b.BaseFee())
tx, err := types.SignTx(types.NewTx(&types.BlobTx{
Nonce: 0,
GasTipCap: uint256.NewInt(1),
GasFeeCap: uint256.MustFromBig(fee),
Gas: params.TxGas,
To: testEthAddrs[0],
BlobFeeCap: uint256.NewInt(1),
BlobHashes: []common.Hash{{1}},
Value: new(uint256.Int),
}), signer, testKeys[0].ToECDSA())
require.NoError(err)
b.AddTx(tx)
}
// FullFaker used to skip header verification so we can generate a block with blobs
_, blocks, _, err := core.GenerateChainWithGenesis(gspec, dummy.NewFullFaker(), 1, 10, blockGen)
require.NoError(err)

// Create a VM with the genesis (will use header verification)
_, vm, _, _, _ := GenesisVM(t, true, genesisJSONCancun, "", "")
defer func() { require.NoError(vm.Shutdown(ctx)) }()

// Verification should fail
vmBlock, err := vm.newBlock(blocks[0])
require.NoError(err)
_, err = vm.ParseBlock(ctx, vmBlock.Bytes())
require.ErrorContains(err, "blobs not enabled on avalanche networks")
err = vmBlock.Verify(ctx)
require.ErrorContains(err, "blobs not enabled on avalanche networks")
}

func TestMinFeeSetAtEUpgrade(t *testing.T) {
require := require.New(t)
now := time.Now()
Expand Down

0 comments on commit f2d2d1e

Please # to comment.