Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

eupgrade/cancun: verify no blobs in header #611

Merged
merged 10 commits into from
Aug 2, 2024
3 changes: 3 additions & 0 deletions consensus/dummy/consensus.go
darioush marked this conversation as resolved.
Show resolved Hide resolved
ceyonur marked this conversation as resolved.
Show resolved Hide resolved
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
darioush marked this conversation as resolved.
Show resolved Hide resolved
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) {
darioush marked this conversation as resolved.
Show resolved Hide resolved
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}},
darioush marked this conversation as resolved.
Show resolved Hide resolved
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
Loading