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

Fix some regolith bugs #43

Merged
merged 3 commits into from
Sep 15, 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
2 changes: 1 addition & 1 deletion core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func applyTransaction(config *chain.Config, engine consensus.EngineReader, gp *G

// if the transaction created a contract, store the creation address in the receipt.
if msg.To() == nil {
receipt.ContractAddress = crypto.CreateAddress(evm.TxContext().Origin, tx.GetNonce())
receipt.ContractAddress = crypto.CreateAddress(evm.TxContext().Origin, nonce)
}
// Set the receipt logs and create a bloom for filtering
receipt.Logs = ibs.GetLogs(tx.Hash())
Expand Down
25 changes: 18 additions & 7 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ func (st *StateTransition) buyGas(gasBailout bool) error {
return fmt.Errorf("%w: address %v", ErrInsufficientFunds, st.msg.From().Hex())
}
var l1Cost *uint256.Int
if optimismConfig := st.evm.ChainConfig().Optimism; optimismConfig != nil && st.evm.ChainRules().IsBedrock {
if st.evm.ChainRules().IsBedrock {
l1Cost = st.evm.Context().L1CostFunc(st.evm.Context().BlockNumber, st.msg)
if l1Cost != nil {
if _, overflow = mgval.AddOverflow(mgval, l1Cost); overflow {
Expand Down Expand Up @@ -304,7 +304,7 @@ func (st *StateTransition) preCheck(gasBailout bool) error {
st.gas += st.msg.Gas() // Add gas here in order to be able to execute calls.
// Don't touch the gas pool for system transactions
if st.msg.IsSystemTx() {
if st.evm.ChainConfig().IsOptimismRegolith(st.evm.Context().Time) {
if st.evm.ChainRules().IsOptimismRegolith {
return fmt.Errorf("%w: address %v", ErrSystemTxNotSupported,
st.msg.From().Hex())
}
Expand Down Expand Up @@ -491,7 +491,8 @@ func (st *StateTransition) innerTransitionDb(refunds bool, gasBailout bool) (*Ex
if refunds {

// if deposit: skip refunds, skip tipping coinbase
if st.msg.IsDepositTx() {
// Regolith changes this behaviour to report the actual gasUsed instead of always reporting all gas used.
if st.msg.IsDepositTx() && !rules.IsOptimismRegolith {
// Record deposits as using all their gas (matches the gas pool)
// System Transactions are special & are not recorded as using any gas (anywhere)
gasUsed := st.msg.Gas()
Expand All @@ -504,14 +505,25 @@ func (st *StateTransition) innerTransitionDb(refunds bool, gasBailout bool) (*Ex
ReturnData: ret,
}, nil
}

// Note for deposit tx there is no ETH refunded for unused gas, but that's taken care of by the fact that gasPrice
// is always 0 for deposit tx. So calling refundGas will ensure the gasUsed accounting is correct without actually
// changing the sender's balance
if rules.IsLondon {
// After EIP-3529: refunds are capped to gasUsed / 5
st.refundGas(params.RefundQuotientEIP3529)
} else {
// Before EIP-3529: refunds were capped to gasUsed / 2
st.refundGas(params.RefundQuotient)
}

if st.msg.IsDepositTx() && rules.IsOptimismRegolith {
// Skip coinbase payments for deposit tx in Regolith
return &ExecutionResult{
UsedGas: st.gasUsed(),
Err: vmerr,
ReturnData: ret,
}, nil
}
}
effectiveTip := st.gasPrice
if rules.IsLondon {
Expand Down Expand Up @@ -550,14 +562,13 @@ func (st *StateTransition) innerTransitionDb(refunds bool, gasBailout bool) (*Ex

log.Info(
"MMDBG Accounting for base fee and l1 fee",
"isOptimism", st.evm.ChainConfig().Optimism != nil,
"isOptimism", st.evm.ChainConfig().IsOptimism(),
"isBedrock", rules.IsBedrock,
"gasUsed", st.gasUsed,
"baseFee", st.evm.Context().BaseFee,
)
// Check that we are post bedrock to be able to create pseudo pre-bedrock blocks (these are pre-bedrock, but don't follow l2 geth rules)
// Note optimismConfig will not be nil if rules.IsOptimismBedrock is true
if optimismConfig := st.evm.ChainConfig().Optimism; optimismConfig != nil && rules.IsBedrock {
if rules.IsBedrock {
st.state.AddBalance(params.OptimismBaseFeeRecipient, new(uint256.Int).Mul(uint256.NewInt(st.gasUsed()), st.evm.Context().BaseFee))
if st.evm.Context().L1CostFunc == nil {
log.Error("Expected L1CostFunc to be set, but it is not")
Expand Down
2 changes: 1 addition & 1 deletion core/types/access_list_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ func (tx AccessListTx) AsMessage(s Signer, _ *big.Int, rules *chain.Rules) (Mess
data: tx.Data,
accessList: tx.AccessList,
checkNonce: true,
rollupDataGas: RollupDataGas(tx),
rollupDataGas: RollupDataGas(tx, rules),
}

if !rules.IsBerlin {
Expand Down
4 changes: 2 additions & 2 deletions core/types/deposit_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ func (tx *DepositTransaction) DecodeRLP(s *rlp.Stream) error {
}

// AsMessage returns the transaction as a core.Message.
func (tx DepositTransaction) AsMessage(s Signer, _ *big.Int, _ *chain.Rules) (Message, error) {
func (tx DepositTransaction) AsMessage(s Signer, _ *big.Int, rules *chain.Rules) (Message, error) {
msg := Message{
txType: DepositTxType,
sourceHash: tx.SourceHash,
Expand All @@ -219,7 +219,7 @@ func (tx DepositTransaction) AsMessage(s Signer, _ *big.Int, _ *chain.Rules) (Me
data: tx.Data,
accessList: nil,
checkNonce: true,
rollupDataGas: RollupDataGas(tx),
rollupDataGas: RollupDataGas(tx, rules),
}
return msg, nil
}
Expand Down
2 changes: 1 addition & 1 deletion core/types/dynamic_fee_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ func (tx DynamicFeeTransaction) AsMessage(s Signer, baseFee *big.Int, rules *cha
data: tx.Data,
accessList: tx.AccessList,
checkNonce: true,
rollupDataGas: RollupDataGas(tx),
rollupDataGas: RollupDataGas(tx, rules),
}
if !rules.IsLondon {
return msg, errors.New("eip-1559 transactions require London")
Expand Down
4 changes: 2 additions & 2 deletions core/types/legacy_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ func (tx *LegacyTx) DecodeRLP(s *rlp.Stream, encodingSize uint64) error {
}

// AsMessage returns the transaction as a core.Message.
func (tx LegacyTx) AsMessage(s Signer, _ *big.Int, _ *chain.Rules) (Message, error) {
func (tx LegacyTx) AsMessage(s Signer, _ *big.Int, rules *chain.Rules) (Message, error) {
msg := Message{
nonce: tx.Nonce,
gasLimit: tx.Gas,
Expand All @@ -379,7 +379,7 @@ func (tx LegacyTx) AsMessage(s Signer, _ *big.Int, _ *chain.Rules) (Message, err
data: tx.Data,
accessList: nil,
checkNonce: true,
rollupDataGas: RollupDataGas(tx),
rollupDataGas: RollupDataGas(tx, rules),
}

var err error
Expand Down
5 changes: 3 additions & 2 deletions core/types/receipt.go
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,8 @@ func (r Receipts) DeriveFields(config *chain.Config, hash libcommon.Hash, number
logIndex++
}
}
if config.IsOptimismBedrock(number) && len(txs) >= 2 { // need at least an info tx and a non-info tx
rules := config.Rules(number, time)
if rules.IsBedrock && len(txs) >= 2 { // need at least an info tx and a non-info tx
if data := txs[0].GetData(); len(data) >= 4+32*8 { // function selector + 8 arguments to setL1BlockValues
l1Basefee := new(uint256.Int).SetBytes(data[4+32*2 : 4+32*3]) // arg index 2
overhead := new(uint256.Int).SetBytes(data[4+32*6 : 4+32*7]) // arg index 6
Expand All @@ -558,7 +559,7 @@ func (r Receipts) DeriveFields(config *chain.Config, hash libcommon.Hash, number
feeScalar := new(big.Float).Quo(fscalar, fdivisor)
for i := 0; i < len(r); i++ {
if !txs[i].IsDepositTx() {
rollupDataGas := RollupDataGas(txs[i]) // Only fake txs for RPC view-calls are 0.
rollupDataGas := RollupDataGas(txs[i], rules) // Only fake txs for RPC view-calls are 0.
r[i].L1GasPrice = l1Basefee.ToBig()
// GasUsed reported in receipt should include the overhead
r[i].L1GasUsed = new(big.Int).Add(new(big.Int).SetUint64(rollupDataGas), overhead.ToBig())
Expand Down
9 changes: 7 additions & 2 deletions core/types/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ func (tm TransactionMisc) From() *atomic.Value {
return &tm.from
}

func RollupDataGas(tx binMarshalable) uint64 {
func RollupDataGas(tx binMarshalable, rules *chain.Rules) uint64 {
var buf bytes.Buffer
if err := tx.MarshalBinary(&buf); err != nil {
// Silent error, invalid txs will not be marshalled/unmarshalled for batch submission anyway.
Expand All @@ -146,7 +146,12 @@ func RollupDataGas(tx binMarshalable) uint64 {
}
}
zeroesGas := zeroes * params.TxDataZeroGas
onesGas := (ones + 68) * params.TxDataNonZeroGasEIP2028
var onesGas uint64
if rules.IsOptimismRegolith {
onesGas = ones * params.TxDataNonZeroGasEIP2028
} else {
onesGas = (ones + 68) * params.TxDataNonZeroGasEIP2028
}
total := zeroesGas + onesGas
log.Info("MMDBG computing rollupDataGas", "total", total, "tx", tx)
return total
Expand Down
5 changes: 3 additions & 2 deletions turbo/jsonrpc/eth_receipts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"testing"

"github.com/holiman/uint256"
"github.com/ledgerwatch/erigon-lib/chain"
"github.com/ledgerwatch/erigon-lib/common"
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/gointerfaces/txpool"
Expand Down Expand Up @@ -125,13 +126,13 @@ func TestGetReceipts(t *testing.T) {
require.Equal(t, 2, len(receipts))

require.Equal(t, new(uint256.Int).SetBytes(l1BaseFee[:]).ToBig(), receipts[0].L1GasPrice)
rollupDataGas1 := types.RollupDataGas(tx1)
rollupDataGas1 := types.RollupDataGas(tx1, &chain.Rules{IsBedrock: true})
require.Equal(t, new(big.Int).Add(new(big.Int).SetUint64(rollupDataGas1), new(uint256.Int).SetBytes(overhead[:]).ToBig()), receipts[0].L1GasUsed)
require.Equal(t, types.L1Cost(rollupDataGas1, new(uint256.Int).SetBytes(l1BaseFee[:]), new(uint256.Int).SetBytes(overhead[:]), new(uint256.Int).SetBytes(scalar[:])).ToBig(), receipts[0].L1Fee)
require.Equal(t, feeScalar, receipts[0].FeeScalar)

require.Equal(t, new(uint256.Int).SetBytes(l1BaseFee[:]).ToBig(), receipts[1].L1GasPrice)
rollupDataGas2 := types.RollupDataGas(tx2)
rollupDataGas2 := types.RollupDataGas(tx2, &chain.Rules{IsBedrock: true})
require.Equal(t, new(big.Int).Add(new(big.Int).SetUint64(rollupDataGas2), new(uint256.Int).SetBytes(overhead[:]).ToBig()), receipts[1].L1GasUsed)
require.Equal(t, types.L1Cost(rollupDataGas2, new(uint256.Int).SetBytes(l1BaseFee[:]), new(uint256.Int).SetBytes(overhead[:]), new(uint256.Int).SetBytes(scalar[:])).ToBig(), receipts[1].L1Fee)
require.Equal(t, feeScalar, receipts[1].FeeScalar)
Expand Down