From ea1da7347eda14d7c5d22cc0fa2294c01817835a Mon Sep 17 00:00:00 2001 From: piersy Date: Fri, 22 Mar 2024 11:00:58 +0000 Subject: [PATCH 1/9] Add list of available rpc apis to the online help (#2287) --- cmd/utils/flags.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 5cf1d561f3..272b68d927 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -521,7 +521,7 @@ var ( } HTTPApiFlag = cli.StringFlag{ Name: "http.api", - Usage: "API's offered over the HTTP-RPC interface", + Usage: "Comma separated list of API's offered over the HTTP-RPC interface choose from admin,debug,eth,istanbul,miner,net,personal,txpool,web3,les,vflux", Value: "", } HTTPPathPrefixFlag = cli.StringFlag{ @@ -574,7 +574,7 @@ var ( } WSApiFlag = cli.StringFlag{ Name: "ws.api", - Usage: "API's offered over the WS-RPC interface", + Usage: "Comma separated list of API's offered over the WS-RPC interface choose from admin,debug,eth,istanbul,miner,net,personal,txpool,web3,les,vflux", Value: "", } WSAllowedOriginsFlag = cli.StringFlag{ From 900eb1ae5749af20024bca30f4d07570ad59b41e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 22 Mar 2024 14:34:58 +0100 Subject: [PATCH 2/9] fix(deps): update module github.com/docker/docker to v24.0.9+incompatible [security] (#2289) Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 6219affceb..88896b6449 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea github.com/deepmap/oapi-codegen v1.8.2 // indirect github.com/dlclark/regexp2 v1.2.0 // indirect - github.com/docker/docker v24.0.7+incompatible + github.com/docker/docker v24.0.9+incompatible github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498 github.com/fatih/color v1.7.0 github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 diff --git a/go.sum b/go.sum index dd05506296..894b847b5b 100644 --- a/go.sum +++ b/go.sum @@ -167,6 +167,8 @@ github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.9+incompatible h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKsAqcl4G0Of9v0= +github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498 h1:Y9vTBSsV4hSwPSj4bacAU/eSnV3dAxVpepaghAdhGoQ= github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= From 272982b71940dae0072523bc69b195620590f841 Mon Sep 17 00:00:00 2001 From: Pastoh Date: Thu, 28 Mar 2024 01:16:10 -0300 Subject: [PATCH 3/9] Celo denominated tx type and implementation (#2278) CIP-66 CELO denominated TX type & implementation (receipt impl still missing) --- accounts/abi/bind/backends/simulated.go | 1 + accounts/external/backend.go | 2 +- common/types.go | 13 -- contracts/erc20gas/erc20gas.go | 14 +- core/error.go | 10 ++ core/state_processor.go | 4 + core/state_transition.go | 79 ++++++++-- core/tx_list.go | 79 ++++++---- core/tx_multicurrency_priceheap.go | 2 +- core/tx_pool.go | 30 +++- core/types/access_list_tx.go | 1 + core/types/celo_denominated_tx.go | 102 ++++++++++++ core/types/celo_dynamic_fee_tx.go | 1 + core/types/celo_dynamic_fee_tx_v2.go | 1 + core/types/dynamic_fee_tx.go | 1 + core/types/legacy_tx.go | 1 + core/types/receipt.go | 5 +- core/types/transaction.go | 31 +++- core/types/transaction_marshalling.go | 78 ++++++++- core/types/transaction_signing.go | 72 +++++++++ e2e_test/e2e_transfer_test.go | 201 +----------------------- graphql/graphql.go | 8 +- interfaces.go | 1 + internal/ethapi/api.go | 34 ++-- internal/ethapi/transaction_args.go | 20 +-- les/odr_test.go | 4 +- light/odr_test.go | 2 +- light/txpool.go | 8 +- signer/core/api.go | 3 +- signer/core/apitypes/types.go | 6 +- tests/state_test_util.go | 2 +- 31 files changed, 511 insertions(+), 305 deletions(-) create mode 100644 core/types/celo_denominated_tx.go diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index a9454e311d..f9602bbddf 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -831,6 +831,7 @@ func (m callMsg) GasPrice() *big.Int { return m.CallMsg.GasPri func (m callMsg) GasFeeCap() *big.Int { return m.CallMsg.GasFeeCap } func (m callMsg) GasTipCap() *big.Int { return m.CallMsg.GasTipCap } func (m callMsg) FeeCurrency() *common.Address { return m.CallMsg.FeeCurrency } +func (m callMsg) MaxFeeInFeeCurrency() *big.Int { return m.CallMsg.MaxFeeInFeeCurrency } func (m callMsg) GatewayFeeRecipient() *common.Address { return m.CallMsg.GatewayFeeRecipient } func (m callMsg) GatewaySet() bool { return m.CallMsg.GatewayFeeRecipient != nil || (m.CallMsg.GatewayFee != nil && m.CallMsg.GatewayFee.Sign() != 0) diff --git a/accounts/external/backend.go b/accounts/external/backend.go index f73d2aad8e..5cc4d93051 100644 --- a/accounts/external/backend.go +++ b/accounts/external/backend.go @@ -223,7 +223,7 @@ func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transactio switch tx.Type() { case types.LegacyTxType, types.AccessListTxType: args.GasPrice = (*hexutil.Big)(tx.GasPrice()) - case types.DynamicFeeTxType, types.CeloDynamicFeeTxType, types.CeloDynamicFeeTxV2Type: + case types.DynamicFeeTxType, types.CeloDynamicFeeTxType, types.CeloDynamicFeeTxV2Type, types.CeloDenominatedTxType: args.MaxFeePerGas = (*hexutil.Big)(tx.GasFeeCap()) args.MaxPriorityFeePerGas = (*hexutil.Big)(tx.GasTipCap()) default: diff --git a/common/types.go b/common/types.go index 7192433e36..c2cde9959f 100644 --- a/common/types.go +++ b/common/types.go @@ -442,16 +442,3 @@ func (ma *MixedcaseAddress) ValidChecksum() bool { func (ma *MixedcaseAddress) Original() string { return ma.original } - -func AreSameAddress(a, b *Address) bool { - // both are nil or point to the same address - if a == b { - return true - } - // if only one is nil - if a == nil || b == nil { - return false - } - // if they point to the same - return *a == *b -} diff --git a/contracts/erc20gas/erc20gas.go b/contracts/erc20gas/erc20gas.go index 910baf7fef..34b50af0f1 100644 --- a/contracts/erc20gas/erc20gas.go +++ b/contracts/erc20gas/erc20gas.go @@ -7,6 +7,7 @@ import ( "github.com/celo-org/celo-blockchain/accounts/abi" "github.com/celo-org/celo-blockchain/common" "github.com/celo-org/celo-blockchain/common/hexutil" + "github.com/celo-org/celo-blockchain/contracts/currency" "github.com/celo-org/celo-blockchain/contracts/internal/n" "github.com/celo-org/celo-blockchain/core/types" "github.com/celo-org/celo-blockchain/core/vm" @@ -27,12 +28,17 @@ var ( // Returns nil if debit is possible, used in tx pool validation func TryDebitFees(tx *types.Transaction, from common.Address, currentVMRunner vm.EVMRunner) error { - cost := new(big.Int).SetUint64(tx.Gas()) - cost.Mul(cost, tx.GasFeeCap()) - + var fee *big.Int = tx.Fee() + if tx.Type() == types.CeloDenominatedTxType { + rate, err := currency.GetExchangeRate(currentVMRunner, tx.FeeCurrency()) + if err != nil { + return err + } + fee = rate.FromBase(fee) + } // The following code is similar to DebitFees, but that function does not work on a vm.EVMRunner, // so we have to adapt it instead of reusing. - transactionData := common.GetEncodedAbi(debitGasFeesSelector, [][]byte{common.AddressToAbi(from), common.AmountToAbi(cost)}) + transactionData := common.GetEncodedAbi(debitGasFeesSelector, [][]byte{common.AddressToAbi(from), common.AmountToAbi(fee)}) ret, err := currentVMRunner.ExecuteAndDiscardChanges(*tx.FeeCurrency(), transactionData, maxGasForDebitGasFeesTransactions, common.Big0) if err != nil { diff --git a/core/error.go b/core/error.go index e968ec9ad5..f5515dd858 100644 --- a/core/error.go +++ b/core/error.go @@ -121,4 +121,14 @@ var ( // ErrGatewayFeeDeprecated is returned when a transaction containing a gateway fee is encountered after the // G hardfork ErrGatewayFeeDeprecated = errors.New("gateway fee is deprecated") + + // ErrDenominatedNoMax is returned when a transaction containing a fee currency has no maxFeeInFeeCurrency set. + ErrDenominatedNoMax = errors.New("CELO denominated tx has no maxFeeInFeeCurrency") + + // ErrDenominatedNoCurrency is returned when a celo-denominated transaction has no fee currency set + ErrDenominatedNoCurrency = errors.New("CELO denominated tx has no fee currency") + + // ErrDenominatedLowMaxFee is returned when a celo denominated transaction, with the current exchange rate, + // the MaxFeeInFeeCurrency cannot cover the tx.Fee() + ErrDenominatedLowMaxFee = errors.New("CELO denominated tx MaxFeeInCurrency cannot cover gas fee costs") ) diff --git a/core/state_processor.go b/core/state_processor.go index 089927b866..c0fa3663d5 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -141,6 +141,10 @@ func applyTransaction(msg types.Message, config *params.ChainConfig, gp *GasPool return nil, ErrTxTypeNotSupported } + if tx.Type() == types.CeloDenominatedTxType && !config.IsHFork(blockNumber) { + return nil, ErrTxTypeNotSupported + } + // Create a new context to be used in the EVM environment txContext := NewEVMTxContext(msg) evm.Reset(txContext, statedb) diff --git a/core/state_transition.go b/core/state_transition.go index 041f66e08d..3441ac9b1a 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -74,6 +74,7 @@ type StateTransition struct { vmRunner vm.EVMRunner gasPriceMinimum *big.Int sysCtx *SysContractCallCtx + erc20FeeDebited *big.Int } // Message represents a message sent to a contract. @@ -86,10 +87,12 @@ type Message interface { GasTipCap() *big.Int Gas() uint64 - // FeeCurrency specifies the currency for gas and gateway fees. + // FeeCurrency specifies the currency from which to pay for the fees // nil correspond to Celo Gold (native currency). // All other values should correspond to ERC20 contract addresses extended to be compatible with gas payments. FeeCurrency() *common.Address + // MaxFeeInFeeCurrency Set iff it's a celo denominated tx. Maximum value of fees when converted to FeeCurrency. + MaxFeeInFeeCurrency() *big.Int GatewayFeeRecipient() *common.Address GatewayFee() *big.Int GatewaySet() bool @@ -214,7 +217,12 @@ func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation b func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool, vmRunner vm.EVMRunner, sysCtx *SysContractCallCtx) *StateTransition { var gasPriceMinimum *big.Int if evm.ChainConfig().IsEspresso(evm.Context.BlockNumber) { - gasPriceMinimum = sysCtx.GetGasPriceMinimum(msg.FeeCurrency()) + var feeCurrency *common.Address = msg.FeeCurrency() + if msg.MaxFeeInFeeCurrency() != nil { + // Celo denominated tx + feeCurrency = nil + } + gasPriceMinimum = sysCtx.GetGasPriceMinimum(feeCurrency) } else { gasPriceMinimum, _ = gpm.GetBaseFeeForCurrency(vmRunner, msg.FeeCurrency(), nil) } @@ -256,7 +264,7 @@ func (st *StateTransition) to() common.Address { } // payFees deducts gas and gateway fees from sender balance and adds the purchased amount of gas to the state. -func (st *StateTransition) payFees(espresso bool) error { +func (st *StateTransition) payFees(espresso bool, feeCurrencyRate *currency.ExchangeRate) error { var isWhiteListed bool if espresso { isWhiteListed = st.sysCtx.IsWhitelisted(st.msg.FeeCurrency()) @@ -267,8 +275,7 @@ func (st *StateTransition) payFees(espresso bool) error { log.Trace("Fee currency not whitelisted", "fee currency address", st.msg.FeeCurrency()) return ErrNonWhitelistedFeeCurrency } - - if err := st.canPayFee(st.msg.From(), st.msg.FeeCurrency(), espresso); err != nil { + if err := st.canPayFee(st.msg.From(), st.msg.FeeCurrency(), espresso, feeCurrencyRate); err != nil { return err } if err := st.gp.SubGas(st.msg.Gas()); err != nil { @@ -277,7 +284,7 @@ func (st *StateTransition) payFees(espresso bool) error { st.initialGas = st.msg.Gas() st.gas += st.msg.Gas() - err := st.debitFee(st.msg.From(), st.msg.FeeCurrency()) + err := st.debitFee(st.msg.From(), st.msg.FeeCurrency(), feeCurrencyRate) return err } @@ -290,7 +297,7 @@ func (st *StateTransition) payFees(espresso bool) error { // For non-native tokens(cUSD, cEUR, ...) as feeCurrency: // - Pre-Espresso: it ensures balance > GasPrice * gas + gatewayFee (3) // - Post-Espresso: it ensures balance >= GasFeeCap * gas + gatewayFee (4) -func (st *StateTransition) canPayFee(accountOwner common.Address, feeCurrency *common.Address, espresso bool) error { +func (st *StateTransition) canPayFee(accountOwner common.Address, feeCurrency *common.Address, espresso bool, feeCurrencyRate *currency.ExchangeRate) error { if feeCurrency == nil { balance := st.state.GetBalance(st.msg.From()) if espresso { @@ -323,12 +330,22 @@ func (st *StateTransition) canPayFee(accountOwner common.Address, feeCurrency *c return err } if espresso { + var feeGap *big.Int // feeGap = GasFeeCap * gas + gatewayFee, as in (4) - feeGap := new(big.Int).SetUint64(st.msg.Gas()) + feeGap = new(big.Int).SetUint64(st.msg.Gas()) feeGap.Mul(feeGap, st.gasFeeCap) if st.msg.GatewayFeeRecipient() != nil { feeGap.Add(feeGap, st.msg.GatewayFee()) } + if st.msg.MaxFeeInFeeCurrency() != nil { + // Celo Denominated Tx: max fee is a tx field + // Translate fees to feeCurrency + feeGap = feeCurrencyRate.FromBase(feeGap) + // Check that fee <= MaxFeeInFeeCurrency + if feeGap.Cmp(st.msg.MaxFeeInFeeCurrency()) > 0 { + return ErrDenominatedLowMaxFee + } + } if balance.Cmp(feeGap) < 0 { return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From().Hex(), balance, feeGap) } @@ -346,7 +363,7 @@ func (st *StateTransition) canPayFee(accountOwner common.Address, feeCurrency *c return nil } -func (st *StateTransition) debitFee(from common.Address, feeCurrency *common.Address) (err error) { +func (st *StateTransition) debitFee(from common.Address, feeCurrency *common.Address, feeCurrencyRate *currency.ExchangeRate) (err error) { if st.evm.Config.SkipDebitCredit { return nil } @@ -361,7 +378,16 @@ func (st *StateTransition) debitFee(from common.Address, feeCurrency *common.Add st.state.SubBalance(from, effectiveFee) return nil } else { - return erc20gas.DebitFees(st.evm, from, effectiveFee, feeCurrency) + var currencyFee *big.Int + if st.msg.MaxFeeInFeeCurrency() == nil { + // Normal feeCurrency tx + currencyFee = effectiveFee + } else { + // Celo denominated tx + currencyFee = feeCurrencyRate.FromBase(effectiveFee) + } + st.erc20FeeDebited = currencyFee + return erc20gas.DebitFees(st.evm, from, currencyFee, feeCurrency) } } @@ -450,6 +476,16 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { if st.evm.ChainConfig().IsGingerbread(st.evm.Context.BlockNumber) && st.msg.GatewaySet() { return nil, ErrGatewayFeeDeprecated } + if !st.evm.ChainConfig().IsHFork(st.evm.Context.BlockNumber) && st.msg.MaxFeeInFeeCurrency() != nil { + return nil, ErrTxTypeNotSupported + } + if st.msg.FeeCurrency() == nil && st.msg.MaxFeeInFeeCurrency() != nil { + return nil, ErrDenominatedNoCurrency + } + feeCurrencyRate, err := currency.GetExchangeRate(st.vmRunner, st.msg.FeeCurrency()) + if err != nil { + return nil, err + } // Check clauses 1-2 if err := st.preCheck(); err != nil { @@ -481,7 +517,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.msg.Gas(), gas) } // Check clauses 3-4, pay the fees (which buys gas), and subtract the intrinsic gas - err = st.payFees(espresso) + err = st.payFees(espresso, feeCurrencyRate) if err != nil { log.Error("Transaction failed to buy gas", "err", err, "gas", gas) return nil, err @@ -517,7 +553,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { st.refundGas(params.RefundQuotientEIP3529) } - err = st.creditTxFees() + err = st.creditTxFees(feeCurrencyRate) if err != nil { return nil, err } @@ -529,7 +565,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { } // creditTxFees calculates the amounts and recipients of transaction fees and credits the accounts. -func (st *StateTransition) creditTxFees() error { +func (st *StateTransition) creditTxFees(feeCurrencyRate *currency.ExchangeRate) error { if st.evm.Config.SkipDebitCredit { return nil } @@ -551,6 +587,23 @@ func (st *StateTransition) creditTxFees() error { // No need to do effectiveTip calculation, because st.gasPrice == effectiveGasPrice, and effectiveTip = effectiveGasPrice - baseTxFee tipTxFee := new(big.Int).Sub(totalTxFee, baseTxFee) + if st.msg.MaxFeeInFeeCurrency() != nil { + // Celo Denominated + + // We want to ensure that + // st.erc20FeeDebited = tipTxFee + baseTxFee + refund + // so that debit and credit totals match. Since the exchange rate + // conversions have limited accuracy, the only way to achieve this + // is to calculate one of the three credit values based on the two + // others after the exchange rate conversion. + tipTxFee = feeCurrencyRate.FromBase(tipTxFee) + baseTxFee = feeCurrencyRate.FromBase(baseTxFee) + totalTxFee.Add(tipTxFee, baseTxFee) + refund.Sub(st.erc20FeeDebited, totalTxFee) // refund = debited - tip - basefee + // No need to exchange gateway fee since it's it's deprecated on G fork, + // and MaxFeeInFeeCurrency can only be present in H fork (which implies G fork) + } + feeCurrency := st.msg.FeeCurrency() gatewayFeeRecipient := st.msg.GatewayFeeRecipient() diff --git a/core/tx_list.go b/core/tx_list.go index 23caa2b9ba..4fa01bd6b3 100644 --- a/core/tx_list.go +++ b/core/tx_list.go @@ -254,11 +254,9 @@ type txList struct { strict bool // Whether nonces are strictly continuous or not txs *txSortedMap // Heap indexed sorted hash map of the transactions - nativecostcap *big.Int // Price of the highest costing transaction paid with native fees (reset only if exceeds balance) - feecaps map[common.Address]*big.Int // Price of the highest costing transaction per fee currency (reset only if exceeds balance) - nativegaspricefloor *big.Int // Lowest gas price minimum in the native currency - gaspricefloors map[common.Address]*big.Int // Lowest gas price minimum per currency (reset only if it is below the gpm) - gascap uint64 // Gas limit of the highest spending transaction (reset only if exceeds block limit) + nativecostcap *big.Int // Price of the highest costing transaction paid with native fees (reset only if exceeds balance) + feecaps map[common.Address]*big.Int // Price of the highest costing transaction per fee currency (reset only if exceeds balance) + gascap uint64 // Gas limit of the highest spending transaction (reset only if exceeds block limit) ctx *atomic.Value // transaction pool context } @@ -267,13 +265,11 @@ type txList struct { // gapped, sortable transaction lists. func newTxList(strict bool, ctx *atomic.Value) *txList { return &txList{ - ctx: ctx, - strict: strict, - txs: newTxSortedMap(), - nativecostcap: new(big.Int), - feecaps: make(map[common.Address]*big.Int), - nativegaspricefloor: nil, - gaspricefloors: make(map[common.Address]*big.Int), + ctx: ctx, + strict: strict, + txs: newTxSortedMap(), + nativecostcap: new(big.Int), + feecaps: make(map[common.Address]*big.Int), } } @@ -292,6 +288,17 @@ func (l *txList) FeeCurrencies() []common.Address { return feeCurrencies } +func toCurrency(celoAmount *big.Int, feeCurrency *common.Address, txCtx *txPoolContext) (*big.Int, error) { + if feeCurrency == nil { + return celoAmount, nil + } + currency, err := txCtx.GetCurrency(feeCurrency) + if err != nil { + return nil, err + } + return currency.FromCELO(celoAmount), nil +} + func toCELO(amount *big.Int, feeCurrency *common.Address, txCtx *txPoolContext) (*big.Int, error) { if feeCurrency == nil { return amount, nil @@ -316,7 +323,7 @@ func (l *txList) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Tran var newGasFeeCap, newGasTipCap *big.Int // Short circuit conversion if both are the same currency - if common.AreSameAddress(old.FeeCurrency(), tx.FeeCurrency()) { + if common.AreEqualAddresses(old.DenominatedFeeCurrency(), tx.DenominatedFeeCurrency()) { if old.GasFeeCapCmp(tx) >= 0 || old.GasTipCapCmp(tx) >= 0 { return false, nil } @@ -325,19 +332,19 @@ func (l *txList) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Tran newGasFeeCap = tx.GasFeeCap() newGasTipCap = tx.GasTipCap() } else { + txCtx := l.ctx.Load().(txPoolContext) // Convert old values into tx fee currency var err error - txCtx := l.ctx.Load().(txPoolContext) - if oldGasFeeCap, err = toCELO(old.GasFeeCap(), old.FeeCurrency(), &txCtx); err != nil { + if oldGasFeeCap, err = toCELO(old.GasFeeCap(), old.DenominatedFeeCurrency(), &txCtx); err != nil { return false, nil } - if oldGasTipCap, err = toCELO(old.GasTipCap(), old.FeeCurrency(), &txCtx); err != nil { + if oldGasTipCap, err = toCELO(old.GasTipCap(), old.DenominatedFeeCurrency(), &txCtx); err != nil { return false, nil } - if newGasFeeCap, err = toCELO(tx.GasFeeCap(), tx.FeeCurrency(), &txCtx); err != nil { + if newGasFeeCap, err = toCELO(tx.GasFeeCap(), tx.DenominatedFeeCurrency(), &txCtx); err != nil { return false, nil } - if newGasTipCap, err = toCELO(tx.GasTipCap(), tx.FeeCurrency(), &txCtx); err != nil { + if newGasTipCap, err = toCELO(tx.GasTipCap(), tx.DenominatedFeeCurrency(), &txCtx); err != nil { return false, nil } @@ -366,17 +373,21 @@ func (l *txList) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Tran if cost := tx.Cost(); l.nativecostcap.Cmp(cost) < 0 { l.nativecostcap = cost } - if gasPrice := tx.GasPrice(); l.nativegaspricefloor == nil || l.nativegaspricefloor.Cmp(gasPrice) > 0 { - l.nativegaspricefloor = gasPrice - } } else { - fee := tx.Fee() + var fee *big.Int = tx.Fee() + if tx.Type() == types.CeloDenominatedTxType { + txCtx := l.ctx.Load().(txPoolContext) + var err error + fee, err = toCurrency(fee, feeCurrency, &txCtx) + if err != nil { + log.Error("Can't get rate for currency: ", "currency", feeCurrency.Hex(), "err", err) + // Can't get rate, don't accept tx + return false, nil + } + } if oldFee, ok := l.feecaps[*feeCurrency]; !ok || oldFee.Cmp(fee) < 0 { l.feecaps[*feeCurrency] = fee } - if gasFloor, ok := l.gaspricefloors[*feeCurrency]; !ok || gasFloor.Cmp(tx.GasPrice()) > 0 { - l.gaspricefloors[*feeCurrency] = tx.GasPrice() - } if value := tx.Value(); l.nativecostcap.Cmp(value) < 0 { l.nativecostcap = value } @@ -436,16 +447,30 @@ func (l *txList) Filter(nativeCostLimit *big.Int, feeLimits map[common.Address]* return tx.Cost().Cmp(nativeCostLimit) > 0 || tx.Gas() > gasLimit || txCtx.celoGasPriceMinimumFloor.Cmp(tx.GasPrice()) > 0 } else { feeLimit := feeLimits[*feeCurrency] - fee := tx.Fee() + var fee *big.Int = tx.Fee() log.Trace("Transaction Filter", "hash", tx.Hash(), "Fee currency", tx.FeeCurrency(), "Value", tx.Value(), "Cost Limit", feeLimit, "Gas", tx.Gas(), "Gas Limit", gasLimit) + if tx.Type() == types.CeloDenominatedTxType { + var err error + fee, err = toCurrency(fee, feeCurrency, &txCtx) + if err != nil { + log.Error("Can't get rate for currency: ", "currency", feeCurrency.Hex(), "err", err) + // Can't get rate, remove tx + return true + } + // Celo denominated tx fee is over maxFeeInFeeCurrency + if fee.Cmp(tx.MaxFeeInFeeCurrency()) > 0 { + return true + } + } + // If any of the following is true, the transaction is invalid // The fees are greater than or equal to the balance in the currency return fee.Cmp(feeLimit) >= 0 || // The value of the tx is greater than the native balance of the account tx.Value().Cmp(nativeCostLimit) > 0 || // The gas price is smaller that the gasPriceMinimumFloor - txCtx.CmpValues(txCtx.celoGasPriceMinimumFloor, nil, tx.GasPrice(), tx.FeeCurrency()) > 0 || + txCtx.CmpValues(txCtx.celoGasPriceMinimumFloor, nil, tx.GasPrice(), tx.DenominatedFeeCurrency()) > 0 || // The gas used is greater than the gas limit tx.Gas() > gasLimit } diff --git a/core/tx_multicurrency_priceheap.go b/core/tx_multicurrency_priceheap.go index 5a809179c7..9bb3e89f11 100644 --- a/core/tx_multicurrency_priceheap.go +++ b/core/tx_multicurrency_priceheap.go @@ -73,7 +73,7 @@ func newMultiCurrencyPriceHeap(currencyCmp CurrencyCmpFn, gpm GasPriceMinimums) // if it's not available in the currencyHeaps func (h *multiCurrencyPriceHeap) getHeapFor(tx *types.Transaction) *priceHeap { fc := tx.FeeCurrency() - if fc == nil { + if fc == nil || tx.Type() == types.CeloDenominatedTxType { return h.nativeCurrencyHeap } if _, ok := h.currencyHeaps[*fc]; !ok { diff --git a/core/tx_pool.go b/core/tx_pool.go index e39491fa5f..a2df0ec9dc 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -279,6 +279,7 @@ type TxPool struct { espresso bool // Fork indicator for the Espresso fork. gingerbread bool // Fork indicator for the Gingerbread fork. gingerbreadP2 bool // Fork indicator for the Gingerbread P2 fork. + hfork bool // Fork indicator for the HFork. currentState *state.StateDB // Current state in the blockchain head currentVMRunner vm.EVMRunner // Current EVMRunner @@ -679,6 +680,10 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { if !pool.gingerbreadP2 && tx.Type() == types.CeloDynamicFeeTxV2Type { return ErrTxTypeNotSupported } + // Reject celo denominated fee until h fork + if !pool.hfork && tx.Type() == types.CeloDenominatedTxType { + return ErrTxTypeNotSupported + } // Reject transactions over defined size to prevent DOS attacks if uint64(tx.Size()) > txMaxSize { return ErrOversizedData @@ -715,8 +720,22 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { return ErrNonWhitelistedFeeCurrency } + // Celo denominated checks + if tx.Type() == types.CeloDenominatedTxType { + if tx.FeeCurrency() == nil { + return ErrDenominatedNoCurrency + } + if tx.MaxFeeInFeeCurrency() == nil { + return ErrDenominatedNoMax + } + // Celo denominated tx fee is over maxFeeInFeeCurrency + if pool.ctx().CmpValues(tx.Fee(), nil, tx.MaxFeeInFeeCurrency(), tx.FeeCurrency()) > 0 { + return ErrDenominatedLowMaxFee + } + } + // Drop non-local transactions under our own minimal accepted gas price or tip - if !local && pool.ctx().CmpValues(tx.GasTipCap(), tx.FeeCurrency(), pool.gasPrice, nil) < 0 { + if !local && pool.ctx().CmpValues(tx.GasTipCap(), tx.DenominatedFeeCurrency(), pool.gasPrice, nil) < 0 { return ErrUnderpriced } // Ensure the transaction adheres to nonce ordering @@ -741,7 +760,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { } ctx := pool.currentCtx.Load().(txPoolContext) - if ctx.CmpValues(ctx.celoGasPriceMinimumFloor, nil, tx.GasPrice(), tx.FeeCurrency()) > 0 { + if ctx.CmpValues(ctx.celoGasPriceMinimumFloor, nil, tx.GasPrice(), tx.DenominatedFeeCurrency()) > 0 { log.Debug("gasPrice less than the minimum floor", "gasPrice", tx.GasPrice(), "feeCurrency", tx.FeeCurrency(), "gasPriceMinimumFloor (Celo)", ctx.celoGasPriceMinimumFloor) return ErrGasPriceDoesNotExceedMinimumFloor } @@ -1425,6 +1444,7 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) { pool.espresso = pool.chainconfig.IsEspresso(next) pool.gingerbread = pool.chainconfig.IsGingerbread(next) pool.gingerbreadP2 = pool.chainconfig.IsGingerbreadP2(next) + pool.hfork = pool.chainconfig.IsHFork(next) } // promoteExecutables moves transactions that have become processable from the @@ -1729,9 +1749,7 @@ func ValidateTransactorBalanceCoversTx(tx *types.Transaction, from common.Addres balance := currentState.GetBalance(from) // cost = GasFeeCap * gas + value - cost := new(big.Int).SetUint64(tx.Gas()) - cost.Mul(cost, tx.GasFeeCap()) - cost.Add(cost, tx.Value()) + cost := tx.Cost() if balance.Cmp(cost) < 0 { log.Debug("ValidateTransactorBalanceCoversTx: insufficient CELO funds", @@ -1996,7 +2014,7 @@ func (t *txLookup) RemoteToLocals(locals *accountSet) int { func (t *txLookup) RemotesBelowTip(threshold *big.Int, txCtx *txPoolContext) types.Transactions { found := make(types.Transactions, 0, 128) t.Range(func(hash common.Hash, tx *types.Transaction, local bool) bool { - curr, _ := txCtx.GetCurrency(tx.FeeCurrency()) + curr, _ := txCtx.GetCurrency(tx.DenominatedFeeCurrency()) if tx.GasTipCapIntCmp(curr.FromCELO(threshold)) < 0 { found = append(found, tx) } diff --git a/core/types/access_list_tx.go b/core/types/access_list_tx.go index 1abb995b49..0474219f10 100644 --- a/core/types/access_list_tx.go +++ b/core/types/access_list_tx.go @@ -119,3 +119,4 @@ func (tx *AccessListTx) feeCurrency() *common.Address { return nil } func (tx *AccessListTx) gatewayFeeRecipient() *common.Address { return nil } func (tx *AccessListTx) gatewayFee() *big.Int { return nil } func (tx *AccessListTx) ethCompatible() bool { return false } +func (tx *AccessListTx) maxFeeInFeeCurrency() *big.Int { return nil } diff --git a/core/types/celo_denominated_tx.go b/core/types/celo_denominated_tx.go new file mode 100644 index 0000000000..140e7b8b65 --- /dev/null +++ b/core/types/celo_denominated_tx.go @@ -0,0 +1,102 @@ +package types + +import ( + "errors" + "math/big" + + "github.com/celo-org/celo-blockchain/common" +) + +var ( + ErrNonCeloDenominated error = errors.New("Tx not CeloDenominated") +) + +type CeloDenominatedTx struct { + ChainID *big.Int + Nonce uint64 + GasTipCap *big.Int + GasFeeCap *big.Int + Gas uint64 + FeeCurrency *common.Address `rlp:"nil"` // nil means native currency + To *common.Address `rlp:"nil"` // nil means contract creation + Value *big.Int + Data []byte + AccessList AccessList + MaxFeeInFeeCurrency *big.Int + + // Signature values + V *big.Int `json:"v" gencodec:"required"` + R *big.Int `json:"r" gencodec:"required"` + S *big.Int `json:"s" gencodec:"required"` +} + +// copy creates a deep copy of the transaction data and initializes all fields. +func (tx *CeloDenominatedTx) copy() TxData { + cpy := &CeloDenominatedTx{ + Nonce: tx.Nonce, + To: copyAddressPtr(tx.To), + Data: common.CopyBytes(tx.Data), + Gas: tx.Gas, + FeeCurrency: copyAddressPtr(tx.FeeCurrency), + // These are copied below. + AccessList: make(AccessList, len(tx.AccessList)), + Value: new(big.Int), + ChainID: new(big.Int), + GasTipCap: new(big.Int), + GasFeeCap: new(big.Int), + V: new(big.Int), + R: new(big.Int), + S: new(big.Int), + } + copy(cpy.AccessList, tx.AccessList) + if tx.Value != nil { + cpy.Value.Set(tx.Value) + } + if tx.ChainID != nil { + cpy.ChainID.Set(tx.ChainID) + } + if tx.GasTipCap != nil { + cpy.GasTipCap.Set(tx.GasTipCap) + } + if tx.GasFeeCap != nil { + cpy.GasFeeCap.Set(tx.GasFeeCap) + } + if tx.V != nil { + cpy.V.Set(tx.V) + } + if tx.R != nil { + cpy.R.Set(tx.R) + } + if tx.S != nil { + cpy.S.Set(tx.S) + } + return cpy +} + +// accessors for innerTx. +func (tx *CeloDenominatedTx) txType() byte { return CeloDenominatedTxType } +func (tx *CeloDenominatedTx) chainID() *big.Int { return tx.ChainID } +func (tx *CeloDenominatedTx) protected() bool { return true } +func (tx *CeloDenominatedTx) accessList() AccessList { return tx.AccessList } +func (tx *CeloDenominatedTx) data() []byte { return tx.Data } +func (tx *CeloDenominatedTx) gas() uint64 { return tx.Gas } +func (tx *CeloDenominatedTx) gasFeeCap() *big.Int { return tx.GasFeeCap } +func (tx *CeloDenominatedTx) gasTipCap() *big.Int { return tx.GasTipCap } +func (tx *CeloDenominatedTx) gasPrice() *big.Int { return tx.GasFeeCap } +func (tx *CeloDenominatedTx) value() *big.Int { return tx.Value } +func (tx *CeloDenominatedTx) nonce() uint64 { return tx.Nonce } +func (tx *CeloDenominatedTx) to() *common.Address { return tx.To } + +func (tx *CeloDenominatedTx) rawSignatureValues() (v, r, s *big.Int) { + return tx.V, tx.R, tx.S +} + +func (tx *CeloDenominatedTx) setSignatureValues(chainID, v, r, s *big.Int) { + tx.ChainID, tx.V, tx.R, tx.S = chainID, v, r, s +} + +func (tx *CeloDenominatedTx) feeCurrency() *common.Address { return tx.FeeCurrency } +func (tx *CeloDenominatedTx) gatewayFeeRecipient() *common.Address { return nil } +func (tx *CeloDenominatedTx) gatewayFee() *big.Int { return nil } +func (tx *CeloDenominatedTx) ethCompatible() bool { return false } +func (tx *CeloDenominatedTx) maxFeeInFeeCurrency() *big.Int { return tx.MaxFeeInFeeCurrency } diff --git a/core/types/celo_dynamic_fee_tx.go b/core/types/celo_dynamic_fee_tx.go index bd9c572c20..0c0fda4e82 100644 --- a/core/types/celo_dynamic_fee_tx.go +++ b/core/types/celo_dynamic_fee_tx.go @@ -116,3 +116,4 @@ func (tx *CeloDynamicFeeTx) feeCurrency() *common.Address { return tx.Fe func (tx *CeloDynamicFeeTx) gatewayFeeRecipient() *common.Address { return tx.GatewayFeeRecipient } func (tx *CeloDynamicFeeTx) gatewayFee() *big.Int { return tx.GatewayFee } func (tx *CeloDynamicFeeTx) ethCompatible() bool { return false } +func (tx *CeloDynamicFeeTx) maxFeeInFeeCurrency() *big.Int { return nil } diff --git a/core/types/celo_dynamic_fee_tx_v2.go b/core/types/celo_dynamic_fee_tx_v2.go index bf46f9f7c0..40bbfb7b30 100644 --- a/core/types/celo_dynamic_fee_tx_v2.go +++ b/core/types/celo_dynamic_fee_tx_v2.go @@ -94,3 +94,4 @@ func (tx *CeloDynamicFeeTxV2) feeCurrency() *common.Address { return tx. func (tx *CeloDynamicFeeTxV2) gatewayFeeRecipient() *common.Address { return nil } func (tx *CeloDynamicFeeTxV2) gatewayFee() *big.Int { return nil } func (tx *CeloDynamicFeeTxV2) ethCompatible() bool { return false } +func (tx *CeloDynamicFeeTxV2) maxFeeInFeeCurrency() *big.Int { return nil } diff --git a/core/types/dynamic_fee_tx.go b/core/types/dynamic_fee_tx.go index 410e42055a..48067005eb 100644 --- a/core/types/dynamic_fee_tx.go +++ b/core/types/dynamic_fee_tx.go @@ -107,3 +107,4 @@ func (tx *DynamicFeeTx) feeCurrency() *common.Address { return nil } func (tx *DynamicFeeTx) gatewayFeeRecipient() *common.Address { return nil } func (tx *DynamicFeeTx) gatewayFee() *big.Int { return nil } func (tx *DynamicFeeTx) ethCompatible() bool { return false } +func (tx *DynamicFeeTx) maxFeeInFeeCurrency() *big.Int { return nil } diff --git a/core/types/legacy_tx.go b/core/types/legacy_tx.go index a4ebcf428a..f477830304 100644 --- a/core/types/legacy_tx.go +++ b/core/types/legacy_tx.go @@ -174,3 +174,4 @@ func (tx *LegacyTx) feeCurrency() *common.Address { return tx.FeeCurrenc func (tx *LegacyTx) gatewayFeeRecipient() *common.Address { return tx.GatewayFeeRecipient } func (tx *LegacyTx) gatewayFee() *big.Int { return tx.GatewayFee } func (tx *LegacyTx) ethCompatible() bool { return tx.EthCompatible } +func (tx *LegacyTx) maxFeeInFeeCurrency() *big.Int { return nil } diff --git a/core/types/receipt.go b/core/types/receipt.go index 0636ae7746..2560e1fb89 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -176,7 +176,7 @@ func (r *Receipt) DecodeRLP(s *rlp.Stream) error { return errEmptyTypedReceipt } r.Type = b[0] - if r.Type == AccessListTxType || r.Type == DynamicFeeTxType || r.Type == CeloDynamicFeeTxType || r.Type == CeloDynamicFeeTxV2Type { + if r.Type == AccessListTxType || r.Type == DynamicFeeTxType || r.Type == CeloDynamicFeeTxType || r.Type == CeloDynamicFeeTxV2Type || r.Type == CeloDenominatedTxType { var dec receiptRLP if err := rlp.DecodeBytes(b[1:], &dec); err != nil { return err @@ -352,6 +352,9 @@ func (rs Receipts) EncodeIndex(i int, w *bytes.Buffer) { case CeloDynamicFeeTxV2Type: w.WriteByte(CeloDynamicFeeTxV2Type) rlp.Encode(w, data) + case CeloDenominatedTxType: + w.WriteByte(CeloDenominatedTxType) + rlp.Encode(w, data) default: // For unsupported types, write nothing. Since this is for // DeriveSha, the error will be caught matching the derived hash diff --git a/core/types/transaction.go b/core/types/transaction.go index a3ceecf5ff..ebec066f06 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -55,6 +55,7 @@ const ( DynamicFeeTxType = 0x02 CeloDynamicFeeTxType = 0x7c // Counting down CeloDynamicFeeTxV2Type = 0x7b + CeloDenominatedTxType = 0x7a ) // Transaction is an Ethereum transaction. @@ -100,8 +101,9 @@ type TxData interface { feeCurrency() *common.Address gatewayFeeRecipient() *common.Address gatewayFee() *big.Int - // Whether this is an ethereum-compatible transaction (i.e. with FeeCurrency, GatewayFeeRecipient and GatewayFee omitted) + // Whether this is an ethereum-compatible transaction (i.e. with FeeCurrency, MaxFeeInFeeCurrency, GatewayFeeRecipient and GatewayFee omitted) ethCompatible() bool + maxFeeInFeeCurrency() *big.Int } // EncodeRLP implements rlp.Encoder @@ -212,6 +214,10 @@ func (tx *Transaction) decodeTyped(b []byte) (TxData, error) { var inner CeloDynamicFeeTxV2 err := rlp.DecodeBytes(b[1:], &inner) return &inner, err + case CeloDenominatedTxType: + var inner CeloDenominatedTx + err := rlp.DecodeBytes(b[1:], &inner) + return &inner, err default: return nil, ErrTxTypeNotSupported } @@ -480,6 +486,9 @@ func (tx *Transaction) GatewaySet() bool { // EthCompatible returns true iff the RLP form of the LegacyTx does not have the celo specific fields. func (tx *Transaction) EthCompatible() bool { return tx.inner.ethCompatible() } +// MaxFeeInFeeCurrency returns the max fee in the fee_currency for celo denominated txs. +func (tx *Transaction) MaxFeeInFeeCurrency() *big.Int { return tx.inner.maxFeeInFeeCurrency() } + // Fee calculates the fess paid by the transaction include the gateway fee. func (tx *Transaction) Fee() *big.Int { return Fee(tx.inner.gasPrice(), tx.inner.gas(), tx.GatewayFee()) @@ -493,12 +502,24 @@ func Fee(gasPrice *big.Int, gasLimit uint64, gatewayFee *big.Int) *big.Int { // CheckEthCompatibility checks that the Celo-only fields are nil-or-0 if EthCompatible is true func (tx *Transaction) CheckEthCompatibility() error { - if tx.EthCompatible() && !(tx.FeeCurrency() == nil && tx.GatewayFeeRecipient() == nil && tx.GatewayFee().Sign() == 0) { + if tx.EthCompatible() && + !(tx.FeeCurrency() == nil && tx.GatewayFeeRecipient() == nil && tx.GatewayFee().Sign() == 0 && tx.MaxFeeInFeeCurrency() == nil) { return ErrEthCompatibleTransactionIsntCompatible } return nil } +// DenominatedFeeCurrency returns in which currency the fields GasPrice, GasTipCap, GasFeeCap, etc are +// denominated in +func (tx *Transaction) DenominatedFeeCurrency() *common.Address { + // not declaring this method in TxData since it's a specific for just one type, + // to avoid cluttering it with more methods. + if tx.Type() == CeloDenominatedTxType { + return nil + } + return tx.FeeCurrency() +} + // Transactions implements DerivableList for transactions. type Transactions []*Transaction @@ -682,6 +703,7 @@ type Message struct { gasFeeCap *big.Int gasTipCap *big.Int feeCurrency *common.Address + maxFeeInFeeCurrency *big.Int gatewayFeeRecipient *common.Address gatewayFee *big.Int data []byte @@ -692,7 +714,7 @@ type Message struct { func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice, gasFeeCap, gasTipCap *big.Int, - feeCurrency, gatewayFeeRecipient *common.Address, gatewayFee *big.Int, + feeCurrency *common.Address, maxFeeInFeeCurrency *big.Int, gatewayFeeRecipient *common.Address, gatewayFee *big.Int, data []byte, accessList AccessList, ethCompatible, isFake bool) Message { m := Message{ from: from, @@ -709,6 +731,7 @@ func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *b // Celo specific fields feeCurrency: feeCurrency, + maxFeeInFeeCurrency: maxFeeInFeeCurrency, gatewayFeeRecipient: gatewayFeeRecipient, gatewayFee: gatewayFee, ethCompatible: ethCompatible, @@ -735,6 +758,7 @@ func (tx *Transaction) AsMessage(s Signer, baseFee *big.Int) (Message, error) { // Celo specific fields feeCurrency: tx.FeeCurrency(), + maxFeeInFeeCurrency: tx.MaxFeeInFeeCurrency(), gatewayFeeRecipient: tx.GatewayFeeRecipient(), gatewayFee: new(big.Int), ethCompatible: tx.EthCompatible(), @@ -770,6 +794,7 @@ func (m Message) Fee() *big.Int { func (m Message) EthCompatible() bool { return m.ethCompatible } func (m Message) FeeCurrency() *common.Address { return m.feeCurrency } +func (m Message) MaxFeeInFeeCurrency() *big.Int { return m.maxFeeInFeeCurrency } func (m Message) GatewayFeeRecipient() *common.Address { return m.gatewayFeeRecipient } func (m Message) GatewayFee() *big.Int { return m.gatewayFee } func (m Message) GatewaySet() bool { diff --git a/core/types/transaction_marshalling.go b/core/types/transaction_marshalling.go index 29efecbd5d..473b73329c 100644 --- a/core/types/transaction_marshalling.go +++ b/core/types/transaction_marshalling.go @@ -46,6 +46,7 @@ type txJSON struct { FeeCurrency *common.Address `json:"feeCurrency"` // nil means native currency GatewayFeeRecipient *common.Address `json:"gatewayFeeRecipient"` // nil means no gateway fee is paid GatewayFee *hexutil.Big `json:"gatewayFee"` + MaxFeeInFeeCurrency *hexutil.Big `json:"maxFeeInFeeCurrency"` // max fee for CELO denominated txs // Access list transaction fields: ChainID *hexutil.Big `json:"chainId,omitempty"` @@ -136,6 +137,21 @@ func (t *Transaction) MarshalJSON() ([]byte, error) { enc.V = (*hexutil.Big)(tx.V) enc.R = (*hexutil.Big)(tx.R) enc.S = (*hexutil.Big)(tx.S) + case *CeloDenominatedTx: + enc.ChainID = (*hexutil.Big)(tx.ChainID) + enc.AccessList = &tx.AccessList + enc.Nonce = (*hexutil.Uint64)(&tx.Nonce) + enc.Gas = (*hexutil.Uint64)(&tx.Gas) + enc.MaxFeePerGas = (*hexutil.Big)(tx.GasFeeCap) + enc.MaxPriorityFeePerGas = (*hexutil.Big)(tx.GasTipCap) + enc.FeeCurrency = t.FeeCurrency() + enc.MaxFeeInFeeCurrency = (*hexutil.Big)(tx.MaxFeeInFeeCurrency) + enc.Value = (*hexutil.Big)(tx.Value) + enc.Data = (*hexutil.Bytes)(&tx.Data) + enc.To = t.To() + enc.V = (*hexutil.Big)(tx.V) + enc.R = (*hexutil.Big)(tx.R) + enc.S = (*hexutil.Big)(tx.S) } return json.Marshal(&enc) } @@ -431,7 +447,67 @@ func (t *Transaction) UnmarshalJSON(input []byte) error { return err } } - + case CeloDenominatedTxType: + var itx CeloDenominatedTx + inner = &itx + // Access list is optional for now. + if dec.AccessList != nil { + itx.AccessList = *dec.AccessList + } + if dec.ChainID == nil { + return errors.New("missing required field 'chainId' in transaction") + } + itx.ChainID = (*big.Int)(dec.ChainID) + if dec.To != nil { + itx.To = dec.To + } + if dec.Nonce == nil { + return errors.New("missing required field 'nonce' in transaction") + } + itx.Nonce = uint64(*dec.Nonce) + if dec.MaxPriorityFeePerGas == nil { + return errors.New("missing required field 'maxPriorityFeePerGas' for txdata") + } + itx.GasTipCap = (*big.Int)(dec.MaxPriorityFeePerGas) + if dec.MaxFeePerGas == nil { + return errors.New("missing required field 'maxFeePerGas' for txdata") + } + itx.GasFeeCap = (*big.Int)(dec.MaxFeePerGas) + if dec.Gas == nil { + return errors.New("missing required field 'gas' for txdata") + } + itx.Gas = uint64(*dec.Gas) + itx.FeeCurrency = dec.FeeCurrency + if dec.MaxFeeInFeeCurrency == nil { + return errors.New("missing required field 'maxFeeInFeeCurrency' in transaction") + } + itx.MaxFeeInFeeCurrency = (*big.Int)(dec.MaxFeeInFeeCurrency) + if dec.Value == nil { + return errors.New("missing required field 'value' in transaction") + } + itx.Value = (*big.Int)(dec.Value) + if dec.Data == nil { + return errors.New("missing required field 'input' in transaction") + } + itx.Data = *dec.Data + if dec.V == nil { + return errors.New("missing required field 'v' in transaction") + } + itx.V = (*big.Int)(dec.V) + if dec.R == nil { + return errors.New("missing required field 'r' in transaction") + } + itx.R = (*big.Int)(dec.R) + if dec.S == nil { + return errors.New("missing required field 's' in transaction") + } + itx.S = (*big.Int)(dec.S) + withSignature := itx.V.Sign() != 0 || itx.R.Sign() != 0 || itx.S.Sign() != 0 + if withSignature { + if err := sanityCheckSignature(itx.V, itx.R, itx.S, false); err != nil { + return err + } + } default: return ErrTxTypeNotSupported } diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index a118158f5a..30151578cf 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -170,6 +170,78 @@ type Signer interface { Equal(Signer) bool } +type hforkSigner struct{ gingerbreadSigner } + +// NewHForkSigner returns a signer that accepts +// - CIP-66 celo denominated fee transactions +// - CIP-64 celo dynamic fee transactions v2 +// - CIP-42 celo dynamic fee transactions +// - EIP-1559 dynamic fee transactions +// - EIP-2930 access list transactions, +// - EIP-155 replay protected transactions, and +// - legacy Homestead transactions. +func NewHForkSigner(chainId *big.Int) Signer { + return hforkSigner{gingerbreadSigner{londonSigner{eip2930Signer{NewEIP155Signer(chainId)}}}} +} + +func (s hforkSigner) Sender(tx *Transaction) (common.Address, error) { + if tx.Type() != CeloDenominatedTxType { + return s.gingerbreadSigner.Sender(tx) + } + V, R, S := tx.RawSignatureValues() + // DynamicFee 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)) + if tx.ChainId().Cmp(s.chainId) != 0 { + return common.Address{}, ErrInvalidChainId + } + return recoverPlain(s.Hash(tx), R, S, V, true) +} + +func (s hforkSigner) Equal(s2 Signer) bool { + x, ok := s2.(hforkSigner) + return ok && x.chainId.Cmp(s.chainId) == 0 +} + +func (s hforkSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) { + txdata, ok := tx.inner.(*CeloDenominatedTx) + if !ok { + return s.gingerbreadSigner.SignatureValues(tx, sig) + } + // Check that chain ID of tx matches the signer. We also accept ID zero here, + // because it indicates that the chain ID was not specified in the tx. + if txdata.ChainID.Sign() != 0 && txdata.ChainID.Cmp(s.chainId) != 0 { + return nil, nil, nil, ErrInvalidChainId + } + R, S, _ = decodeSignature(sig) + V = big.NewInt(int64(sig[64])) + return R, S, V, nil +} + +// Hash returns the hash to be signed by the sender. +// It does not uniquely identify the transaction. +func (s hforkSigner) Hash(tx *Transaction) common.Hash { + if tx.Type() == CeloDenominatedTxType { + return prefixedRlpHash( + tx.Type(), + []interface{}{ + s.chainId, + tx.Nonce(), + tx.GasTipCap(), + tx.GasFeeCap(), + tx.Gas(), + tx.To(), + tx.Value(), + tx.Data(), + tx.AccessList(), + tx.FeeCurrency(), + tx.MaxFeeInFeeCurrency(), + }) + } + return s.gingerbreadSigner.Hash(tx) + +} + type gingerbreadSigner struct{ londonSigner } // NewGingerbreadSigner returns a signer that accepts diff --git a/e2e_test/e2e_transfer_test.go b/e2e_test/e2e_transfer_test.go index 87129b93e2..4ebbbf929f 100644 --- a/e2e_test/e2e_transfer_test.go +++ b/e2e_test/e2e_transfer_test.go @@ -112,30 +112,6 @@ func TestTransferCELO(t *testing.T) { }, expectedErr: nil, }, - { - name: "CeloDynamicFeeTxType - gas = MaxFeePerGas - BaseFee", - txArgs: ðapi.TransactionArgs{ - To: &recipient.Address, - Value: (*hexutil.Big)(new(big.Int).SetInt64(oneCelo)), - MaxFeePerGas: (*hexutil.Big)(datum.Mul(datum, new(big.Int).SetInt64(4))), - MaxPriorityFeePerGas: (*hexutil.Big)(datum.Mul(datum, new(big.Int).SetInt64(4))), - GatewayFee: (*hexutil.Big)(new(big.Int).SetInt64(oneCelo / 10)), - GatewayFeeRecipient: &gateWayFeeRecipient.Address, - }, - expectedErr: core.ErrGatewayFeeDeprecated, - }, - { - name: "CeloDynamicFeeTxType - MaxPriorityFeePerGas", - txArgs: ðapi.TransactionArgs{ - To: &recipient.Address, - Value: (*hexutil.Big)(new(big.Int).SetInt64(oneCelo)), - MaxFeePerGas: (*hexutil.Big)(datum.Mul(datum, new(big.Int).SetInt64(4))), - MaxPriorityFeePerGas: (*hexutil.Big)(datum), - GatewayFee: (*hexutil.Big)(new(big.Int).SetInt64(oneCelo / 10)), - GatewayFeeRecipient: &gateWayFeeRecipient.Address, - }, - expectedErr: core.ErrGatewayFeeDeprecated, - }, { name: "CeloDynamicFeeTxV2Type - gas = MaxFeePerGas - BaseFee", txArgs: ðapi.TransactionArgs{ @@ -174,7 +150,7 @@ func TestTransferCELO(t *testing.T) { blockNum, err := client.BlockNumber(ctx) require.NoError(t, err) signer := types.MakeSigner(devAccounts[0].ChainConfig, new(big.Int).SetUint64(blockNum)) - tx, err := prepareTransaction(*tc.txArgs, sender.Key, sender.Address, signer, client, true) + tx, err := prepareTransaction(*tc.txArgs, sender.Key, sender.Address, signer, client) require.NoError(t, err) err = client.SendTransaction(ctx, tx) if tc.expectedErr != nil { @@ -249,177 +225,8 @@ func TestTransferCELO(t *testing.T) { } } -// TestTransferCELO checks following accounts: -// - Sender account has transfer value, transaction fee deducted -// - Receiver account has transfer value added. -// - Governance account has base fee added. -// - validator account has tip fee added. -func TestTransferCELOPreGingerbread(t *testing.T) { - ac := test.AccountConfig(1, 3) - var gingerbreadBlock *big.Int = nil - gc, ec, err := test.BuildConfig(ac, gingerbreadBlock) - - require.NoError(t, err) - network, shutdown, err := test.NewNetwork(ac, gc, ec) - require.NoError(t, err) - defer shutdown() - ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) - defer cancel() - - node := network[0] // validator node - client := node.WsClient - devAccounts := test.Accounts(ac.DeveloperAccounts(), gc.ChainConfig()) - sender := devAccounts[0] - recipient := devAccounts[1] - gateWayFeeRecipient := devAccounts[2] - - // Get datum to set GasPrice/MaxFeePerGas/MaxPriorityFeePerGas to sensible values - header, err := network[0].WsClient.HeaderByNumber(ctx, nil) - require.NoError(t, err) - datum, err := network[0].Eth.APIBackend.GasPriceMinimumForHeader(ctx, nil, header) - require.NoError(t, err) - - testCases := []struct { - name string - txArgs *ethapi.TransactionArgs - }{ - { - name: "eth compatible LegacyTxType", - txArgs: ðapi.TransactionArgs{ - To: &recipient.Address, - Value: (*hexutil.Big)(new(big.Int).SetInt64(oneCelo)), - GasPrice: (*hexutil.Big)(datum.Mul(datum, new(big.Int).SetInt64(4))), - }, - }, - { - name: "eth incompatible LegacyTxType", - txArgs: ðapi.TransactionArgs{ - To: &recipient.Address, - Value: (*hexutil.Big)(new(big.Int).SetInt64(oneCelo)), - GasPrice: (*hexutil.Big)(datum.Mul(datum, new(big.Int).SetInt64(4))), - GatewayFee: (*hexutil.Big)(new(big.Int).SetInt64(oneCelo / 10)), - GatewayFeeRecipient: &gateWayFeeRecipient.Address, - }, - }, - { - name: "AccessListTxType", - txArgs: ðapi.TransactionArgs{ - To: &recipient.Address, - Value: (*hexutil.Big)(new(big.Int).SetInt64(oneCelo)), - GasPrice: (*hexutil.Big)(datum.Mul(datum, new(big.Int).SetInt64(4))), - AccessList: &types.AccessList{}, - }, - }, - { - name: "DynamicFeeTxType - tip = MaxFeePerGas - BaseFee", - txArgs: ðapi.TransactionArgs{ - To: &recipient.Address, - Value: (*hexutil.Big)(new(big.Int).SetInt64(oneCelo)), - MaxFeePerGas: (*hexutil.Big)(datum.Mul(datum, new(big.Int).SetInt64(4))), - MaxPriorityFeePerGas: (*hexutil.Big)(datum.Mul(datum, new(big.Int).SetInt64(4))), - }, - }, - { - name: "DynamicFeeTxType - tip = MaxPriorityFeePerGas", - txArgs: ðapi.TransactionArgs{ - To: &recipient.Address, - Value: (*hexutil.Big)(new(big.Int).SetInt64(oneCelo)), - MaxFeePerGas: (*hexutil.Big)(datum.Mul(datum, new(big.Int).SetInt64(4))), - MaxPriorityFeePerGas: (*hexutil.Big)(datum), - }, - }, - { - name: "CeloDynamicFeeTxType - gas = MaxFeePerGas - BaseFee", - txArgs: ðapi.TransactionArgs{ - To: &recipient.Address, - Value: (*hexutil.Big)(new(big.Int).SetInt64(oneCelo)), - MaxFeePerGas: (*hexutil.Big)(datum.Mul(datum, new(big.Int).SetInt64(4))), - MaxPriorityFeePerGas: (*hexutil.Big)(datum.Mul(datum, new(big.Int).SetInt64(4))), - GatewayFee: (*hexutil.Big)(new(big.Int).SetInt64(oneCelo / 10)), - GatewayFeeRecipient: &gateWayFeeRecipient.Address, - }, - }, - { - name: "CeloDynamicFeeTxType - MaxPriorityFeePerGas", - txArgs: ðapi.TransactionArgs{ - To: &recipient.Address, - Value: (*hexutil.Big)(new(big.Int).SetInt64(oneCelo)), - MaxFeePerGas: (*hexutil.Big)(datum.Mul(datum, new(big.Int).SetInt64(4))), - MaxPriorityFeePerGas: (*hexutil.Big)(datum), - GatewayFee: (*hexutil.Big)(new(big.Int).SetInt64(oneCelo / 10)), - GatewayFeeRecipient: &gateWayFeeRecipient.Address, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - watcher := test.NewBalanceWatcher(client, []common.Address{sender.Address, recipient.Address, gateWayFeeRecipient.Address, node.Address}) - blockNum, err := client.BlockNumber(ctx) - require.NoError(t, err) - signer := types.MakeSigner(devAccounts[0].ChainConfig, new(big.Int).SetUint64(blockNum)) - tx, err := prepareTransaction(*tc.txArgs, sender.Key, sender.Address, signer, client, false) - require.NoError(t, err) - err = client.SendTransaction(ctx, tx) - require.NoError(t, err, "SendTransaction failed", "tx", *tx) - err = network.AwaitTransactions(ctx, tx) - require.NoError(t, err) - watcher.Update() - receipt, err := client.TransactionReceipt(ctx, tx.Hash()) - require.NoError(t, err) - - // check value goes to recipient - expected := tx.Value() - actual := watcher.Delta(recipient.Address) - assert.Equal(t, expected, actual, "Recipient's balance increase unexpected", "expected", expected.Int64(), "actual", actual.Int64()) - - // Check tip goes to validator - header, err := network[0].WsClient.HeaderByNumber(ctx, receipt.BlockNumber) - require.NoError(t, err) - gpm, err := network[0].Eth.APIBackend.GasPriceMinimumForHeader(ctx, nil, header) - require.NoError(t, err) - baseFee := new(big.Int).Mul(gpm, new(big.Int).SetUint64(receipt.GasUsed)) - switch tx.Type() { - case types.LegacyTxType, types.AccessListTxType: - fee := new(big.Int).Mul(tx.GasPrice(), new(big.Int).SetUint64(receipt.GasUsed)) - expected = new(big.Int).Sub(fee, baseFee) - case types.DynamicFeeTxType, types.CeloDynamicFeeTxType, types.CeloDynamicFeeTxV2Type: - expected = tx.EffectiveGasTipValue(gpm) - expected.Mul(expected, new(big.Int).SetUint64(receipt.GasUsed)) - } - actual = watcher.Delta(node.Address) - assert.Equal(t, expected, actual, "Validator's balance increase unexpected", "expected", expected.Int64(), "actual", actual.Int64()) - - // check value + tx fee + gateway fee are subtracted from sender - var fee *big.Int - switch tx.Type() { - case types.LegacyTxType, types.AccessListTxType: - fee = new(big.Int).Mul(tx.GasPrice(), new(big.Int).SetUint64(receipt.GasUsed)) - case types.DynamicFeeTxType, types.CeloDynamicFeeTxType, types.CeloDynamicFeeTxV2Type: - tip := tx.EffectiveGasTipValue(gpm) - tip.Mul(tip, new(big.Int).SetUint64(receipt.GasUsed)) - fee = new(big.Int).Add(tip, baseFee) - } - consumed := new(big.Int).Add(tx.Value(), fee) - if tx.GatewayFeeRecipient() != nil && tx.GatewayFee() != nil { - consumed.Add(consumed, tx.GatewayFee()) - } - expected = new(big.Int).Neg(consumed) - actual = watcher.Delta(sender.Address) - assert.Equal(t, expected, actual, "Sender's balance decrease unexpected", "expected", expected.Int64(), "actual", expected.Int64()) - - // Check gateway fee - if tx.GatewayFeeRecipient() != nil && tx.GatewayFee() != nil { - expected = tx.GatewayFee() - actual = watcher.Delta(gateWayFeeRecipient.Address) - assert.Equal(t, expected, actual, "gateWayFeeRecipient's balance increase unexpected", "expected", expected.Int64(), "actual", actual.Int64()) - } - }) - } -} - // prepareTransaction prepares gasPrice, gasLimit and sign the transaction. -func prepareTransaction(txArgs ethapi.TransactionArgs, senderKey *ecdsa.PrivateKey, sender common.Address, signer types.Signer, client *ethclient.Client, isGingerbreadP2 bool) (*types.Transaction, error) { +func prepareTransaction(txArgs ethapi.TransactionArgs, senderKey *ecdsa.PrivateKey, sender common.Address, signer types.Signer, client *ethclient.Client) (*types.Transaction, error) { ctx, cancel := context.WithTimeout(context.Background(), time.Second*2) defer cancel() @@ -441,7 +248,7 @@ func prepareTransaction(txArgs ethapi.TransactionArgs, senderKey *ecdsa.PrivateK } // Create the transaction and sign it - rawTx := txArgs.ToTransaction(isGingerbreadP2) + rawTx := txArgs.ToTransaction() signed, err := types.SignTx(rawTx, signer, senderKey) if err != nil { return nil, err @@ -509,7 +316,7 @@ func TestTransferERC20(t *testing.T) { blockNum, err := client.BlockNumber(ctx) require.NoError(t, err) signer := types.MakeSigner(devAccounts[0].ChainConfig, new(big.Int).SetUint64(blockNum)) - tx, err := prepareTransaction(*tc.txArgs, sender.Key, sender.Address, signer, client, true) + tx, err := prepareTransaction(*tc.txArgs, sender.Key, sender.Address, signer, client) require.NoError(t, err) err = client.SendTransaction(ctx, tx) if tc.expectedErr != nil { diff --git a/graphql/graphql.go b/graphql/graphql.go index bfd2f777ba..7aa8505578 100644 --- a/graphql/graphql.go +++ b/graphql/graphql.go @@ -228,9 +228,9 @@ func (t *Transaction) GasPrice(ctx context.Context) (hexutil.Big, error) { switch tx.Type() { case types.AccessListTxType: return hexutil.Big(*tx.GasPrice()), nil - case types.DynamicFeeTxType, types.CeloDynamicFeeTxType, types.CeloDynamicFeeTxV2Type: + case types.DynamicFeeTxType, types.CeloDynamicFeeTxType, types.CeloDynamicFeeTxV2Type, types.CeloDenominatedTxType: if t.block != nil { - if baseFee, _ := t.block.BaseFeePerGasForCurrency(ctx, tx.FeeCurrency()); baseFee != nil { + if baseFee, _ := t.block.BaseFeePerGasForCurrency(ctx, tx.DenominatedFeeCurrency()); baseFee != nil { // price = min(tip, gasFeeCap - baseFee) + baseFee return (hexutil.Big)(*math.BigMin(new(big.Int).Add(tx.GasTipCap(), baseFee.ToInt()), tx.GasFeeCap())), nil } @@ -247,9 +247,9 @@ func (t *Transaction) EffectiveGasPrice(ctx context.Context) (*hexutil.Big, erro return nil, err } switch tx.Type() { - case types.DynamicFeeTxType, types.CeloDynamicFeeTxType, types.CeloDynamicFeeTxV2Type: + case types.DynamicFeeTxType, types.CeloDynamicFeeTxType, types.CeloDynamicFeeTxV2Type, types.CeloDenominatedTxType: if t.block != nil { - if baseFee, _ := t.block.BaseFeePerGasForCurrency(ctx, tx.FeeCurrency()); baseFee != nil { + if baseFee, _ := t.block.BaseFeePerGasForCurrency(ctx, tx.DenominatedFeeCurrency()); baseFee != nil { // price = min(tip, gasFeeCap - baseFee) + baseFee return (*hexutil.Big)(math.BigMin(new(big.Int).Add(tx.GasTipCap(), baseFee.ToInt()), tx.GasFeeCap())), nil } diff --git a/interfaces.go b/interfaces.go index 39102012a3..cce7465a00 100644 --- a/interfaces.go +++ b/interfaces.go @@ -117,6 +117,7 @@ type CallMsg struct { To *common.Address // the destination contract (nil for contract creation) Gas uint64 // if 0, the call executes with near-infinite gas FeeCurrency *common.Address // 0 for the native currency + MaxFeeInFeeCurrency *big.Int // Set iff it's a celo denominated tx. Maximum value of fees when converted to FeeCurrency. GatewayFeeRecipient *common.Address // 0 for no gateway fee GatewayFee *big.Int // 0 for no gateway fee GasPrice *big.Int // wei <-> gas exchange ratio diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 94281a5d7d..1f5364fddd 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -426,7 +426,7 @@ func (s *PrivateAccountAPI) signTransaction(ctx context.Context, args *Transacti return nil, err } // Assemble the transaction and sign with the wallet - tx := args.toTransaction(s.b.ChainConfig().IsGingerbreadP2(s.b.CurrentHeader().Number)) + tx := args.toTransaction() return wallet.SignTxWithPassphrase(account, passwd, tx, s.b.ChainConfig().ChainID) } @@ -469,7 +469,7 @@ func (s *PrivateAccountAPI) SignTransaction(ctx context.Context, args Transactio return nil, fmt.Errorf("nonce not specified") } // Before actually signing the transaction, ensure the transaction fee is reasonable. - tx := args.toTransaction(s.b.ChainConfig().IsGingerbreadP2(s.b.CurrentHeader().Number)) + tx := args.toTransaction() if err := checkFeeFromCeloTx(ctx, s.b, tx); err != nil { return nil, err } @@ -1313,9 +1313,9 @@ func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber result.TransactionIndex = (*hexutil.Uint64)(&index) } // Celo specifics - if tx.Type() == types.LegacyTxType || tx.Type() == types.CeloDynamicFeeTxType || tx.Type() == types.CeloDynamicFeeTxV2Type { + if tx.Type() == types.LegacyTxType || tx.Type() == types.CeloDynamicFeeTxType || tx.Type() == types.CeloDynamicFeeTxV2Type || tx.Type() == types.CeloDenominatedTxType { result.FeeCurrency = tx.FeeCurrency() - if tx.Type() != types.CeloDynamicFeeTxV2Type { + if tx.Type() == types.LegacyTxType || tx.Type() == types.CeloDynamicFeeTxType { result.GatewayFeeRecipient = tx.GatewayFeeRecipient() result.GatewayFee = (*hexutil.Big)(tx.GatewayFee()) } @@ -1326,7 +1326,7 @@ func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber al := tx.AccessList() result.Accesses = &al result.ChainID = (*hexutil.Big)(tx.ChainId()) - case types.DynamicFeeTxType, types.CeloDynamicFeeTxType, types.CeloDynamicFeeTxV2Type: + case types.DynamicFeeTxType, types.CeloDynamicFeeTxType, types.CeloDynamicFeeTxV2Type, types.CeloDenominatedTxType: al := tx.AccessList() result.Accesses = &al result.ChainID = (*hexutil.Big)(tx.ChainId()) @@ -1335,7 +1335,12 @@ func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber // if the transaction has been mined, compute the effective gas price // if blockHash != (common.Hash{}) { // This is from upstream (check the function comment above). if inABlock { - baseFee, err := baseFeeFn(tx.FeeCurrency()) + var currency *common.Address = tx.FeeCurrency() + // Celo Denominated txs are denominated in celo + if tx.Type() == types.CeloDenominatedTxType { + currency = nil + } + baseFee, err := baseFeeFn(currency) if err == nil { // price = min(tip, gasFeeCap - baseFee) + baseFee price := math.BigMin(new(big.Int).Add(tx.GasTipCap(), baseFee), tx.GasFeeCap()) @@ -1489,7 +1494,7 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH vmRunner := b.NewEVMRunner(header, statedb) res, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), vmRunner, sysCtx) if err != nil { - return nil, 0, nil, fmt.Errorf("failed to apply transaction: %v err: %v", args.toTransaction(false).Hash(), err) + return nil, 0, nil, fmt.Errorf("failed to apply transaction: %v err: %v", args.toTransaction().Hash(), err) } if tracer.Equal(prevTracer) { return accessList, res.UsedGas, res.Err, nil @@ -1667,12 +1672,12 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, ha fields["effectiveGasPrice"] = hexutil.Uint64(tx.GasPrice().Uint64()) } else { // var gasPrice *big.Int = new(big.Int) - if tx.Type() == types.DynamicFeeTxType || tx.Type() == types.CeloDynamicFeeTxType || tx.Type() == types.CeloDynamicFeeTxV2Type { + if tx.Type() == types.DynamicFeeTxType || tx.Type() == types.CeloDynamicFeeTxType || tx.Type() == types.CeloDynamicFeeTxV2Type || tx.Type() == types.CeloDenominatedTxType { header, err := s.b.HeaderByHash(ctx, blockHash) if err != nil { return nil, err } - gasPriceMinimum, err := s.b.GasPriceMinimumForHeader(ctx, tx.FeeCurrency(), header) + gasPriceMinimum, err := s.b.GasPriceMinimumForHeader(ctx, tx.DenominatedFeeCurrency(), header) if err == nil { fields["effectiveGasPrice"] = hexutil.Uint64(new(big.Int).Add(gasPriceMinimum, tx.EffectiveGasTipValue(gasPriceMinimum)).Uint64()) } @@ -1785,7 +1790,7 @@ func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args Tra return common.Hash{}, err } // Assemble the transaction and sign with the wallet - tx := args.toTransaction(s.b.ChainConfig().IsGingerbreadP2(s.b.CurrentHeader().Number)) + tx := args.toTransaction() signed, err := wallet.SignTx(account, tx, s.b.ChainConfig().ChainID) if err != nil { @@ -1803,7 +1808,7 @@ func (s *PublicTransactionPoolAPI) FillTransaction(ctx context.Context, args Tra return nil, err } // Assemble the transaction and obtain rlp - tx := args.toTransaction(s.b.ChainConfig().IsGingerbreadP2(s.b.CurrentHeader().Number)) + tx := args.toTransaction() data, err := tx.MarshalBinary() if err != nil { return nil, err @@ -1869,7 +1874,7 @@ func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args Tra return nil, err } // Before actually sign the transaction, ensure the transaction fee is reasonable. - tx := args.toTransaction(s.b.ChainConfig().IsGingerbreadP2(s.b.CurrentHeader().Number)) + tx := args.toTransaction() if err := checkFeeFromCeloTx(ctx, s.b, tx); err != nil { return nil, err } @@ -1917,8 +1922,7 @@ func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs Transact if err := sendArgs.setDefaults(ctx, s.b); err != nil { return common.Hash{}, err } - isGingerbreadP2 := s.b.ChainConfig().IsGingerbreadP2(s.b.CurrentHeader().Number) - matchTx := sendArgs.toTransaction(isGingerbreadP2) + matchTx := sendArgs.toTransaction() // Before replacing the old transaction, ensure the _new_ transaction fee is reasonable. var price = matchTx.GasPrice() @@ -1948,7 +1952,7 @@ func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs Transact if gasLimit != nil && *gasLimit != 0 { sendArgs.Gas = gasLimit } - signedTx, err := s.sign(sendArgs.from(), sendArgs.toTransaction(isGingerbreadP2)) + signedTx, err := s.sign(sendArgs.from(), sendArgs.toTransaction()) if err != nil { return common.Hash{}, err } diff --git a/internal/ethapi/transaction_args.go b/internal/ethapi/transaction_args.go index a01e4c1978..2151e9591f 100644 --- a/internal/ethapi/transaction_args.go +++ b/internal/ethapi/transaction_args.go @@ -41,6 +41,7 @@ type TransactionArgs struct { MaxFeePerGas *hexutil.Big `json:"maxFeePerGas"` MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas"` FeeCurrency *common.Address `json:"feeCurrency"` + MaxFeeInFeeCurrency *hexutil.Big `json:"maxFeeInFeeCurrency"` GatewayFeeRecipient *common.Address `json:"gatewayFeeRecipient"` GatewayFee *hexutil.Big `json:"gatewayFee"` Value *hexutil.Big `json:"value"` @@ -260,13 +261,14 @@ func (args *TransactionArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (t if args.AccessList != nil { accessList = *args.AccessList } - msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, gasFeeCap, gasTipCap, args.FeeCurrency, args.GatewayFeeRecipient, args.GatewayFee.ToInt(), data, accessList, args.EthCompatible, true) + maxFeeInFeeCurrency := args.MaxFeeInFeeCurrency.ToInt() + msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, gasFeeCap, gasTipCap, args.FeeCurrency, maxFeeInFeeCurrency, args.GatewayFeeRecipient, args.GatewayFee.ToInt(), data, accessList, args.EthCompatible, true) return msg, nil } // toTransaction converts the arguments to a transaction. // This assumes that setDefaults has been called. -func (args *TransactionArgs) toTransaction(isGingerbreadP2 bool) *types.Transaction { +func (args *TransactionArgs) toTransaction() *types.Transaction { var data types.TxData switch { case args.MaxFeePerGas != nil: @@ -274,8 +276,9 @@ func (args *TransactionArgs) toTransaction(isGingerbreadP2 bool) *types.Transact if args.AccessList != nil { al = *args.AccessList } - if args.GatewayFeeRecipient != nil || args.GatewayFee != nil || (!isGingerbreadP2 && args.FeeCurrency != nil) { - data = &types.CeloDynamicFeeTx{ + + if args.FeeCurrency != nil && args.MaxFeeInFeeCurrency != nil { + data = &types.CeloDenominatedTx{ To: args.To, ChainID: (*big.Int)(args.ChainID), Nonce: uint64(*args.Nonce), @@ -283,13 +286,12 @@ func (args *TransactionArgs) toTransaction(isGingerbreadP2 bool) *types.Transact GasFeeCap: (*big.Int)(args.MaxFeePerGas), GasTipCap: (*big.Int)(args.MaxPriorityFeePerGas), FeeCurrency: args.FeeCurrency, - GatewayFeeRecipient: args.GatewayFeeRecipient, - GatewayFee: (*big.Int)(args.GatewayFee), + MaxFeeInFeeCurrency: (*big.Int)(args.MaxFeeInFeeCurrency), Value: (*big.Int)(args.Value), Data: args.data(), AccessList: al, } - } else if isGingerbreadP2 && args.FeeCurrency != nil { + } else if args.FeeCurrency != nil { data = &types.CeloDynamicFeeTxV2{ To: args.To, ChainID: (*big.Int)(args.ChainID), @@ -347,8 +349,8 @@ func (args *TransactionArgs) toTransaction(isGingerbreadP2 bool) *types.Transact // ToTransaction converts the arguments to a transaction. // This assumes that setDefaults has been called. -func (args *TransactionArgs) ToTransaction(isGingerbread bool) *types.Transaction { - return args.toTransaction(isGingerbread) +func (args *TransactionArgs) ToTransaction() *types.Transaction { + return args.toTransaction() } func (args *TransactionArgs) checkEthCompatibility() error { diff --git a/les/odr_test.go b/les/odr_test.go index 9eb7a8a0ad..99677d306e 100644 --- a/les/odr_test.go +++ b/les/odr_test.go @@ -140,7 +140,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai from := statedb.GetOrNewStateObject(bankAddr) from.SetBalance(math.MaxBig256) - msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), 100000, new(big.Int), new(big.Int), new(big.Int), nil, nil, new(big.Int), data, nil, false, true)} + msg := callmsg{types.NewMessage(from.Address(), &testContractAddr, 0, new(big.Int), 100000, new(big.Int), new(big.Int), new(big.Int), nil, nil, nil, new(big.Int), data, nil, false, true)} context := core.NewEVMBlockContext(header, bc, nil) txContext := core.NewEVMTxContext(msg) @@ -154,7 +154,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai header := lc.GetHeaderByHash(bhash) state := light.NewState(ctx, header, lc.Odr()) state.SetBalance(bankAddr, math.MaxBig256) - msg := callmsg{types.NewMessage(bankAddr, &testContractAddr, 0, new(big.Int), 100000, new(big.Int), new(big.Int), new(big.Int), nil, nil, new(big.Int), data, nil, false, true)} + msg := callmsg{types.NewMessage(bankAddr, &testContractAddr, 0, new(big.Int), 100000, new(big.Int), new(big.Int), new(big.Int), nil, nil, nil, new(big.Int), data, nil, false, true)} context := core.NewEVMBlockContext(header, lc, nil) txContext := core.NewEVMTxContext(msg) vmenv := vm.NewEVM(context, txContext, state, config, vm.Config{NoBaseFee: true}) diff --git a/light/odr_test.go b/light/odr_test.go index 26c79a674b..92f22a4494 100644 --- a/light/odr_test.go +++ b/light/odr_test.go @@ -243,7 +243,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain // Perform read-only call. st.SetBalance(testBankAddress, math.MaxBig256) - msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 1000000, new(big.Int), new(big.Int), new(big.Int), nil, nil, nil, data, nil, false, true)} + msg := callmsg{types.NewMessage(testBankAddress, &testContractAddr, 0, new(big.Int), 1000000, new(big.Int), new(big.Int), new(big.Int), nil, nil, nil, nil, data, nil, false, true)} txContext := core.NewEVMTxContext(msg) context := core.NewEVMBlockContext(header, chain, nil) vmenv := vm.NewEVM(context, txContext, st, config, vm.Config{NoBaseFee: true}) diff --git a/light/txpool.go b/light/txpool.go index 1ade4456ac..6c06d24f1f 100644 --- a/light/txpool.go +++ b/light/txpool.go @@ -75,6 +75,7 @@ type TxPool struct { espresso bool // Fork indicator whether Espresso has been activated gingerbread bool // Fork indicator whether Gingerbread has been activated gingerbreadP2 bool // Fork indicator whether Gingerbread has been activated + hfork bool // Fork indicator whether HFork has been activated } // TxRelayBackend provides an interface to the mechanism that forwards transactions to the @@ -332,7 +333,8 @@ func (pool *TxPool) setNewHead(head *types.Header) { pool.donut = pool.config.IsDonut(next) pool.espresso = pool.config.IsEspresso(next) pool.gingerbread = pool.config.IsGingerbread(next) - pool.gingerbreadP2 = pool.config.IsGingerbread(next) + pool.gingerbreadP2 = pool.config.IsGingerbreadP2(next) + pool.hfork = pool.config.IsHFork(next) } // Stop stops the light transaction pool @@ -395,6 +397,10 @@ func (pool *TxPool) validateTx(ctx context.Context, tx *types.Transaction) error if !pool.gingerbreadP2 && tx.Type() == types.CeloDynamicFeeTxV2Type { return core.ErrTxTypeNotSupported } + // Reject celo denominated fee until h fork + if !pool.hfork && tx.Type() == types.CeloDenominatedTxType { + return core.ErrTxTypeNotSupported + } // Validate the transaction sender and it's sig. Throw // if the from fields is invalid. diff --git a/signer/core/api.go b/signer/core/api.go index bf608cdf42..45bda35bcf 100644 --- a/signer/core/api.go +++ b/signer/core/api.go @@ -565,9 +565,8 @@ func (api *SignerAPI) SignTransaction(ctx context.Context, args apitypes.SendTxA if err != nil { return nil, err } - // TODO Change flag after gingerbreadP2 activation // Convert fields into a real transaction - var unsignedTx = result.Transaction.ToTransaction(false) + var unsignedTx = result.Transaction.ToTransaction() // Get the password for the transaction pw, err := api.lookupOrQueryPassword(acc.Address, "Account password", fmt.Sprintf("Please enter the password for account %s", acc.Address.String())) diff --git a/signer/core/apitypes/types.go b/signer/core/apitypes/types.go index cb1622c0d4..0e58b37eca 100644 --- a/signer/core/apitypes/types.go +++ b/signer/core/apitypes/types.go @@ -101,10 +101,10 @@ func (args SendTxArgs) String() string { } func (args SendTxArgs) CheckEthCompatibility() error { - return args.ToTransaction(false).CheckEthCompatibility() + return args.ToTransaction().CheckEthCompatibility() } -func (args *SendTxArgs) ToTransaction(isGingerbreadP2 bool) *types.Transaction { +func (args *SendTxArgs) ToTransaction() *types.Transaction { // Upstream refactored this method to copy what txArgs.ToTransaction is doing in // bb1f7ebf203f40dae714a3b8445918cfcfc9a7db in order to be able to compile the code to // WebAssembly. Duplicating this logic right now does not seem to be worth it for celo @@ -135,5 +135,5 @@ func (args *SendTxArgs) ToTransaction(isGingerbreadP2 bool) *types.Transaction { to := args.To.Address() txArgs.To = &to } - return txArgs.ToTransaction(isGingerbreadP2) + return txArgs.ToTransaction() } diff --git a/tests/state_test_util.go b/tests/state_test_util.go index ce2ef86811..a8f1221581 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -346,7 +346,7 @@ func (tx *stTransaction) toMessage(ps stPostState, baseFee *big.Int) (core.Messa } msg := types.NewMessage(from, to, tx.Nonce, value, gasLimit, gasPrice, - tx.MaxFeePerGas, tx.MaxPriorityFeePerGas, nil, nil, nil, data, accessList, false, false) + tx.MaxFeePerGas, tx.MaxPriorityFeePerGas, nil, nil, nil, nil, data, accessList, false, false) return msg, nil } From 6351612d67d4cf5e18708a0536f0cb43afa19e43 Mon Sep 17 00:00:00 2001 From: Mohamed Sohail Date: Wed, 3 Apr 2024 17:19:02 +0800 Subject: [PATCH 4/9] feat (internal/ethapi): implement eth_getBlockReceipts (#2284) * feat (internal/ethapi): implement eth_getBlockReceipts * ref: #2187 * inline-docs (eth-client): add description for BlockReceipts * refactor (ethapi/api.go): generateReceiptResponse helper * generateReceiptResponse now receives a context and a backend interface so as to also compute the effectiveGasPrice field in transaction receipts * reconcile: receipt changes from master 272982b (#2278) --- ethclient/ethclient.go | 10 +++++ internal/ethapi/api.go | 84 ++++++++++++++++++++++++++----------- internal/web3ext/web3ext.go | 5 +++ 3 files changed, 75 insertions(+), 24 deletions(-) diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index 68b5945cab..8f8b7ae0e6 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -331,6 +331,16 @@ func (ec *Client) TransactionReceipt(ctx context.Context, txHash common.Hash) (* return r, err } +// BlockReceipts returns the receipts of a given block number or hash +func (ec *Client) BlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) ([]*types.Receipt, error) { + var r []*types.Receipt + err := ec.c.CallContext(ctx, &r, "eth_getBlockReceipts", blockNrOrHash) + if err == nil && r == nil { + return nil, ethereum.NotFound + } + return r, err +} + type rpcProgress struct { StartingBlock hexutil.Uint64 CurrentBlock hexutil.Uint64 diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 1f5364fddd..08edaa9c94 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -824,6 +824,36 @@ func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.A return res[:], state.Error() } +// GetBlockReceipts returns the block receipts for the given block hash or number or tag. +func (s *PublicBlockChainAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) ([]map[string]interface{}, error) { + block, err := s.b.BlockByNumberOrHash(ctx, blockNrOrHash) + if block == nil || err != nil { + // When the block doesn't exist, the RPC method should return JSON null + // as per specification. + return nil, nil + } + receipts, err := s.b.GetReceipts(ctx, block.Hash()) + if err != nil { + return nil, err + } + txs := block.Transactions() + if len(txs) != len(receipts) { + return nil, fmt.Errorf("receipts length mismatch: %d vs %d", len(txs), len(receipts)) + } + + // Derive the sender. + signer := types.MakeSigner(s.b.ChainConfig(), block.Number()) + result := make([]map[string]interface{}, len(receipts)) + for i, receipt := range receipts { + result[i], err = generateReceiptResponse(ctx, s.b, receipt, signer, txs[i], block.Hash(), block.NumberU64(), uint64(i)) + if err != nil { + return nil, err + } + } + + return result, nil +} + // OverrideAccount indicates the overriding fields of account during the execution // of a message call. // Note, state and stateDiff can't be specified at the same time. If state is @@ -1666,25 +1696,9 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, ha bigblock := new(big.Int).SetUint64(blockNumber) signer := types.MakeSigner(s.b.ChainConfig(), bigblock) - fields := generateReceiptResponse(receipt, signer, tx, blockHash, blockNumber, index) - // Assign the effective gas price paid - if !s.b.ChainConfig().IsLondon(bigblock) { - fields["effectiveGasPrice"] = hexutil.Uint64(tx.GasPrice().Uint64()) - } else { - // var gasPrice *big.Int = new(big.Int) - if tx.Type() == types.DynamicFeeTxType || tx.Type() == types.CeloDynamicFeeTxType || tx.Type() == types.CeloDynamicFeeTxV2Type || tx.Type() == types.CeloDenominatedTxType { - header, err := s.b.HeaderByHash(ctx, blockHash) - if err != nil { - return nil, err - } - gasPriceMinimum, err := s.b.GasPriceMinimumForHeader(ctx, tx.DenominatedFeeCurrency(), header) - if err == nil { - fields["effectiveGasPrice"] = hexutil.Uint64(new(big.Int).Add(gasPriceMinimum, tx.EffectiveGasTipValue(gasPriceMinimum)).Uint64()) - } - // if err != nil, it's due to a state prune. In this case no effectiveGasPrice will be returned. - } else { - fields["effectiveGasPrice"] = hexutil.Uint64(tx.GasPrice().Uint64()) - } + fields, err := generateReceiptResponse(ctx, s.b, receipt, signer, tx, blockHash, blockNumber, index) + if err != nil { + return nil, err } return fields, nil } @@ -1714,7 +1728,10 @@ func (s *PublicTransactionPoolAPI) GetBlockReceipt(ctx context.Context, hash com } else { receipt = receipts[index] } - fields := generateReceiptResponse(receipt, nil, nil, hash, blockNumber, index) + fields, err := generateReceiptResponse(ctx, s.b, receipt, nil, nil, hash, blockNumber, index) + if err != nil { + return nil, err + } return fields, nil } @@ -2074,8 +2091,8 @@ func toHexSlice(b [][]byte) []string { return r } -// generateReceiptResponse is a helper function which generates the response for GetTransactionReceipt() and GetBlockReceipt() -func generateReceiptResponse(receipt *types.Receipt, signer types.Signer, tx *types.Transaction, blockHash common.Hash, blockNumber uint64, index uint64) map[string]interface{} { +// generateReceiptResponse is a helper function which generates the response for GetTransactionReceipt(), GetBlockReceipt() and GetBlockReceipts() +func generateReceiptResponse(ctx context.Context, backend Backend, receipt *types.Receipt, signer types.Signer, tx *types.Transaction, blockHash common.Hash, blockNumber uint64, index uint64) (map[string]interface{}, error) { fields := map[string]interface{}{ "blockHash": blockHash, "blockNumber": hexutil.Uint64(blockNumber), @@ -2111,7 +2128,26 @@ func generateReceiptResponse(receipt *types.Receipt, signer types.Signer, tx *ty // Derive the sender. fields["from"], _ = types.Sender(signer, tx) fields["to"] = tx.To() - + // Assign the effective gas price paid + if backend.ChainConfig().IsLondon(new(big.Int).SetUint64(blockNumber)) { + fields["effectiveGasPrice"] = hexutil.Uint64(tx.GasPrice().Uint64()) + } else { + // var gasPrice *big.Int = new(big.Int) + if tx.Type() == types.DynamicFeeTxType || tx.Type() == types.CeloDynamicFeeTxType || tx.Type() == types.CeloDynamicFeeTxV2Type || tx.Type() == types.CeloDenominatedTxType { + header, err := backend.HeaderByHash(ctx, blockHash) + if err != nil { + return nil, err + } + gasPriceMinimum, err := backend.GasPriceMinimumForHeader(ctx, tx.DenominatedFeeCurrency(), header) + if err == nil { + fields["effectiveGasPrice"] = hexutil.Uint64(new(big.Int).Add(gasPriceMinimum, tx.EffectiveGasTipValue(gasPriceMinimum)).Uint64()) + } + // if err != nil, it's due to a state prune. In this case no effectiveGasPrice will be returned. + } else { + fields["effectiveGasPrice"] = hexutil.Uint64(tx.GasPrice().Uint64()) + } + } } - return fields + + return fields, nil } diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index 551a728f80..ebdf3f3b0c 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -452,6 +452,11 @@ web3._extend({ params: 1, outputFormatter: web3._extend.formatters.outputTransactionReceiptFormatter }), + new web3._extend.Method({ + name: 'getBlockReceipts', + call: 'eth_getBlockReceipts', + params: 1, + }), new web3._extend.Method({ name: 'getRawTransaction', call: 'eth_getRawTransactionByHash', From b1cd99a8c83b0aa96d5d0bcd2ab330f75b682c3e Mon Sep 17 00:00:00 2001 From: Paul Lange Date: Wed, 10 Apr 2024 11:32:09 +0200 Subject: [PATCH 5/9] Update minimal go version in modfile (#2294) * Increase minimum go version * Run `go mod tidy` after go version increase --- go.mod | 62 ++++++++++++++++++++++++++++++++++++++++++++++------------ go.sum | 61 +++------------------------------------------------------ 2 files changed, 52 insertions(+), 71 deletions(-) diff --git a/go.mod b/go.mod index 88896b6449..80b97188e5 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,9 @@ module github.com/celo-org/celo-blockchain -go 1.15 +go 1.19 require ( - github.com/Azure/azure-pipeline-go v0.2.2 // indirect github.com/Azure/azure-storage-blob-go v0.7.0 - github.com/Azure/go-autorest/autorest/adal v0.8.0 // indirect - github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect github.com/VictoriaMetrics/fastcache v1.6.0 github.com/aws/aws-sdk-go-v2 v1.2.0 github.com/aws/aws-sdk-go-v2/config v1.1.1 @@ -23,14 +20,10 @@ require ( github.com/consensys/gnark-crypto v0.12.1 github.com/davecgh/go-spew v1.1.1 github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea - github.com/deepmap/oapi-codegen v1.8.2 // indirect - github.com/dlclark/regexp2 v1.2.0 // indirect github.com/docker/docker v24.0.9+incompatible github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498 github.com/fatih/color v1.7.0 github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 - github.com/go-ole/go-ole v1.2.5 // indirect - github.com/go-sourcemap/sourcemap v2.1.2+incompatible // indirect github.com/go-stack/stack v1.8.0 github.com/golang/protobuf v1.4.3 github.com/golang/snappy v0.0.4 @@ -46,16 +39,13 @@ require ( github.com/huin/goupnp v1.0.2 github.com/influxdata/influxdb v1.8.3 github.com/influxdata/influxdb-client-go/v2 v2.4.0 - github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458 github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e github.com/julienschmidt/httprouter v1.2.0 github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356 - github.com/kylelemons/godebug v1.1.0 // indirect github.com/logrusorgru/aurora v2.0.3+incompatible github.com/mattn/go-colorable v0.1.8 github.com/mattn/go-isatty v0.0.12 - github.com/naoina/go-stringutil v0.1.0 // indirect github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 github.com/olekukonko/tablewriter v0.0.5 github.com/onsi/gomega v1.10.1 @@ -67,17 +57,63 @@ require ( github.com/shopspring/decimal v1.2.0 github.com/stretchr/testify v1.8.2 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 - github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef golang.org/x/crypto v0.17.0 - golang.org/x/net v0.17.0 // indirect golang.org/x/sync v0.1.0 golang.org/x/sys v0.15.0 golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 gopkg.in/urfave/cli.v1 v1.20.0 +) + +require ( + filippo.io/edwards25519 v1.0.0-alpha.2 // indirect + github.com/Azure/azure-pipeline-go v0.2.2 // indirect + github.com/Azure/go-autorest/autorest/adal v0.8.0 // indirect + github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.1.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.1.1 // indirect + github.com/aws/smithy-go v1.1.0 // indirect + github.com/bits-and-blooms/bitset v1.7.0 // indirect + github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect + github.com/celo-org/celo-bls-go-android v0.3.3 // indirect + github.com/celo-org/celo-bls-go-ios v0.3.3 // indirect + github.com/celo-org/celo-bls-go-linux v0.3.3 // indirect + github.com/celo-org/celo-bls-go-macos v0.3.3 // indirect + github.com/celo-org/celo-bls-go-other v0.3.3 // indirect + github.com/celo-org/celo-bls-go-windows v0.3.3 // indirect + github.com/consensys/bavard v0.1.13 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/deepmap/oapi-codegen v1.8.2 // indirect + github.com/dlclark/regexp2 v1.2.0 // indirect + github.com/go-ole/go-ole v1.2.5 // indirect + github.com/go-sourcemap/sourcemap v2.1.2+incompatible // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect + github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/mitchellh/mapstructure v1.4.1 // indirect + github.com/mitchellh/pointerstructure v1.2.0 // indirect + github.com/mmcloughlin/addchain v0.4.0 // indirect + github.com/naoina/go-stringutil v0.1.0 // indirect + github.com/opentracing/opentracing-go v1.1.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect + github.com/tklauser/go-sysconf v0.3.5 // indirect + github.com/tklauser/numcpus v0.2.2 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + google.golang.org/protobuf v1.23.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect + rsc.io/tmplfunc v0.0.3 // indirect ) // Use our fork which disables bitcode diff --git a/go.sum b/go.sum index 894b847b5b..cfc8f2ee3e 100644 --- a/go.sum +++ b/go.sum @@ -35,7 +35,6 @@ github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSW github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc= github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= @@ -85,12 +84,10 @@ github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13P github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= github.com/btcsuite/btcd v0.23.2 h1:/YOgUp25sdCnP5ho6Hl3s0E438zlX+Kak7E6TgBgoT0= github.com/btcsuite/btcd v0.23.2/go.mod h1:0QJIIN1wwIXF/3G/m87gIwGniDMDQqjVn4SZgnFpsYY= -github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA= github.com/btcsuite/btcd/btcec/v2 v2.1.1/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= github.com/btcsuite/btcd/btcec/v2 v2.1.3 h1:xM/n3yIhHAhHy04z4i43C8p4ehixJZMsnrVJkgl+MTE= github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A= -github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE= github.com/btcsuite/btcd/btcutil v1.1.1 h1:hDcDaXiP0uEzR8Biqo2weECKqEw0uHDZ9ixIWevVQqY= github.com/btcsuite/btcd/btcutil v1.1.1/go.mod h1:nbKlBMNm9FGsdvKvu0essceubPiAcI57pYBNnsLAa34= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= @@ -126,7 +123,6 @@ github.com/celo-org/mobile v0.0.0-20210324213558-66ac87d7fb95/go.mod h1:skQtrUTU github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -141,8 +137,6 @@ github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -165,8 +159,6 @@ github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMa github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk= github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= -github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v24.0.9+incompatible h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKsAqcl4G0Of9v0= github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498 h1:Y9vTBSsV4hSwPSj4bacAU/eSnV3dAxVpepaghAdhGoQ= @@ -323,19 +315,15 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= -github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= @@ -401,7 +389,6 @@ github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQm github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -425,12 +412,11 @@ github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1 github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeCE= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= @@ -445,9 +431,7 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -477,7 +461,6 @@ github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPU github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -494,10 +477,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -525,9 +504,6 @@ golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKG golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -549,11 +525,6 @@ golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -568,7 +539,6 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -604,37 +574,16 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -669,9 +618,6 @@ golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -725,7 +671,6 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= From 7859a7830e69b2b1933d0ccd5ab2058c344b0e19 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Apr 2024 09:52:24 +0000 Subject: [PATCH 6/9] chore(deps): update module golang.org/x/net to v0.23.0 [security] (#2296) Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 80b97188e5..0997b51ea5 100644 --- a/go.mod +++ b/go.mod @@ -58,9 +58,9 @@ require ( github.com/stretchr/testify v1.8.2 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef - golang.org/x/crypto v0.17.0 + golang.org/x/crypto v0.21.0 golang.org/x/sync v0.1.0 - golang.org/x/sys v0.15.0 + golang.org/x/sys v0.18.0 golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 @@ -106,7 +106,7 @@ require ( github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tklauser/numcpus v0.2.2 // indirect - golang.org/x/net v0.17.0 // indirect + golang.org/x/net v0.23.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/protobuf v1.23.0 // indirect diff --git a/go.sum b/go.sum index cfc8f2ee3e..0d5ee2481c 100644 --- a/go.sum +++ b/go.sum @@ -479,6 +479,8 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -527,6 +529,8 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -576,6 +580,8 @@ golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= From d832d98cea1f1ab7187ac0169b27642bd3767bf1 Mon Sep 17 00:00:00 2001 From: piersy Date: Thu, 11 Apr 2024 10:34:13 +0100 Subject: [PATCH 7/9] Fix eth_getBlockReceipts (#2295) Updated the api method to take into account the celo block receipt. There was previous confusion around whether eth_getBlockReceipts was working or not, as it had worked for some people but not others. This confusion was caused because block receipts are only added when logs have been generated by system calls. Before gingerbread, we would update the gas price minimum on every block and hence create a log for the update, but post gingerbread the only updates that are happening are for epoch blocks. Co-authored-by: Paul Lange --- internal/ethapi/api.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 08edaa9c94..6d5346144e 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -837,7 +837,9 @@ func (s *PublicBlockChainAPI) GetBlockReceipts(ctx context.Context, blockNrOrHas return nil, err } txs := block.Transactions() - if len(txs) != len(receipts) { + // We need to account for the block receipt, which if present will mean + // that there is one more receipt than transactions. + if len(txs) != len(receipts) && len(txs)+1 != len(receipts) { return nil, fmt.Errorf("receipts length mismatch: %d vs %d", len(txs), len(receipts)) } @@ -845,7 +847,11 @@ func (s *PublicBlockChainAPI) GetBlockReceipts(ctx context.Context, blockNrOrHas signer := types.MakeSigner(s.b.ChainConfig(), block.Number()) result := make([]map[string]interface{}, len(receipts)) for i, receipt := range receipts { - result[i], err = generateReceiptResponse(ctx, s.b, receipt, signer, txs[i], block.Hash(), block.NumberU64(), uint64(i)) + var tx *types.Transaction + if i < len(txs) { + tx = txs[i] + } + result[i], err = generateReceiptResponse(ctx, s.b, receipt, signer, tx, block.Hash(), block.NumberU64(), uint64(i)) if err != nil { return nil, err } From 6c57fae9321518b1328f5af7b5fc2839e9a51179 Mon Sep 17 00:00:00 2001 From: piersy Date: Fri, 12 Apr 2024 16:07:42 +0100 Subject: [PATCH 8/9] Allow use of "finalized" tag in rpc requests (#2298) * Allow use of finalized tag in rpc requests This PR allows the use of the "finalized" tag to retrieve blocks or headers via the RPC. Using the "finalized" tag is equivalent to using the "latest" tag because all blocks are final in celo. This is to supprt integration with chainlink since their system depends on retrieving finalized blocks. --- e2e_test/e2e_test.go | 34 ++++++++++++++++++++++++++++++++++ internal/jsre/deps/web3.js | 2 +- rpc/types.go | 13 +++++++++++-- rpc/types_test.go | 33 ++++++++++++++++++--------------- 4 files changed, 64 insertions(+), 18 deletions(-) diff --git a/e2e_test/e2e_test.go b/e2e_test/e2e_test.go index 573431065e..fc73486ec6 100644 --- a/e2e_test/e2e_test.go +++ b/e2e_test/e2e_test.go @@ -881,3 +881,37 @@ func TestSettingGingerbreadOnGenesisBlock(t *testing.T) { require.Greater(t, block.BaseFee().Uint64(), uint64(0)) require.Greater(t, block.GasLimit(), uint64(0)) } + +// This test checks that retreiveing the "finalized" block results in the same response as retrieving the "latest" block. +func TestGetFinalizedBlock(t *testing.T) { + ac := test.AccountConfig(2, 2) + gingerbreadBlock := common.Big0 + gc, ec, err := test.BuildConfig(ac, gingerbreadBlock) + require.NoError(t, err) + network, shutdown, err := test.NewNetwork(ac, gc, ec) + require.NoError(t, err) + defer shutdown() + ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) + defer cancel() + + // Wait for at least one block to be built. + err = network.AwaitBlock(ctx, 1) + require.NoError(t, err) + + // Stop one of the two validators, so no more blocks can be created. + err = network[1].Close() + require.NoError(t, err) + + c := network[0].WsClient.GetRPCClient() + h := types.Header{} + err = c.CallContext(ctx, &h, "eth_getHeaderByNumber", "latest") + require.NoError(t, err) + require.GreaterOrEqual(t, h.Number.Uint64(), uint64(1)) + + h2 := types.Header{} + err = c.CallContext(ctx, &h2, "eth_getHeaderByNumber", "finalized") + require.NoError(t, err) + + // Check latest and finalzed block are the same + require.Equal(t, h.Hash(), h2.Hash()) +} diff --git a/internal/jsre/deps/web3.js b/internal/jsre/deps/web3.js index 950576f4d9..522002bff6 100644 --- a/internal/jsre/deps/web3.js +++ b/internal/jsre/deps/web3.js @@ -3696,7 +3696,7 @@ var outputBigNumberFormatter = function (number) { }; var isPredefinedBlockNumber = function (blockNumber) { - return blockNumber === 'latest' || blockNumber === 'pending' || blockNumber === 'earliest'; + return blockNumber === 'latest' || blockNumber === 'pending' || blockNumber === 'earliest' || blockNumber === 'finalized'; }; var inputDefaultBlockNumberFormatter = function (blockNumber) { diff --git a/rpc/types.go b/rpc/types.go index 23f645911d..49e988c336 100644 --- a/rpc/types.go +++ b/rpc/types.go @@ -84,8 +84,10 @@ type RPCTransaction struct { EthCompatible bool `json:"ethCompatible"` } -// UnmarshalJSON parses the given JSON fragment into a BlockNumber. It supports: -// - "latest", "earliest" or "pending" as string arguments +// UnmarshalJSON parses the given JSON fragment into a BlockNumber. It +// supports: - "finalized", latest", "earliest" or "pending" as string +// arguments where finalized is equivalent to latest since all blocks are final +// in celo. // - the block number // Returned errors: // - an invalid block number error when the given argument isn't a known strings @@ -106,6 +108,9 @@ func (bn *BlockNumber) UnmarshalJSON(data []byte) error { case "pending": *bn = PendingBlockNumber return nil + case "finalized": + *bn = LatestBlockNumber + return nil } blckNum, err := hexutil.DecodeUint64(input) @@ -172,6 +177,10 @@ func (bnh *BlockNumberOrHash) UnmarshalJSON(data []byte) error { bn := LatestBlockNumber bnh.BlockNumber = &bn return nil + case "finalized": + bn := LatestBlockNumber + bnh.BlockNumber = &bn + return nil case "pending": bn := PendingBlockNumber bnh.BlockNumber = &bn diff --git a/rpc/types_test.go b/rpc/types_test.go index ec80a14f35..8958b79018 100644 --- a/rpc/types_test.go +++ b/rpc/types_test.go @@ -45,9 +45,10 @@ func TestBlockNumberJSONUnmarshal(t *testing.T) { 11: {`"pending"`, false, PendingBlockNumber}, 12: {`"latest"`, false, LatestBlockNumber}, 13: {`"earliest"`, false, EarliestBlockNumber}, - 14: {`someString`, true, BlockNumber(0)}, - 15: {`""`, true, BlockNumber(0)}, - 16: {``, true, BlockNumber(0)}, + 14: {`"finalized"`, false, LatestBlockNumber}, + 15: {`someString`, true, BlockNumber(0)}, + 16: {`""`, true, BlockNumber(0)}, + 17: {``, true, BlockNumber(0)}, } for i, test := range tests { @@ -87,18 +88,20 @@ func TestBlockNumberOrHash_UnmarshalJSON(t *testing.T) { 11: {`"pending"`, false, BlockNumberOrHashWithNumber(PendingBlockNumber)}, 12: {`"latest"`, false, BlockNumberOrHashWithNumber(LatestBlockNumber)}, 13: {`"earliest"`, false, BlockNumberOrHashWithNumber(EarliestBlockNumber)}, - 14: {`someString`, true, BlockNumberOrHash{}}, - 15: {`""`, true, BlockNumberOrHash{}}, - 16: {``, true, BlockNumberOrHash{}}, - 17: {`"0x0000000000000000000000000000000000000000000000000000000000000000"`, false, BlockNumberOrHashWithHash(common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), false)}, - 18: {`{"blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000"}`, false, BlockNumberOrHashWithHash(common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), false)}, - 19: {`{"blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","requireCanonical":false}`, false, BlockNumberOrHashWithHash(common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), false)}, - 20: {`{"blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","requireCanonical":true}`, false, BlockNumberOrHashWithHash(common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), true)}, - 21: {`{"blockNumber":"0x1"}`, false, BlockNumberOrHashWithNumber(1)}, - 22: {`{"blockNumber":"pending"}`, false, BlockNumberOrHashWithNumber(PendingBlockNumber)}, - 23: {`{"blockNumber":"latest"}`, false, BlockNumberOrHashWithNumber(LatestBlockNumber)}, - 24: {`{"blockNumber":"earliest"}`, false, BlockNumberOrHashWithNumber(EarliestBlockNumber)}, - 25: {`{"blockNumber":"0x1", "blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000"}`, true, BlockNumberOrHash{}}, + 14: {`"finalized"`, false, BlockNumberOrHashWithNumber(LatestBlockNumber)}, + 15: {`someString`, true, BlockNumberOrHash{}}, + 16: {`""`, true, BlockNumberOrHash{}}, + 17: {``, true, BlockNumberOrHash{}}, + 18: {`"0x0000000000000000000000000000000000000000000000000000000000000000"`, false, BlockNumberOrHashWithHash(common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), false)}, + 19: {`{"blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000"}`, false, BlockNumberOrHashWithHash(common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), false)}, + 20: {`{"blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","requireCanonical":false}`, false, BlockNumberOrHashWithHash(common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), false)}, + 21: {`{"blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000","requireCanonical":true}`, false, BlockNumberOrHashWithHash(common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), true)}, + 22: {`{"blockNumber":"0x1"}`, false, BlockNumberOrHashWithNumber(1)}, + 23: {`{"blockNumber":"pending"}`, false, BlockNumberOrHashWithNumber(PendingBlockNumber)}, + 24: {`{"blockNumber":"latest"}`, false, BlockNumberOrHashWithNumber(LatestBlockNumber)}, + 25: {`{"blockNumber":"earliest"}`, false, BlockNumberOrHashWithNumber(EarliestBlockNumber)}, + 26: {`{"blockNumber":"finalized"}`, false, BlockNumberOrHashWithNumber(LatestBlockNumber)}, + 27: {`{"blockNumber":"0x1", "blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000"}`, true, BlockNumberOrHash{}}, } for i, test := range tests { From 15ad6b180dcf79ec0a202b56346cf79c4eb7f651 Mon Sep 17 00:00:00 2001 From: Paul Lange Date: Wed, 17 Apr 2024 13:00:40 +0200 Subject: [PATCH 9/9] Add `--json` flag to `mycelo env` (#2300) * chore: remove unused code * mycelo: Add `--json` flag to `mycelo env` --- cmd/mycelo/env_commands.go | 30 +++++++++++++++++++++++++- mycelo/env/accounts.go | 44 -------------------------------------- 2 files changed, 29 insertions(+), 45 deletions(-) diff --git a/cmd/mycelo/env_commands.go b/cmd/mycelo/env_commands.go index a469d9aa18..3205b85aa9 100644 --- a/cmd/mycelo/env_commands.go +++ b/cmd/mycelo/env_commands.go @@ -1,6 +1,7 @@ package main import ( + "encoding/json" "fmt" "github.com/celo-org/celo-blockchain/cmd/utils" @@ -22,6 +23,7 @@ var getAccountCommand = cli.Command{ Flags: []cli.Flag{ idxFlag, accountTypeFlag, + jsonFlag, }, } @@ -36,6 +38,10 @@ var ( Usage: `Account type (validator, developer, txNode, faucet, attestation, priceOracle, proxy, attestationBot, votingBot, txNodePrivate, validatorGroup, admin)`, Value: &env.DeveloperAT, } + jsonFlag = cli.BoolFlag{ + Name: "json", + Usage: "output json", + } ) func getAccount(ctx *cli.Context) error { @@ -52,6 +58,28 @@ func getAccount(ctx *cli.Context) error { return err } - fmt.Printf("AccountType: %s\nIndex:%d\nAddress: %s\nPrivateKey: %s\n", accountType, idx, account.Address.Hex(), account.PrivateKeyHex()) + jsonOutput := ctx.Bool(jsonFlag.Name) + + if jsonOutput { + output := struct { + AccountType string `json:"accountType"` + Index int `json:"index"` + Address string `json:"address"` + PrivateKey string `json:"privateKey"` + }{ + AccountType: accountType.String(), + Index: idx, + Address: account.Address.Hex(), + PrivateKey: account.PrivateKeyHex(), + } + + jsonData, err := json.Marshal(output) + if err != nil { + return err + } + fmt.Println(string(jsonData)) + } else { + fmt.Printf("AccountType: %s\nIndex:%d\nAddress: %s\nPrivateKey: %s\n", accountType, idx, account.Address.Hex(), account.PrivateKeyHex()) + } return nil } diff --git a/mycelo/env/accounts.go b/mycelo/env/accounts.go index 7a80cce65a..dd38bc9e47 100644 --- a/mycelo/env/accounts.go +++ b/mycelo/env/accounts.go @@ -285,47 +285,3 @@ func DeriveAccountList(mnemonic string, accountType AccountType, qty int) ([]Acc return accounts, nil } - -// MustGenerateRandomAccount creates new account or panics -func MustGenerateRandomAccount() Account { - acc, err := GenerateRandomAccount() - if err != nil { - panic(err) - } - return acc -} - -// GenerateRandomAccount creates a random new account -func GenerateRandomAccount() (Account, error) { - privateKey, err := crypto.GenerateKey() - if err != nil { - return Account{}, err - } - return NewAccount(privateKey), nil -} - -// NewAccount creates a new account for the specified private key -func NewAccount(key *ecdsa.PrivateKey) Account { - return Account{ - PrivateKey: key, - Address: crypto.PubkeyToAddress(key.PublicKey), - } -} - -// UnmarshalJSON implements json.Unmarshaler -func (a *Account) UnmarshalJSON(b []byte) error { - var data struct { - PrivateKey string - Address common.Address - } - if err := json.Unmarshal(b, &data); err != nil { - return err - } - a.Address = data.Address - key, err := crypto.HexToECDSA(data.PrivateKey) - if err != nil { - return err - } - a.PrivateKey = key - return nil -}