diff --git a/arbitrum/apibackend.go b/arbitrum/apibackend.go
index 1171625d401d..663c4f2288a5 100644
--- a/arbitrum/apibackend.go
+++ b/arbitrum/apibackend.go
@@ -65,7 +65,7 @@ func (a *APIBackend) SyncProgress() ethereum.SyncProgress {
}
func (a *APIBackend) SuggestGasTipCap(ctx context.Context) (*big.Int, error) {
- return big.NewInt(1), nil // TODO: Implement
+ return big.NewInt(0), nil // there's no tips in L2
}
func (a *APIBackend) FeeHistory(ctx context.Context, blockCount int, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, error) {
diff --git a/core/state_transition.go b/core/state_transition.go
index 8e7b0d0812f9..efa20edf66ac 100644
--- a/core/state_transition.go
+++ b/core/state_transition.go
@@ -32,12 +32,6 @@ import (
var emptyCodeHash = crypto.Keccak256Hash(nil)
-type TxProcessingHook interface {
- InterceptMessage() *ExecutionResult
- GasChargingHook(gasRemaining *uint64) error
- EndTxHook(totalGasUsed uint64, success bool) error
-}
-
/*
The State Transitioning Model
@@ -56,8 +50,6 @@ The state transitioning model does all the necessary work to work out a valid ne
6) Derive new state root
*/
type StateTransition struct {
- processingHook TxProcessingHook
-
gp *GasPool
msg Message
gas uint64
@@ -165,17 +157,14 @@ func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation b
return gas, nil
}
-var CreateTxProcessingHook func(msg Message, evm *vm.EVM) TxProcessingHook
+var ReadyEVMForL2 func(evm *vm.EVM, msg Message)
// NewStateTransition initialises and returns a new state transition object.
func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition {
- var processingHook TxProcessingHook
- if CreateTxProcessingHook != nil {
- processingHook = CreateTxProcessingHook(msg, evm)
+ if ReadyEVMForL2 != nil {
+ ReadyEVMForL2(evm, msg)
}
return &StateTransition{
- processingHook: processingHook,
-
gp: gp,
evm: evm,
msg: msg,
@@ -302,7 +291,7 @@ func (st *StateTransition) transitionDbImpl() (*ExecutionResult, error) {
// 6. caller has enough balance to cover asset transfer for **topmost** call
// There are no tips in L2
- if st.evm.ChainConfig().Arbitrum && st.gasPrice.Cmp(st.evm.Context.BaseFee) == -1 {
+ if st.evm.ChainConfig().IsArbitrum() && st.gasPrice.Cmp(st.evm.Context.BaseFee) == -1 {
st.gasPrice = st.evm.Context.BaseFee
}
@@ -327,11 +316,9 @@ func (st *StateTransition) transitionDbImpl() (*ExecutionResult, error) {
}
st.gas -= gas
- if st.processingHook != nil {
- err = st.processingHook.GasChargingHook(&st.gas)
- if err != nil {
- return nil, err
- }
+ err = st.evm.ProcessingHook.GasChargingHook(&st.gas)
+ if err != nil {
+ return nil, err
}
// Check clause 6
@@ -376,12 +363,17 @@ func (st *StateTransition) transitionDbImpl() (*ExecutionResult, error) {
}
func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
- if st.processingHook != nil {
- res := st.processingHook.InterceptMessage()
- if res != nil {
- return res, nil
+
+ isDeposit := st.evm.ProcessingHook.StartTxHook()
+ if isDeposit {
+ res := &ExecutionResult{
+ UsedGas: 0,
+ Err: nil,
+ ReturnData: nil,
}
+ return res, nil
}
+
res, err := st.transitionDbImpl()
if err != nil && !errors.Is(err, ErrNonceTooLow) && !errors.Is(err, ErrNonceTooHigh) {
res = &ExecutionResult{
@@ -392,15 +384,21 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
err = nil
}
- if err == nil && st.processingHook != nil {
- st.processingHook.EndTxHook(st.gas, res.Err == nil)
+ if err == nil {
+ st.evm.ProcessingHook.EndTxHook(st.gas, res.Err == nil)
}
return res, err
}
func (st *StateTransition) refundGas(refundQuotient uint64) {
+
+ nonrefundable := st.evm.ProcessingHook.NonrefundableGas()
+ if nonrefundable >= st.gasUsed() {
+ return
+ }
+
// Apply refund counter, capped to a refund quotient
- refund := st.gasUsed() / refundQuotient
+ refund := (st.gasUsed() - nonrefundable) / refundQuotient
if refund > st.state.GetRefund() {
refund = st.state.GetRefund()
}
diff --git a/core/types/arb_types.go b/core/types/arb_types.go
index 5d331cf1d29d..0cc727728753 100644
--- a/core/types/arb_types.go
+++ b/core/types/arb_types.go
@@ -130,6 +130,111 @@ func (tx *ArbitrumContractTx) rawSignatureValues() (v, r, s *big.Int) {
func (tx *ArbitrumContractTx) setSignatureValues(chainID, v, r, s *big.Int) {}
func (tx *ArbitrumContractTx) isFake() bool { return true }
+type ArbitrumRetryTx struct {
+ ArbitrumContractTx
+ TicketId common.Hash
+ RefundTo common.Address
+}
+
+func (tx *ArbitrumRetryTx) txType() byte { return ArbitrumRetryTxType }
+
+func (tx *ArbitrumRetryTx) copy() TxData {
+ return &ArbitrumRetryTx{
+ *tx.ArbitrumContractTx.copy().(*ArbitrumContractTx),
+ tx.TicketId,
+ tx.RefundTo,
+ }
+}
+
+func (tx *ArbitrumRetryTx) chainID() *big.Int { return tx.ArbitrumContractTx.chainID() }
+func (tx *ArbitrumRetryTx) accessList() AccessList { return tx.ArbitrumContractTx.accessList() }
+func (tx *ArbitrumRetryTx) data() []byte { return tx.ArbitrumContractTx.data() }
+func (tx *ArbitrumRetryTx) gas() uint64 { return tx.ArbitrumContractTx.gas() }
+func (tx *ArbitrumRetryTx) gasPrice() *big.Int { return tx.ArbitrumContractTx.gasPrice() }
+func (tx *ArbitrumRetryTx) gasTipCap() *big.Int { return tx.ArbitrumContractTx.gasTipCap() }
+func (tx *ArbitrumRetryTx) gasFeeCap() *big.Int { return tx.ArbitrumContractTx.gasFeeCap() }
+func (tx *ArbitrumRetryTx) value() *big.Int { return tx.ArbitrumContractTx.value() }
+func (tx *ArbitrumRetryTx) nonce() uint64 { return tx.ArbitrumContractTx.nonce() }
+func (tx *ArbitrumRetryTx) to() *common.Address { return tx.ArbitrumContractTx.to() }
+func (tx *ArbitrumRetryTx) rawSignatureValues() (v, r, s *big.Int) {
+ return tx.ArbitrumContractTx.rawSignatureValues()
+}
+func (tx *ArbitrumRetryTx) setSignatureValues(chainID, v, r, s *big.Int) {
+ tx.ArbitrumContractTx.setSignatureValues(chainID, v, r, s)
+}
+func (tx *ArbitrumRetryTx) isFake() bool { return true }
+
+type ArbitrumSubmitRetryableTx struct {
+ ChainId *big.Int
+ RequestId common.Hash
+ From common.Address
+
+ DepositValue *big.Int
+ GasPrice *big.Int // wei per gas
+ Gas uint64 // gas limit
+ To *common.Address `rlp:"nil"` // nil means contract creation
+ Value *big.Int // wei amount
+ Beneficiary common.Address
+ SubmissionFeePaid *big.Int
+ FeeRefundAddr common.Address
+ Data []byte // contract invocation input data
+}
+
+func (tx *ArbitrumSubmitRetryableTx) txType() byte { return ArbitrumSubmitRetryableTxType }
+
+func (tx *ArbitrumSubmitRetryableTx) copy() TxData {
+ cpy := &ArbitrumSubmitRetryableTx{
+ ChainId: new(big.Int),
+ RequestId: tx.RequestId,
+ DepositValue: new(big.Int),
+ GasPrice: new(big.Int),
+ Gas: tx.Gas,
+ From: tx.From,
+ To: tx.To,
+ Value: new(big.Int),
+ Beneficiary: tx.Beneficiary,
+ SubmissionFeePaid: new(big.Int),
+ FeeRefundAddr: tx.FeeRefundAddr,
+ Data: common.CopyBytes(tx.Data),
+ }
+ if tx.ChainId != nil {
+ cpy.ChainId.Set(tx.ChainId)
+ }
+ if tx.DepositValue != nil {
+ cpy.DepositValue.Set(tx.DepositValue)
+ }
+ if tx.GasPrice != nil {
+ cpy.GasPrice.Set(tx.GasPrice)
+ }
+ if tx.To != nil {
+ tmp := *tx.To
+ cpy.To = &tmp
+ }
+ if tx.Value != nil {
+ cpy.Value.Set(tx.Value)
+ }
+ if tx.SubmissionFeePaid != nil {
+ cpy.SubmissionFeePaid.Set(tx.SubmissionFeePaid)
+ }
+ return cpy
+}
+
+func (tx *ArbitrumSubmitRetryableTx) chainID() *big.Int { return tx.ChainId }
+func (tx *ArbitrumSubmitRetryableTx) accessList() AccessList { return nil }
+func (tx *ArbitrumSubmitRetryableTx) data() []byte { return tx.Data }
+func (tx *ArbitrumSubmitRetryableTx) gas() uint64 { return tx.Gas }
+func (tx *ArbitrumSubmitRetryableTx) gasPrice() *big.Int { return tx.GasPrice }
+func (tx *ArbitrumSubmitRetryableTx) gasTipCap() *big.Int { return tx.GasPrice }
+func (tx *ArbitrumSubmitRetryableTx) gasFeeCap() *big.Int { return tx.GasPrice }
+func (tx *ArbitrumSubmitRetryableTx) value() *big.Int { return tx.Value }
+func (tx *ArbitrumSubmitRetryableTx) nonce() uint64 { return 0 }
+func (tx *ArbitrumSubmitRetryableTx) to() *common.Address { return tx.To }
+func (tx *ArbitrumSubmitRetryableTx) rawSignatureValues() (v, r, s *big.Int) {
+ return bigZero, bigZero, bigZero
+}
+func (tx *ArbitrumSubmitRetryableTx) setSignatureValues(chainID, v, r, s *big.Int) {}
+func (tx *ArbitrumSubmitRetryableTx) isFake() bool { return true }
+
type ArbitrumDepositTx struct {
ChainId *big.Int
L1RequestId common.Hash
@@ -159,7 +264,7 @@ func (d *ArbitrumDepositTx) copy() TxData {
func (d *ArbitrumDepositTx) chainID() *big.Int { return d.ChainId }
func (d *ArbitrumDepositTx) accessList() AccessList { return nil }
func (d *ArbitrumDepositTx) data() []byte { return nil }
-func (d ArbitrumDepositTx) gas() uint64 { return 0 }
+func (d *ArbitrumDepositTx) gas() uint64 { return 0 }
func (d *ArbitrumDepositTx) gasPrice() *big.Int { return bigZero }
func (d *ArbitrumDepositTx) gasTipCap() *big.Int { return bigZero }
func (d *ArbitrumDepositTx) gasFeeCap() *big.Int { return bigZero }
diff --git a/core/types/arbitrum_signer.go b/core/types/arbitrum_signer.go
index d9cf4a057782..0b5c4d94ff60 100644
--- a/core/types/arbitrum_signer.go
+++ b/core/types/arbitrum_signer.go
@@ -22,6 +22,10 @@ func (s arbitrumSigner) Sender(tx *Transaction) (common.Address, error) {
return inner.From, nil
case *ArbitrumDepositTx:
return arbAddress, nil
+ case *ArbitrumRetryTx:
+ return inner.From, nil
+ case *ArbitrumSubmitRetryableTx:
+ return inner.From, nil
default:
return s.Signer.Sender(tx)
}
@@ -40,6 +44,10 @@ func (s arbitrumSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *b
return bigZero, bigZero, bigZero, nil
case *ArbitrumDepositTx:
return bigZero, bigZero, bigZero, nil
+ case *ArbitrumRetryTx:
+ return bigZero, bigZero, bigZero, nil
+ case *ArbitrumSubmitRetryableTx:
+ return bigZero, bigZero, bigZero, nil
default:
return s.Signer.SignatureValues(tx, sig)
}
diff --git a/core/types/transaction.go b/core/types/transaction.go
index f9c068cc7aac..95138ba62c73 100644
--- a/core/types/transaction.go
+++ b/core/types/transaction.go
@@ -45,10 +45,12 @@ const (
LegacyTxType = iota
AccessListTxType
DynamicFeeTxType
- ArbitrumDepositTxType = 100
- ArbitrumUnsignedTxType = 101
- ArbitrumContractTxType = 102
- ArbitrumWrappedTxType = 103
+ ArbitrumDepositTxType = 100
+ ArbitrumUnsignedTxType = 101
+ ArbitrumContractTxType = 102
+ ArbitrumWrappedTxType = 103
+ ArbitrumRetryTxType = 104
+ ArbitrumSubmitRetryableTxType = 105
)
// Transaction is an Ethereum transaction.
@@ -201,6 +203,14 @@ func (tx *Transaction) decodeTyped(b []byte, arbParsing bool) (TxData, error) {
var inner ArbitrumWrappedTx
err := rlp.DecodeBytes(b[1:], &inner)
return &inner, err
+ case ArbitrumRetryTxType:
+ var inner ArbitrumRetryTx
+ err := rlp.DecodeBytes(b[1:], &inner)
+ return &inner, err
+ case ArbitrumSubmitRetryableTxType:
+ var inner ArbitrumSubmitRetryableTx
+ err := rlp.DecodeBytes(b[1:], &inner)
+ return &inner, err
}
}
switch b[0] {
@@ -406,6 +416,10 @@ func (tx *Transaction) Hash() common.Hash {
var h common.Hash
if tx.Type() == LegacyTxType {
h = rlpHash(tx.inner)
+ } else if tx.Type() == ArbitrumSubmitRetryableTxType {
+ h = tx.inner.(*ArbitrumSubmitRetryableTx).RequestId // this is required by the retryables API
+ } else if tx.Type() == ArbitrumRetryTxType {
+ h = tx.inner.(*ArbitrumRetryTx).RequestId // for this type, RequestId was initialized with the desired tx hash
} else {
h = prefixedRlpHash(tx.Type(), tx.inner)
}
diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go
index 073a1e7907a3..d5e7b0393a5d 100644
--- a/core/types/transaction_signing.go
+++ b/core/types/transaction_signing.go
@@ -51,7 +51,7 @@ func MakeSigner(config *params.ChainConfig, blockNumber *big.Int) Signer {
default:
signer = FrontierSigner{}
}
- if config.IsArbitrum(blockNumber) {
+ if config.IsArbitrum() {
signer = NewArbitrumSigner(signer)
}
return signer
@@ -277,6 +277,14 @@ func (s eip2930Signer) Sender(tx *Transaction) (common.Address, error) {
// AL txs are defined to use 0 and 1 as their recovery
// id, add 27 to become equivalent to unprotected Homestead signatures.
V = new(big.Int).Add(V, big.NewInt(27))
+ case ArbitrumDepositTxType:
+ return tx.inner.(*ArbitrumDepositTx).To, nil
+ case ArbitrumUnsignedTxType:
+ return tx.inner.(*ArbitrumUnsignedTx).From, nil
+ case ArbitrumContractTxType:
+ return tx.inner.(*ArbitrumContractTx).From, nil
+ case ArbitrumWrappedTxType:
+ return s.Sender(NewTx(tx.inner.(*ArbitrumWrappedTx).TxData))
default:
return common.Address{}, ErrTxTypeNotSupported
}
diff --git a/core/vm/arbitrum_evm.go b/core/vm/arbitrum_evm.go
new file mode 100644
index 000000000000..231085129199
--- /dev/null
+++ b/core/vm/arbitrum_evm.go
@@ -0,0 +1,42 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package vm
+
+type TxProcessingHook interface {
+ StartTxHook() bool
+ GasChargingHook(gasRemaining *uint64) error
+ EndTxHook(totalGasUsed uint64, success bool)
+ NonrefundableGas() uint64
+}
+
+type DefaultTxProcessor struct{}
+
+func (p DefaultTxProcessor) StartTxHook() bool {
+ return false
+}
+
+func (p DefaultTxProcessor) GasChargingHook(gasRemaining *uint64) error {
+ return nil
+}
+
+func (p DefaultTxProcessor) EndTxHook(totalGasUsed uint64, success bool) {
+ return
+}
+
+func (p DefaultTxProcessor) NonrefundableGas() uint64 {
+ return 0
+}
diff --git a/core/vm/evm.go b/core/vm/evm.go
index 5661fdc7e395..c60a99155991 100644
--- a/core/vm/evm.go
+++ b/core/vm/evm.go
@@ -84,9 +84,9 @@ type BlockContext struct {
// All fields can change between transactions.
type TxContext struct {
// Message information
- Origin common.Address // Provides information for ORIGIN
- GasPrice *big.Int // Provides information for GASPRICE
- OriginWasRemapped bool // Arbitrum addition, provides information for ArbSys precopmile
+ Origin common.Address // Provides information for ORIGIN
+ GasPrice *big.Int // Provides information for GASPRICE
+ OriginWasRemapped bool // Arbitrum addition, provides information for ArbSys precopmile
}
// EVM is the Ethereum Virtual Machine base object and provides
@@ -124,18 +124,21 @@ type EVM struct {
// available gas is calculated in gasCall* according to the 63/64 rule and later
// applied in opCall*.
callGasTemp uint64
+
+ ProcessingHook TxProcessingHook
}
// NewEVM returns a new EVM. The returned EVM is not thread safe and should
// only ever be used *once*.
func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig *params.ChainConfig, config Config) *EVM {
evm := &EVM{
- Context: blockCtx,
- TxContext: txCtx,
- StateDB: statedb,
- Config: config,
- chainConfig: chainConfig,
- chainRules: chainConfig.Rules(blockCtx.BlockNumber),
+ Context: blockCtx,
+ TxContext: txCtx,
+ StateDB: statedb,
+ Config: config,
+ chainConfig: chainConfig,
+ chainRules: chainConfig.Rules(blockCtx.BlockNumber),
+ ProcessingHook: DefaultTxProcessor{},
}
evm.interpreter = NewEVMInterpreter(evm, config)
return evm
diff --git a/params/config.go b/params/config.go
index 24f159ccd94c..cf781694321f 100644
--- a/params/config.go
+++ b/params/config.go
@@ -258,16 +258,16 @@ var (
//
// This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields.
- AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, false}
+ AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, EthereumParams()}
// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
// and accepted by the Ethereum core developers into the Clique consensus.
//
// This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields.
- AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, false}
+ AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, EthereumParams()}
- TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, false}
+ TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, EthereumParams()}
TestRules = TestChainConfig.Rules(new(big.Int))
)
@@ -357,7 +357,7 @@ type ChainConfig struct {
Ethash *EthashConfig `json:"ethash,omitempty"`
Clique *CliqueConfig `json:"clique,omitempty"`
- Arbitrum bool `json:"abitrum,omitempty`
+ ArbitrumChainParams ArbitrumChainParams `json:"abitrum,omitempty`
}
// EthashConfig is the consensus engine configs for proof-of-work based sealing.
@@ -485,10 +485,6 @@ func (c *ChainConfig) IsTerminalPoWBlock(parentTotalDiff *big.Int, totalDiff *bi
return parentTotalDiff.Cmp(c.TerminalTotalDifficulty) < 0 && totalDiff.Cmp(c.TerminalTotalDifficulty) >= 0
}
-func (c *ChainConfig) IsArbitrum(_ *big.Int) bool {
- return c.Arbitrum
-}
-
// CheckCompatible checks whether scheduled fork transitions have been imported
// with a mismatching chain configuration.
func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError {
@@ -691,6 +687,6 @@ func (c *ChainConfig) Rules(num *big.Int) Rules {
IsIstanbul: c.IsIstanbul(num),
IsBerlin: c.IsBerlin(num),
IsLondon: c.IsLondon(num),
- IsArbitrum: c.IsArbitrum(num),
+ IsArbitrum: c.IsArbitrum(),
}
}
diff --git a/params/config_arbitrum.go b/params/config_arbitrum.go
new file mode 100644
index 000000000000..1e37c528907b
--- /dev/null
+++ b/params/config_arbitrum.go
@@ -0,0 +1,111 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package params
+
+import (
+ "math/big"
+
+ "github.com/ethereum/go-ethereum/common"
+)
+
+type ArbitrumChainParams struct {
+ EnableArbOS bool
+ AllowDebugPrecompiles bool
+ DataAvailabilityCommittee bool
+}
+
+func (c *ChainConfig) IsArbitrum() bool {
+ return c.ArbitrumChainParams.EnableArbOS
+}
+
+func (c *ChainConfig) DebugMode() bool {
+ return c.ArbitrumChainParams.AllowDebugPrecompiles
+}
+
+func ArbitrumOneParams() ArbitrumChainParams {
+ return ArbitrumChainParams{
+ EnableArbOS: true,
+ AllowDebugPrecompiles: false,
+ DataAvailabilityCommittee: false,
+ }
+}
+
+func ArbitrumTestParams() ArbitrumChainParams {
+ return ArbitrumChainParams{
+ EnableArbOS: true,
+ AllowDebugPrecompiles: true,
+ DataAvailabilityCommittee: false,
+ }
+}
+
+func EthereumParams() ArbitrumChainParams {
+ return ArbitrumChainParams{
+ EnableArbOS: false,
+ AllowDebugPrecompiles: false,
+ DataAvailabilityCommittee: false,
+ }
+}
+
+func ArbitrumOneChainConfig() *ChainConfig {
+ return &ChainConfig{
+ ChainID: big.NewInt(412345),
+ HomesteadBlock: big.NewInt(0),
+ DAOForkBlock: nil,
+ DAOForkSupport: true,
+ EIP150Block: big.NewInt(0),
+ EIP150Hash: common.Hash{},
+ EIP155Block: big.NewInt(0),
+ EIP158Block: big.NewInt(0),
+ ByzantiumBlock: big.NewInt(0),
+ ConstantinopleBlock: big.NewInt(0),
+ PetersburgBlock: big.NewInt(0),
+ IstanbulBlock: big.NewInt(0),
+ MuirGlacierBlock: big.NewInt(0),
+ BerlinBlock: big.NewInt(0),
+ LondonBlock: big.NewInt(0),
+ ArbitrumChainParams: ArbitrumOneParams(),
+ Clique: &CliqueConfig{
+ Period: 0,
+ Epoch: 0,
+ },
+ }
+}
+
+func ArbitrumTestChainConfig() *ChainConfig {
+ return &ChainConfig{
+ ChainID: big.NewInt(412345),
+ HomesteadBlock: big.NewInt(0),
+ DAOForkBlock: nil,
+ DAOForkSupport: true,
+ EIP150Block: big.NewInt(0),
+ EIP150Hash: common.Hash{},
+ EIP155Block: big.NewInt(0),
+ EIP158Block: big.NewInt(0),
+ ByzantiumBlock: big.NewInt(0),
+ ConstantinopleBlock: big.NewInt(0),
+ PetersburgBlock: big.NewInt(0),
+ IstanbulBlock: big.NewInt(0),
+ MuirGlacierBlock: big.NewInt(0),
+ BerlinBlock: big.NewInt(0),
+ LondonBlock: big.NewInt(0),
+ ArbitrumChainParams: ArbitrumTestParams(),
+ Clique: &CliqueConfig{
+ Period: 0,
+ Epoch: 0,
+ },
+ }
+}