From 6eb8de4d9a8af5926060ca2e1712e483875b885d Mon Sep 17 00:00:00 2001 From: Chen Chen <34592639+envestcc@users.noreply.github.com> Date: Sat, 21 Sep 2024 15:23:40 +0800 Subject: [PATCH] [eip1559] basefee into rewardingpool (#4394) --- action/protocol/account/transfer.go | 16 ++-- action/protocol/execution/evm/evm.go | 4 +- action/protocol/execution/evm/evm_test.go | 2 +- action/protocol/poll/consortium.go | 2 +- action/protocol/poll/staking_committee.go | 2 +- action/protocol/protocol.go | 31 +++--- action/protocol/rewarding/fund.go | 94 +++++++++---------- action/protocol/rewarding/protocol.go | 4 +- .../staking/handler_stake_migrate_test.go | 2 +- action/protocol/staking/handlers_test.go | 2 +- action/protocol/staking/protocol.go | 4 +- action/rlp_tx_test.go | 18 ---- go.mod | 2 +- go.sum | 4 +- state/factory/workingset.go | 2 +- 15 files changed, 83 insertions(+), 106 deletions(-) diff --git a/action/protocol/account/transfer.go b/action/protocol/account/transfer.go index dc081fce58..e9dcd5ef7c 100644 --- a/action/protocol/account/transfer.go +++ b/action/protocol/account/transfer.go @@ -41,14 +41,12 @@ func (p *Protocol) handleTransfer(ctx context.Context, elp action.Envelope, sm p return nil, errors.Wrapf(err, "failed to load or create the account of sender %s", actionCtx.Caller.String()) } - gasFee, baseFee, err := protocol.SplitGas(ctx, elp, actionCtx.IntrinsicGas) + priorityFee, baseFee, err := protocol.SplitGas(ctx, elp, actionCtx.IntrinsicGas) if err != nil { return nil, errors.Wrapf(err, "failed to split gas") } - total := big.NewInt(0).Add(tsf.Amount(), gasFee) - if baseFee != nil { - total.Add(total, baseFee) - } + total := big.NewInt(0).Add(tsf.Amount(), priorityFee) + total.Add(total, baseFee) if !sender.HasSufficientBalance(total) { return nil, errors.Wrapf( state.ErrNotEnoughBalance, @@ -62,11 +60,11 @@ func (p *Protocol) handleTransfer(ctx context.Context, elp action.Envelope, sm p var depositLog []*action.TransactionLog if !fCtx.FixDoubleChargeGas { // charge sender gas - if err := sender.SubBalance(gasFee); err != nil { + if err := sender.SubBalance(baseFee); err != nil { return nil, errors.Wrapf(err, "failed to charge the gas for sender %s", actionCtx.Caller.String()) } if p.depositGas != nil { - depositLog, err = p.depositGas(ctx, sm, gasFee) + depositLog, err = p.depositGas(ctx, sm, baseFee) if err != nil { return nil, err } @@ -100,7 +98,7 @@ func (p *Protocol) handleTransfer(ctx context.Context, elp action.Envelope, sm p } if fCtx.FixDoubleChargeGas { if p.depositGas != nil { - depositLog, err = p.depositGas(ctx, sm, gasFee, protocol.BurnGasOption(baseFee, iotextypes.TransactionLogType_NATIVE_TRANSFER)) + depositLog, err = p.depositGas(ctx, sm, baseFee, protocol.PriorityFeeOption(priorityFee)) if err != nil { return nil, err } @@ -142,7 +140,7 @@ func (p *Protocol) handleTransfer(ctx context.Context, elp action.Envelope, sm p if fCtx.FixDoubleChargeGas { if p.depositGas != nil { - depositLog, err = p.depositGas(ctx, sm, gasFee, protocol.BurnGasOption(baseFee, iotextypes.TransactionLogType_NATIVE_TRANSFER)) + depositLog, err = p.depositGas(ctx, sm, baseFee, protocol.PriorityFeeOption(priorityFee)) if err != nil { return nil, err } diff --git a/action/protocol/execution/evm/evm.go b/action/protocol/execution/evm/evm.go index 2ec489afc9..8448b14c45 100644 --- a/action/protocol/execution/evm/evm.go +++ b/action/protocol/execution/evm/evm.go @@ -267,11 +267,11 @@ func ExecuteContract( } } if consumedGas > 0 { - gasFee, baseFee, err := protocol.SplitGas(ctx, execution, consumedGas) + priorityFee, baseFee, err := protocol.SplitGas(ctx, execution, consumedGas) if err != nil { return nil, nil, errors.Wrapf(err, "failed to split gas") } - depositLog, err = ps.helperCtx.DepositGasFunc(ctx, sm, gasFee, protocol.BurnGasOption(baseFee, iotextypes.TransactionLogType_NATIVE_TRANSFER)) + depositLog, err = ps.helperCtx.DepositGasFunc(ctx, sm, baseFee, protocol.PriorityFeeOption(priorityFee)) if err != nil { return nil, nil, err } diff --git a/action/protocol/execution/evm/evm_test.go b/action/protocol/execution/evm/evm_test.go index 014bd60741..12c0214ede 100644 --- a/action/protocol/execution/evm/evm_test.go +++ b/action/protocol/execution/evm/evm_test.go @@ -60,7 +60,7 @@ func TestExecuteContractFailure(t *testing.T) { GetBlockTime: func(uint64) (time.Time, error) { return time.Time{}, nil }, - DepositGasFunc: func(context.Context, protocol.StateManager, *big.Int, ...protocol.Option) ([]*action.TransactionLog, error) { + DepositGasFunc: func(context.Context, protocol.StateManager, *big.Int, ...protocol.DepositOption) ([]*action.TransactionLog, error) { return nil, nil }, }) diff --git a/action/protocol/poll/consortium.go b/action/protocol/poll/consortium.go index bea17c79ff..6fe99b587d 100644 --- a/action/protocol/poll/consortium.go +++ b/action/protocol/poll/consortium.go @@ -127,7 +127,7 @@ func (cc *consortiumCommittee) CreateGenesisStates(ctx context.Context, sm proto return hash.ZeroHash256, nil }, GetBlockTime: getBlockTime, - DepositGasFunc: func(context.Context, protocol.StateManager, *big.Int, ...protocol.Option) ([]*action.TransactionLog, error) { + DepositGasFunc: func(context.Context, protocol.StateManager, *big.Int, ...protocol.DepositOption) ([]*action.TransactionLog, error) { return nil, nil }, }) diff --git a/action/protocol/poll/staking_committee.go b/action/protocol/poll/staking_committee.go index 684115fe72..11a1fc238b 100644 --- a/action/protocol/poll/staking_committee.go +++ b/action/protocol/poll/staking_committee.go @@ -135,7 +135,7 @@ func (sc *stakingCommittee) CreateGenesisStates(ctx context.Context, sm protocol // make sure the returned timestamp is after the current block time so that evm upgrades based on timestamp (Shanghai and onwards) are disabled return blkCtx.BlockTimeStamp.Add(5 * time.Second), nil }, - DepositGasFunc: func(context.Context, protocol.StateManager, *big.Int, ...protocol.Option) ([]*action.TransactionLog, error) { + DepositGasFunc: func(context.Context, protocol.StateManager, *big.Int, ...protocol.DepositOption) ([]*action.TransactionLog, error) { return nil, nil }, }) diff --git a/action/protocol/protocol.go b/action/protocol/protocol.go index 466c5d9b02..9273315b2c 100644 --- a/action/protocol/protocol.go +++ b/action/protocol/protocol.go @@ -11,7 +11,6 @@ import ( "github.com/iotexproject/go-pkgs/hash" "github.com/iotexproject/iotex-address/address" - "github.com/iotexproject/iotex-proto/golang/iotextypes" "github.com/pkg/errors" "go.uber.org/zap" @@ -81,23 +80,28 @@ type ActionHandler interface { } type ( - Options struct { - BurnAmount *big.Int - BurnLogType iotextypes.TransactionLogType + DepositOptionCfg struct { + PriorityFee *big.Int + BlobGasFee *big.Int } - Option func(*Options) + DepositOption func(*DepositOptionCfg) ) -func BurnGasOption(amount *big.Int, logType iotextypes.TransactionLogType) Option { - return func(opts *Options) { - opts.BurnAmount = amount - opts.BurnLogType = logType +func PriorityFeeOption(priorityFee *big.Int) DepositOption { + return func(opts *DepositOptionCfg) { + opts.PriorityFee = priorityFee + } +} + +func BlobGasFeeOption(blobGasFee *big.Int) DepositOption { + return func(opts *DepositOptionCfg) { + opts.BlobGasFee = blobGasFee } } // DepositGas deposits gas to rewarding pool and burns baseFee -type DepositGas func(context.Context, StateManager, *big.Int, ...Option) ([]*action.TransactionLog, error) +type DepositGas func(context.Context, StateManager, *big.Int, ...DepositOption) ([]*action.TransactionLog, error) // View stores the view for all protocols type View map[string]interface{} @@ -129,13 +133,14 @@ func SplitGas(ctx context.Context, tx action.TxDynamicGas, usedGas uint64) (*big baseFee = MustGetBlockchainCtx(ctx).Tip.BaseFee gas = new(big.Int).SetUint64(usedGas) ) + if baseFee == nil { + // treat as basefee if before enabling EIP-1559 + return new(big.Int), new(big.Int).Mul(tx.GasFeeCap(), gas), nil + } priority, err := action.EffectiveGasTip(tx, baseFee) if err != nil { return nil, nil, err } - if baseFee == nil { - return priority.Mul(priority, gas), nil, nil - } // after enabling EIP-1559, fee is split into 2 parts // priority fee goes to the rewarding pool (or block producer) as before // base fee will be burnt diff --git a/action/protocol/rewarding/fund.go b/action/protocol/rewarding/fund.go index dd5ae40900..470a9bbe99 100644 --- a/action/protocol/rewarding/fund.go +++ b/action/protocol/rewarding/fund.go @@ -63,20 +63,14 @@ func (p *Protocol) Deposit( sm protocol.StateManager, amount *big.Int, transactionLogType iotextypes.TransactionLogType, - opts ...protocol.Option, ) ([]*action.TransactionLog, error) { + if isZero(amount) { + return nil, nil + } var ( actionCtx = protocol.MustGetActionCtx(ctx) accountCreationOpts = []state.AccountCreationOption{} - options = protocol.Options{} ) - // apply protocol options - for _, o := range opts { - o(&options) - } - if isZero(amount) && isZero(options.BurnAmount) { - return nil, nil - } if protocol.MustGetFeatureCtx(ctx).CreateLegacyNonceAccount { accountCreationOpts = append(accountCreationOpts, state.LegacyNonceAccountTypeOption()) } @@ -85,58 +79,28 @@ func (p *Protocol) Deposit( if err != nil { return nil, err } - if !isZero(amount) { - if err := acc.SubBalance(amount); err != nil { - return nil, err - } - } - burnAmount := options.BurnAmount - if !isZero(burnAmount) { - if err := acc.SubBalance(burnAmount); err != nil { - return nil, err - } + if err := acc.SubBalance(amount); err != nil { + return nil, err } if err := accountutil.StoreAccount(sm, actionCtx.Caller, acc); err != nil { return nil, err } // Add balance to fund var ( - f = fund{} - burnAddr, _ = address.FromString(address.ZeroAddress) - tLog = []*action.TransactionLog{} + f = fund{} + tLog = []*action.TransactionLog{} ) - if !isZero(amount) { - tLog = append(tLog, &action.TransactionLog{ - Type: transactionLogType, - Sender: actionCtx.Caller.String(), - Recipient: address.RewardingPoolAddr, - Amount: amount, - }) - } + tLog = append(tLog, &action.TransactionLog{ + Type: transactionLogType, + Sender: actionCtx.Caller.String(), + Recipient: address.RewardingPoolAddr, + Amount: amount, + }) if _, err := p.state(ctx, sm, _fundKey, &f); err != nil { return nil, err } f.totalBalance = big.NewInt(0).Add(f.totalBalance, amount) f.unclaimedBalance = big.NewInt(0).Add(f.unclaimedBalance, amount) - if !isZero(burnAmount) { - // add burnAmount to burnAddr - burn, err := accountutil.LoadAccount(sm, burnAddr, accountCreationOpts...) - if err != nil { - return nil, err - } - if err := burn.AddBalance(burnAmount); err != nil { - return nil, err - } - if err := accountutil.StoreAccount(sm, burnAddr, burn); err != nil { - return nil, err - } - tLog = append(tLog, &action.TransactionLog{ - Type: options.BurnLogType, - Sender: actionCtx.Caller.String(), - Recipient: burnAddr.String(), - Amount: burnAmount, - }) - } if err := p.putState(ctx, sm, _fundKey, &f); err != nil { return nil, err } @@ -170,7 +134,7 @@ func (p *Protocol) AvailableBalance( } // DepositGas deposits gas into the rewarding fund -func DepositGas(ctx context.Context, sm protocol.StateManager, amount *big.Int, opts ...protocol.Option) ([]*action.TransactionLog, error) { +func DepositGas(ctx context.Context, sm protocol.StateManager, amount *big.Int, opts ...protocol.DepositOption) ([]*action.TransactionLog, error) { // TODO: we bypass the gas deposit for the actions in genesis block. Later we should remove this after we remove // genesis actions blkCtx := protocol.MustGetBlockCtx(ctx) @@ -185,7 +149,35 @@ func DepositGas(ctx context.Context, sm protocol.StateManager, amount *big.Int, if rp == nil { return nil, nil } - return rp.Deposit(ctx, sm, amount, iotextypes.TransactionLogType_GAS_FEE, opts...) + var ( + logs []*action.TransactionLog + err error + ) + if !isZero(amount) { + logs, err = rp.Deposit(ctx, sm, amount, iotextypes.TransactionLogType_GAS_FEE) + if err != nil { + return nil, err + } + } + cfg := protocol.DepositOptionCfg{} + for _, opt := range opts { + opt(&cfg) + } + if !isZero(cfg.PriorityFee) { + slogs, err := rp.Deposit(ctx, sm, cfg.PriorityFee, iotextypes.TransactionLogType_PRIORITY_FEE) + if err != nil { + return nil, err + } + logs = append(logs, slogs...) + } + if !isZero(cfg.BlobGasFee) { + slogs, err := rp.Deposit(ctx, sm, cfg.BlobGasFee, iotextypes.TransactionLogType_BLOB_FEE) + if err != nil { + return nil, err + } + logs = append(logs, slogs...) + } + return logs, nil } func isZero(a *big.Int) bool { diff --git a/action/protocol/rewarding/protocol.go b/action/protocol/rewarding/protocol.go index c138f0c9fe..4a5eb582d5 100644 --- a/action/protocol/rewarding/protocol.go +++ b/action/protocol/rewarding/protocol.go @@ -424,11 +424,11 @@ func (p *Protocol) settleAction( } skipUpdateForSystemAction := protocol.MustGetFeatureCtx(ctx).FixGasAndNonceUpdate if !isSystemAction || !skipUpdateForSystemAction { - gasFee, baseFee, err := protocol.SplitGas(ctx, act, actionCtx.IntrinsicGas) + priorityFee, baseFee, err := protocol.SplitGas(ctx, act, actionCtx.IntrinsicGas) if err != nil { return nil, errors.Wrapf(err, "failed to split gas") } - depositLog, err := DepositGas(ctx, sm, gasFee, protocol.BurnGasOption(baseFee, iotextypes.TransactionLogType_NATIVE_TRANSFER)) + depositLog, err := DepositGas(ctx, sm, baseFee, protocol.PriorityFeeOption(priorityFee)) if err != nil { return nil, err } diff --git a/action/protocol/staking/handler_stake_migrate_test.go b/action/protocol/staking/handler_stake_migrate_test.go index 578ad89e03..a2f3d203a5 100644 --- a/action/protocol/staking/handler_stake_migrate_test.go +++ b/action/protocol/staking/handler_stake_migrate_test.go @@ -153,7 +153,7 @@ func TestHandleStakeMigrate(t *testing.T) { r.Equal(uint64(iotextypes.ReceiptStatus_Success), receipts[1].Status) excPrtl := execution.NewProtocol( func(u uint64) (hash.Hash256, error) { return hash.ZeroHash256, nil }, - func(context.Context, protocol.StateManager, *big.Int, ...protocol.Option) ([]*action.TransactionLog, error) { + func(context.Context, protocol.StateManager, *big.Int, ...protocol.DepositOption) ([]*action.TransactionLog, error) { return nil, nil }, func(uint64) (time.Time, error) { return time.Now(), nil }, diff --git a/action/protocol/staking/handlers_test.go b/action/protocol/staking/handlers_test.go index 29d91c0030..37fdbabaed 100644 --- a/action/protocol/staking/handlers_test.go +++ b/action/protocol/staking/handlers_test.go @@ -3307,7 +3307,7 @@ func setupAccount(sm protocol.StateManager, addr address.Address, balance int64) return accountutil.StoreAccount(sm, addr, account) } -func depositGas(ctx context.Context, sm protocol.StateManager, gasFee *big.Int, opts ...protocol.Option) ([]*action.TransactionLog, error) { +func depositGas(ctx context.Context, sm protocol.StateManager, gasFee *big.Int, opts ...protocol.DepositOption) ([]*action.TransactionLog, error) { actionCtx := protocol.MustGetActionCtx(ctx) // Subtract balance from caller acc, err := accountutil.LoadAccount(sm, actionCtx.Caller) diff --git a/action/protocol/staking/protocol.go b/action/protocol/staking/protocol.go index 6f2e77ea72..8f2714d7ba 100644 --- a/action/protocol/staking/protocol.go +++ b/action/protocol/staking/protocol.go @@ -698,11 +698,11 @@ func (p *Protocol) settleAction( actionCtx = protocol.MustGetActionCtx(ctx) blkCtx = protocol.MustGetBlockCtx(ctx) ) - gasFee, baseFee, err := protocol.SplitGas(ctx, act, gasToBeDeducted) + priorityFee, baseFee, err := protocol.SplitGas(ctx, act, gasToBeDeducted) if err != nil { return nil, errors.Wrapf(err, "failed to split gas") } - depositLog, err := p.helperCtx.DepositGas(ctx, sm, gasFee, protocol.BurnGasOption(baseFee, iotextypes.TransactionLogType_NATIVE_TRANSFER)) + depositLog, err := p.helperCtx.DepositGas(ctx, sm, baseFee, protocol.PriorityFeeOption(priorityFee)) if err != nil { return nil, errors.Wrap(err, "failed to deposit gas") } diff --git a/action/rlp_tx_test.go b/action/rlp_tx_test.go index 81cafd118e..74fc9fe6d6 100644 --- a/action/rlp_tx_test.go +++ b/action/rlp_tx_test.go @@ -291,24 +291,6 @@ var ( } ) -func TestNewEthSignerError(t *testing.T) { - require := require.New(t) - singer, err := NewEthSigner(iotextypes.Encoding_ETHEREUM_ACCESSLIST, 1) - require.ErrorIs(err, ErrInvalidAct) - require.Nil(singer) - - tx := types.NewTx(&types.DynamicFeeTx{ - To: nil, - Nonce: 4, - Value: big.NewInt(4), - Gas: 4, - GasTipCap: big.NewInt(44), - GasFeeCap: big.NewInt(1045), - }) - _, _, _, err = ExtractTypeSigPubkey(tx) - require.ErrorIs(err, ErrNotSupported) -} - func TestEthTxDecodeVerify(t *testing.T) { require := require.New(t) var ( diff --git a/go.mod b/go.mod index c8456f4c47..e5914b71a4 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,7 @@ require ( github.com/iotexproject/iotex-address v0.2.8 github.com/iotexproject/iotex-antenna-go/v2 v2.5.1 github.com/iotexproject/iotex-election v0.3.5-0.20210611041425-20ddf674363d - github.com/iotexproject/iotex-proto v0.6.4-0.20240921015631-53754f857c48 + github.com/iotexproject/iotex-proto v0.6.4-0.20240921011815-fc5513dc9564 github.com/ipfs/go-ipfs-api v0.7.0 github.com/libp2p/go-libp2p v0.32.2 github.com/mackerelio/go-osstat v0.2.4 diff --git a/go.sum b/go.sum index 958fb372bb..5e421b1778 100644 --- a/go.sum +++ b/go.sum @@ -1184,8 +1184,8 @@ github.com/iotexproject/iotex-antenna-go/v2 v2.5.1/go.mod h1:8pDZcM45M0gY6jm3PoM github.com/iotexproject/iotex-election v0.3.5-0.20210611041425-20ddf674363d h1:/j1xCAC9YiG/8UKqYvycS/v3ddVsb1G7AMyLXOjeYI0= github.com/iotexproject/iotex-election v0.3.5-0.20210611041425-20ddf674363d/go.mod h1:GRWevxtqQ4gPMrd7Qxhr29/7aTgvjiTp+rFI9KMMZEo= github.com/iotexproject/iotex-proto v0.5.0/go.mod h1:Xg6REkv+nTZN+OC22xXIQuqKdTWWHwOAJEXCoMpDwtI= -github.com/iotexproject/iotex-proto v0.6.4-0.20240921015631-53754f857c48 h1:TwlS6DHX+feaUezPjkKvBWsd9KOvbNvkxVTjKsfuvfU= -github.com/iotexproject/iotex-proto v0.6.4-0.20240921015631-53754f857c48/go.mod h1:Hxct427jhlu08PHQ44Jwh//hZVhXKq+XO/Mdqwc6dNc= +github.com/iotexproject/iotex-proto v0.6.4-0.20240921011815-fc5513dc9564 h1:k2jID4GQObL6rBXVsDNolNp6Vwbzs8o/3UrzxsmsZkU= +github.com/iotexproject/iotex-proto v0.6.4-0.20240921011815-fc5513dc9564/go.mod h1:Hxct427jhlu08PHQ44Jwh//hZVhXKq+XO/Mdqwc6dNc= github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= github.com/ipfs/boxo v0.8.1/go.mod h1:xJ2hVb4La5WyD7GvKYE0lq2g1rmQZoCD2K4WNrV6aZI= diff --git a/state/factory/workingset.go b/state/factory/workingset.go index 6d70a9b775..857b734206 100644 --- a/state/factory/workingset.go +++ b/state/factory/workingset.go @@ -215,7 +215,7 @@ func (ws *workingSet) handleBlob(ctx context.Context, act *action.SealedEnvelope receipt.BlobGasUsed = act.BlobGas() receipt.BlobGasPrice = block.CalcBlobFee(protocol.MustGetBlockchainCtx(ctx).Tip.ExcessBlobGas) blobFee := new(big.Int).Mul(receipt.BlobGasPrice, new(big.Int).SetUint64(receipt.BlobGasUsed)) - logs, err := rewarding.DepositGas(ctx, ws, nil, protocol.BurnGasOption(blobFee, iotextypes.TransactionLogType_BLOB_FEE)) + logs, err := rewarding.DepositGas(ctx, ws, new(big.Int), protocol.BlobGasFeeOption(blobFee)) if err != nil { return err }