Skip to content

Commit

Permalink
Merge branch 'master' into jcortejoso/container-ci-cd-refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
jcortejoso authored Apr 18, 2024
2 parents 7ed73a3 + 15ad6b1 commit 599128a
Show file tree
Hide file tree
Showing 42 changed files with 748 additions and 466 deletions.
1 change: 1 addition & 0 deletions accounts/abi/bind/backends/simulated.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion accounts/external/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
30 changes: 29 additions & 1 deletion cmd/mycelo/env_commands.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"encoding/json"
"fmt"

"github.com/celo-org/celo-blockchain/cmd/utils"
Expand All @@ -22,6 +23,7 @@ var getAccountCommand = cli.Command{
Flags: []cli.Flag{
idxFlag,
accountTypeFlag,
jsonFlag,
},
}

Expand All @@ -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 {
Expand All @@ -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
}
4 changes: 2 additions & 2 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down Expand Up @@ -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{
Expand Down
13 changes: 0 additions & 13 deletions common/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
14 changes: 10 additions & 4 deletions contracts/erc20gas/erc20gas.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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 {
Expand Down
10 changes: 10 additions & 0 deletions core/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
)
4 changes: 4 additions & 0 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
79 changes: 66 additions & 13 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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())
Expand All @@ -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 {
Expand All @@ -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
}

Expand All @@ -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 {
Expand Down Expand Up @@ -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)
}
Expand All @@ -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
}
Expand All @@ -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)
}
}

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
}
Expand All @@ -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
}
Expand All @@ -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()
Expand Down
Loading

0 comments on commit 599128a

Please sign in to comment.