Skip to content

Commit

Permalink
Correctly add cancun data.
Browse files Browse the repository at this point in the history
  • Loading branch information
cabrador committed Jul 25, 2024
1 parent abdeac0 commit 27f45f7
Show file tree
Hide file tree
Showing 6 changed files with 268 additions and 170 deletions.
73 changes: 73 additions & 0 deletions rlp/berlin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package rlp

import (
"math/big"

"github.com/Fantom-foundation/Substate/types"
)

const berlinBlock = 37_455_223

// IsBerlinFork returns true if block is part of the berlin fork block range
func IsBerlinFork(block uint64) bool {
return block >= berlinBlock && block < londonBlock
}

// berlinRLP represents legacy RLP structure between Berlin and London fork starting at berlinBlock ending at londonBlock
type berlinRLP struct {
InputAlloc WorldState
OutputAlloc WorldState
Env *legacyEnv
Message *berlinMessage
Result *Result
}

// toRLP transforms r into RLP format which is compatible with the currently used Geth fork.
func (r berlinRLP) toRLP() *RLP {
return &RLP{
InputSubstate: r.InputAlloc,
OutputSubstate: r.OutputAlloc,
Env: r.Env.toEnv(),
Message: r.Message.toMessage(),
Result: r.Result,
}

}

type berlinMessage struct {
Nonce uint64
CheckNonce bool
GasPrice *big.Int
Gas uint64

From types.Address
To *types.Address `rlp:"nil"` // nil means contract creation
Value *big.Int
Data []byte

InitCodeHash *types.Hash `rlp:"nil"` // NOT nil for contract creation

AccessList types.AccessList // missing in substate DB from Geth v1.9.x
}

// toMessage transforms m into RLP format which is compatible with the currently used Geth fork.
func (m berlinMessage) toMessage() *Message {
return &Message{
londonMessage: londonMessage{
Nonce: m.Nonce,
CheckNonce: m.CheckNonce,
GasPrice: m.GasPrice,
Gas: m.Gas,
From: m.From,
To: m.To,
Value: new(big.Int).Set(m.Value),
Data: m.Data,
InitCodeHash: m.InitCodeHash,
AccessList: m.AccessList,

// Same behavior as AccessListTx.gasFeeCap() and AccessListTx.gasTipCap()
GasFeeCap: m.GasPrice,
GasTipCap: m.GasPrice,
},
}
}
127 changes: 32 additions & 95 deletions rlp/legacy.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,6 @@ import (
"github.com/Fantom-foundation/Substate/types"
)

const (
berlinBlock = 37_455_223
londonBlock = 37_534_833
)

// IsLondonFork returns true if block is part of the london fork block range
func IsLondonFork(block uint64) bool {
return block >= londonBlock
}

// IsBerlinFork returns true if block is part of the berlin fork block range
func IsBerlinFork(block uint64) bool {
return block >= berlinBlock && block < londonBlock
}

// legacySubstateRLP represents legacy RLP structure between before Berlin fork thus before berlinBlock
type legacySubstateRLP struct {
InputAlloc WorldState
Expand All @@ -30,12 +15,13 @@ type legacySubstateRLP struct {
Result *Result
}

func (r legacySubstateRLP) toLondon() *RLP {
// toRLP transforms r into RLP format which is compatible with the currently used Geth fork.
func (r legacySubstateRLP) toRLP() *RLP {
return &RLP{
InputSubstate: r.InputAlloc,
OutputSubstate: r.OutputAlloc,
Env: r.Env.toLondon(),
Message: r.Message.toLondon(),
Env: r.Env.toEnv(),
Message: r.Message.toMessage(),
Result: r.Result,
}
}
Expand All @@ -54,22 +40,25 @@ type legacyMessage struct {
InitCodeHash *types.Hash `rlp:"nil"` // NOT nil for contract creation
}

func (m legacyMessage) toLondon() *Message {
// toMessage transforms m into RLP format which is compatible with the currently used Geth fork.
func (m legacyMessage) toMessage() *Message {
return &Message{
Nonce: m.Nonce,
CheckNonce: m.CheckNonce,
GasPrice: m.GasPrice,
Gas: m.Gas,
From: m.From,
To: m.To,
Value: new(big.Int).Set(m.Value),
Data: m.Data,
InitCodeHash: m.InitCodeHash,
AccessList: nil, // access list was not present before berlin fork?

// Same behavior as AccessListTx.gasFeeCap() and AccessListTx.gasTipCap()
GasFeeCap: m.GasPrice,
GasTipCap: m.GasPrice,
londonMessage: londonMessage{
Nonce: m.Nonce,
CheckNonce: m.CheckNonce,
GasPrice: m.GasPrice,
Gas: m.Gas,
From: m.From,
To: m.To,
Value: new(big.Int).Set(m.Value),
Data: m.Data,
InitCodeHash: m.InitCodeHash,
AccessList: nil, // access list was not present before berlin fork?

// Same behavior as AccessListTx.gasFeeCap() and AccessListTx.gasTipCap()
GasFeeCap: m.GasPrice,
GasTipCap: m.GasPrice,
},
}
}

Expand All @@ -82,68 +71,16 @@ type legacyEnv struct {
BlockHashes [][2]types.Hash
}

func (e legacyEnv) toLondon() *Env {
// toEnv transforms e into RLP format which is compatible with the currently used Geth fork.
func (e legacyEnv) toEnv() *Env {
return &Env{
Coinbase: e.Coinbase,
Difficulty: e.Difficulty,
GasLimit: e.GasLimit,
Number: e.Number,
Timestamp: e.Timestamp,
BlockHashes: e.BlockHashes,
}
}

// berlinRLP represents legacy RLP structure between Berlin and London fork starting at berlinBlock ending at londonBlock
type berlinRLP struct {
InputAlloc WorldState
OutputAlloc WorldState
Env *legacyEnv
Message *berlinMessage
Result *Result
}

func (r berlinRLP) toLondon() *RLP {
return &RLP{
InputSubstate: r.InputAlloc,
OutputSubstate: r.OutputAlloc,
Env: r.Env.toLondon(),
Message: r.Message.toLondon(),
Result: r.Result,
}

}

type berlinMessage struct {
Nonce uint64
CheckNonce bool
GasPrice *big.Int
Gas uint64

From types.Address
To *types.Address `rlp:"nil"` // nil means contract creation
Value *big.Int
Data []byte

InitCodeHash *types.Hash `rlp:"nil"` // NOT nil for contract creation

AccessList types.AccessList // missing in substate DB from Geth v1.9.x
}

func (m berlinMessage) toLondon() *Message {
return &Message{
Nonce: m.Nonce,
CheckNonce: m.CheckNonce,
GasPrice: m.GasPrice,
Gas: m.Gas,
From: m.From,
To: m.To,
Value: new(big.Int).Set(m.Value),
Data: m.Data,
InitCodeHash: m.InitCodeHash,
AccessList: m.AccessList,

// Same behavior as AccessListTx.gasFeeCap() and AccessListTx.gasTipCap()
GasFeeCap: m.GasPrice,
GasTipCap: m.GasPrice,
londonEnv: londonEnv{
Coinbase: e.Coinbase,
Difficulty: e.Difficulty,
GasLimit: e.GasLimit,
Number: e.Number,
Timestamp: e.Timestamp,
BlockHashes: e.BlockHashes,
},
}
}
145 changes: 145 additions & 0 deletions rlp/london.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package rlp

import (
"math/big"

"github.com/Fantom-foundation/Substate/substate"
"github.com/Fantom-foundation/Substate/types"
)

const londonBlock = 37_534_833

// IsLondonFork returns true if block is part of the london fork block range
func IsLondonFork(block uint64) bool {
return block >= londonBlock
}

func NewLondonRLP(substate *substate.Substate) *londonRLP {
return &londonRLP{
InputSubstate: NewWorldState(substate.InputSubstate),
OutputSubstate: NewWorldState(substate.OutputSubstate),
Env: newLondonEnv(substate.Env),
Message: newLondonMessage(substate.Message),
Result: NewResult(substate.Result),
}
}

// londonRLP represents RLP structure after londonBlock and before cancun fork.
type londonRLP struct {
InputSubstate WorldState
OutputSubstate WorldState
Env londonEnv
Message londonMessage
Result *Result
}

// toRLP transforms r into RLP format which is compatible with the currently used Geth fork.
func (r londonRLP) toRLP() *RLP {
return &RLP{
InputSubstate: r.InputSubstate,
OutputSubstate: r.OutputSubstate,
Env: r.Env.toEnv(),
Message: r.Message.toMessage(),
Result: r.Result,
}
}

func newLondonEnv(env *substate.Env) londonEnv {
e := londonEnv{
Coinbase: env.Coinbase,
Difficulty: env.Difficulty,
GasLimit: env.GasLimit,
Number: env.Number,
Timestamp: env.Timestamp,
}

var sortedNum64 []uint64
for num64 := range env.BlockHashes {
sortedNum64 = append(sortedNum64, num64)
}

for _, num64 := range sortedNum64 {
num := types.BigToHash(new(big.Int).SetUint64(num64))
blockHash := env.BlockHashes[num64]
pair := [2]types.Hash{num, blockHash}
e.BlockHashes = append(e.BlockHashes, pair)
}

e.BaseFee = nil
if env.BaseFee != nil {
baseFeeHash := types.BigToHash(env.BaseFee)
e.BaseFee = &baseFeeHash
}

return e
}

type londonEnv struct {
Coinbase types.Address
Difficulty *big.Int
GasLimit uint64
Number uint64
Timestamp uint64
BlockHashes [][2]types.Hash

BaseFee *types.Hash `rlp:"nil"` // missing in substate DB from Geth <= v1.10.3
}

// toEnv transforms m into RLP format which is compatible with the currently used Geth fork.
func (e londonEnv) toEnv() *Env {
return &Env{
londonEnv: e,
}
}

func newLondonMessage(message *substate.Message) londonMessage {
m := londonMessage{
Nonce: message.Nonce,
CheckNonce: message.CheckNonce,
GasPrice: message.GasPrice,
Gas: message.Gas,
From: message.From,
To: message.To,
Value: new(big.Int).Set(message.Value),
Data: message.Data,
InitCodeHash: nil,
AccessList: message.AccessList,
GasFeeCap: message.GasFeeCap,
GasTipCap: message.GasTipCap,
}

if m.To == nil {
// put contract creation init code into codeDB
dataHash := message.DataHash()
m.InitCodeHash = &dataHash
m.Data = nil
}

return m
}

type londonMessage struct {
Nonce uint64
CheckNonce bool
GasPrice *big.Int
Gas uint64

From types.Address
To *types.Address `rlp:"nil"` // nil means contract creation
Value *big.Int
Data []byte

InitCodeHash *types.Hash `rlp:"nil"` // NOT nil for contract creation

AccessList types.AccessList // missing in substate DB from Geth v1.9.x

GasFeeCap *big.Int // missing in substate DB from Geth <= v1.10.3
GasTipCap *big.Int // missing in substate DB from Geth <= v1.10.3
}

// toMessage transforms m into RLP format which is compatible with the currently used Geth fork.
func (m londonMessage) toMessage() *Message {
return &Message{
londonMessage: m,
}
}
Loading

0 comments on commit 27f45f7

Please sign in to comment.