diff --git a/action/actctx.go b/action/actctx.go index 26fd70ed98..25f42be2bf 100644 --- a/action/actctx.go +++ b/action/actctx.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019 IoTeX Foundation +// Copyright (c) 2024 IoTeX Foundation // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. @@ -14,11 +14,13 @@ import ( // AbstractAction is an abstract implementation of Action interface type AbstractAction struct { - version uint32 - chainID uint32 - nonce uint64 - gasLimit uint64 - gasPrice *big.Int + version uint32 + chainID uint32 + nonce uint64 + gasLimit uint64 + gasPrice *big.Int + gasTipCap *big.Int + gasFeeCap *big.Int } // Version returns the version @@ -57,6 +59,22 @@ func (act *AbstractAction) SetGasPrice(val *big.Int) { act.gasPrice = val } +// GasTipCap returns the gas tip cap +func (act *AbstractAction) GasTipCap() *big.Int { + if act.gasTipCap == nil { + return act.GasPrice() + } + return new(big.Int).Set(act.gasTipCap) +} + +// GasFeeCap returns the gas fee cap +func (act *AbstractAction) GasFeeCap() *big.Int { + if act.gasFeeCap == nil { + return act.GasPrice() + } + return new(big.Int).Set(act.gasFeeCap) +} + // BasicActionSize returns the basic size of action func (act *AbstractAction) BasicActionSize() uint32 { // VersionSizeInBytes + NonceSizeInBytes + GasSizeInBytes @@ -69,21 +87,32 @@ func (act *AbstractAction) BasicActionSize() uint32 { } // SetEnvelopeContext sets the struct according to input -func (act *AbstractAction) SetEnvelopeContext(elp Envelope) { +func (act *AbstractAction) SetEnvelopeContext(in *AbstractAction) { if act == nil { return } - act.version = elp.Version() - act.chainID = elp.ChainID() - act.nonce = elp.Nonce() - act.gasLimit = elp.GasLimit() - act.gasPrice = elp.GasPrice() + *act = *in + if in.gasPrice != nil { + act.gasPrice = new(big.Int).Set(in.gasPrice) + } + if in.gasTipCap != nil { + act.gasTipCap = new(big.Int).Set(in.gasTipCap) + } + if in.gasFeeCap != nil { + act.gasFeeCap = new(big.Int).Set(in.gasFeeCap) + } } // SanityCheck validates the variables in the action func (act *AbstractAction) SanityCheck() error { // Reject execution of negative gas price - if act.GasPrice().Sign() < 0 { + if act.gasPrice != nil && act.gasPrice.Sign() < 0 { + return ErrNegativeValue + } + if act.gasTipCap != nil && act.gasTipCap.Sign() < 0 { + return ErrNegativeValue + } + if act.gasFeeCap != nil && act.gasFeeCap.Sign() < 0 { return ErrNegativeValue } return nil @@ -99,6 +128,12 @@ func (act *AbstractAction) toProto() *iotextypes.ActionCore { if act.gasPrice != nil { actCore.GasPrice = act.gasPrice.String() } + if act.gasTipCap != nil { + actCore.GasTipCap = act.gasTipCap.String() + } + if act.gasFeeCap != nil { + actCore.GasFeeCap = act.gasFeeCap.String() + } return &actCore } @@ -107,12 +142,27 @@ func (act *AbstractAction) fromProto(pb *iotextypes.ActionCore) error { act.nonce = pb.GetNonce() act.gasLimit = pb.GetGasLimit() act.chainID = pb.GetChainID() + + var ok bool if price := pb.GetGasPrice(); price == "" { act.gasPrice = &big.Int{} } else { - var ok bool if act.gasPrice, ok = new(big.Int).SetString(price, 10); !ok { - return errors.Errorf("invalid gas prcie %s", price) + return errors.Errorf("invalid gasPrice %s", price) + } + } + if gasTip := pb.GetGasTipCap(); gasTip == "" { + act.gasTipCap = nil + } else { + if act.gasTipCap, ok = new(big.Int).SetString(gasTip, 10); !ok { + return errors.Errorf("invalid gasTipCap %s", gasTip) + } + } + if gasFee := pb.GetGasFeeCap(); gasFee == "" { + act.gasFeeCap = nil + } else { + if act.gasFeeCap, ok = new(big.Int).SetString(gasFee, 10); !ok { + return errors.Errorf("invalid gasFeeCap %s", gasFee) } } return nil diff --git a/action/action.go b/action/action.go index 22e0b74154..a829085dfa 100644 --- a/action/action.go +++ b/action/action.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019 IoTeX Foundation +// Copyright (c) 2024 IoTeX Foundation // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. @@ -28,7 +28,7 @@ type ( actionPayload interface { Cost() (*big.Int, error) IntrinsicGas() (uint64, error) - SetEnvelopeContext(Envelope) + SetEnvelopeContext(*AbstractAction) SanityCheck() error } diff --git a/action/action_deserializer_test.go b/action/action_deserializer_test.go index 8a48b2c523..3a47920232 100644 --- a/action/action_deserializer_test.go +++ b/action/action_deserializer_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2022 IoTeX Foundation +// Copyright (c) 2024 IoTeX Foundation // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. @@ -24,11 +24,11 @@ import ( func TestActionDeserializer(t *testing.T) { r := require.New(t) for _, v := range []struct { - id uint32 - hash string + id uint32 + hash, hash2 string }{ - {0, "322884fb04663019be6fb461d9453827487eafdd57b4de3bd89a7d77c9bf8395"}, - {1, "80af7840d73772d3022d8bdc46278fb755352e5e9d5f2a1f12ee7ec4f1ea98e9"}, + {0, "322884fb04663019be6fb461d9453827487eafdd57b4de3bd89a7d77c9bf8395", "0562e100b057804ee3cb4fa906a897852aa8075013a02ef1e229360f1e5ee339"}, + {1, "80af7840d73772d3022d8bdc46278fb755352e5e9d5f2a1f12ee7ec4f1ea98e9", "405343d671c395d77835b8857cc25317e3bf02680f8c875a4fe12087b0446184"}, } { se, err := createSealedEnvelope(v.id) r.NoError(err) @@ -43,10 +43,14 @@ func TestActionDeserializer(t *testing.T) { // use valid signature and reset se.Hash se.signature = _validSig se.hash = hash.ZeroHash256 - se.Hash() + rHash, err = se.Hash() + r.NoError(err) + r.Equal(v.hash2, hex.EncodeToString(rHash[:])) se1, err := (&Deserializer{}).ActionToSealedEnvelope(se.Proto()) - se1.Hash() r.NoError(err) + rHash, err = se1.Hash() + r.NoError(err) + r.Equal(v.hash2, hex.EncodeToString(rHash[:])) r.Equal(se, se1) } } diff --git a/action/builder.go b/action/builder.go index 8ac0a648cb..7bc541fc28 100644 --- a/action/builder.go +++ b/action/builder.go @@ -1,4 +1,4 @@ -// Copyright (c) 2019 IoTeX Foundation +// Copyright (c) 2024 IoTeX Foundation // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. @@ -146,7 +146,7 @@ func (b *EnvelopeBuilder) build() Envelope { if b.elp.payload == nil { panic("cannot build Envelope w/o a valid payload") } - b.elp.payload.SetEnvelopeContext(&b.elp) + b.elp.payload.SetEnvelopeContext(&b.elp.AbstractAction) return &b.elp } diff --git a/action/envelope.go b/action/envelope.go index 9631a634ed..b1d3373d7b 100644 --- a/action/envelope.go +++ b/action/envelope.go @@ -1,3 +1,8 @@ +// Copyright (c) 2024 IoTeX Foundation +// This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability +// or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. +// This source code is governed by Apache License 2.0 that can be found in the LICENSE file. + package action import ( @@ -17,6 +22,8 @@ type ( ChainID() uint32 GasLimit() uint64 GasPrice() *big.Int + GasTipCap() *big.Int + GasFeeCap() *big.Int Destination() (string, bool) Cost() (*big.Int, error) IntrinsicGas() (uint64, error) @@ -221,7 +228,7 @@ func (elp *envelope) LoadProto(pbAct *iotextypes.ActionCore) error { default: return errors.Errorf("no applicable action to handle proto type %T", pbAct.Action) } - elp.payload.SetEnvelopeContext(elp) + elp.payload.SetEnvelopeContext(&elp.AbstractAction) return nil } diff --git a/go.mod b/go.mod index 6fc3d1fab4..3430968c50 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,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.0 + github.com/iotexproject/iotex-proto v0.6.1-0.20240423171003-091249266f6a github.com/ipfs/go-ipfs-api v0.2.0 github.com/libp2p/go-libp2p-core v0.8.5 github.com/mackerelio/go-osstat v0.2.4 diff --git a/go.sum b/go.sum index 1b5a839cbb..f3681087bb 100644 --- a/go.sum +++ b/go.sum @@ -664,8 +664,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.0 h1:UIwPq5QuuPwR7G4OZzmyBsbvEJ+YH6oHyzRjxGk9Fow= -github.com/iotexproject/iotex-proto v0.6.0/go.mod h1:wQpCk3Df0fPID+K8ohiICGj+cWRmcQ3wanT+aSrnIPo= +github.com/iotexproject/iotex-proto v0.6.1-0.20240423171003-091249266f6a h1:8gK1TO66Wsc/93WNMUyWKGHQB2/1Al5vLFNyfBz2af4= +github.com/iotexproject/iotex-proto v0.6.1-0.20240423171003-091249266f6a/go.mod h1:wQpCk3Df0fPID+K8ohiICGj+cWRmcQ3wanT+aSrnIPo= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= diff --git a/test/mock/mock_envelope/mock_envelope.go b/test/mock/mock_envelope/mock_envelope.go index 99019077cd..1d3401bead 100644 --- a/test/mock/mock_envelope/mock_envelope.go +++ b/test/mock/mock_envelope/mock_envelope.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: action/envelope.go +// Source: ./action/envelope.go // Package mock_envelope is a generated GoMock package. package mock_envelope @@ -94,6 +94,20 @@ func (mr *MockEnvelopeMockRecorder) Destination() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Destination", reflect.TypeOf((*MockEnvelope)(nil).Destination)) } +// GasFeeCap mocks base method. +func (m *MockEnvelope) GasFeeCap() *big.Int { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GasFeeCap") + ret0, _ := ret[0].(*big.Int) + return ret0 +} + +// GasFeeCap indicates an expected call of GasFeeCap. +func (mr *MockEnvelopeMockRecorder) GasFeeCap() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GasFeeCap", reflect.TypeOf((*MockEnvelope)(nil).GasFeeCap)) +} + // GasLimit mocks base method. func (m *MockEnvelope) GasLimit() uint64 { m.ctrl.T.Helper() @@ -122,6 +136,20 @@ func (mr *MockEnvelopeMockRecorder) GasPrice() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GasPrice", reflect.TypeOf((*MockEnvelope)(nil).GasPrice)) } +// GasTipCap mocks base method. +func (m *MockEnvelope) GasTipCap() *big.Int { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GasTipCap") + ret0, _ := ret[0].(*big.Int) + return ret0 +} + +// GasTipCap indicates an expected call of GasTipCap. +func (mr *MockEnvelopeMockRecorder) GasTipCap() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GasTipCap", reflect.TypeOf((*MockEnvelope)(nil).GasTipCap)) +} + // IntrinsicGas mocks base method. func (m *MockEnvelope) IntrinsicGas() (uint64, error) { m.ctrl.T.Helper()