mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 10:22:23 +00:00
gofmt rollup packages (#556)
This commit is contained in:
parent
94995b7e10
commit
76756cea1c
4 changed files with 174 additions and 174 deletions
|
|
@ -1,145 +1,145 @@
|
||||||
package fees
|
package fees
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/scroll-tech/go-ethereum/common"
|
"github.com/scroll-tech/go-ethereum/common"
|
||||||
"github.com/scroll-tech/go-ethereum/core/types"
|
"github.com/scroll-tech/go-ethereum/core/types"
|
||||||
"github.com/scroll-tech/go-ethereum/crypto"
|
"github.com/scroll-tech/go-ethereum/crypto"
|
||||||
"github.com/scroll-tech/go-ethereum/params"
|
"github.com/scroll-tech/go-ethereum/params"
|
||||||
"github.com/scroll-tech/go-ethereum/rollup/rcfg"
|
"github.com/scroll-tech/go-ethereum/rollup/rcfg"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// txExtraDataBytes is the number of bytes that we commit to L1 in addition
|
// txExtraDataBytes is the number of bytes that we commit to L1 in addition
|
||||||
// to the RLP-encoded signed transaction. Note that these are all assumed
|
// to the RLP-encoded signed transaction. Note that these are all assumed
|
||||||
// to be non-zero.
|
// to be non-zero.
|
||||||
// - tx length prefix: 4 bytes
|
// - tx length prefix: 4 bytes
|
||||||
txExtraDataBytes = uint64(4)
|
txExtraDataBytes = uint64(4)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Message represents the interface of a message.
|
// Message represents the interface of a message.
|
||||||
// It should be a subset of the methods found on
|
// It should be a subset of the methods found on
|
||||||
// types.Message
|
// types.Message
|
||||||
type Message interface {
|
type Message interface {
|
||||||
From() common.Address
|
From() common.Address
|
||||||
To() *common.Address
|
To() *common.Address
|
||||||
GasPrice() *big.Int
|
GasPrice() *big.Int
|
||||||
Gas() uint64
|
Gas() uint64
|
||||||
GasFeeCap() *big.Int
|
GasFeeCap() *big.Int
|
||||||
GasTipCap() *big.Int
|
GasTipCap() *big.Int
|
||||||
Value() *big.Int
|
Value() *big.Int
|
||||||
Nonce() uint64
|
Nonce() uint64
|
||||||
Data() []byte
|
Data() []byte
|
||||||
AccessList() types.AccessList
|
AccessList() types.AccessList
|
||||||
IsL1MessageTx() bool
|
IsL1MessageTx() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// StateDB represents the StateDB interface
|
// StateDB represents the StateDB interface
|
||||||
// required to compute the L1 fee
|
// required to compute the L1 fee
|
||||||
type StateDB interface {
|
type StateDB interface {
|
||||||
GetState(common.Address, common.Hash) common.Hash
|
GetState(common.Address, common.Hash) common.Hash
|
||||||
GetBalance(addr common.Address) *big.Int
|
GetBalance(addr common.Address) *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
func EstimateL1DataFeeForMessage(msg Message, baseFee, chainID *big.Int, signer types.Signer, state StateDB) (*big.Int, error) {
|
func EstimateL1DataFeeForMessage(msg Message, baseFee, chainID *big.Int, signer types.Signer, state StateDB) (*big.Int, error) {
|
||||||
if msg.IsL1MessageTx() {
|
if msg.IsL1MessageTx() {
|
||||||
return big.NewInt(0), nil
|
return big.NewInt(0), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned := asUnsignedTx(msg, baseFee, chainID)
|
unsigned := asUnsignedTx(msg, baseFee, chainID)
|
||||||
// with v=1
|
// with v=1
|
||||||
tx, err := unsigned.WithSignature(signer, append(bytes.Repeat([]byte{0xff}, crypto.SignatureLength-1), 0x01))
|
tx, err := unsigned.WithSignature(signer, append(bytes.Repeat([]byte{0xff}, crypto.SignatureLength-1), 0x01))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
raw, err := rlpEncode(tx)
|
raw, err := rlpEncode(tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
l1BaseFee, overhead, scalar := readGPOStorageSlots(rcfg.L1GasPriceOracleAddress, state)
|
l1BaseFee, overhead, scalar := readGPOStorageSlots(rcfg.L1GasPriceOracleAddress, state)
|
||||||
l1DataFee := calculateEncodedL1DataFee(raw, overhead, l1BaseFee, scalar)
|
l1DataFee := calculateEncodedL1DataFee(raw, overhead, l1BaseFee, scalar)
|
||||||
return l1DataFee, nil
|
return l1DataFee, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// asUnsignedTx turns a Message into a types.Transaction
|
// asUnsignedTx turns a Message into a types.Transaction
|
||||||
func asUnsignedTx(msg Message, baseFee, chainID *big.Int) *types.Transaction {
|
func asUnsignedTx(msg Message, baseFee, chainID *big.Int) *types.Transaction {
|
||||||
if baseFee == nil {
|
if baseFee == nil {
|
||||||
if msg.AccessList() == nil {
|
if msg.AccessList() == nil {
|
||||||
return asUnsignedLegacyTx(msg)
|
return asUnsignedLegacyTx(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
return asUnsignedAccessListTx(msg, chainID)
|
return asUnsignedAccessListTx(msg, chainID)
|
||||||
}
|
}
|
||||||
|
|
||||||
return asUnsignedDynamicTx(msg, chainID)
|
return asUnsignedDynamicTx(msg, chainID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func asUnsignedLegacyTx(msg Message) *types.Transaction {
|
func asUnsignedLegacyTx(msg Message) *types.Transaction {
|
||||||
return types.NewTx(&types.LegacyTx{
|
return types.NewTx(&types.LegacyTx{
|
||||||
Nonce: msg.Nonce(),
|
Nonce: msg.Nonce(),
|
||||||
To: msg.To(),
|
To: msg.To(),
|
||||||
Value: msg.Value(),
|
Value: msg.Value(),
|
||||||
Gas: msg.Gas(),
|
Gas: msg.Gas(),
|
||||||
GasPrice: msg.GasPrice(),
|
GasPrice: msg.GasPrice(),
|
||||||
Data: msg.Data(),
|
Data: msg.Data(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func asUnsignedAccessListTx(msg Message, chainID *big.Int) *types.Transaction {
|
func asUnsignedAccessListTx(msg Message, chainID *big.Int) *types.Transaction {
|
||||||
return types.NewTx(&types.AccessListTx{
|
return types.NewTx(&types.AccessListTx{
|
||||||
Nonce: msg.Nonce(),
|
Nonce: msg.Nonce(),
|
||||||
To: msg.To(),
|
To: msg.To(),
|
||||||
Value: msg.Value(),
|
Value: msg.Value(),
|
||||||
Gas: msg.Gas(),
|
Gas: msg.Gas(),
|
||||||
GasPrice: msg.GasPrice(),
|
GasPrice: msg.GasPrice(),
|
||||||
Data: msg.Data(),
|
Data: msg.Data(),
|
||||||
AccessList: msg.AccessList(),
|
AccessList: msg.AccessList(),
|
||||||
ChainID: chainID,
|
ChainID: chainID,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func asUnsignedDynamicTx(msg Message, chainID *big.Int) *types.Transaction {
|
func asUnsignedDynamicTx(msg Message, chainID *big.Int) *types.Transaction {
|
||||||
return types.NewTx(&types.DynamicFeeTx{
|
return types.NewTx(&types.DynamicFeeTx{
|
||||||
Nonce: msg.Nonce(),
|
Nonce: msg.Nonce(),
|
||||||
To: msg.To(),
|
To: msg.To(),
|
||||||
Value: msg.Value(),
|
Value: msg.Value(),
|
||||||
Gas: msg.Gas(),
|
Gas: msg.Gas(),
|
||||||
GasFeeCap: msg.GasFeeCap(),
|
GasFeeCap: msg.GasFeeCap(),
|
||||||
GasTipCap: msg.GasTipCap(),
|
GasTipCap: msg.GasTipCap(),
|
||||||
Data: msg.Data(),
|
Data: msg.Data(),
|
||||||
AccessList: msg.AccessList(),
|
AccessList: msg.AccessList(),
|
||||||
ChainID: chainID,
|
ChainID: chainID,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// rlpEncode RLP encodes the transaction into bytes
|
// rlpEncode RLP encodes the transaction into bytes
|
||||||
func rlpEncode(tx *types.Transaction) ([]byte, error) {
|
func rlpEncode(tx *types.Transaction) ([]byte, error) {
|
||||||
raw := new(bytes.Buffer)
|
raw := new(bytes.Buffer)
|
||||||
if err := tx.EncodeRLP(raw); err != nil {
|
if err := tx.EncodeRLP(raw); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return raw.Bytes(), nil
|
return raw.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readGPOStorageSlots(addr common.Address, state StateDB) (*big.Int, *big.Int, *big.Int) {
|
func readGPOStorageSlots(addr common.Address, state StateDB) (*big.Int, *big.Int, *big.Int) {
|
||||||
l1BaseFee := state.GetState(addr, rcfg.L1BaseFeeSlot)
|
l1BaseFee := state.GetState(addr, rcfg.L1BaseFeeSlot)
|
||||||
overhead := state.GetState(addr, rcfg.OverheadSlot)
|
overhead := state.GetState(addr, rcfg.OverheadSlot)
|
||||||
scalar := state.GetState(addr, rcfg.ScalarSlot)
|
scalar := state.GetState(addr, rcfg.ScalarSlot)
|
||||||
return l1BaseFee.Big(), overhead.Big(), scalar.Big()
|
return l1BaseFee.Big(), overhead.Big(), scalar.Big()
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculateEncodedL1DataFee computes the L1 fee for an RLP-encoded tx
|
// calculateEncodedL1DataFee computes the L1 fee for an RLP-encoded tx
|
||||||
func calculateEncodedL1DataFee(data []byte, overhead, l1GasPrice *big.Int, scalar *big.Int) *big.Int {
|
func calculateEncodedL1DataFee(data []byte, overhead, l1GasPrice *big.Int, scalar *big.Int) *big.Int {
|
||||||
l1GasUsed := CalculateL1GasUsed(data, overhead)
|
l1GasUsed := CalculateL1GasUsed(data, overhead)
|
||||||
l1DataFee := new(big.Int).Mul(l1GasUsed, l1GasPrice)
|
l1DataFee := new(big.Int).Mul(l1GasUsed, l1GasPrice)
|
||||||
return mulAndScale(l1DataFee, scalar, rcfg.Precision)
|
return mulAndScale(l1DataFee, scalar, rcfg.Precision)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CalculateL1GasUsed computes the L1 gas used based on the calldata and
|
// CalculateL1GasUsed computes the L1 gas used based on the calldata and
|
||||||
|
|
@ -147,79 +147,79 @@ func calculateEncodedL1DataFee(data []byte, overhead, l1GasPrice *big.Int, scala
|
||||||
// batch submission goes down via contract optimizations. This will not overflow
|
// batch submission goes down via contract optimizations. This will not overflow
|
||||||
// under standard network conditions.
|
// under standard network conditions.
|
||||||
func CalculateL1GasUsed(data []byte, overhead *big.Int) *big.Int {
|
func CalculateL1GasUsed(data []byte, overhead *big.Int) *big.Int {
|
||||||
zeroes, ones := zeroesAndOnes(data)
|
zeroes, ones := zeroesAndOnes(data)
|
||||||
zeroesGas := zeroes * params.TxDataZeroGas
|
zeroesGas := zeroes * params.TxDataZeroGas
|
||||||
onesGas := (ones + txExtraDataBytes) * params.TxDataNonZeroGasEIP2028
|
onesGas := (ones + txExtraDataBytes) * params.TxDataNonZeroGasEIP2028
|
||||||
l1Gas := new(big.Int).SetUint64(zeroesGas + onesGas)
|
l1Gas := new(big.Int).SetUint64(zeroesGas + onesGas)
|
||||||
return new(big.Int).Add(l1Gas, overhead)
|
return new(big.Int).Add(l1Gas, overhead)
|
||||||
}
|
}
|
||||||
|
|
||||||
// zeroesAndOnes counts the number of 0 bytes and non 0 bytes in a byte slice
|
// zeroesAndOnes counts the number of 0 bytes and non 0 bytes in a byte slice
|
||||||
func zeroesAndOnes(data []byte) (uint64, uint64) {
|
func zeroesAndOnes(data []byte) (uint64, uint64) {
|
||||||
var zeroes uint64
|
var zeroes uint64
|
||||||
var ones uint64
|
var ones uint64
|
||||||
for _, byt := range data {
|
for _, byt := range data {
|
||||||
if byt == 0 {
|
if byt == 0 {
|
||||||
zeroes++
|
zeroes++
|
||||||
} else {
|
} else {
|
||||||
ones++
|
ones++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return zeroes, ones
|
return zeroes, ones
|
||||||
}
|
}
|
||||||
|
|
||||||
// mulAndScale multiplies a big.Int by a big.Int and then scale it by precision,
|
// mulAndScale multiplies a big.Int by a big.Int and then scale it by precision,
|
||||||
// rounded towards zero
|
// rounded towards zero
|
||||||
func mulAndScale(x *big.Int, y *big.Int, precision *big.Int) *big.Int {
|
func mulAndScale(x *big.Int, y *big.Int, precision *big.Int) *big.Int {
|
||||||
z := new(big.Int).Mul(x, y)
|
z := new(big.Int).Mul(x, y)
|
||||||
return new(big.Int).Quo(z, precision)
|
return new(big.Int).Quo(z, precision)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CalculateL1DataFee(tx *types.Transaction, state StateDB) (*big.Int, error) {
|
func CalculateL1DataFee(tx *types.Transaction, state StateDB) (*big.Int, error) {
|
||||||
if tx.IsL1MessageTx() {
|
if tx.IsL1MessageTx() {
|
||||||
return big.NewInt(0), nil
|
return big.NewInt(0), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
raw, err := rlpEncode(tx)
|
raw, err := rlpEncode(tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
l1BaseFee, overhead, scalar := readGPOStorageSlots(rcfg.L1GasPriceOracleAddress, state)
|
l1BaseFee, overhead, scalar := readGPOStorageSlots(rcfg.L1GasPriceOracleAddress, state)
|
||||||
l1DataFee := calculateEncodedL1DataFee(raw, overhead, l1BaseFee, scalar)
|
l1DataFee := calculateEncodedL1DataFee(raw, overhead, l1BaseFee, scalar)
|
||||||
return l1DataFee, nil
|
return l1DataFee, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func calculateL2Fee(tx *types.Transaction) *big.Int {
|
func calculateL2Fee(tx *types.Transaction) *big.Int {
|
||||||
l2GasLimit := new(big.Int).SetUint64(tx.Gas())
|
l2GasLimit := new(big.Int).SetUint64(tx.Gas())
|
||||||
return new(big.Int).Mul(tx.GasPrice(), l2GasLimit)
|
return new(big.Int).Mul(tx.GasPrice(), l2GasLimit)
|
||||||
}
|
}
|
||||||
|
|
||||||
func VerifyFee(signer types.Signer, tx *types.Transaction, state StateDB) error {
|
func VerifyFee(signer types.Signer, tx *types.Transaction, state StateDB) error {
|
||||||
from, err := types.Sender(signer, tx)
|
from, err := types.Sender(signer, tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("invalid transaction: invalid sender")
|
return errors.New("invalid transaction: invalid sender")
|
||||||
}
|
}
|
||||||
|
|
||||||
balance := state.GetBalance(from)
|
balance := state.GetBalance(from)
|
||||||
l2Fee := calculateL2Fee(tx)
|
l2Fee := calculateL2Fee(tx)
|
||||||
l1DataFee, err := CalculateL1DataFee(tx, state)
|
l1DataFee, err := CalculateL1DataFee(tx, state)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid transaction: %w", err)
|
return fmt.Errorf("invalid transaction: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cost := tx.Value()
|
cost := tx.Value()
|
||||||
cost = cost.Add(cost, l2Fee)
|
cost = cost.Add(cost, l2Fee)
|
||||||
if balance.Cmp(cost) < 0 {
|
if balance.Cmp(cost) < 0 {
|
||||||
return errors.New("invalid transaction: insufficient funds for gas * price + value")
|
return errors.New("invalid transaction: insufficient funds for gas * price + value")
|
||||||
}
|
}
|
||||||
|
|
||||||
cost = cost.Add(cost, l1DataFee)
|
cost = cost.Add(cost, l1DataFee)
|
||||||
if balance.Cmp(cost) < 0 {
|
if balance.Cmp(cost) < 0 {
|
||||||
return errors.New("invalid transaction: insufficient funds for l1fee + gas * price + value")
|
return errors.New("invalid transaction: insufficient funds for l1fee + gas * price + value")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check GasPrice is in an expected range
|
// TODO: check GasPrice is in an expected range
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,20 @@
|
||||||
package fees
|
package fees
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCalculateEncodedL1DataFee(t *testing.T) {
|
func TestCalculateEncodedL1DataFee(t *testing.T) {
|
||||||
l1BaseFee := new(big.Int).SetUint64(15000000)
|
l1BaseFee := new(big.Int).SetUint64(15000000)
|
||||||
|
|
||||||
data := []byte{0, 10, 1, 0}
|
data := []byte{0, 10, 1, 0}
|
||||||
overhead := new(big.Int).SetUint64(100)
|
overhead := new(big.Int).SetUint64(100)
|
||||||
scalar := new(big.Int).SetUint64(10)
|
scalar := new(big.Int).SetUint64(10)
|
||||||
|
|
||||||
expected := new(big.Int).SetUint64(184) // 184.2
|
expected := new(big.Int).SetUint64(184) // 184.2
|
||||||
actual := calculateEncodedL1DataFee(data, overhead, l1BaseFee, scalar)
|
actual := calculateEncodedL1DataFee(data, overhead, l1BaseFee, scalar)
|
||||||
assert.Equal(t, expected, actual)
|
assert.Equal(t, expected, actual)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,32 @@
|
||||||
package rcfg
|
package rcfg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/scroll-tech/go-ethereum/common"
|
"github.com/scroll-tech/go-ethereum/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// verify in consensus layer when decentralizing sequencer
|
// verify in consensus layer when decentralizing sequencer
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// L2MessageQueueAddress is the address of the L2MessageQueue
|
// L2MessageQueueAddress is the address of the L2MessageQueue
|
||||||
// predeploy
|
// predeploy
|
||||||
// see contracts/src/L2/predeploys/L2MessageQueue.sol
|
// see contracts/src/L2/predeploys/L2MessageQueue.sol
|
||||||
L2MessageQueueAddress = common.HexToAddress("0x5300000000000000000000000000000000000000")
|
L2MessageQueueAddress = common.HexToAddress("0x5300000000000000000000000000000000000000")
|
||||||
WithdrawTrieRootSlot = common.BigToHash(big.NewInt(0))
|
WithdrawTrieRootSlot = common.BigToHash(big.NewInt(0))
|
||||||
|
|
||||||
// ScrollFeeVaultAddress is the address of the L2TxFeeVault
|
// ScrollFeeVaultAddress is the address of the L2TxFeeVault
|
||||||
// predeploy
|
// predeploy
|
||||||
// see scroll-tech/scroll/contracts/src/L2/predeploys/L2TxFeeVault.sol
|
// see scroll-tech/scroll/contracts/src/L2/predeploys/L2TxFeeVault.sol
|
||||||
ScrollFeeVaultAddress = common.HexToAddress("0x5300000000000000000000000000000000000005")
|
ScrollFeeVaultAddress = common.HexToAddress("0x5300000000000000000000000000000000000005")
|
||||||
|
|
||||||
// L1GasPriceOracleAddress is the address of the L1GasPriceOracle
|
// L1GasPriceOracleAddress is the address of the L1GasPriceOracle
|
||||||
// predeploy
|
// predeploy
|
||||||
// see scroll-tech/scroll/contracts/src/L2/predeploys/L1GasPriceOracle.sol
|
// see scroll-tech/scroll/contracts/src/L2/predeploys/L1GasPriceOracle.sol
|
||||||
L1GasPriceOracleAddress = common.HexToAddress("0x5300000000000000000000000000000000000002")
|
L1GasPriceOracleAddress = common.HexToAddress("0x5300000000000000000000000000000000000002")
|
||||||
Precision = new(big.Int).SetUint64(1e9)
|
Precision = new(big.Int).SetUint64(1e9)
|
||||||
L1BaseFeeSlot = common.BigToHash(big.NewInt(1))
|
L1BaseFeeSlot = common.BigToHash(big.NewInt(1))
|
||||||
OverheadSlot = common.BigToHash(big.NewInt(2))
|
OverheadSlot = common.BigToHash(big.NewInt(2))
|
||||||
ScalarSlot = common.BigToHash(big.NewInt(3))
|
ScalarSlot = common.BigToHash(big.NewInt(3))
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
package withdrawtrie
|
package withdrawtrie
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/scroll-tech/go-ethereum/common"
|
"github.com/scroll-tech/go-ethereum/common"
|
||||||
"github.com/scroll-tech/go-ethereum/rollup/rcfg"
|
"github.com/scroll-tech/go-ethereum/rollup/rcfg"
|
||||||
)
|
)
|
||||||
|
|
||||||
// StateDB represents the StateDB interface
|
// StateDB represents the StateDB interface
|
||||||
// required to get withdraw trie root
|
// required to get withdraw trie root
|
||||||
type StateDB interface {
|
type StateDB interface {
|
||||||
GetState(common.Address, common.Hash) common.Hash
|
GetState(common.Address, common.Hash) common.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadWTRSlot reads WithdrawTrieRoot slot in L2MessageQueue predeploy, i.e., `messageRoot`
|
// ReadWTRSlot reads WithdrawTrieRoot slot in L2MessageQueue predeploy, i.e., `messageRoot`
|
||||||
// in contracts/src/libraries/common/AppendOnlyMerkleTree.sol
|
// in contracts/src/libraries/common/AppendOnlyMerkleTree.sol
|
||||||
func ReadWTRSlot(addr common.Address, state StateDB) common.Hash {
|
func ReadWTRSlot(addr common.Address, state StateDB) common.Hash {
|
||||||
return state.GetState(addr, rcfg.WithdrawTrieRootSlot)
|
return state.GetState(addr, rcfg.WithdrawTrieRootSlot)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue