Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat: apply op geth changes #20

Merged
merged 4 commits into from
Mar 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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