From b5750141992f445b66b6e98a6ba37b91fc0c3817 Mon Sep 17 00:00:00 2001 From: Ed Felten Date: Thu, 28 Oct 2021 08:06:29 -0400 Subject: [PATCH 01/23] Add ArbitrumRetryTx type --- core/types/arb_types.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/core/types/arb_types.go b/core/types/arb_types.go index 5d331cf1d29d..b45b309e576a 100644 --- a/core/types/arb_types.go +++ b/core/types/arb_types.go @@ -130,6 +130,28 @@ 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) 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 tx.ArbitrumContractTx.isFake() } + type ArbitrumDepositTx struct { ChainId *big.Int L1RequestId common.Hash From be063734458dcd6eed37bfd733e4d08b8e43709f Mon Sep 17 00:00:00 2001 From: Ed Felten Date: Thu, 28 Oct 2021 16:42:01 -0400 Subject: [PATCH 02/23] Fill out methods and ser/de for ArbRetryTx --- core/types/arb_types.go | 33 +++++++++++++++++++++++++++++++++ core/types/arbitrum_signer.go | 4 ++++ core/types/transaction.go | 5 +++++ 3 files changed, 42 insertions(+) diff --git a/core/types/arb_types.go b/core/types/arb_types.go index b45b309e576a..db598a692c6e 100644 --- a/core/types/arb_types.go +++ b/core/types/arb_types.go @@ -136,6 +136,39 @@ type ArbitrumRetryTx struct { RefundTo common.Address } +func (tx *ArbitrumRetryTx) txType() byte { return ArbitrumRetryTxType } + +func (tx *ArbitrumRetryTx) copy() TxData { + contractTx := ArbitrumContractTx{ + ChainId: new(big.Int), + RequestId: tx.RequestId, + GasPrice: new(big.Int), + Gas: tx.Gas, + From: tx.From, + To: nil, + Value: new(big.Int), + Data: common.CopyBytes(tx.Data), + } + if tx.ChainId != nil { + contractTx.ChainId.Set(tx.ChainId) + } + if tx.GasPrice != nil { + contractTx.GasPrice.Set(tx.GasPrice) + } + if tx.To != nil { + tmp := *tx.To + contractTx.To = &tmp + } + if tx.Value != nil { + contractTx.Value.Set(tx.Value) + } + return &ArbitrumRetryTx{ + contractTx, + 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() } diff --git a/core/types/arbitrum_signer.go b/core/types/arbitrum_signer.go index d9cf4a057782..3f082b55c16b 100644 --- a/core/types/arbitrum_signer.go +++ b/core/types/arbitrum_signer.go @@ -22,6 +22,8 @@ func (s arbitrumSigner) Sender(tx *Transaction) (common.Address, error) { return inner.From, nil case *ArbitrumDepositTx: return arbAddress, nil + case *ArbitrumRetryTx: + return inner.From, nil default: return s.Signer.Sender(tx) } @@ -40,6 +42,8 @@ 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 default: return s.Signer.SignatureValues(tx, sig) } diff --git a/core/types/transaction.go b/core/types/transaction.go index 0271ee4946b3..3b332b68be7c 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -49,6 +49,7 @@ const ( ArbitrumUnsignedTxType = 201 ArbitrumContractTxType = 202 ArbitrumWrappedTxType = 203 + ArbitrumRetryTxType = 204 ) // Transaction is an Ethereum transaction. @@ -201,6 +202,10 @@ 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 } } switch b[0] { From 203d5c4d08408dee8dd4434459c8d9d12649e029 Mon Sep 17 00:00:00 2001 From: Ed Felten Date: Thu, 28 Oct 2021 17:04:27 -0400 Subject: [PATCH 03/23] Add ArbitrumSubmitRetryableTx type --- core/types/arb_types.go | 57 +++++++++++++++++++++++++++++++++++++++ core/types/transaction.go | 5 ++++ 2 files changed, 62 insertions(+) diff --git a/core/types/arb_types.go b/core/types/arb_types.go index db598a692c6e..9fd35e6a3ed5 100644 --- a/core/types/arb_types.go +++ b/core/types/arb_types.go @@ -185,6 +185,63 @@ func (tx *ArbitrumRetryTx) rawSignatureValues() (v, r, s *big.Int) { func (tx *ArbitrumRetryTx) setSignatureValues(chainID, v, r, s *big.Int) { tx.ArbitrumContractTx.setSignatureValues(chainID, v, r, s)} func (tx *ArbitrumRetryTx) isFake() bool { return tx.ArbitrumContractTx.isFake() } +type ArbitrumSubmitRetryableTx struct { + ChainId *big.Int + RequestId common.Hash + From common.Address + + GasPrice *big.Int // wei per gas + Gas uint64 // gas limit + To *common.Address `rlp:"nil"` // nil means contract creation + Value *big.Int // wei amount + 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, + GasPrice: new(big.Int), + Gas: tx.Gas, + From: tx.From, + To: nil, + Value: new(big.Int), + Data: common.CopyBytes(tx.Data), + } + if tx.ChainId != nil { + cpy.ChainId.Set(tx.ChainId) + } + 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) + } + 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 diff --git a/core/types/transaction.go b/core/types/transaction.go index 3b332b68be7c..fdcf8a1f488d 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -50,6 +50,7 @@ const ( ArbitrumContractTxType = 202 ArbitrumWrappedTxType = 203 ArbitrumRetryTxType = 204 + ArbitrumSubmitRetryableTxType = 205 ) // Transaction is an Ethereum transaction. @@ -206,6 +207,10 @@ func (tx *Transaction) decodeTyped(b []byte, arbParsing bool) (TxData, error) { 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] { From a60ab22019a35a584182435d95119f80f5983879 Mon Sep 17 00:00:00 2001 From: Ed Felten Date: Fri, 5 Nov 2021 10:13:02 -0400 Subject: [PATCH 04/23] Add ArbSubmitRetryableTx field and reformat --- core/types/arb_types.go | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/core/types/arb_types.go b/core/types/arb_types.go index 9fd35e6a3ed5..cee050c4eff1 100644 --- a/core/types/arb_types.go +++ b/core/types/arb_types.go @@ -132,8 +132,8 @@ func (tx *ArbitrumContractTx) isFake() bool { re type ArbitrumRetryTx struct { ArbitrumContractTx - TicketId common.Hash - RefundTo common.Address + TicketId common.Hash + RefundTo common.Address } func (tx *ArbitrumRetryTx) txType() byte { return ArbitrumRetryTxType } @@ -182,33 +182,37 @@ func (tx *ArbitrumRetryTx) to() *common.Address { return tx.ArbitrumContractT 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 tx.ArbitrumContractTx.isFake() } +func (tx *ArbitrumRetryTx) setSignatureValues(chainID, v, r, s *big.Int) { + tx.ArbitrumContractTx.setSignatureValues(chainID, v, r, s) +} +func (tx *ArbitrumRetryTx) isFake() bool { return tx.ArbitrumContractTx.isFake() } type ArbitrumSubmitRetryableTx struct { ChainId *big.Int RequestId common.Hash From common.Address - GasPrice *big.Int // wei per gas - Gas uint64 // gas limit - To *common.Address `rlp:"nil"` // nil means contract creation - Value *big.Int // wei amount - Data []byte // contract invocation input data + 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 + 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, - GasPrice: new(big.Int), - Gas: tx.Gas, - From: tx.From, - To: nil, - Value: new(big.Int), - Data: common.CopyBytes(tx.Data), + ChainId: new(big.Int), + RequestId: tx.RequestId, + GasPrice: new(big.Int), + Gas: tx.Gas, + From: tx.From, + To: nil, + Value: new(big.Int), + Beneficiary: tx.Beneficiary, + Data: common.CopyBytes(tx.Data), } if tx.ChainId != nil { cpy.ChainId.Set(tx.ChainId) From 14fb7671185bb682c782f078d9da058ffb1f8a63 Mon Sep 17 00:00:00 2001 From: Ed Felten Date: Mon, 8 Nov 2021 14:13:19 -0500 Subject: [PATCH 05/23] Bug fixes --- core/types/arb_types.go | 2 +- core/types/transaction.go | 14 +++++++------- core/types/transaction_signing.go | 12 ++++++++++++ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/core/types/arb_types.go b/core/types/arb_types.go index cee050c4eff1..6ad744d4202e 100644 --- a/core/types/arb_types.go +++ b/core/types/arb_types.go @@ -275,7 +275,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/transaction.go b/core/types/transaction.go index fdcf8a1f488d..ca48e209bded 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -45,12 +45,12 @@ const ( LegacyTxType = iota AccessListTxType DynamicFeeTxType - ArbitrumDepositTxType = 200 - ArbitrumUnsignedTxType = 201 - ArbitrumContractTxType = 202 - ArbitrumWrappedTxType = 203 - ArbitrumRetryTxType = 204 - ArbitrumSubmitRetryableTxType = 205 + ArbitrumDepositTxType = 100 + ArbitrumUnsignedTxType = 101 + ArbitrumContractTxType = 102 + ArbitrumWrappedTxType = 103 + ArbitrumRetryTxType = 104 + ArbitrumSubmitRetryableTxType = 105 ) // Transaction is an Ethereum transaction. @@ -172,7 +172,7 @@ func (tx *Transaction) UnmarshalBinary(b []byte) error { return nil } // It's an EIP2718 typed transaction envelope. - inner, err := tx.decodeTyped(b, false) + inner, err := tx.decodeTyped(b, true) if err != nil { return err } diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index 073a1e7907a3..0920f72336a8 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -277,6 +277,18 @@ 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)) + case ArbitrumRetryTxType: + return tx.inner.(*ArbitrumRetryTx).From, nil + case ArbitrumSubmitRetryableTxType: + return tx.inner.(*ArbitrumSubmitRetryableTx).From, nil default: return common.Address{}, ErrTxTypeNotSupported } From 12c0cdb4920cc670a0e1506adc81148a2c6a1060 Mon Sep 17 00:00:00 2001 From: Ed Felten Date: Wed, 17 Nov 2021 12:25:19 -0500 Subject: [PATCH 06/23] Add SubmitRetryableTx to case statements --- core/types/arbitrum_signer.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/types/arbitrum_signer.go b/core/types/arbitrum_signer.go index 3f082b55c16b..0b5c4d94ff60 100644 --- a/core/types/arbitrum_signer.go +++ b/core/types/arbitrum_signer.go @@ -24,6 +24,8 @@ func (s arbitrumSigner) Sender(tx *Transaction) (common.Address, error) { return arbAddress, nil case *ArbitrumRetryTx: return inner.From, nil + case *ArbitrumSubmitRetryableTx: + return inner.From, nil default: return s.Signer.Sender(tx) } @@ -44,6 +46,8 @@ func (s arbitrumSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *b 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) } From a2e19f82e4eed71bd34f55953a395dd4154f9c29 Mon Sep 17 00:00:00 2001 From: Ed Felten Date: Fri, 19 Nov 2021 07:28:36 -0500 Subject: [PATCH 07/23] Retryables pass first test --- core/state_transition.go | 4 ++-- core/types/arb_types.go | 38 +++++++++++++++++++++++++------------- core/types/transaction.go | 2 ++ 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/core/state_transition.go b/core/state_transition.go index f8e5fe2d69ef..98bb7fd91bf7 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -33,7 +33,7 @@ import ( var emptyCodeHash = crypto.Keccak256Hash(nil) type TxProcessingHook interface { - InterceptMessage() (*ExecutionResult, error) + StartTxHook() (*ExecutionResult, error) ExtraGasChargingHook(gasRemaining *uint64, gasPool *GasPool) error EndTxHook(totalGasUsed uint64, gasPool *GasPool, success bool) error } @@ -366,7 +366,7 @@ func (st *StateTransition) transitionDbImpl() (*ExecutionResult, error) { func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { if st.processingHook != nil { - res, err := st.processingHook.InterceptMessage() + res, err := st.processingHook.StartTxHook() if res != nil || err != nil { return res, err } diff --git a/core/types/arb_types.go b/core/types/arb_types.go index 6ad744d4202e..512076dd69cd 100644 --- a/core/types/arb_types.go +++ b/core/types/arb_types.go @@ -188,16 +188,19 @@ func (tx *ArbitrumRetryTx) setSignatureValues(chainID, v, r, s *big.Int) { func (tx *ArbitrumRetryTx) isFake() bool { return tx.ArbitrumContractTx.isFake() } type ArbitrumSubmitRetryableTx struct { - ChainId *big.Int - RequestId common.Hash - From common.Address - - 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 - Data []byte // contract invocation input data + 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 } @@ -206,17 +209,23 @@ func (tx *ArbitrumSubmitRetryableTx) copy() TxData { cpy := &ArbitrumSubmitRetryableTx{ ChainId: new(big.Int), RequestId: tx.RequestId, - GasPrice: new(big.Int), + DepositValue: tx.DepositValue, + GasPrice: tx.GasPrice, Gas: tx.Gas, From: tx.From, - To: nil, - Value: new(big.Int), + To: tx.To, + Value: tx.Value, Beneficiary: tx.Beneficiary, + SubmissionFeePaid: tx.SubmissionFeePaid, + 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) } @@ -227,6 +236,9 @@ func (tx *ArbitrumSubmitRetryableTx) copy() TxData { if tx.Value != nil { cpy.Value.Set(tx.Value) } + if tx.SubmissionFeePaid != nil { + cpy.SubmissionFeePaid.Set(tx.SubmissionFeePaid) + } return cpy } diff --git a/core/types/transaction.go b/core/types/transaction.go index ca48e209bded..2a49852ef150 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -422,6 +422,8 @@ 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 } else { h = prefixedRlpHash(tx.Type(), tx.inner) } From 36bcc1d0b82eb08409b02a7367c4e5154d0a707d Mon Sep 17 00:00:00 2001 From: Ed Felten Date: Tue, 23 Nov 2021 12:40:47 -0500 Subject: [PATCH 08/23] Small improvement --- core/types/arb_types.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/types/arb_types.go b/core/types/arb_types.go index 512076dd69cd..de0b72502775 100644 --- a/core/types/arb_types.go +++ b/core/types/arb_types.go @@ -185,7 +185,7 @@ func (tx *ArbitrumRetryTx) rawSignatureValues() (v, r, s *big.Int) { func (tx *ArbitrumRetryTx) setSignatureValues(chainID, v, r, s *big.Int) { tx.ArbitrumContractTx.setSignatureValues(chainID, v, r, s) } -func (tx *ArbitrumRetryTx) isFake() bool { return tx.ArbitrumContractTx.isFake() } +func (tx *ArbitrumRetryTx) isFake() bool { return true } type ArbitrumSubmitRetryableTx struct { ChainId *big.Int From 18b0028b967a4db7d7f67af0ffa785408542849f Mon Sep 17 00:00:00 2001 From: Ed Felten Date: Wed, 24 Nov 2021 08:39:13 -0500 Subject: [PATCH 09/23] Fix tx hashing for retry txs --- core/types/transaction.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/types/transaction.go b/core/types/transaction.go index 2a49852ef150..3bca8865c2d6 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -424,6 +424,8 @@ func (tx *Transaction) Hash() common.Hash { h = rlpHash(tx.inner) } else if tx.Type() == ArbitrumSubmitRetryableTxType { h = tx.inner.(*ArbitrumSubmitRetryableTx).RequestId + } else if tx.Type() == ArbitrumRetryTxType { + h = tx.inner.(*ArbitrumRetryTx).RequestId } else { h = prefixedRlpHash(tx.Type(), tx.inner) } From c4b86e3ff484c017c68d19e2bc3e258dca56c07e Mon Sep 17 00:00:00 2001 From: Ed Felten Date: Wed, 24 Nov 2021 08:45:57 -0500 Subject: [PATCH 10/23] Refactor --- core/types/arb_types.go | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/core/types/arb_types.go b/core/types/arb_types.go index de0b72502775..5d700dfccb1e 100644 --- a/core/types/arb_types.go +++ b/core/types/arb_types.go @@ -139,31 +139,8 @@ type ArbitrumRetryTx struct { func (tx *ArbitrumRetryTx) txType() byte { return ArbitrumRetryTxType } func (tx *ArbitrumRetryTx) copy() TxData { - contractTx := ArbitrumContractTx{ - ChainId: new(big.Int), - RequestId: tx.RequestId, - GasPrice: new(big.Int), - Gas: tx.Gas, - From: tx.From, - To: nil, - Value: new(big.Int), - Data: common.CopyBytes(tx.Data), - } - if tx.ChainId != nil { - contractTx.ChainId.Set(tx.ChainId) - } - if tx.GasPrice != nil { - contractTx.GasPrice.Set(tx.GasPrice) - } - if tx.To != nil { - tmp := *tx.To - contractTx.To = &tmp - } - if tx.Value != nil { - contractTx.Value.Set(tx.Value) - } return &ArbitrumRetryTx{ - contractTx, + *tx.ArbitrumContractTx.copy().(*ArbitrumContractTx), tx.TicketId, tx.RefundTo, } From 8d99bc4c508099d1603bf52efdc2608a4add0e19 Mon Sep 17 00:00:00 2001 From: Rachel Franks Date: Tue, 14 Dec 2021 15:28:48 -0600 Subject: [PATCH 11/23] edit hooks --- arbitrum/apibackend.go | 2 +- core/state_transition.go | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/arbitrum/apibackend.go b/arbitrum/apibackend.go index c8e03fa20f9c..508e4c9741c8 100644 --- a/arbitrum/apibackend.go +++ b/arbitrum/apibackend.go @@ -69,7 +69,7 @@ func (a *APIBackend) SuggestGasTipCap(ctx context.Context) (*big.Int, error) { } func (a *APIBackend) FeeHistory(ctx context.Context, blockCount int, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, error) { - panic("not implemented") // TODO: Implement + return nil, nil, nil, nil, errors.New("not implemented") } func (a *APIBackend) ChainDb() ethdb.Database { diff --git a/core/state_transition.go b/core/state_transition.go index f8e5fe2d69ef..6184b27f1ea9 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -34,8 +34,8 @@ var emptyCodeHash = crypto.Keccak256Hash(nil) type TxProcessingHook interface { InterceptMessage() (*ExecutionResult, error) - ExtraGasChargingHook(gasRemaining *uint64, gasPool *GasPool) error - EndTxHook(totalGasUsed uint64, gasPool *GasPool, success bool) error + ExtraGasChargingHook(gasRemaining *uint64) error + EndTxHook(totalGasUsed uint64, success bool) error } /* @@ -320,7 +320,10 @@ func (st *StateTransition) transitionDbImpl() (*ExecutionResult, error) { st.gas -= gas if st.processingHook != nil { - st.processingHook.ExtraGasChargingHook(&st.gas, st.gp) + err = st.processingHook.ExtraGasChargingHook(&st.gas) + if err != nil { + return nil, err + } } // Check clause 6 @@ -382,7 +385,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { } if err == nil && st.processingHook != nil { - st.processingHook.EndTxHook(st.gas, st.gp, res.Err == nil) + st.processingHook.EndTxHook(st.gas, res.Err == nil) } return res, err } From 13562a66dbb361a18186a6e95a6cf8fa5837f7ec Mon Sep 17 00:00:00 2001 From: Ed Felten Date: Wed, 15 Dec 2021 08:10:41 -0500 Subject: [PATCH 12/23] Address code review comments --- core/types/arb_types.go | 48 +++++++++++++++---------------- core/types/transaction.go | 6 ++-- core/types/transaction_signing.go | 4 --- 3 files changed, 27 insertions(+), 31 deletions(-) diff --git a/core/types/arb_types.go b/core/types/arb_types.go index 5d700dfccb1e..0cc727728753 100644 --- a/core/types/arb_types.go +++ b/core/types/arb_types.go @@ -165,37 +165,37 @@ func (tx *ArbitrumRetryTx) setSignatureValues(chainID, v, r, s *big.Int) { 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 + 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 + 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: tx.DepositValue, - GasPrice: tx.GasPrice, - Gas: tx.Gas, - From: tx.From, - To: tx.To, - Value: tx.Value, - Beneficiary: tx.Beneficiary, - SubmissionFeePaid: tx.SubmissionFeePaid, - FeeRefundAddr: tx.FeeRefundAddr, - Data: common.CopyBytes(tx.Data), + 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) diff --git a/core/types/transaction.go b/core/types/transaction.go index dbfb050a0bf5..95138ba62c73 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -172,7 +172,7 @@ func (tx *Transaction) UnmarshalBinary(b []byte) error { return nil } // It's an EIP2718 typed transaction envelope. - inner, err := tx.decodeTyped(b, true) + inner, err := tx.decodeTyped(b, false) if err != nil { return err } @@ -417,9 +417,9 @@ func (tx *Transaction) Hash() common.Hash { if tx.Type() == LegacyTxType { h = rlpHash(tx.inner) } else if tx.Type() == ArbitrumSubmitRetryableTxType { - h = tx.inner.(*ArbitrumSubmitRetryableTx).RequestId + h = tx.inner.(*ArbitrumSubmitRetryableTx).RequestId // this is required by the retryables API } else if tx.Type() == ArbitrumRetryTxType { - h = tx.inner.(*ArbitrumRetryTx).RequestId + 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 0920f72336a8..3e6e1797d3f1 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -285,10 +285,6 @@ func (s eip2930Signer) Sender(tx *Transaction) (common.Address, error) { return tx.inner.(*ArbitrumContractTx).From, nil case ArbitrumWrappedTxType: return s.Sender(NewTx(tx.inner.(*ArbitrumWrappedTx).TxData)) - case ArbitrumRetryTxType: - return tx.inner.(*ArbitrumRetryTx).From, nil - case ArbitrumSubmitRetryableTxType: - return tx.inner.(*ArbitrumSubmitRetryableTx).From, nil default: return common.Address{}, ErrTxTypeNotSupported } From 39ffcdf8bff090c73a21a3f9a18c861d70eb8a06 Mon Sep 17 00:00:00 2001 From: Rachel Franks Date: Thu, 16 Dec 2021 16:34:23 -0600 Subject: [PATCH 13/23] edit hooks --- core/state_transition.go | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/core/state_transition.go b/core/state_transition.go index 82e3d12e41b6..5aef0a267169 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -33,8 +33,8 @@ import ( var emptyCodeHash = crypto.Keccak256Hash(nil) type TxProcessingHook interface { - InterceptMessage() (*ExecutionResult, error) - ExtraGasChargingHook(gasRemaining *uint64) error + InterceptMessage() *ExecutionResult + GasChargingHook(gasRemaining *uint64, intrinsicGas uint64) error EndTxHook(totalGasUsed uint64, success bool) error } @@ -301,6 +301,11 @@ func (st *StateTransition) transitionDbImpl() (*ExecutionResult, error) { // 5. there is no overflow when calculating intrinsic gas // 6. caller has enough balance to cover asset transfer for **topmost** call + // There are no tips in L2 + if st.gasPrice.Cmp(st.evm.Context.BaseFee) == -1 { + st.gasPrice = st.evm.Context.BaseFee + } + // Check clauses 1-3, buy gas if everything is correct if err := st.preCheck(); err != nil { return nil, err @@ -323,7 +328,7 @@ func (st *StateTransition) transitionDbImpl() (*ExecutionResult, error) { st.gas -= gas if st.processingHook != nil { - err = st.processingHook.ExtraGasChargingHook(&st.gas) + err = st.processingHook.GasChargingHook(&st.gas, gas) if err != nil { return nil, err } @@ -372,9 +377,9 @@ func (st *StateTransition) transitionDbImpl() (*ExecutionResult, error) { func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { if st.processingHook != nil { - res, err := st.processingHook.InterceptMessage() - if res != nil || err != nil { - return res, err + res := st.processingHook.InterceptMessage() + if res != nil { + return res, nil } } res, err := st.transitionDbImpl() From 7796513b75e9658eff9ce47f78276623ac69bc23 Mon Sep 17 00:00:00 2001 From: Rachel Franks Date: Thu, 16 Dec 2021 16:36:43 -0600 Subject: [PATCH 14/23] only set gasPrice to basefee when arbitrum --- core/state_transition.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/state_transition.go b/core/state_transition.go index 5aef0a267169..28a83ecf68d5 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -302,7 +302,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.gasPrice.Cmp(st.evm.Context.BaseFee) == -1 { + if st.evm.ChainConfig().Arbitrum && st.gasPrice.Cmp(st.evm.Context.BaseFee) == -1 { st.gasPrice = st.evm.Context.BaseFee } From 04f6b516c13967f80c7c52881d30e0be94010c9f Mon Sep 17 00:00:00 2001 From: Rachel Franks Date: Thu, 16 Dec 2021 16:44:45 -0600 Subject: [PATCH 15/23] don't pass IntrinsicGas --- core/state_transition.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/state_transition.go b/core/state_transition.go index 28a83ecf68d5..8e7b0d0812f9 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -34,7 +34,7 @@ var emptyCodeHash = crypto.Keccak256Hash(nil) type TxProcessingHook interface { InterceptMessage() *ExecutionResult - GasChargingHook(gasRemaining *uint64, intrinsicGas uint64) error + GasChargingHook(gasRemaining *uint64) error EndTxHook(totalGasUsed uint64, success bool) error } @@ -328,7 +328,7 @@ func (st *StateTransition) transitionDbImpl() (*ExecutionResult, error) { st.gas -= gas if st.processingHook != nil { - err = st.processingHook.GasChargingHook(&st.gas, gas) + err = st.processingHook.GasChargingHook(&st.gas) if err != nil { return nil, err } From e877dadf301b7564a252f98e51f380efeda2061f Mon Sep 17 00:00:00 2001 From: Rachel Franks Date: Tue, 21 Dec 2021 01:15:05 -0600 Subject: [PATCH 16/23] add nonrefundable gas --- core/state_transition.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/core/state_transition.go b/core/state_transition.go index 8e7b0d0812f9..cc1a4e7f9f64 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -36,6 +36,7 @@ type TxProcessingHook interface { InterceptMessage() *ExecutionResult GasChargingHook(gasRemaining *uint64) error EndTxHook(totalGasUsed uint64, success bool) error + NonrefundableGas() uint64 } /* @@ -399,8 +400,17 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { } func (st *StateTransition) refundGas(refundQuotient uint64) { + + var nonrefundable uint64 + if st.processingHook != nil { + nonrefundable = st.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() } From ea48a84848321e69c6648864851d95947ca4e011 Mon Sep 17 00:00:00 2001 From: Rachel Franks Date: Wed, 22 Dec 2021 01:19:39 -0600 Subject: [PATCH 17/23] no tip cap --- arbitrum/apibackend.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum/apibackend.go b/arbitrum/apibackend.go index 1171625d401d..a68922085b20 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 // TODO: Implement } func (a *APIBackend) FeeHistory(ctx context.Context, blockCount int, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, error) { From 60b0022806a37aad525c842a01f9dffb100dfea9 Mon Sep 17 00:00:00 2001 From: Rachel Franks Date: Wed, 22 Dec 2021 17:52:11 -0600 Subject: [PATCH 18/23] hook refactor --- core/state_transition.go | 48 +++++++++++++++------------------------- core/vm/evm.go | 46 ++++++++++++++++++++++++++++++-------- 2 files changed, 55 insertions(+), 39 deletions(-) diff --git a/core/state_transition.go b/core/state_transition.go index cc1a4e7f9f64..db11bf78c802 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -32,13 +32,6 @@ import ( var emptyCodeHash = crypto.Keccak256Hash(nil) -type TxProcessingHook interface { - InterceptMessage() *ExecutionResult - GasChargingHook(gasRemaining *uint64) error - EndTxHook(totalGasUsed uint64, success bool) error - NonrefundableGas() uint64 -} - /* The State Transitioning Model @@ -57,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 @@ -166,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, @@ -328,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 @@ -377,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.InterceptMessage() + 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{ @@ -393,18 +384,15 @@ 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) { - var nonrefundable uint64 - if st.processingHook != nil { - nonrefundable = st.processingHook.NonrefundableGas() - } + nonrefundable := st.evm.ProcessingHook.NonrefundableGas() if nonrefundable >= st.gasUsed() { return } diff --git a/core/vm/evm.go b/core/vm/evm.go index 5661fdc7e395..591434b32b32 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,46 @@ type EVM struct { // available gas is calculated in gasCall* according to the 63/64 rule and later // applied in opCall*. callGasTemp uint64 + + ProcessingHook TxProcessingHook +} + +type TxProcessingHook interface { + InterceptMessage() bool + GasChargingHook(gasRemaining *uint64) error + EndTxHook(totalGasUsed uint64, success bool) error + NonrefundableGas() uint64 +} + +type DefaultTxProcessor struct{} + +func (p DefaultTxProcessor) InterceptMessage() bool { + return false +} + +func (p DefaultTxProcessor) GasChargingHook(gasRemaining *uint64) error { + return nil +} + +func (p DefaultTxProcessor) EndTxHook(totalGasUsed uint64, success bool) error { + return nil +} + +func (p DefaultTxProcessor) NonrefundableGas() uint64 { + return 0 } // 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 From 03987d881c7864757807e908454de2e996b46357 Mon Sep 17 00:00:00 2001 From: Rachel Franks Date: Wed, 22 Dec 2021 19:01:09 -0600 Subject: [PATCH 19/23] mark as done --- arbitrum/apibackend.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum/apibackend.go b/arbitrum/apibackend.go index a68922085b20..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(0), 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) { From 498b60ae06540ed93099af0e656367967983baf7 Mon Sep 17 00:00:00 2001 From: Rachel Franks Date: Wed, 22 Dec 2021 19:24:44 -0600 Subject: [PATCH 20/23] move arbitrum code to its own file --- core/vm/arbitrum_evm.go | 42 +++++++++++++++++++++++++++++++++++++++++ core/vm/evm.go | 25 ------------------------ 2 files changed, 42 insertions(+), 25 deletions(-) create mode 100644 core/vm/arbitrum_evm.go diff --git a/core/vm/arbitrum_evm.go b/core/vm/arbitrum_evm.go new file mode 100644 index 000000000000..ed41d1f7997b --- /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 { + InterceptMessage() bool + GasChargingHook(gasRemaining *uint64) error + EndTxHook(totalGasUsed uint64, success bool) error + NonrefundableGas() uint64 +} + +type DefaultTxProcessor struct{} + +func (p DefaultTxProcessor) InterceptMessage() bool { + return false +} + +func (p DefaultTxProcessor) GasChargingHook(gasRemaining *uint64) error { + return nil +} + +func (p DefaultTxProcessor) EndTxHook(totalGasUsed uint64, success bool) error { + return nil +} + +func (p DefaultTxProcessor) NonrefundableGas() uint64 { + return 0 +} diff --git a/core/vm/evm.go b/core/vm/evm.go index 591434b32b32..c60a99155991 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -128,31 +128,6 @@ type EVM struct { ProcessingHook TxProcessingHook } -type TxProcessingHook interface { - InterceptMessage() bool - GasChargingHook(gasRemaining *uint64) error - EndTxHook(totalGasUsed uint64, success bool) error - NonrefundableGas() uint64 -} - -type DefaultTxProcessor struct{} - -func (p DefaultTxProcessor) InterceptMessage() bool { - return false -} - -func (p DefaultTxProcessor) GasChargingHook(gasRemaining *uint64) error { - return nil -} - -func (p DefaultTxProcessor) EndTxHook(totalGasUsed uint64, success bool) error { - return nil -} - -func (p DefaultTxProcessor) NonrefundableGas() uint64 { - return 0 -} - // 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 { From f796d1a6abc99ff0d4ff668e1213a7dfe2d27a0d Mon Sep 17 00:00:00 2001 From: Rachel Franks Date: Tue, 4 Jan 2022 01:00:12 -0600 Subject: [PATCH 21/23] make EndTxHook infallable --- core/vm/arbitrum_evm.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/vm/arbitrum_evm.go b/core/vm/arbitrum_evm.go index 07a1d9ec869a..231085129199 100644 --- a/core/vm/arbitrum_evm.go +++ b/core/vm/arbitrum_evm.go @@ -19,7 +19,7 @@ package vm type TxProcessingHook interface { StartTxHook() bool GasChargingHook(gasRemaining *uint64) error - EndTxHook(totalGasUsed uint64, success bool) error + EndTxHook(totalGasUsed uint64, success bool) NonrefundableGas() uint64 } @@ -33,8 +33,8 @@ func (p DefaultTxProcessor) GasChargingHook(gasRemaining *uint64) error { return nil } -func (p DefaultTxProcessor) EndTxHook(totalGasUsed uint64, success bool) error { - return nil +func (p DefaultTxProcessor) EndTxHook(totalGasUsed uint64, success bool) { + return } func (p DefaultTxProcessor) NonrefundableGas() uint64 { From 50d16fe17a3f59157d20ce04ac1ae2b69d62a160 Mon Sep 17 00:00:00 2001 From: Rachel Franks Date: Thu, 6 Jan 2022 14:59:58 -0600 Subject: [PATCH 22/23] Arbitrum params --- core/state_transition.go | 2 +- core/types/transaction_signing.go | 2 +- params/config.go | 14 +++----- params/config_arbitrum.go | 55 +++++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 params/config_arbitrum.go diff --git a/core/state_transition.go b/core/state_transition.go index d91ec839052c..efa20edf66ac 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -291,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 } diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index 3e6e1797d3f1..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 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..d6dc81aceabc --- /dev/null +++ b/params/config_arbitrum.go @@ -0,0 +1,55 @@ +// 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 + +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, + } +} From c06d16cafe6fbeda7316fe901dd951b02e687ad5 Mon Sep 17 00:00:00 2001 From: Rachel Franks Date: Thu, 6 Jan 2022 17:28:34 -0600 Subject: [PATCH 23/23] arbitrum chain params --- params/config_arbitrum.go | 56 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/params/config_arbitrum.go b/params/config_arbitrum.go index d6dc81aceabc..1e37c528907b 100644 --- a/params/config_arbitrum.go +++ b/params/config_arbitrum.go @@ -16,6 +16,12 @@ package params +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" +) + type ArbitrumChainParams struct { EnableArbOS bool AllowDebugPrecompiles bool @@ -53,3 +59,53 @@ func EthereumParams() ArbitrumChainParams { 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, + }, + } +}