Skip to content

Commit

Permalink
Remove gas limit field from pre-Gingerbread additional fields record …
Browse files Browse the repository at this point in the history
…in local DB
  • Loading branch information
Kourin1996 committed Jan 9, 2025
1 parent 38bf0e4 commit a67a0ad
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 252 deletions.
39 changes: 11 additions & 28 deletions core/rawdb/celo_accessors.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,50 +5,33 @@ import (

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/rlp"
)

var (
CeloPreGingerbreadFieldsPrefix = []byte("celoPgbFields-") // CeloPreGingerbreadFieldsPrefix + block hash -> PreGingerbreadAdditionalFields
CeloPreGingerbreadBaseFeePrefix = []byte("celoPgbBlockBaseFee-") // CeloPreGingerbreadBlockBaseFeePrefix + block hash -> BaseFee
)

type PreGingerbreadFields struct {
BaseFee *big.Int
GasLimit *big.Int
}

// preGingerbreadAdditionalFieldsKey calculates a database key for PreGingerbreadAdditionalFields for the given block hash
func preGingerbreadAdditionalFieldsKey(hash common.Hash) []byte {
return append(CeloPreGingerbreadFieldsPrefix, hash[:]...)
// preGingerbreadBlockBaseFeeKey calculates a database key of pre-Gingerbread block BaseFee for the given block hash
func preGingerbreadBlockBaseFeeKey(hash common.Hash) []byte {
return append(CeloPreGingerbreadBaseFeePrefix, hash[:]...)
}

// ReadPreGingerbreadAdditionalFields reads PreGingerbreadAdditionalFields from the given database for the given block hash
func ReadPreGingerbreadAdditionalFields(db ethdb.KeyValueReader, blockHash common.Hash) (*PreGingerbreadFields, error) {
data, _ := db.Get(preGingerbreadAdditionalFieldsKey(blockHash))
// ReadPreGingerbreadBlockBaseFee reads BaseFee of pre-Gingerbread block from the given database for the given block hash
func ReadPreGingerbreadBlockBaseFee(db ethdb.KeyValueReader, blockHash common.Hash) (*big.Int, error) {
data, _ := db.Get(preGingerbreadBlockBaseFeeKey(blockHash))
if len(data) == 0 {
return nil, nil
}

fields := &PreGingerbreadFields{}

err := rlp.DecodeBytes(data, fields)
if err != nil {
return nil, err
}

return fields, nil
return new(big.Int).SetBytes(data), nil
}

// WritePreGingerbreadAdditionalFields writes PreGingerbreadAdditionalFields to the given database for the given block hash
func WritePreGingerbreadAdditionalFields(db ethdb.KeyValueWriter, blockHash common.Hash, data *PreGingerbreadFields) error {
rawData, err := rlp.EncodeToBytes(data)
if err != nil {
return err
}

if err := db.Put(preGingerbreadAdditionalFieldsKey(blockHash), rawData); err != nil {
return err
}

return nil
// WritePreGingerbreadBlockBaseFee writes BaseFee of pre-Gingerbread block to the given database at the given block hash
func WritePreGingerbreadBlockBaseFee(db ethdb.KeyValueWriter, blockHash common.Hash, baseFee *big.Int) error {
return db.Put(preGingerbreadBlockBaseFeeKey(blockHash), baseFee.Bytes())
}
125 changes: 13 additions & 112 deletions core/rawdb/celo_accessors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,127 +5,28 @@ import (
"testing"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/rlp"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

// TestPreGingerbreadAdditionalFields tests ReadPreGingerbreadAdditionalFields function
func TestPreGingerbreadAdditionalFields(t *testing.T) {
db := NewMemoryDatabase()

mockData, err := rlp.EncodeToBytes(&PreGingerbreadFields{
BaseFee: big.NewInt(1000),
GasLimit: big.NewInt(2000),
})
assert.NoError(t, err)

type SeedData struct {
hash common.Hash
data []byte
}

tests := []struct {
name string
seedData []SeedData
hash common.Hash
expectedRes *PreGingerbreadFields
returnsError bool
}{
{
name: "should return nil if data is not found",
seedData: []SeedData{},
hash: common.HexToHash("0x1"),
expectedRes: nil,
returnsError: false,
},
{
name: "should return data",
seedData: []SeedData{
{
hash: common.HexToHash("0x2"),
data: mockData,
},
},
hash: common.HexToHash("0x2"),
expectedRes: &PreGingerbreadFields{
BaseFee: big.NewInt(1000),
GasLimit: big.NewInt(2000),
},
returnsError: false,
},
{
name: "should return error if data is broken",
seedData: []SeedData{
{
hash: common.HexToHash("0x3"),
data: []byte{0x1, 0x2, 0x3},
},
},
hash: common.HexToHash("0x3"),
expectedRes: nil,
returnsError: true,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
for _, seed := range test.seedData {
err := db.Put(preGingerbreadAdditionalFieldsKey(seed.hash), seed.data)
assert.NoError(t, err)
}

t.Cleanup(func() {
for _, seed := range test.seedData {
err := db.Delete(preGingerbreadAdditionalFieldsKey(seed.hash))
assert.NoError(t, err)
}
})

res, err := ReadPreGingerbreadAdditionalFields(db, test.hash)
assert.Equal(t, test.expectedRes, res)

if test.returnsError {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
})
}
}

// TestWritePreGingerbreadAdditionalFields tests WritePreGingerbreadAdditionalFields function
func TestWritePreGingerbreadAdditionalFields(t *testing.T) {
// TestReadAndWritePreGingerbreadBlockBaseFee tests reading and writing pre-gingerbread block base fee to database
func TestReadAndWritePreGingerbreadBlockBaseFee(t *testing.T) {
db := NewMemoryDatabase()

hash := common.HexToHash("0x1")
data := []*PreGingerbreadFields{
{
BaseFee: big.NewInt(0),
GasLimit: big.NewInt(2000),
},
{
BaseFee: big.NewInt(3000),
GasLimit: big.NewInt(0),
},
{
BaseFee: big.NewInt(5000),
GasLimit: big.NewInt(6000),
},
}
value := big.NewInt(1234)

// Make sure that the data is not found
record0, err := ReadPreGingerbreadAdditionalFields(db, hash)
assert.NoError(t, err)
record0, err := ReadPreGingerbreadBlockBaseFee(db, hash)
require.NoError(t, err)
assert.Nil(t, record0)

for _, d := range data {
// Write data
err := WritePreGingerbreadAdditionalFields(db, hash, d)
assert.NoError(t, err)
// Write data
err = WritePreGingerbreadBlockBaseFee(db, hash, value)
require.NoError(t, err)

// Read data
record, err := ReadPreGingerbreadAdditionalFields(db, hash)
assert.NoError(t, err)
assert.Equal(t, d, record)
}
// Read data
record, err := ReadPreGingerbreadBlockBaseFee(db, hash)
require.NoError(t, err)
assert.Equal(t, value, record)
}
48 changes: 18 additions & 30 deletions internal/ethapi/celo_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,44 +34,37 @@ func PopulatePreGingerbreadBlockFields(ctx context.Context, backend CeloBackend,

// PopulatePreGingerbreadHeaderFields populates the baseFee and gasLimit fields of the header for pre-gingerbread blocks
func PopulatePreGingerbreadHeaderFields(ctx context.Context, backend CeloBackend, header *types.Header) *types.Header {
isGingerbread := backend.ChainConfig().IsGingerbread(header.Number)
if isGingerbread {
// If the block is post-Gingerbread, return the header as is
if backend.ChainConfig().IsGingerbread(header.Number) {
return header
}

var (
baseFee *big.Int
gasLimit *big.Int
baseFee *big.Int
)

fields, err := rawdb.ReadPreGingerbreadAdditionalFields(backend.ChainDb(), header.Hash())
if fields != nil {
if fields.BaseFee != nil && fields.BaseFee.BitLen() != 0 {
baseFee = fields.BaseFee
}
if fields.GasLimit != nil && fields.GasLimit.BitLen() != 0 {
gasLimit = fields.GasLimit
}
} else {
if chainId := backend.ChainConfig().ChainID; chainId != nil {
gasLimit = retrievePreGingerbreadGasLimit(chainId.Uint64(), header.Number)
}

baseFee, err := rawdb.ReadPreGingerbreadBlockBaseFee(backend.ChainDb(), header.Hash())
if baseFee == nil {
if err != nil {
log.Debug("failed to read pre-gingerbread fields", "err", err)
log.Debug("failed to load pre-Gingerbread block base fee from database", "block", header.Number.Uint64(), "err", err)
}

// If the record is not found, get the values and store them
baseFee, err = retrievePreGingerbreadBlockBaseFee(ctx, backend, header.Number)
if err != nil {
log.Debug("Not adding baseFeePerGas to RPC response, failed to retrieve gas price minimum", "block", header.Number.Uint64(), "err", err)
log.Debug("Not adding to RPC response, failed to retrieve pre-Gingerbread block base fee", "block", header.Number.Uint64(), "err", err)
}

gasLimit = retrievePreGingerbreadGasLimit(backend, header.Number)

if baseFee != nil || gasLimit != nil {
err = rawdb.WritePreGingerbreadAdditionalFields(backend.ChainDb(), header.Hash(), &rawdb.PreGingerbreadFields{
BaseFee: baseFee,
GasLimit: gasLimit,
})
// Store the base fee for future use
if baseFee != nil {
err = rawdb.WritePreGingerbreadBlockBaseFee(backend.ChainDb(), header.Hash(), baseFee)
if err != nil {
log.Debug("failed to write pre-gingerbread fields", "err", err)
log.Debug("failed to write pre-Gingerbread block base fee", "block", header.Number.Uint64(), "err", err)
}
}
}
Expand All @@ -87,15 +80,10 @@ func PopulatePreGingerbreadHeaderFields(ctx context.Context, backend CeloBackend
}

// retrievePreGingerbreadGasLimit retrieves a gas limit at given height from hardcoded values
func retrievePreGingerbreadGasLimit(backend CeloBackend, height *big.Int) *big.Int {
if backend.ChainConfig().ChainID == nil {
log.Debug("Not adding gasLimit to RPC response, unknown network")
return nil
}

limits, ok := params.PreGingerbreadNetworkGasLimits[backend.ChainConfig().ChainID.Uint64()]
func retrievePreGingerbreadGasLimit(chainId uint64, height *big.Int) *big.Int {
limits, ok := params.PreGingerbreadNetworkGasLimits[chainId]
if !ok {
log.Debug("Not adding gasLimit to RPC response, unknown network", "chainID", backend.ChainConfig().ChainID)
log.Debug("Not adding gasLimit to RPC response, unknown network", "chainID", chainId)
return nil
}

Expand Down
Loading

0 comments on commit a67a0ad

Please sign in to comment.