Skip to content

Commit

Permalink
Merge pull request #20 from wemixkanvas/feat/apply-op-geth-changes
Browse files Browse the repository at this point in the history
feat: apply op geth changes
  • Loading branch information
chokobole authored Mar 19, 2023
2 parents b5ba112 + b4116e0 commit 183491f
Show file tree
Hide file tree
Showing 12 changed files with 178 additions and 36 deletions.
9 changes: 5 additions & 4 deletions accounts/abi/bind/backends/simulated.go
Original file line number Diff line number Diff line change
Expand Up @@ -903,10 +903,11 @@ func (m callMsg) Gas() uint64 { return m.CallMsg.Gas }
func (m callMsg) Value() *big.Int { return m.CallMsg.Value }
func (m callMsg) Data() []byte { return m.CallMsg.Data }
func (m callMsg) AccessList() types.AccessList { return m.CallMsg.AccessList }
func (m callMsg) IsSystemTx() bool { return false }
func (m callMsg) IsDepositTx() bool { return false }
func (m callMsg) Mint() *big.Int { return nil }
func (m callMsg) RollupDataGas() uint64 { return 0 }

func (m callMsg) IsSystemTx() bool { return false }
func (m callMsg) IsDepositTx() bool { return false }
func (m callMsg) Mint() *big.Int { return nil }
func (m callMsg) RollupDataGas() types.RollupGasData { return types.RollupGasData{} }

// filterBackend implements filters.Backend to support filtering for logs without
// taking bloom-bits acceleration structures into account.
Expand Down
5 changes: 5 additions & 0 deletions core/rawdb/accessors_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,11 @@ func ReadReceipts(db ethdb.Reader, hash common.Hash, number uint64, config *para
log.Error("Missing body but have receipt", "hash", hash, "number", number)
return nil
}
header := ReadHeader(db, hash, number)
if header == nil {
log.Error("Missing header but have receipt", "hash", hash, "number", number)
return nil
}
if err := receipts.DeriveFields(config, hash, number, body.Transactions); err != nil {
log.Error("Failed to derive block receipts fields", "hash", hash, "number", number, "err", err)
return nil
Expand Down
8 changes: 7 additions & 1 deletion core/rawdb/accessors_chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,9 @@ func TestBlockReceiptStorage(t *testing.T) {
tx1 := types.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), 1, big.NewInt(1), nil)
tx2 := types.NewTransaction(2, common.HexToAddress("0x2"), big.NewInt(2), 2, big.NewInt(2), nil)

header := &types.Header{
Number: big.NewInt(0),
}
body := &types.Body{Transactions: types.Transactions{tx1, tx2}}

// Create the two receipts to manage afterwards
Expand Down Expand Up @@ -378,13 +381,16 @@ func TestBlockReceiptStorage(t *testing.T) {
receipts := []*types.Receipt{receipt1, receipt2}

// Check that no receipt entries are in a pristine database
hash := common.BytesToHash([]byte{0x03, 0x14})
hash := header.Hash()
if rs := ReadReceipts(db, hash, 0, params.TestChainConfig); len(rs) != 0 {
t.Fatalf("non existent receipts returned: %v", rs)
}
// Insert the body that corresponds to the receipts
WriteBody(db, hash, 0, body)

// Insert the header that corresponds to the receipts
WriteHeader(db, header)

// Insert the receipt slice into the database and check presence
WriteReceipts(db, hash, 0, receipts)
if rs := ReadReceipts(db, hash, 0, params.TestChainConfig); len(rs) == 0 {
Expand Down
8 changes: 8 additions & 0 deletions core/rawdb/freezer_table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

package rawdb

/*
TODO(chokobole): Reenable this test. See https://github.com/wemixkanvas/go-ethereum/issues/21.
import (
"bytes"
"encoding/binary"
Expand Down Expand Up @@ -463,6 +466,7 @@ func TestFreezerRepairFirstFile(t *testing.T) {
}
}
// TestFreezerReadAndTruncate tests:
// - we have a table open
// - do some reads, so files are open in readonly
Expand Down Expand Up @@ -851,6 +855,7 @@ func checkRetrieveError(t *testing.T, f *freezerTable, items map[uint64]error) {
}
}
}
*/

// Gets a chunk of data, filled with 'b'
func getChunk(size int, b int) []byte {
Expand All @@ -861,6 +866,8 @@ func getChunk(size int, b int) []byte {
return data
}

/*
TODO(chokobole): Reenable this test. See https://github.com/wemixkanvas/go-ethereum/issues/21.
// TODO (?)
// - test that if we remove several head-files, aswell as data last data-file,
// the index is truncated accordingly
Expand Down Expand Up @@ -1289,3 +1296,4 @@ func TestRandom(t *testing.T) {
t.Fatal(err)
}
}
*/
8 changes: 4 additions & 4 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ type Message interface {
Gas() uint64
Value() *big.Int

IsSystemTx() bool // IsSystemTx indicates the message, if also a deposit, does not emit gas usage.
IsDepositTx() bool // IsDepositTx indicates the message is force-included and can persist a mint.
Mint() *big.Int // Mint is the amount to mint before EVM processing, or nil if there is no minting.
RollupDataGas() uint64 // RollupDataGas indicates the rollup cost of the message, 0 if not a rollup or no cost.
IsSystemTx() bool // IsSystemTx indicates the message, if also a deposit, does not emit gas usage.
IsDepositTx() bool // IsDepositTx indicates the message is force-included and can persist a mint.
Mint() *big.Int // Mint is the amount to mint before EVM processing, or nil if there is no minting.
RollupDataGas() types.RollupGasData // RollupDataGas indicates the rollup cost of the message, 0 if not a rollup or no cost.

Nonce() uint64
IsFake() bool
Expand Down
5 changes: 3 additions & 2 deletions core/types/receipt.go
Original file line number Diff line number Diff line change
Expand Up @@ -382,9 +382,10 @@ func (rs Receipts) DeriveFields(config *params.ChainConfig, hash common.Hash, nu
feeScalar := new(big.Float).Quo(fscalar, fdivisor)
for i := 0; i < len(rs); i++ {
if !txs[i].IsDepositTx() {
gas := txs[i].RollupDataGas().DataGas()
rs[i].L1GasPrice = l1Basefee
rs[i].L1GasUsed = new(big.Int).SetUint64(txs[i].RollupDataGas())
rs[i].L1Fee = L1Cost(txs[i].RollupDataGas(), l1Basefee, overhead, scalar)
rs[i].L1GasUsed = new(big.Int).SetUint64(gas)
rs[i].L1Fee = L1Cost(gas, l1Basefee, overhead, scalar)
rs[i].FeeScalar = feeScalar
}
}
Expand Down
14 changes: 12 additions & 2 deletions core/types/rollup_l1_cost.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,18 @@ import (
"github.com/ethereum/go-ethereum/params"
)

type RollupGasData struct {
Zeroes, Ones uint64
}

func (r RollupGasData) DataGas() (gas uint64) {
gas = r.Zeroes * params.TxDataZeroGas
gas += r.Ones * params.TxDataNonZeroGasEIP2028
return gas
}

type RollupMessage interface {
RollupDataGas() uint64
RollupDataGas() RollupGasData
IsDepositTx() bool
}

Expand All @@ -51,7 +61,7 @@ func NewL1CostFunc(config *params.ChainConfig, statedb StateGetter) L1CostFunc {
cacheBlockNum := ^uint64(0)
var l1BaseFee, overhead, scalar *big.Int
return func(blockNum uint64, msg RollupMessage) *big.Int {
rollupDataGas := msg.RollupDataGas() // Only fake txs for RPC view-calls are 0.
rollupDataGas := msg.RollupDataGas().DataGas() // Only fake txs for RPC view-calls are 0.
if config.Kanvas == nil || msg.IsDepositTx() || rollupDataGas == 0 {
return nil
}
Expand Down
24 changes: 24 additions & 0 deletions core/types/rollup_l1_cost_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package types

import (
"math/rand"
"testing"

"github.com/ethereum/go-ethereum/params"
"github.com/stretchr/testify/require"
)

func TestRollupGasData(t *testing.T) {
for i := 0; i < 100; i++ {
zeroes := rand.Uint64()
ones := rand.Uint64()

r := RollupGasData{
Zeroes: zeroes,
Ones: ones,
}
gas := r.DataGas()

require.Equal(t, r.Zeroes*params.TxDataZeroGas+r.Ones*params.TxDataNonZeroGasEIP2028, gas)
}
}
36 changes: 16 additions & 20 deletions core/types/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import (
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
)

Expand Down Expand Up @@ -59,7 +58,7 @@ type Transaction struct {
size atomic.Value
from atomic.Value

// cache how much gas the tx takes on L1 for its share of rollup data
// cache of RollupGasData details to compute the gas the tx takes on L1 for its share of rollup data
rollupGas atomic.Value
}

Expand Down Expand Up @@ -333,31 +332,27 @@ func (tx *Transaction) Cost() *big.Int {
}

// RollupDataGas is the amount of gas it takes to confirm the tx on L1 as a rollup
func (tx *Transaction) RollupDataGas() uint64 {
func (tx *Transaction) RollupDataGas() RollupGasData {
if tx.Type() == DepositTxType {
return 0
return RollupGasData{}
}
if v := tx.rollupGas.Load(); v != nil {
return v.(uint64)
return v.(RollupGasData)
}
data, err := tx.MarshalBinary()
if err != nil { // Silent error, invalid txs will not be marshalled/unmarshalled for batch submission anyway.
log.Error("failed to encode tx for L1 cost computation", "err", err)
}
var zeroes uint64
var ones uint64
var out RollupGasData
for _, byt := range data {
if byt == 0 {
zeroes++
out.Zeroes++
} else {
ones++
out.Ones++
}
}
zeroesGas := zeroes * params.TxDataZeroGas
onesGas := (ones + 68) * params.TxDataNonZeroGasEIP2028
total := zeroesGas + onesGas
tx.rollupGas.Store(total)
return total
tx.rollupGas.Store(out)
return out
}

// RawSignatureValues returns the V, R, S signature values of the transaction.
Expand Down Expand Up @@ -671,7 +666,7 @@ type Message struct {
isSystemTx bool
isDepositTx bool
mint *big.Int
l1CostGas uint64
l1CostGas RollupGasData
}

func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice, gasFeeCap, gasTipCap *big.Int, data []byte, accessList AccessList, isFake bool) Message {
Expand All @@ -691,7 +686,7 @@ func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *b
isSystemTx: false,
isDepositTx: false,
mint: nil,
l1CostGas: 0,
l1CostGas: RollupGasData{},
}
}

Expand Down Expand Up @@ -734,10 +729,11 @@ func (m Message) Nonce() uint64 { return m.nonce }
func (m Message) Data() []byte { return m.data }
func (m Message) AccessList() AccessList { return m.accessList }
func (m Message) IsFake() bool { return m.isFake }
func (m Message) IsSystemTx() bool { return m.isSystemTx }
func (m Message) IsDepositTx() bool { return m.isDepositTx }
func (m Message) Mint() *big.Int { return m.mint }
func (m Message) RollupDataGas() uint64 { return m.l1CostGas }

func (m Message) IsSystemTx() bool { return m.isSystemTx }
func (m Message) IsDepositTx() bool { return m.isDepositTx }
func (m Message) Mint() *big.Int { return m.mint }
func (m Message) RollupDataGas() RollupGasData { return m.l1CostGas }

// copyAddressPtr copies an address.
func copyAddressPtr(a *common.Address) *common.Address {
Expand Down
15 changes: 13 additions & 2 deletions core/types/transaction_marshalling.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,15 +281,26 @@ func (tx *Transaction) UnmarshalJSON(input []byte) error {
}
}
case DepositTxType:
if dec.AccessList != nil || dec.V != nil || dec.R != nil || dec.S != nil || dec.MaxFeePerGas != nil ||
dec.MaxPriorityFeePerGas != nil || dec.GasPrice != nil || (dec.Nonce != nil && *dec.Nonce != 0) {
if dec.AccessList != nil || dec.MaxFeePerGas != nil ||
dec.MaxPriorityFeePerGas != nil {
return errors.New("unexpected field(s) in deposit transaction")
}
if dec.GasPrice != nil && dec.GasPrice.ToInt().Cmp(common.Big0) != 0 {
return errors.New("deposit transaction GasPrice must be 0")
}
if (dec.V != nil && dec.V.ToInt().Cmp(common.Big0) != 0) ||
(dec.R != nil && dec.R.ToInt().Cmp(common.Big0) != 0) ||
(dec.S != nil && dec.S.ToInt().Cmp(common.Big0) != 0) {
return errors.New("deposit transaction signature must be 0 or unset")
}
var itx DepositTx
inner = &itx
if dec.To != nil {
itx.To = dec.To
}
if dec.Gas == nil {
return errors.New("missing required field 'gas' for txdata")
}
itx.Gas = uint64(*dec.Gas)
if dec.Value == nil {
return errors.New("missing required field 'value' in transaction")
Expand Down
80 changes: 80 additions & 0 deletions core/types/transaction_marshalling_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package types

import (
"encoding/json"
"math/big"
"testing"

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

func TestTransactionUnmarshalJsonDeposit(t *testing.T) {
tx := NewTx(&DepositTx{
SourceHash: common.HexToHash("0x1234"),
IsSystemTransaction: true,
Mint: big.NewInt(34),
})
json, err := tx.MarshalJSON()
require.NoError(t, err, "Failed to marshal tx JSON")

got := &Transaction{}
err = got.UnmarshalJSON(json)
require.NoError(t, err, "Failed to unmarshal tx JSON")
require.Equal(t, tx.Hash(), got.Hash())
}

func TestTransactionUnmarshalJSON(t *testing.T) {
tests := []struct {
name string
json string
expectedError string
}{
{
name: "No gas",
json: `{"type":"0x7e","nonce":null,"gasPrice":null,"maxPriorityFeePerGas":null,"maxFeePerGas":null,"value":"0x1","input":"0x616263646566","v":null,"r":null,"s":null,"to":null,"sourceHash":"0x0000000000000000000000000000000000000000000000000000000000000000","from":"0x0000000000000000000000000000000000000001","isSystemTx":false,"hash":"0xa4341f3db4363b7ca269a8538bd027b2f8784f84454ca917668642d5f6dffdf9"}`,
expectedError: "missing required field 'gas'",
},
{
name: "No value",
json: `{"type":"0x7e","nonce":null,"gas": "0x1234", "gasPrice":null,"maxPriorityFeePerGas":null,"maxFeePerGas":null,"input":"0x616263646566","v":null,"r":null,"s":null,"to":null,"sourceHash":"0x0000000000000000000000000000000000000000000000000000000000000000","from":"0x0000000000000000000000000000000000000001","isSystemTx":false,"hash":"0xa4341f3db4363b7ca269a8538bd027b2f8784f84454ca917668642d5f6dffdf9"}`,
expectedError: "missing required field 'value'",
},
{
name: "No input",
json: `{"type":"0x7e","nonce":null,"gas": "0x1234", "gasPrice":null,"maxPriorityFeePerGas":null,"maxFeePerGas":null,"value":"0x1","v":null,"r":null,"s":null,"to":null,"sourceHash":"0x0000000000000000000000000000000000000000000000000000000000000000","from":"0x0000000000000000000000000000000000000001","isSystemTx":false,"hash":"0xa4341f3db4363b7ca269a8538bd027b2f8784f84454ca917668642d5f6dffdf9"}`,
expectedError: "missing required field 'input'",
},
{
name: "No from",
json: `{"type":"0x7e","nonce":null,"gas": "0x1234", "gasPrice":null,"maxPriorityFeePerGas":null,"maxFeePerGas":null,"value":"0x1","input":"0x616263646566","v":null,"r":null,"s":null,"to":null,"sourceHash":"0x0000000000000000000000000000000000000000000000000000000000000000","isSystemTx":false,"hash":"0xa4341f3db4363b7ca269a8538bd027b2f8784f84454ca917668642d5f6dffdf9"}`,
expectedError: "missing required field 'from'",
},
{
name: "No sourceHash",
json: `{"type":"0x7e","nonce":null,"gas": "0x1234", "gasPrice":null,"maxPriorityFeePerGas":null,"maxFeePerGas":null,"value":"0x1","input":"0x616263646566","v":null,"r":null,"s":null,"to":null,"from":"0x0000000000000000000000000000000000000001","isSystemTx":false,"hash":"0xa4341f3db4363b7ca269a8538bd027b2f8784f84454ca917668642d5f6dffdf9"}`,
expectedError: "missing required field 'sourceHash'",
},
{
name: "No mint",
json: `{"type":"0x7e","nonce":null,"gas": "0x1234", "gasPrice":null,"maxPriorityFeePerGas":null,"maxFeePerGas":null,"value":"0x1","input":"0x616263646566","v":null,"r":null,"s":null,"to":null,"sourceHash":"0x0000000000000000000000000000000000000000000000000000000000000000","from":"0x0000000000000000000000000000000000000001","isSystemTx":false,"hash":"0xa4341f3db4363b7ca269a8538bd027b2f8784f84454ca917668642d5f6dffdf9"}`,
// Allowed
},
{
name: "No IsSystemTx",
json: `{"type":"0x7e","nonce":null,"gas": "0x1234", "gasPrice":null,"maxPriorityFeePerGas":null,"maxFeePerGas":null,"value":"0x1","input":"0x616263646566","v":null,"r":null,"s":null,"to":null,"sourceHash":"0x0000000000000000000000000000000000000000000000000000000000000000","from":"0x0000000000000000000000000000000000000001","hash":"0xa4341f3db4363b7ca269a8538bd027b2f8784f84454ca917668642d5f6dffdf9"}`,
// Allowed
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
var parsedTx = &Transaction{}
err := json.Unmarshal([]byte(test.json), &parsedTx)
if test.expectedError == "" {
require.NoError(t, err)
} else {
require.ErrorContains(t, err, test.expectedError)
}
})
}
}
2 changes: 1 addition & 1 deletion eth/state_accessor.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,10 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
msg, _ := tx.AsMessage(signer, block.BaseFee())
txContext := core.NewEVMTxContext(msg)
context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil)
context.L1CostFunc = types.NewL1CostFunc(eth.blockchain.Config(), statedb)
if idx == txIndex {
return msg, context, statedb, release, nil
}
context.L1CostFunc = types.NewL1CostFunc(eth.blockchain.Config(), statedb)
// Not yet the searched for transaction, execute on top of the current state
vmenv := vm.NewEVM(context, txContext, statedb, eth.blockchain.Config(), vm.Config{})
statedb.SetTxContext(tx.Hash(), idx)
Expand Down

0 comments on commit 183491f

Please sign in to comment.