From 21659f0c4d2d767584c9dd601ef221654943a63d Mon Sep 17 00:00:00 2001 From: ququzone Date: Tue, 8 Nov 2022 15:52:46 +0800 Subject: [PATCH 01/12] add rewarding execute action --- action/builder.go | 30 +++- action/rewarding.go | 352 ++++++++++++++++++++++++++++++++++++++++ api/web3server_utils.go | 3 + 3 files changed, 384 insertions(+), 1 deletion(-) create mode 100644 action/rewarding.go diff --git a/action/builder.go b/action/builder.go index 3b8e9901d5..16ebd9b203 100644 --- a/action/builder.go +++ b/action/builder.go @@ -23,7 +23,8 @@ type Builder struct { } var ( - _stakingProtocolAddr, _ = address.FromString(address.StakingProtocolAddr) + _stakingProtocolAddr, _ = address.FromString(address.StakingProtocolAddr) + _rewardingProtocolAddr, _ = address.FromString(address.RewardingPoolAddr) ) // SetVersion sets action's version. @@ -203,6 +204,20 @@ func (b *EnvelopeBuilder) BuildStakingAction(tx *types.Transaction) (Envelope, e return b.build(), nil } +// BuildRewardingAction loads rewarding action into envelope from abi-encoded data +func (b *EnvelopeBuilder) BuildRewardingAction(tx *types.Transaction) (Envelope, error) { + if !bytes.Equal(tx.To().Bytes(), _rewardingProtocolAddr.Bytes()) { + return nil, ErrInvalidAct + } + b.setEnvelopeCommonFields(tx) + act, err := newRewardingActionFromABIBinary(tx.Data()) + if err != nil { + return nil, err + } + b.elp.payload = act + return b.build(), nil +} + func newStakingActionFromABIBinary(data []byte) (actionPayload, error) { if len(data) <= 4 { return nil, ErrInvalidABI @@ -236,3 +251,16 @@ func newStakingActionFromABIBinary(data []byte) (actionPayload, error) { } return nil, ErrInvalidABI } + +func newRewardingActionFromABIBinary(data []byte) (actionPayload, error) { + if len(data) <= 4 { + return nil, ErrInvalidABI + } + if act, err := NewRewardingClaimFromABIBinary(data); err == nil { + return act, nil + } + if act, err := NewRewardingDepositFromABIBinary(data); err == nil { + return act, nil + } + return nil, ErrInvalidABI +} diff --git a/action/rewarding.go b/action/rewarding.go new file mode 100644 index 0000000000..d5869acb29 --- /dev/null +++ b/action/rewarding.go @@ -0,0 +1,352 @@ +package action + +import ( + "bytes" + "math/big" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/iotexproject/iotex-address/address" + "github.com/iotexproject/iotex-core/pkg/util/byteutil" + "github.com/iotexproject/iotex-core/pkg/version" + "github.com/iotexproject/iotex-proto/golang/iotextypes" + "github.com/pkg/errors" + "google.golang.org/protobuf/proto" +) + +const ( + // RewardingDataGas represents the rewarding data gas per uint + RewardingDataGas = uint64(100) + // RewardingBaseIntrinsicGas represents the base intrinsic gas for rewarding + RewardingBaseIntrinsicGas = uint64(10000) + + _rewardingInterfaceABI = `[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint8[]", + "name": "data", + "type": "uint8[]" + } + ], + "name": "claim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint8[]", + "name": "data", + "type": "uint8[]" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } + ]` +) + +var ( + _rewardingClaimMethod abi.Method + _rewardingDepositMethod abi.Method +) + +type ( + Rewarding struct { + AbstractAction + + amount *big.Int + data []byte + } + + RewardingClaim struct { + Rewarding + } + + RewardingDeposit struct { + Rewarding + } +) + +func init() { + rewardingInterface, err := abi.JSON(strings.NewReader(_rewardingInterfaceABI)) + if err != nil { + panic(err) + } + var ok bool + _rewardingClaimMethod, ok = rewardingInterface.Methods["claim"] + if !ok { + panic("fail to load the claim method") + } + _rewardingDepositMethod, ok = rewardingInterface.Methods["deposit"] + if !ok { + panic("fail to load the deposit method") + } +} + +// Amount returns the amount +func (r *Rewarding) Amount() *big.Int { return r.amount } + +// Payload returns the data bytes +func (r *Rewarding) Data() []byte { return r.data } + +// IntrinsicGas returns the intrinsic gas +func (r *Rewarding) IntrinsicGas() (uint64, error) { + dataSize := uint64(len(r.Data())) + return CalculateIntrinsicGas(RewardingBaseIntrinsicGas, RewardingDataGas, dataSize) +} + +// SanityCheck validates the variables in the action +func (r *Rewarding) SanityCheck() error { + if r.Amount().Sign() <= 0 { + return errors.Wrap(ErrInvalidAmount, "negative value") + } + + return r.AbstractAction.SanityCheck() +} + +func (r *Rewarding) encodeABIBinary(method abi.Method) ([]byte, error) { + data, err := method.Inputs.Pack(r.amount, r.data) + if err != nil { + return nil, err + } + return append(method.ID, data...), nil +} + +// NewRewardingClaim returns a RewardingClaim instance +func NewRewardingClaim( + nonce uint64, + amount *big.Int, + data []byte, + gasLimit uint64, + gasPrice *big.Int, +) (*RewardingClaim, error) { + return &RewardingClaim{ + Rewarding{ + AbstractAction: AbstractAction{ + version: version.ProtocolVersion, + nonce: nonce, + gasLimit: gasLimit, + gasPrice: gasPrice, + }, + amount: amount, + data: data, + }, + }, nil +} + +// Serialize returns a raw byte stream of the RewardingClaim struct +func (r *RewardingClaim) Serialize() []byte { + return byteutil.Must(proto.Marshal(r.Proto())) +} + +// Proto converts to protobuf RewardingClaim Action +func (r *RewardingClaim) Proto() *iotextypes.ClaimFromRewardingFund { + act := &iotextypes.ClaimFromRewardingFund{ + Data: r.data, + } + + if r.amount != nil { + act.Amount = r.amount.String() + } + return act +} + +// LoadProto converts a protobuf's Action to RewardingClaim +func (r *RewardingClaim) LoadProto(pbAct *iotextypes.ClaimFromRewardingFund) error { + if pbAct == nil { + return ErrNilProto + } + + r.data = pbAct.GetData() + if pbAct.GetAmount() == "" { + r.amount = big.NewInt(0) + } else { + amount, ok := new(big.Int).SetString(pbAct.GetAmount(), 10) + if !ok { + return errors.Errorf("invalid amount %s", pbAct.GetAmount()) + } + r.amount = amount + } + + return nil +} + +// EncodeABIBinary encodes data in abi encoding +func (r *RewardingClaim) EncodeABIBinary() ([]byte, error) { + return r.encodeABIBinary(_rewardingClaimMethod) +} + +// ToEthTx converts action to eth-compatible tx +func (r *RewardingClaim) ToEthTx() (*types.Transaction, error) { + addr, err := address.FromString(address.RewardingPoolAddr) + if err != nil { + return nil, err + } + ethAddr := common.BytesToAddress(addr.Bytes()) + data, err := r.encodeABIBinary(_rewardingClaimMethod) + if err != nil { + return nil, err + } + return types.NewTransaction(r.Nonce(), ethAddr, big.NewInt(0), r.GasLimit(), r.GasPrice(), data), nil +} + +// Cost returns the total cost +func (r *RewardingClaim) Cost() (*big.Int, error) { + intrinsicGas, err := r.IntrinsicGas() + if err != nil { + return nil, errors.Wrap(err, "failed to get intrinsic gas for rewarding claim") + } + fee := big.NewInt(0).Mul(r.GasPrice(), big.NewInt(0).SetUint64(intrinsicGas)) + return fee, nil +} + +// NewRewardingClaimFromABIBinary decodes data into action +func NewRewardingClaimFromABIBinary(data []byte) (*RewardingClaim, error) { + var ( + paramsMap = map[string]interface{}{} + ok bool + ac RewardingClaim + ) + // sanity check + if len(data) <= 4 || !bytes.Equal(_rewardingClaimMethod.ID[:], data[:4]) { + return nil, errDecodeFailure + } + if err := _rewardingClaimMethod.Inputs.UnpackIntoMap(paramsMap, data[4:]); err != nil { + return nil, err + } + if ac.amount, ok = paramsMap["amount"].(*big.Int); !ok { + return nil, errDecodeFailure + } + if ac.data, ok = paramsMap["data"].([]byte); !ok { + return nil, errDecodeFailure + } + return &ac, nil +} + +// NewRewardingDeposit returns a RewardingDeposit instance +func NewRewardingDeposit( + nonce uint64, + amount *big.Int, + data []byte, + gasLimit uint64, + gasPrice *big.Int, +) (*RewardingDeposit, error) { + return &RewardingDeposit{ + Rewarding{ + AbstractAction: AbstractAction{ + version: version.ProtocolVersion, + nonce: nonce, + gasLimit: gasLimit, + gasPrice: gasPrice, + }, + amount: amount, + data: data, + }, + }, nil +} + +// Serialize returns a raw byte stream of the RewardingDeposit struct +func (r *RewardingDeposit) Serialize() []byte { + return byteutil.Must(proto.Marshal(r.Proto())) +} + +// Proto converts to protobuf RewardingDeposit Action +func (r *RewardingDeposit) Proto() *iotextypes.ClaimFromRewardingFund { + act := &iotextypes.ClaimFromRewardingFund{ + Data: r.data, + } + + if r.amount != nil { + act.Amount = r.amount.String() + } + return act +} + +// LoadProto converts a protobuf's Action to RewardingDeposit +func (r *RewardingDeposit) LoadProto(pbAct *iotextypes.DepositToRewardingFund) error { + if pbAct == nil { + return ErrNilProto + } + + r.data = pbAct.GetData() + if pbAct.GetAmount() == "" { + r.amount = big.NewInt(0) + } else { + amount, ok := new(big.Int).SetString(pbAct.GetAmount(), 10) + if !ok { + return errors.Errorf("invalid amount %s", pbAct.GetAmount()) + } + r.amount = amount + } + + return nil +} + +// EncodeABIBinary encodes data in abi encoding +func (r *RewardingDeposit) EncodeABIBinary() ([]byte, error) { + return r.encodeABIBinary(_rewardingDepositMethod) +} + +// ToEthTx converts action to eth-compatible tx +func (r *RewardingDeposit) ToEthTx() (*types.Transaction, error) { + addr, err := address.FromString(address.RewardingPoolAddr) + if err != nil { + return nil, err + } + ethAddr := common.BytesToAddress(addr.Bytes()) + data, err := r.encodeABIBinary(_rewardingDepositMethod) + if err != nil { + return nil, err + } + return types.NewTransaction(r.Nonce(), ethAddr, big.NewInt(0), r.GasLimit(), r.GasPrice(), data), nil +} + +// Cost returns the total cost +func (r *RewardingDeposit) Cost() (*big.Int, error) { + intrinsicGas, err := r.IntrinsicGas() + if err != nil { + return nil, errors.Wrap(err, "failed to get intrinsic gas for rewarding deposit") + } + fee := big.NewInt(0).Mul(r.GasPrice(), big.NewInt(0).SetUint64(intrinsicGas)) + return new(big.Int).Add(r.amount, fee), nil +} + +// NewRewardingDepopsitFromABIBinary decodes data into action +func NewRewardingDepositFromABIBinary(data []byte) (*RewardingDeposit, error) { + var ( + paramsMap = map[string]interface{}{} + ok bool + ac RewardingDeposit + ) + // sanity check + if len(data) <= 4 || !bytes.Equal(_rewardingDepositMethod.ID[:], data[:4]) { + return nil, errDecodeFailure + } + if err := _rewardingDepositMethod.Inputs.UnpackIntoMap(paramsMap, data[4:]); err != nil { + return nil, err + } + if ac.amount, ok = paramsMap["amount"].(*big.Int); !ok { + return nil, errDecodeFailure + } + if ac.data, ok = paramsMap["data"].([]byte); !ok { + return nil, errDecodeFailure + } + return &ac, nil +} diff --git a/api/web3server_utils.go b/api/web3server_utils.go index 14374e9d31..de3b0a43c6 100644 --- a/api/web3server_utils.go +++ b/api/web3server_utils.go @@ -176,6 +176,9 @@ func (svr *web3Handler) ethTxToEnvelope(tx *types.Transaction) (action.Envelope, if to == address.StakingProtocolAddr { return elpBuilder.BuildStakingAction(tx) } + if to == address.RewardingPoolAddr { + return elpBuilder.BuildRewardingAction(tx) + } isContract, err := svr.checkContractAddr(to) if err != nil { return nil, err From d55f02dcf1aa933fb0870a600c2acaa08fb07e3a Mon Sep 17 00:00:00 2001 From: ququzone Date: Wed, 9 Nov 2022 11:52:16 +0800 Subject: [PATCH 02/12] add rewarding execute test --- action/rewarding.go | 25 +-- action/rewarding_test.go | 352 +++++++++++++++++++++++++++++++++++++++ api/web3server_utils.go | 2 +- 3 files changed, 368 insertions(+), 11 deletions(-) create mode 100644 action/rewarding_test.go diff --git a/action/rewarding.go b/action/rewarding.go index d5869acb29..c79c2bf3b0 100644 --- a/action/rewarding.go +++ b/action/rewarding.go @@ -101,7 +101,12 @@ func init() { } // Amount returns the amount -func (r *Rewarding) Amount() *big.Int { return r.amount } +func (r *Rewarding) Amount() *big.Int { + if r.amount == nil { + return big.NewInt(0) + } + return r.amount +} // Payload returns the data bytes func (r *Rewarding) Data() []byte { return r.data } @@ -122,7 +127,7 @@ func (r *Rewarding) SanityCheck() error { } func (r *Rewarding) encodeABIBinary(method abi.Method) ([]byte, error) { - data, err := method.Inputs.Pack(r.amount, r.data) + data, err := method.Inputs.Pack(r.Amount(), r.Data()) if err != nil { return nil, err } @@ -195,12 +200,12 @@ func (r *RewardingClaim) EncodeABIBinary() ([]byte, error) { // ToEthTx converts action to eth-compatible tx func (r *RewardingClaim) ToEthTx() (*types.Transaction, error) { - addr, err := address.FromString(address.RewardingPoolAddr) + addr, err := address.FromString(address.RewardingProtocol) if err != nil { return nil, err } ethAddr := common.BytesToAddress(addr.Bytes()) - data, err := r.encodeABIBinary(_rewardingClaimMethod) + data, err := r.EncodeABIBinary() if err != nil { return nil, err } @@ -268,8 +273,8 @@ func (r *RewardingDeposit) Serialize() []byte { } // Proto converts to protobuf RewardingDeposit Action -func (r *RewardingDeposit) Proto() *iotextypes.ClaimFromRewardingFund { - act := &iotextypes.ClaimFromRewardingFund{ +func (r *RewardingDeposit) Proto() *iotextypes.DepositToRewardingFund { + act := &iotextypes.DepositToRewardingFund{ Data: r.data, } @@ -306,16 +311,16 @@ func (r *RewardingDeposit) EncodeABIBinary() ([]byte, error) { // ToEthTx converts action to eth-compatible tx func (r *RewardingDeposit) ToEthTx() (*types.Transaction, error) { - addr, err := address.FromString(address.RewardingPoolAddr) + addr, err := address.FromString(address.RewardingProtocol) if err != nil { return nil, err } ethAddr := common.BytesToAddress(addr.Bytes()) - data, err := r.encodeABIBinary(_rewardingDepositMethod) + data, err := r.EncodeABIBinary() if err != nil { return nil, err } - return types.NewTransaction(r.Nonce(), ethAddr, big.NewInt(0), r.GasLimit(), r.GasPrice(), data), nil + return types.NewTransaction(r.Nonce(), ethAddr, r.Amount(), r.GasLimit(), r.GasPrice(), data), nil } // Cost returns the total cost @@ -325,7 +330,7 @@ func (r *RewardingDeposit) Cost() (*big.Int, error) { return nil, errors.Wrap(err, "failed to get intrinsic gas for rewarding deposit") } fee := big.NewInt(0).Mul(r.GasPrice(), big.NewInt(0).SetUint64(intrinsicGas)) - return new(big.Int).Add(r.amount, fee), nil + return new(big.Int).Add(r.Amount(), fee), nil } // NewRewardingDepopsitFromABIBinary decodes data into action diff --git a/action/rewarding_test.go b/action/rewarding_test.go new file mode 100644 index 0000000000..ec0b5087ec --- /dev/null +++ b/action/rewarding_test.go @@ -0,0 +1,352 @@ +package action + +import ( + "encoding/hex" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/iotexproject/iotex-address/address" + "github.com/iotexproject/iotex-proto/golang/iotextypes" + "github.com/stretchr/testify/require" +) + +var _defaultGasPrice = big.NewInt(1000000000000) + +func TestRewardingClaimProto(t *testing.T) { + r := require.New(t) + + rc := &RewardingClaim{} + r.EqualValues(big.NewInt(0), rc.Amount()) + + p := rc.Proto() + r.NotNil(p) + r.IsType(&iotextypes.ClaimFromRewardingFund{}, p) + r.Nil(p.Data) + r.EqualValues("", p.Amount) + + rc.amount = big.NewInt(100) + rc.data = []byte{1} + p = rc.Proto() + r.NotNil(p) + r.EqualValues([]byte{1}, p.Data) + r.EqualValues("100", p.Amount) +} + +func TestRewardingClaimSerialize(t *testing.T) { + r := require.New(t) + + rc := &RewardingClaim{} + data := rc.Serialize() + r.NotNil(data) + r.EqualValues([]byte{}, data) + + rc.amount = big.NewInt(100) + rc.data = []byte{1} + data = rc.Serialize() + r.NotNil(data) + r.EqualValues("0a03313030120101", hex.EncodeToString(data)) +} + +func TestRewardingClaimIntrinsicGas(t *testing.T) { + r := require.New(t) + + rc := &RewardingClaim{} + gas, err := rc.IntrinsicGas() + r.Nil(err) + r.EqualValues(10000, gas) + + rc.amount = big.NewInt(100000000) + gas, err = rc.IntrinsicGas() + r.Nil(err) + r.EqualValues(10000, gas) + + rc.data = []byte{1} + gas, err = rc.IntrinsicGas() + r.Nil(err) + r.EqualValues(10100, gas) +} + +func TestRewardingClaimSanityCheck(t *testing.T) { + r := require.New(t) + + rc := &RewardingClaim{} + err := rc.SanityCheck() + r.NotNil(err) + r.EqualValues("negative value: invalid amount", err.Error()) + + rc.amount = big.NewInt(1) + err = rc.SanityCheck() + r.Nil(err) + + rc.amount = big.NewInt(-1) + err = rc.SanityCheck() + r.NotNil(err) + r.EqualValues("negative value: invalid amount", err.Error()) +} + +func TestRewardingClaimCost(t *testing.T) { + r := require.New(t) + + rc := &RewardingClaim{} + rc.gasPrice = _defaultGasPrice + cost, err := rc.Cost() + r.Nil(err) + r.EqualValues("10000000000000000", cost.String()) + + rc.amount = big.NewInt(100) + cost, err = rc.Cost() + r.Nil(err) + r.EqualValues("10000000000000000", cost.String()) + + rc.data = []byte{1} + cost, err = rc.Cost() + r.Nil(err) + r.EqualValues("10100000000000000", cost.String()) +} + +func TestRewardingClaimEncodeABIBinary(t *testing.T) { + r := require.New(t) + + rc := &RewardingClaim{} + data, err := rc.EncodeABIBinary() + r.Nil(err) + r.EqualValues( + "2df163ef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", + hex.EncodeToString(data), + ) + + rc.amount = big.NewInt(101) + data, err = rc.EncodeABIBinary() + r.Nil(err) + r.EqualValues( + "2df163ef000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", + hex.EncodeToString(data), + ) + + rc.data = []byte{1, 2, 3} + data, err = rc.EncodeABIBinary() + r.Nil(err) + r.EqualValues( + "2df163ef000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", + hex.EncodeToString(data), + ) +} + +func TestRewardingClaimToEthTx(t *testing.T) { + r := require.New(t) + + rewardingPool, _ := address.FromString(address.RewardingProtocol) + rewardEthAddr := common.BytesToAddress(rewardingPool.Bytes()) + + rc := &RewardingClaim{} + tx, err := rc.ToEthTx() + r.Nil(err) + r.EqualValues(rewardEthAddr, *tx.To()) + r.EqualValues( + "2df163ef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", + hex.EncodeToString(tx.Data()), + ) + r.EqualValues("0", tx.Value().String()) + + rc.amount = big.NewInt(101) + tx, err = rc.ToEthTx() + r.Nil(err) + r.EqualValues(rewardEthAddr, *tx.To()) + r.EqualValues( + "2df163ef000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", + hex.EncodeToString(tx.Data()), + ) + r.EqualValues("0", tx.Value().String()) + + rc.data = []byte{1, 2, 3} + tx, err = rc.ToEthTx() + r.Nil(err) + r.EqualValues(rewardEthAddr, *tx.To()) + r.EqualValues( + "2df163ef000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", + hex.EncodeToString(tx.Data()), + ) + r.EqualValues("0", tx.Value().String()) +} + +func TestNewRewardingClaimFromABIBinary(t *testing.T) { + r := require.New(t) + + data, _ := hex.DecodeString("2df163ef000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003") + + rc, err := NewRewardingClaimFromABIBinary(data) + r.Nil(err) + r.IsType(&RewardingClaim{}, rc) + r.EqualValues("101", rc.Amount().String()) + r.EqualValues([]byte{1, 2, 3}, rc.Data()) +} + +func TestRewardingDepositProto(t *testing.T) { + r := require.New(t) + + rp := &RewardingDeposit{} + r.EqualValues(big.NewInt(0), rp.Amount()) + + p := rp.Proto() + r.NotNil(p) + r.IsType(&iotextypes.DepositToRewardingFund{}, p) + r.Nil(p.Data) + r.EqualValues("", p.Amount) + + rp.amount = big.NewInt(100) + rp.data = []byte{1} + p = rp.Proto() + r.NotNil(p) + r.EqualValues([]byte{1}, p.Data) + r.EqualValues("100", p.Amount) +} + +func TestRewardingDepositSerialize(t *testing.T) { + r := require.New(t) + + rp := &RewardingDeposit{} + data := rp.Serialize() + r.NotNil(data) + r.EqualValues([]byte{}, data) + + rp.amount = big.NewInt(100) + rp.data = []byte{1} + data = rp.Serialize() + r.NotNil(data) + r.EqualValues("0a03313030120101", hex.EncodeToString(data)) +} + +func TestRewardingDepositIntrinsicGas(t *testing.T) { + r := require.New(t) + + rp := &RewardingDeposit{} + gas, err := rp.IntrinsicGas() + r.Nil(err) + r.EqualValues(10000, gas) + + rp.amount = big.NewInt(100000000) + gas, err = rp.IntrinsicGas() + r.Nil(err) + r.EqualValues(10000, gas) + + rp.data = []byte{1} + gas, err = rp.IntrinsicGas() + r.Nil(err) + r.EqualValues(10100, gas) +} + +func TestRewardingDepositSanityCheck(t *testing.T) { + r := require.New(t) + + rp := &RewardingDeposit{} + err := rp.SanityCheck() + r.NotNil(err) + r.EqualValues("negative value: invalid amount", err.Error()) + + rp.amount = big.NewInt(1) + err = rp.SanityCheck() + r.Nil(err) + + rp.amount = big.NewInt(-1) + err = rp.SanityCheck() + r.NotNil(err) + r.EqualValues("negative value: invalid amount", err.Error()) +} + +func TestRewardingDepositCost(t *testing.T) { + r := require.New(t) + + rp := &RewardingDeposit{} + rp.gasPrice = _defaultGasPrice + cost, err := rp.Cost() + r.Nil(err) + r.EqualValues("10000000000000000", cost.String()) + + rp.amount = big.NewInt(100) + cost, err = rp.Cost() + r.Nil(err) + r.EqualValues("10000000000000100", cost.String()) + + rp.data = []byte{1} + cost, err = rp.Cost() + r.Nil(err) + r.EqualValues("10100000000000100", cost.String()) +} + +func TestRewardingDepositEncodeABIBinary(t *testing.T) { + r := require.New(t) + + rp := &RewardingDeposit{} + data, err := rp.EncodeABIBinary() + r.Nil(err) + r.EqualValues( + "27852a6b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", + hex.EncodeToString(data), + ) + + rp.amount = big.NewInt(101) + data, err = rp.EncodeABIBinary() + r.Nil(err) + r.EqualValues( + "27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", + hex.EncodeToString(data), + ) + + rp.data = []byte{1, 2, 3} + data, err = rp.EncodeABIBinary() + r.Nil(err) + r.EqualValues( + "27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", + hex.EncodeToString(data), + ) +} + +func TestRewardingDepositToEthTx(t *testing.T) { + r := require.New(t) + + rewardingPool, _ := address.FromString(address.RewardingProtocol) + rewardEthAddr := common.BytesToAddress(rewardingPool.Bytes()) + + rp := &RewardingDeposit{} + tx, err := rp.ToEthTx() + r.Nil(err) + r.EqualValues(rewardEthAddr, *tx.To()) + r.EqualValues( + "27852a6b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", + hex.EncodeToString(tx.Data()), + ) + r.EqualValues("0", tx.Value().String()) + + rp.amount = big.NewInt(101) + tx, err = rp.ToEthTx() + r.Nil(err) + r.EqualValues(rewardEthAddr, *tx.To()) + r.EqualValues( + "27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", + hex.EncodeToString(tx.Data()), + ) + r.EqualValues("101", tx.Value().String()) + + rp.data = []byte{1, 2, 3} + tx, err = rp.ToEthTx() + r.Nil(err) + r.EqualValues(rewardEthAddr, *tx.To()) + r.EqualValues( + "27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", + hex.EncodeToString(tx.Data()), + ) + r.EqualValues("101", tx.Value().String()) +} + +func TestNewRewardingDepositFromABIBinary(t *testing.T) { + r := require.New(t) + + data, _ := hex.DecodeString("27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003") + + rp, err := NewRewardingDepositFromABIBinary(data) + r.Nil(err) + r.IsType(&RewardingDeposit{}, rp) + r.EqualValues("101", rp.Amount().String()) + r.EqualValues([]byte{1, 2, 3}, rp.Data()) +} diff --git a/api/web3server_utils.go b/api/web3server_utils.go index de3b0a43c6..047f7534b7 100644 --- a/api/web3server_utils.go +++ b/api/web3server_utils.go @@ -176,7 +176,7 @@ func (svr *web3Handler) ethTxToEnvelope(tx *types.Transaction) (action.Envelope, if to == address.StakingProtocolAddr { return elpBuilder.BuildStakingAction(tx) } - if to == address.RewardingPoolAddr { + if to == address.RewardingProtocol { return elpBuilder.BuildRewardingAction(tx) } isContract, err := svr.checkContractAddr(to) From d9c8c0743f3fb0142fdc18fe89dd3aec3fcd3a91 Mon Sep 17 00:00:00 2001 From: ququzone Date: Wed, 9 Nov 2022 12:07:35 +0800 Subject: [PATCH 03/12] add commmet for public type --- action/rewarding.go | 7 +++++-- action/rewarding_test.go | 13 ++++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/action/rewarding.go b/action/rewarding.go index c79c2bf3b0..20fa0aa509 100644 --- a/action/rewarding.go +++ b/action/rewarding.go @@ -68,6 +68,7 @@ var ( ) type ( + // Rewarding base struct for rewarding Rewarding struct { AbstractAction @@ -75,10 +76,12 @@ type ( data []byte } + // RewardingClaim struct for rewarding claim RewardingClaim struct { Rewarding } + // RewardingDeposit struct for rewarding deposit RewardingDeposit struct { Rewarding } @@ -108,7 +111,7 @@ func (r *Rewarding) Amount() *big.Int { return r.amount } -// Payload returns the data bytes +// Data returns the data bytes func (r *Rewarding) Data() []byte { return r.data } // IntrinsicGas returns the intrinsic gas @@ -333,7 +336,7 @@ func (r *RewardingDeposit) Cost() (*big.Int, error) { return new(big.Int).Add(r.Amount(), fee), nil } -// NewRewardingDepopsitFromABIBinary decodes data into action +// NewRewardingDepositFromABIBinary decodes data into action func NewRewardingDepositFromABIBinary(data []byte) (*RewardingDeposit, error) { var ( paramsMap = map[string]interface{}{} diff --git a/action/rewarding_test.go b/action/rewarding_test.go index ec0b5087ec..a68c2b9ecb 100644 --- a/action/rewarding_test.go +++ b/action/rewarding_test.go @@ -11,7 +11,10 @@ import ( "github.com/stretchr/testify/require" ) -var _defaultGasPrice = big.NewInt(1000000000000) +var ( + _defaultGasPrice = big.NewInt(1000000000000) + _errNegativeNumberMsg = "negative value: invalid amount" +) func TestRewardingClaimProto(t *testing.T) { r := require.New(t) @@ -73,7 +76,7 @@ func TestRewardingClaimSanityCheck(t *testing.T) { rc := &RewardingClaim{} err := rc.SanityCheck() r.NotNil(err) - r.EqualValues("negative value: invalid amount", err.Error()) + r.EqualValues(_errNegativeNumberMsg, err.Error()) rc.amount = big.NewInt(1) err = rc.SanityCheck() @@ -82,7 +85,7 @@ func TestRewardingClaimSanityCheck(t *testing.T) { rc.amount = big.NewInt(-1) err = rc.SanityCheck() r.NotNil(err) - r.EqualValues("negative value: invalid amount", err.Error()) + r.EqualValues(_errNegativeNumberMsg, err.Error()) } func TestRewardingClaimCost(t *testing.T) { @@ -242,7 +245,7 @@ func TestRewardingDepositSanityCheck(t *testing.T) { rp := &RewardingDeposit{} err := rp.SanityCheck() r.NotNil(err) - r.EqualValues("negative value: invalid amount", err.Error()) + r.EqualValues(_errNegativeNumberMsg, err.Error()) rp.amount = big.NewInt(1) err = rp.SanityCheck() @@ -251,7 +254,7 @@ func TestRewardingDepositSanityCheck(t *testing.T) { rp.amount = big.NewInt(-1) err = rp.SanityCheck() r.NotNil(err) - r.EqualValues("negative value: invalid amount", err.Error()) + r.EqualValues(_errNegativeNumberMsg, err.Error()) } func TestRewardingDepositCost(t *testing.T) { From 6bcbc3da95d7a77692b1e46462391d7085b5fad4 Mon Sep 17 00:00:00 2001 From: ququzone Date: Wed, 9 Nov 2022 13:28:06 +0800 Subject: [PATCH 04/12] add builder test --- action/builder.go | 2 +- action/builder_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/action/builder.go b/action/builder.go index 16ebd9b203..c2ef238018 100644 --- a/action/builder.go +++ b/action/builder.go @@ -24,7 +24,7 @@ type Builder struct { var ( _stakingProtocolAddr, _ = address.FromString(address.StakingProtocolAddr) - _rewardingProtocolAddr, _ = address.FromString(address.RewardingPoolAddr) + _rewardingProtocolAddr, _ = address.FromString(address.RewardingProtocol) ) // SetVersion sets action's version. diff --git a/action/builder_test.go b/action/builder_test.go index a29767a517..21fcf15a2e 100644 --- a/action/builder_test.go +++ b/action/builder_test.go @@ -7,10 +7,14 @@ package action import ( + "encoding/hex" "math/big" "testing" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/iotexproject/iotex-core/pkg/version" ) @@ -28,3 +32,40 @@ func TestActionBuilder(t *testing.T) { assert.Equal(t, uint64(10003), act.GasLimit()) assert.Equal(t, big.NewInt(10004), act.GasPrice()) } + +func TestBuildRewardingAction(t *testing.T) { + r := require.New(t) + + eb := &EnvelopeBuilder{} + eb.SetChainID(2) + + claimData, _ := hex.DecodeString("2df163ef000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000") + tx := types.NewTransaction(1, common.HexToAddress("0x0000000000000000000000000000000000000001"), big.NewInt(100), 10000, big.NewInt(10004), claimData) + + env, err := eb.BuildRewardingAction(tx) + r.Nil(env) + r.EqualValues("invalid action type", err.Error()) + + tx = types.NewTransaction(1, common.HexToAddress(_rewardingProtocolAddr.Hex()), big.NewInt(100), 10000, big.NewInt(10004), claimData) + env, err = eb.BuildRewardingAction(tx) + r.Nil(err) + r.IsType(&RewardingClaim{}, env.Action()) + r.EqualValues(big.NewInt(10004), env.GasPrice()) + r.EqualValues(10000, env.GasLimit()) + r.EqualValues(big.NewInt(101), env.Action().(*RewardingClaim).Amount()) + + depositData, _ := hex.DecodeString("27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003") + tx = types.NewTransaction(1, common.HexToAddress("0x0000000000000000000000000000000000000001"), big.NewInt(100), 10000, big.NewInt(10004), depositData) + + env, err = eb.BuildRewardingAction(tx) + r.Nil(env) + r.EqualValues("invalid action type", err.Error()) + + tx = types.NewTransaction(1, common.HexToAddress(_rewardingProtocolAddr.Hex()), big.NewInt(100), 10000, big.NewInt(10004), depositData) + env, err = eb.BuildRewardingAction(tx) + r.Nil(err) + r.IsType(&RewardingDeposit{}, env.Action()) + r.EqualValues(big.NewInt(10004), env.GasPrice()) + r.EqualValues(10000, env.GasLimit()) + r.EqualValues(big.NewInt(101), env.Action().(*RewardingDeposit).Amount()) +} From 43937052f869422c6f9e34a97dadb0954b341791 Mon Sep 17 00:00:00 2001 From: ququzone Date: Wed, 9 Nov 2022 16:34:51 +0800 Subject: [PATCH 05/12] complete web3 rewarding read --- .../rewarding/ethabi/availablebalance.go | 72 ++++++++++++++ action/protocol/rewarding/ethabi/base.go | 55 +++++++++++ .../protocol/rewarding/ethabi/totalbalance.go | 72 ++++++++++++++ .../rewarding/ethabi/unclaimedbalance.go | 94 +++++++++++++++++++ api/web3server.go | 16 ++++ 5 files changed, 309 insertions(+) create mode 100644 action/protocol/rewarding/ethabi/availablebalance.go create mode 100644 action/protocol/rewarding/ethabi/base.go create mode 100644 action/protocol/rewarding/ethabi/totalbalance.go create mode 100644 action/protocol/rewarding/ethabi/unclaimedbalance.go diff --git a/action/protocol/rewarding/ethabi/availablebalance.go b/action/protocol/rewarding/ethabi/availablebalance.go new file mode 100644 index 0000000000..22cf64417e --- /dev/null +++ b/action/protocol/rewarding/ethabi/availablebalance.go @@ -0,0 +1,72 @@ +package ethabi + +import ( + "encoding/hex" + "math/big" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/iotexproject/iotex-proto/golang/iotexapi" + "github.com/iotexproject/iotex-proto/golang/protocol" +) + +const _availableBalanceInterfaceABI = `[ + { + "inputs": [], + "name": "availableBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +]` + +var _availableBalanceMethod abi.Method + +func init() { + _interface, err := abi.JSON(strings.NewReader(_availableBalanceInterfaceABI)) + if err != nil { + panic(err) + } + var ok bool + _availableBalanceMethod, ok = _interface.Methods["availableBalance"] + if !ok { + panic("fail to load the method") + } +} + +// AvailableBalanceStateContext context for AvailableBalance +type AvailableBalanceStateContext struct { + *baseStateContext +} + +func newAvailableBalanceStateContext() (*AvailableBalanceStateContext, error) { + return &AvailableBalanceStateContext{ + &baseStateContext{ + &Parameters{ + MethodName: []byte(protocol.ReadAvailableBalanceMethodName), + Arguments: nil, + }, + }, + }, nil +} + +// EncodeToEth encode proto to eth +func (r *AvailableBalanceStateContext) EncodeToEth(resp *iotexapi.ReadStateResponse) (string, error) { + total, ok := new(big.Int).SetString(string(resp.Data), 10) + if !ok { + return "", errConvertBigNumber + } + + data, err := _availableBalanceMethod.Outputs.Pack(total) + if err != nil { + return "", nil + } + + return hex.EncodeToString(data), nil +} diff --git a/action/protocol/rewarding/ethabi/base.go b/action/protocol/rewarding/ethabi/base.go new file mode 100644 index 0000000000..35e51771cf --- /dev/null +++ b/action/protocol/rewarding/ethabi/base.go @@ -0,0 +1,55 @@ +package ethabi + +import ( + "encoding/hex" + "errors" + + "github.com/iotexproject/iotex-proto/golang/iotexapi" +) + +var ( + errInvalidCallData = errors.New("invalid call binary data") + errInvalidCallSig = errors.New("invalid call sig") + errConvertBigNumber = errors.New("convert big number error") + errDecodeFailure = errors.New("decode data error") +) + +type ( + // Parameters state request parameters + Parameters struct { + MethodName []byte + Arguments [][]byte + } + + // StateContext context for ReadState + StateContext interface { + Parameters() *Parameters + EncodeToEth(*iotexapi.ReadStateResponse) (string, error) + } + + baseStateContext struct { + parameters *Parameters + } +) + +func (r *baseStateContext) Parameters() *Parameters { + return r.parameters +} + +// BuildReadStateRequest decode eth_call data to StateContext +func BuildReadStateRequest(data []byte) (StateContext, error) { + if len(data) < 4 { + return nil, errInvalidCallData + } + + switch methodSig := hex.EncodeToString(data[:4]); methodSig { + case hex.EncodeToString(_totalBalanceMethod.ID): + return newTotalBalanceStateContext() + case hex.EncodeToString(_availableBalanceMethod.ID): + return newAvailableBalanceStateContext() + case hex.EncodeToString(_unclaimedBalanceMethod.ID): + return newUnclaimedBalanceStateContext(data[4:]) + default: + return nil, errInvalidCallSig + } +} diff --git a/action/protocol/rewarding/ethabi/totalbalance.go b/action/protocol/rewarding/ethabi/totalbalance.go new file mode 100644 index 0000000000..ffa3c91b64 --- /dev/null +++ b/action/protocol/rewarding/ethabi/totalbalance.go @@ -0,0 +1,72 @@ +package ethabi + +import ( + "encoding/hex" + "math/big" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/iotexproject/iotex-proto/golang/iotexapi" + "github.com/iotexproject/iotex-proto/golang/protocol" +) + +const _totalBalanceInterfaceABI = `[ + { + "inputs": [], + "name": "totalBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +]` + +var _totalBalanceMethod abi.Method + +func init() { + _interface, err := abi.JSON(strings.NewReader(_totalBalanceInterfaceABI)) + if err != nil { + panic(err) + } + var ok bool + _totalBalanceMethod, ok = _interface.Methods["totalBalance"] + if !ok { + panic("fail to load the method") + } +} + +// TotalBalanceStateContext context for TotalBalance +type TotalBalanceStateContext struct { + *baseStateContext +} + +func newTotalBalanceStateContext() (*TotalBalanceStateContext, error) { + return &TotalBalanceStateContext{ + &baseStateContext{ + &Parameters{ + MethodName: []byte(protocol.ReadTotalBalanceMethodName), + Arguments: nil, + }, + }, + }, nil +} + +// EncodeToEth encode proto to eth +func (r *TotalBalanceStateContext) EncodeToEth(resp *iotexapi.ReadStateResponse) (string, error) { + total, ok := new(big.Int).SetString(string(resp.Data), 10) + if !ok { + return "", errConvertBigNumber + } + + data, err := _totalBalanceMethod.Outputs.Pack(total) + if err != nil { + return "", nil + } + + return hex.EncodeToString(data), nil +} diff --git a/action/protocol/rewarding/ethabi/unclaimedbalance.go b/action/protocol/rewarding/ethabi/unclaimedbalance.go new file mode 100644 index 0000000000..46116b88dc --- /dev/null +++ b/action/protocol/rewarding/ethabi/unclaimedbalance.go @@ -0,0 +1,94 @@ +package ethabi + +import ( + "encoding/hex" + "math/big" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/iotexproject/iotex-address/address" + "github.com/iotexproject/iotex-proto/golang/iotexapi" + "github.com/iotexproject/iotex-proto/golang/protocol" +) + +const _unclaimedBalanceInterfaceABI = `[ + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "unclaimedBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +]` + +var _unclaimedBalanceMethod abi.Method + +func init() { + _interface, err := abi.JSON(strings.NewReader(_unclaimedBalanceInterfaceABI)) + if err != nil { + panic(err) + } + var ok bool + _unclaimedBalanceMethod, ok = _interface.Methods["unclaimedBalance"] + if !ok { + panic("fail to load the method") + } +} + +// UnclaimedBalanceStateContext context for UnclaimedBalance +type UnclaimedBalanceStateContext struct { + *baseStateContext +} + +func newUnclaimedBalanceStateContext(data []byte) (*UnclaimedBalanceStateContext, error) { + paramsMap := map[string]interface{}{} + ok := false + if err := _unclaimedBalanceMethod.Inputs.UnpackIntoMap(paramsMap, data); err != nil { + return nil, err + } + var account common.Address + if account, ok = paramsMap["account"].(common.Address); !ok { + return nil, errDecodeFailure + } + accountAddress, err := address.FromBytes(account[:]) + if err != nil { + return nil, err + } + + return &UnclaimedBalanceStateContext{ + &baseStateContext{ + &Parameters{ + MethodName: []byte(protocol.ReadUnclaimedBalanceMethodName), + Arguments: [][]byte{[]byte(accountAddress.String())}, + }, + }, + }, nil +} + +// EncodeToEth encode proto to eth +func (r *UnclaimedBalanceStateContext) EncodeToEth(resp *iotexapi.ReadStateResponse) (string, error) { + total, ok := new(big.Int).SetString(string(resp.Data), 10) + if !ok { + return "", errConvertBigNumber + } + + data, err := _unclaimedBalanceMethod.Outputs.Pack(total) + if err != nil { + return "", nil + } + + return hex.EncodeToString(data), nil +} diff --git a/api/web3server.go b/api/web3server.go index c09eff81fb..a9525f38cd 100644 --- a/api/web3server.go +++ b/api/web3server.go @@ -22,6 +22,7 @@ import ( "go.uber.org/zap" "github.com/iotexproject/iotex-core/action" + rewardingabi "github.com/iotexproject/iotex-core/action/protocol/rewarding/ethabi" apitypes "github.com/iotexproject/iotex-core/api/types" "github.com/iotexproject/iotex-core/pkg/log" "github.com/iotexproject/iotex-core/pkg/tracer" @@ -329,6 +330,21 @@ func (svr *web3Handler) call(in *gjson.Result) (interface{}, error) { if to == _metamaskBalanceContractAddr { return nil, nil } + if to == address.RewardingProtocol { + sctx, err := rewardingabi.BuildReadStateRequest(data) + if err != nil { + return nil, err + } + states, err := svr.coreService.ReadState("rewarding", "", sctx.Parameters().MethodName, sctx.Parameters().Arguments) + if err != nil { + return nil, err + } + ret, err := sctx.EncodeToEth(states) + if err != nil { + return nil, err + } + return "0x" + ret, nil + } exec, _ := action.NewExecution(to, 0, value, gasLimit, big.NewInt(0), data) ret, _, err := svr.coreService.ReadContract(context.Background(), callerAddr, exec) if err != nil { From ecee44647f5f22c0193fa94b5dfeac9354404475 Mon Sep 17 00:00:00 2001 From: ququzone Date: Wed, 9 Nov 2022 17:21:28 +0800 Subject: [PATCH 06/12] complete web3 rewarding read test --- .../rewarding/ethabi/availablebalance_test.go | 26 +++++++++++++ action/protocol/rewarding/ethabi/base_test.go | 37 +++++++++++++++++++ .../rewarding/ethabi/totalbalance_test.go | 26 +++++++++++++ .../rewarding/ethabi/unclaimedbalance_test.go | 36 ++++++++++++++++++ 4 files changed, 125 insertions(+) create mode 100644 action/protocol/rewarding/ethabi/availablebalance_test.go create mode 100644 action/protocol/rewarding/ethabi/base_test.go create mode 100644 action/protocol/rewarding/ethabi/totalbalance_test.go create mode 100644 action/protocol/rewarding/ethabi/unclaimedbalance_test.go diff --git a/action/protocol/rewarding/ethabi/availablebalance_test.go b/action/protocol/rewarding/ethabi/availablebalance_test.go new file mode 100644 index 0000000000..e683b546b2 --- /dev/null +++ b/action/protocol/rewarding/ethabi/availablebalance_test.go @@ -0,0 +1,26 @@ +package ethabi + +import ( + "math/big" + "testing" + + "github.com/iotexproject/iotex-proto/golang/iotexapi" + "github.com/stretchr/testify/require" +) + +func TestAvailableBalanceEncodeToEth(t *testing.T) { + r := require.New(t) + + ctx, err := newAvailableBalanceStateContext() + r.Nil(err) + r.EqualValues("AvailableBalance", string(ctx.parameters.MethodName)) + + amount := big.NewInt(10000) + resp := &iotexapi.ReadStateResponse{ + Data: []byte(amount.String()), + } + + data, err := ctx.EncodeToEth(resp) + r.Nil(err) + r.EqualValues("0000000000000000000000000000000000000000000000000000000000002710", data) +} diff --git a/action/protocol/rewarding/ethabi/base_test.go b/action/protocol/rewarding/ethabi/base_test.go new file mode 100644 index 0000000000..e5c8c9b01e --- /dev/null +++ b/action/protocol/rewarding/ethabi/base_test.go @@ -0,0 +1,37 @@ +package ethabi + +import ( + "encoding/hex" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestBuildReadStateRequest(t *testing.T) { + r := require.New(t) + + data, _ := hex.DecodeString("1234") + ctx, err := BuildReadStateRequest(data) + r.Nil(ctx) + r.EqualError(errInvalidCallData, err.Error()) + + data, _ = hex.DecodeString("12345678") + ctx, err = BuildReadStateRequest(data) + r.Nil(ctx) + r.EqualError(errInvalidCallSig, err.Error()) + + data, _ = hex.DecodeString("ad7a672f") + ctx, err = BuildReadStateRequest(data) + r.Nil(err) + r.IsType(&TotalBalanceStateContext{}, ctx) + + data, _ = hex.DecodeString("ab2f0e51") + ctx, err = BuildReadStateRequest(data) + r.Nil(err) + r.IsType(&AvailableBalanceStateContext{}, ctx) + + data, _ = hex.DecodeString("01cbf5fb0000000000000000000000000000000000000000000000000000000000000001") + ctx, err = BuildReadStateRequest(data) + r.Nil(err) + r.IsType(&UnclaimedBalanceStateContext{}, ctx) +} diff --git a/action/protocol/rewarding/ethabi/totalbalance_test.go b/action/protocol/rewarding/ethabi/totalbalance_test.go new file mode 100644 index 0000000000..4e8339ce00 --- /dev/null +++ b/action/protocol/rewarding/ethabi/totalbalance_test.go @@ -0,0 +1,26 @@ +package ethabi + +import ( + "math/big" + "testing" + + "github.com/iotexproject/iotex-proto/golang/iotexapi" + "github.com/stretchr/testify/require" +) + +func TestTotalBalanceEncodeToEth(t *testing.T) { + r := require.New(t) + + ctx, err := newTotalBalanceStateContext() + r.Nil(err) + r.EqualValues("TotalBalance", string(ctx.parameters.MethodName)) + + amount := big.NewInt(10000) + resp := &iotexapi.ReadStateResponse{ + Data: []byte(amount.String()), + } + + data, err := ctx.EncodeToEth(resp) + r.Nil(err) + r.EqualValues("0000000000000000000000000000000000000000000000000000000000002710", data) +} diff --git a/action/protocol/rewarding/ethabi/unclaimedbalance_test.go b/action/protocol/rewarding/ethabi/unclaimedbalance_test.go new file mode 100644 index 0000000000..5edc381747 --- /dev/null +++ b/action/protocol/rewarding/ethabi/unclaimedbalance_test.go @@ -0,0 +1,36 @@ +package ethabi + +import ( + "encoding/hex" + "math/big" + "testing" + + "github.com/iotexproject/iotex-proto/golang/iotexapi" + "github.com/stretchr/testify/require" +) + +func TestUnclaimedBalanceEncodeToEth(t *testing.T) { + r := require.New(t) + + ctx := &UnclaimedBalanceStateContext{} + + amount := big.NewInt(10000) + resp := &iotexapi.ReadStateResponse{ + Data: []byte(amount.String()), + } + + data, err := ctx.EncodeToEth(resp) + r.Nil(err) + r.EqualValues("0000000000000000000000000000000000000000000000000000000000002710", data) +} + +func TestNewUnclaimedBalanceStateContext(t *testing.T) { + r := require.New(t) + + data, _ := hex.DecodeString("0000000000000000000000000000000000000000000000000000000000000001") + + ctx, err := newUnclaimedBalanceStateContext(data) + r.Nil(err) + r.EqualValues("io1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqps833xv", string(ctx.parameters.Arguments[0])) + r.EqualValues("UnclaimedBalance", string(ctx.parameters.MethodName)) +} From 48d23e5a6eb3c24d1c26bd06fa21b1b53aa42f08 Mon Sep 17 00:00:00 2001 From: ququzone Date: Mon, 14 Nov 2022 09:04:54 +0800 Subject: [PATCH 07/12] remove read api and receive create rewarding action enterance --- .../rewarding/ethabi/availablebalance.go | 72 -------------- .../rewarding/ethabi/availablebalance_test.go | 26 ----- action/protocol/rewarding/ethabi/base.go | 55 ----------- action/protocol/rewarding/ethabi/base_test.go | 37 -------- .../protocol/rewarding/ethabi/totalbalance.go | 72 -------------- .../rewarding/ethabi/totalbalance_test.go | 26 ----- .../rewarding/ethabi/unclaimedbalance.go | 94 ------------------- .../rewarding/ethabi/unclaimedbalance_test.go | 36 ------- api/web3server.go | 16 ---- api/web3server_utils.go | 3 - 10 files changed, 437 deletions(-) delete mode 100644 action/protocol/rewarding/ethabi/availablebalance.go delete mode 100644 action/protocol/rewarding/ethabi/availablebalance_test.go delete mode 100644 action/protocol/rewarding/ethabi/base.go delete mode 100644 action/protocol/rewarding/ethabi/base_test.go delete mode 100644 action/protocol/rewarding/ethabi/totalbalance.go delete mode 100644 action/protocol/rewarding/ethabi/totalbalance_test.go delete mode 100644 action/protocol/rewarding/ethabi/unclaimedbalance.go delete mode 100644 action/protocol/rewarding/ethabi/unclaimedbalance_test.go diff --git a/action/protocol/rewarding/ethabi/availablebalance.go b/action/protocol/rewarding/ethabi/availablebalance.go deleted file mode 100644 index 22cf64417e..0000000000 --- a/action/protocol/rewarding/ethabi/availablebalance.go +++ /dev/null @@ -1,72 +0,0 @@ -package ethabi - -import ( - "encoding/hex" - "math/big" - "strings" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/iotexproject/iotex-proto/golang/iotexapi" - "github.com/iotexproject/iotex-proto/golang/protocol" -) - -const _availableBalanceInterfaceABI = `[ - { - "inputs": [], - "name": "availableBalance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - } -]` - -var _availableBalanceMethod abi.Method - -func init() { - _interface, err := abi.JSON(strings.NewReader(_availableBalanceInterfaceABI)) - if err != nil { - panic(err) - } - var ok bool - _availableBalanceMethod, ok = _interface.Methods["availableBalance"] - if !ok { - panic("fail to load the method") - } -} - -// AvailableBalanceStateContext context for AvailableBalance -type AvailableBalanceStateContext struct { - *baseStateContext -} - -func newAvailableBalanceStateContext() (*AvailableBalanceStateContext, error) { - return &AvailableBalanceStateContext{ - &baseStateContext{ - &Parameters{ - MethodName: []byte(protocol.ReadAvailableBalanceMethodName), - Arguments: nil, - }, - }, - }, nil -} - -// EncodeToEth encode proto to eth -func (r *AvailableBalanceStateContext) EncodeToEth(resp *iotexapi.ReadStateResponse) (string, error) { - total, ok := new(big.Int).SetString(string(resp.Data), 10) - if !ok { - return "", errConvertBigNumber - } - - data, err := _availableBalanceMethod.Outputs.Pack(total) - if err != nil { - return "", nil - } - - return hex.EncodeToString(data), nil -} diff --git a/action/protocol/rewarding/ethabi/availablebalance_test.go b/action/protocol/rewarding/ethabi/availablebalance_test.go deleted file mode 100644 index e683b546b2..0000000000 --- a/action/protocol/rewarding/ethabi/availablebalance_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package ethabi - -import ( - "math/big" - "testing" - - "github.com/iotexproject/iotex-proto/golang/iotexapi" - "github.com/stretchr/testify/require" -) - -func TestAvailableBalanceEncodeToEth(t *testing.T) { - r := require.New(t) - - ctx, err := newAvailableBalanceStateContext() - r.Nil(err) - r.EqualValues("AvailableBalance", string(ctx.parameters.MethodName)) - - amount := big.NewInt(10000) - resp := &iotexapi.ReadStateResponse{ - Data: []byte(amount.String()), - } - - data, err := ctx.EncodeToEth(resp) - r.Nil(err) - r.EqualValues("0000000000000000000000000000000000000000000000000000000000002710", data) -} diff --git a/action/protocol/rewarding/ethabi/base.go b/action/protocol/rewarding/ethabi/base.go deleted file mode 100644 index 35e51771cf..0000000000 --- a/action/protocol/rewarding/ethabi/base.go +++ /dev/null @@ -1,55 +0,0 @@ -package ethabi - -import ( - "encoding/hex" - "errors" - - "github.com/iotexproject/iotex-proto/golang/iotexapi" -) - -var ( - errInvalidCallData = errors.New("invalid call binary data") - errInvalidCallSig = errors.New("invalid call sig") - errConvertBigNumber = errors.New("convert big number error") - errDecodeFailure = errors.New("decode data error") -) - -type ( - // Parameters state request parameters - Parameters struct { - MethodName []byte - Arguments [][]byte - } - - // StateContext context for ReadState - StateContext interface { - Parameters() *Parameters - EncodeToEth(*iotexapi.ReadStateResponse) (string, error) - } - - baseStateContext struct { - parameters *Parameters - } -) - -func (r *baseStateContext) Parameters() *Parameters { - return r.parameters -} - -// BuildReadStateRequest decode eth_call data to StateContext -func BuildReadStateRequest(data []byte) (StateContext, error) { - if len(data) < 4 { - return nil, errInvalidCallData - } - - switch methodSig := hex.EncodeToString(data[:4]); methodSig { - case hex.EncodeToString(_totalBalanceMethod.ID): - return newTotalBalanceStateContext() - case hex.EncodeToString(_availableBalanceMethod.ID): - return newAvailableBalanceStateContext() - case hex.EncodeToString(_unclaimedBalanceMethod.ID): - return newUnclaimedBalanceStateContext(data[4:]) - default: - return nil, errInvalidCallSig - } -} diff --git a/action/protocol/rewarding/ethabi/base_test.go b/action/protocol/rewarding/ethabi/base_test.go deleted file mode 100644 index e5c8c9b01e..0000000000 --- a/action/protocol/rewarding/ethabi/base_test.go +++ /dev/null @@ -1,37 +0,0 @@ -package ethabi - -import ( - "encoding/hex" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestBuildReadStateRequest(t *testing.T) { - r := require.New(t) - - data, _ := hex.DecodeString("1234") - ctx, err := BuildReadStateRequest(data) - r.Nil(ctx) - r.EqualError(errInvalidCallData, err.Error()) - - data, _ = hex.DecodeString("12345678") - ctx, err = BuildReadStateRequest(data) - r.Nil(ctx) - r.EqualError(errInvalidCallSig, err.Error()) - - data, _ = hex.DecodeString("ad7a672f") - ctx, err = BuildReadStateRequest(data) - r.Nil(err) - r.IsType(&TotalBalanceStateContext{}, ctx) - - data, _ = hex.DecodeString("ab2f0e51") - ctx, err = BuildReadStateRequest(data) - r.Nil(err) - r.IsType(&AvailableBalanceStateContext{}, ctx) - - data, _ = hex.DecodeString("01cbf5fb0000000000000000000000000000000000000000000000000000000000000001") - ctx, err = BuildReadStateRequest(data) - r.Nil(err) - r.IsType(&UnclaimedBalanceStateContext{}, ctx) -} diff --git a/action/protocol/rewarding/ethabi/totalbalance.go b/action/protocol/rewarding/ethabi/totalbalance.go deleted file mode 100644 index ffa3c91b64..0000000000 --- a/action/protocol/rewarding/ethabi/totalbalance.go +++ /dev/null @@ -1,72 +0,0 @@ -package ethabi - -import ( - "encoding/hex" - "math/big" - "strings" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/iotexproject/iotex-proto/golang/iotexapi" - "github.com/iotexproject/iotex-proto/golang/protocol" -) - -const _totalBalanceInterfaceABI = `[ - { - "inputs": [], - "name": "totalBalance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - } -]` - -var _totalBalanceMethod abi.Method - -func init() { - _interface, err := abi.JSON(strings.NewReader(_totalBalanceInterfaceABI)) - if err != nil { - panic(err) - } - var ok bool - _totalBalanceMethod, ok = _interface.Methods["totalBalance"] - if !ok { - panic("fail to load the method") - } -} - -// TotalBalanceStateContext context for TotalBalance -type TotalBalanceStateContext struct { - *baseStateContext -} - -func newTotalBalanceStateContext() (*TotalBalanceStateContext, error) { - return &TotalBalanceStateContext{ - &baseStateContext{ - &Parameters{ - MethodName: []byte(protocol.ReadTotalBalanceMethodName), - Arguments: nil, - }, - }, - }, nil -} - -// EncodeToEth encode proto to eth -func (r *TotalBalanceStateContext) EncodeToEth(resp *iotexapi.ReadStateResponse) (string, error) { - total, ok := new(big.Int).SetString(string(resp.Data), 10) - if !ok { - return "", errConvertBigNumber - } - - data, err := _totalBalanceMethod.Outputs.Pack(total) - if err != nil { - return "", nil - } - - return hex.EncodeToString(data), nil -} diff --git a/action/protocol/rewarding/ethabi/totalbalance_test.go b/action/protocol/rewarding/ethabi/totalbalance_test.go deleted file mode 100644 index 4e8339ce00..0000000000 --- a/action/protocol/rewarding/ethabi/totalbalance_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package ethabi - -import ( - "math/big" - "testing" - - "github.com/iotexproject/iotex-proto/golang/iotexapi" - "github.com/stretchr/testify/require" -) - -func TestTotalBalanceEncodeToEth(t *testing.T) { - r := require.New(t) - - ctx, err := newTotalBalanceStateContext() - r.Nil(err) - r.EqualValues("TotalBalance", string(ctx.parameters.MethodName)) - - amount := big.NewInt(10000) - resp := &iotexapi.ReadStateResponse{ - Data: []byte(amount.String()), - } - - data, err := ctx.EncodeToEth(resp) - r.Nil(err) - r.EqualValues("0000000000000000000000000000000000000000000000000000000000002710", data) -} diff --git a/action/protocol/rewarding/ethabi/unclaimedbalance.go b/action/protocol/rewarding/ethabi/unclaimedbalance.go deleted file mode 100644 index 46116b88dc..0000000000 --- a/action/protocol/rewarding/ethabi/unclaimedbalance.go +++ /dev/null @@ -1,94 +0,0 @@ -package ethabi - -import ( - "encoding/hex" - "math/big" - "strings" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/iotexproject/iotex-address/address" - "github.com/iotexproject/iotex-proto/golang/iotexapi" - "github.com/iotexproject/iotex-proto/golang/protocol" -) - -const _unclaimedBalanceInterfaceABI = `[ - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "unclaimedBalance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - } -]` - -var _unclaimedBalanceMethod abi.Method - -func init() { - _interface, err := abi.JSON(strings.NewReader(_unclaimedBalanceInterfaceABI)) - if err != nil { - panic(err) - } - var ok bool - _unclaimedBalanceMethod, ok = _interface.Methods["unclaimedBalance"] - if !ok { - panic("fail to load the method") - } -} - -// UnclaimedBalanceStateContext context for UnclaimedBalance -type UnclaimedBalanceStateContext struct { - *baseStateContext -} - -func newUnclaimedBalanceStateContext(data []byte) (*UnclaimedBalanceStateContext, error) { - paramsMap := map[string]interface{}{} - ok := false - if err := _unclaimedBalanceMethod.Inputs.UnpackIntoMap(paramsMap, data); err != nil { - return nil, err - } - var account common.Address - if account, ok = paramsMap["account"].(common.Address); !ok { - return nil, errDecodeFailure - } - accountAddress, err := address.FromBytes(account[:]) - if err != nil { - return nil, err - } - - return &UnclaimedBalanceStateContext{ - &baseStateContext{ - &Parameters{ - MethodName: []byte(protocol.ReadUnclaimedBalanceMethodName), - Arguments: [][]byte{[]byte(accountAddress.String())}, - }, - }, - }, nil -} - -// EncodeToEth encode proto to eth -func (r *UnclaimedBalanceStateContext) EncodeToEth(resp *iotexapi.ReadStateResponse) (string, error) { - total, ok := new(big.Int).SetString(string(resp.Data), 10) - if !ok { - return "", errConvertBigNumber - } - - data, err := _unclaimedBalanceMethod.Outputs.Pack(total) - if err != nil { - return "", nil - } - - return hex.EncodeToString(data), nil -} diff --git a/action/protocol/rewarding/ethabi/unclaimedbalance_test.go b/action/protocol/rewarding/ethabi/unclaimedbalance_test.go deleted file mode 100644 index 5edc381747..0000000000 --- a/action/protocol/rewarding/ethabi/unclaimedbalance_test.go +++ /dev/null @@ -1,36 +0,0 @@ -package ethabi - -import ( - "encoding/hex" - "math/big" - "testing" - - "github.com/iotexproject/iotex-proto/golang/iotexapi" - "github.com/stretchr/testify/require" -) - -func TestUnclaimedBalanceEncodeToEth(t *testing.T) { - r := require.New(t) - - ctx := &UnclaimedBalanceStateContext{} - - amount := big.NewInt(10000) - resp := &iotexapi.ReadStateResponse{ - Data: []byte(amount.String()), - } - - data, err := ctx.EncodeToEth(resp) - r.Nil(err) - r.EqualValues("0000000000000000000000000000000000000000000000000000000000002710", data) -} - -func TestNewUnclaimedBalanceStateContext(t *testing.T) { - r := require.New(t) - - data, _ := hex.DecodeString("0000000000000000000000000000000000000000000000000000000000000001") - - ctx, err := newUnclaimedBalanceStateContext(data) - r.Nil(err) - r.EqualValues("io1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqps833xv", string(ctx.parameters.Arguments[0])) - r.EqualValues("UnclaimedBalance", string(ctx.parameters.MethodName)) -} diff --git a/api/web3server.go b/api/web3server.go index a9525f38cd..c09eff81fb 100644 --- a/api/web3server.go +++ b/api/web3server.go @@ -22,7 +22,6 @@ import ( "go.uber.org/zap" "github.com/iotexproject/iotex-core/action" - rewardingabi "github.com/iotexproject/iotex-core/action/protocol/rewarding/ethabi" apitypes "github.com/iotexproject/iotex-core/api/types" "github.com/iotexproject/iotex-core/pkg/log" "github.com/iotexproject/iotex-core/pkg/tracer" @@ -330,21 +329,6 @@ func (svr *web3Handler) call(in *gjson.Result) (interface{}, error) { if to == _metamaskBalanceContractAddr { return nil, nil } - if to == address.RewardingProtocol { - sctx, err := rewardingabi.BuildReadStateRequest(data) - if err != nil { - return nil, err - } - states, err := svr.coreService.ReadState("rewarding", "", sctx.Parameters().MethodName, sctx.Parameters().Arguments) - if err != nil { - return nil, err - } - ret, err := sctx.EncodeToEth(states) - if err != nil { - return nil, err - } - return "0x" + ret, nil - } exec, _ := action.NewExecution(to, 0, value, gasLimit, big.NewInt(0), data) ret, _, err := svr.coreService.ReadContract(context.Background(), callerAddr, exec) if err != nil { diff --git a/api/web3server_utils.go b/api/web3server_utils.go index 047f7534b7..14374e9d31 100644 --- a/api/web3server_utils.go +++ b/api/web3server_utils.go @@ -176,9 +176,6 @@ func (svr *web3Handler) ethTxToEnvelope(tx *types.Transaction) (action.Envelope, if to == address.StakingProtocolAddr { return elpBuilder.BuildStakingAction(tx) } - if to == address.RewardingProtocol { - return elpBuilder.BuildRewardingAction(tx) - } isContract, err := svr.checkContractAddr(to) if err != nil { return nil, err From 8dd263f981a465f3f93a43042421c0a71202c3cc Mon Sep 17 00:00:00 2001 From: ququzone Date: Mon, 14 Nov 2022 15:38:07 +0800 Subject: [PATCH 08/12] add test to rlp tx test --- action/builder.go | 4 +- action/builder_test.go | 8 +- action/claimreward.go | 87 +++++++++ action/claimreward_test.go | 165 ++++++++++++++++ action/depositreward.go | 90 ++++++++- action/depositreward_test.go | 156 +++++++++++++++ action/rewarding.go | 360 ----------------------------------- action/rewarding_test.go | 355 ---------------------------------- action/rlp_tx_test.go | 29 +++ 9 files changed, 532 insertions(+), 722 deletions(-) create mode 100644 action/claimreward_test.go create mode 100644 action/depositreward_test.go delete mode 100644 action/rewarding.go delete mode 100644 action/rewarding_test.go diff --git a/action/builder.go b/action/builder.go index c2ef238018..0ffe5a77a6 100644 --- a/action/builder.go +++ b/action/builder.go @@ -256,10 +256,10 @@ func newRewardingActionFromABIBinary(data []byte) (actionPayload, error) { if len(data) <= 4 { return nil, ErrInvalidABI } - if act, err := NewRewardingClaimFromABIBinary(data); err == nil { + if act, err := NewClaimFromRewardingFundFromABIBinary(data); err == nil { return act, nil } - if act, err := NewRewardingDepositFromABIBinary(data); err == nil { + if act, err := NewDepositToRewardingFundFromABIBinary(data); err == nil { return act, nil } return nil, ErrInvalidABI diff --git a/action/builder_test.go b/action/builder_test.go index 21fcf15a2e..b1e6964494 100644 --- a/action/builder_test.go +++ b/action/builder_test.go @@ -49,10 +49,10 @@ func TestBuildRewardingAction(t *testing.T) { tx = types.NewTransaction(1, common.HexToAddress(_rewardingProtocolAddr.Hex()), big.NewInt(100), 10000, big.NewInt(10004), claimData) env, err = eb.BuildRewardingAction(tx) r.Nil(err) - r.IsType(&RewardingClaim{}, env.Action()) + r.IsType(&ClaimFromRewardingFund{}, env.Action()) r.EqualValues(big.NewInt(10004), env.GasPrice()) r.EqualValues(10000, env.GasLimit()) - r.EqualValues(big.NewInt(101), env.Action().(*RewardingClaim).Amount()) + r.EqualValues(big.NewInt(101), env.Action().(*ClaimFromRewardingFund).Amount()) depositData, _ := hex.DecodeString("27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003") tx = types.NewTransaction(1, common.HexToAddress("0x0000000000000000000000000000000000000001"), big.NewInt(100), 10000, big.NewInt(10004), depositData) @@ -64,8 +64,8 @@ func TestBuildRewardingAction(t *testing.T) { tx = types.NewTransaction(1, common.HexToAddress(_rewardingProtocolAddr.Hex()), big.NewInt(100), 10000, big.NewInt(10004), depositData) env, err = eb.BuildRewardingAction(tx) r.Nil(err) - r.IsType(&RewardingDeposit{}, env.Action()) + r.IsType(&DepositToRewardingFund{}, env.Action()) r.EqualValues(big.NewInt(10004), env.GasPrice()) r.EqualValues(10000, env.GasLimit()) - r.EqualValues(big.NewInt(101), env.Action().(*RewardingDeposit).Amount()) + r.EqualValues(big.NewInt(101), env.Action().(*DepositToRewardingFund).Amount()) } diff --git a/action/claimreward.go b/action/claimreward.go index 3c6f4244cb..69b7996961 100644 --- a/action/claimreward.go +++ b/action/claimreward.go @@ -7,22 +7,63 @@ package action import ( + "bytes" "math/big" + "strings" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" "github.com/pkg/errors" "google.golang.org/protobuf/proto" + "github.com/iotexproject/iotex-address/address" "github.com/iotexproject/iotex-core/pkg/util/byteutil" "github.com/iotexproject/iotex-proto/golang/iotextypes" ) +const _claimRewardingInterfaceABI = `[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint8[]", + "name": "data", + "type": "uint8[]" + } + ], + "name": "claim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +]` + var ( // ClaimFromRewardingFundBaseGas represents the base intrinsic gas for claimFromRewardingFund ClaimFromRewardingFundBaseGas = uint64(10000) // ClaimFromRewardingFundGasPerByte represents the claimFromRewardingFund payload gas per uint ClaimFromRewardingFundGasPerByte = uint64(100) + + _claimRewardingMethod abi.Method ) +func init() { + rewardingInterface, err := abi.JSON(strings.NewReader(_claimRewardingInterfaceABI)) + if err != nil { + panic(err) + } + var ok bool + _claimRewardingMethod, ok = rewardingInterface.Methods["claim"] + if !ok { + panic("fail to load the claim method") + } +} + // ClaimFromRewardingFund is the action to claim reward from the rewarding fund type ClaimFromRewardingFund struct { AbstractAction @@ -109,3 +150,49 @@ func (b *ClaimFromRewardingFundBuilder) Build() ClaimFromRewardingFund { b.claim.AbstractAction = b.Builder.Build() return b.claim } + +// EncodeABIBinary encodes data in abi encoding +func (r *ClaimFromRewardingFund) EncodeABIBinary() ([]byte, error) { + data, err := _claimRewardingMethod.Inputs.Pack(r.Amount(), r.Data()) + if err != nil { + return nil, err + } + return append(_claimRewardingMethod.ID, data...), nil +} + +// ToEthTx converts action to eth-compatible tx +func (r *ClaimFromRewardingFund) ToEthTx() (*types.Transaction, error) { + addr, err := address.FromString(address.RewardingProtocol) + if err != nil { + return nil, err + } + ethAddr := common.BytesToAddress(addr.Bytes()) + data, err := r.EncodeABIBinary() + if err != nil { + return nil, err + } + return types.NewTransaction(r.Nonce(), ethAddr, big.NewInt(0), r.GasLimit(), r.GasPrice(), data), nil +} + +// NewClaimFromRewardingFundFromABIBinary decodes data into action +func NewClaimFromRewardingFundFromABIBinary(data []byte) (*ClaimFromRewardingFund, error) { + var ( + paramsMap = map[string]interface{}{} + ok bool + ac ClaimFromRewardingFund + ) + // sanity check + if len(data) <= 4 || !bytes.Equal(_claimRewardingMethod.ID[:], data[:4]) { + return nil, errDecodeFailure + } + if err := _claimRewardingMethod.Inputs.UnpackIntoMap(paramsMap, data[4:]); err != nil { + return nil, err + } + if ac.amount, ok = paramsMap["amount"].(*big.Int); !ok { + return nil, errDecodeFailure + } + if ac.data, ok = paramsMap["data"].([]byte); !ok { + return nil, errDecodeFailure + } + return &ac, nil +} diff --git a/action/claimreward_test.go b/action/claimreward_test.go new file mode 100644 index 0000000000..b74c234e0f --- /dev/null +++ b/action/claimreward_test.go @@ -0,0 +1,165 @@ +package action + +import ( + "encoding/hex" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/iotexproject/iotex-address/address" + "github.com/iotexproject/iotex-proto/golang/iotextypes" + "github.com/stretchr/testify/require" +) + +var ( + _defaultGasPrice = big.NewInt(1000000000000) + _errNegativeNumberMsg = "negative value" +) + +func TestClaimRewardProto(t *testing.T) { + r := require.New(t) + + rc := &ClaimFromRewardingFund{} + + p := rc.Proto() + r.NotNil(p) + r.IsType(&iotextypes.ClaimFromRewardingFund{}, p) + r.Nil(p.Data) + + rc.amount = big.NewInt(100) + rc.data = []byte{1} + p = rc.Proto() + r.NotNil(p) + r.EqualValues([]byte{1}, p.Data) + r.EqualValues("100", p.Amount) +} + +func TestClaimRewardSerialize(t *testing.T) { + r := require.New(t) + + rc := &ClaimFromRewardingFund{} + data := rc.Serialize() + r.NotNil(data) + + rc.amount = big.NewInt(100) + rc.data = []byte{1} + data = rc.Serialize() + r.NotNil(data) + r.EqualValues("0a03313030120101", hex.EncodeToString(data)) +} + +func TestClaimRewardIntrinsicGas(t *testing.T) { + r := require.New(t) + + rc := &ClaimFromRewardingFund{} + gas, err := rc.IntrinsicGas() + r.Nil(err) + r.EqualValues(10000, gas) + + rc.amount = big.NewInt(100000000) + gas, err = rc.IntrinsicGas() + r.Nil(err) + r.EqualValues(10000, gas) + + rc.data = []byte{1} + gas, err = rc.IntrinsicGas() + r.Nil(err) + r.EqualValues(10100, gas) +} + +func TestClaimRewardSanityCheck(t *testing.T) { + r := require.New(t) + + rc := &ClaimFromRewardingFund{} + + rc.amount = big.NewInt(1) + err := rc.SanityCheck() + r.Nil(err) + + rc.amount = big.NewInt(-1) + err = rc.SanityCheck() + r.NotNil(err) + r.EqualValues(_errNegativeNumberMsg, err.Error()) +} + +func TestClaimRewardCost(t *testing.T) { + r := require.New(t) + + rc := &ClaimFromRewardingFund{} + rc.gasPrice = _defaultGasPrice + cost, err := rc.Cost() + r.Nil(err) + r.EqualValues("10000000000000000", cost.String()) + + rc.amount = big.NewInt(100) + cost, err = rc.Cost() + r.Nil(err) + r.EqualValues("10000000000000000", cost.String()) + + rc.data = []byte{1} + cost, err = rc.Cost() + r.Nil(err) + r.EqualValues("10100000000000000", cost.String()) +} + +func TestClaimRewardEncodeABIBinary(t *testing.T) { + r := require.New(t) + + rc := &ClaimFromRewardingFund{} + rc.amount = big.NewInt(101) + data, err := rc.EncodeABIBinary() + r.Nil(err) + r.EqualValues( + "2df163ef000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", + hex.EncodeToString(data), + ) + + rc.data = []byte{1, 2, 3} + data, err = rc.EncodeABIBinary() + r.Nil(err) + r.EqualValues( + "2df163ef000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", + hex.EncodeToString(data), + ) +} + +func TestClaimRewardToEthTx(t *testing.T) { + r := require.New(t) + + rewardingPool, _ := address.FromString(address.RewardingProtocol) + rewardEthAddr := common.BytesToAddress(rewardingPool.Bytes()) + + rc := &ClaimFromRewardingFund{} + + rc.amount = big.NewInt(101) + tx, err := rc.ToEthTx() + r.Nil(err) + r.EqualValues(rewardEthAddr, *tx.To()) + r.EqualValues( + "2df163ef000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", + hex.EncodeToString(tx.Data()), + ) + r.EqualValues("0", tx.Value().String()) + + rc.data = []byte{1, 2, 3} + tx, err = rc.ToEthTx() + r.Nil(err) + r.EqualValues(rewardEthAddr, *tx.To()) + r.EqualValues( + "2df163ef000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", + hex.EncodeToString(tx.Data()), + ) + r.EqualValues("0", tx.Value().String()) +} + +func TestNewRewardingClaimFromABIBinary(t *testing.T) { + r := require.New(t) + + data, _ := hex.DecodeString("2df163ef000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003") + + rc, err := NewClaimFromRewardingFundFromABIBinary(data) + r.Nil(err) + r.IsType(&ClaimFromRewardingFund{}, rc) + r.EqualValues("101", rc.Amount().String()) + r.EqualValues([]byte{1, 2, 3}, rc.Data()) +} diff --git a/action/depositreward.go b/action/depositreward.go index 68d5ad0034..75a2e21eca 100644 --- a/action/depositreward.go +++ b/action/depositreward.go @@ -7,22 +7,63 @@ package action import ( + "bytes" "math/big" + "strings" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" "github.com/pkg/errors" "google.golang.org/protobuf/proto" + "github.com/iotexproject/iotex-address/address" "github.com/iotexproject/iotex-core/pkg/util/byteutil" "github.com/iotexproject/iotex-proto/golang/iotextypes" ) +const _depositRewardInterfaceABI = `[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint8[]", + "name": "data", + "type": "uint8[]" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } +]` + var ( // DepositToRewardingFundBaseGas represents the base intrinsic gas for depositToRewardingFund DepositToRewardingFundBaseGas = uint64(10000) // DepositToRewardingFundGasPerByte represents the depositToRewardingFund payload gas per uint DepositToRewardingFundGasPerByte = uint64(100) + + _depositRewardMethod abi.Method ) +func init() { + rewardingInterface, err := abi.JSON(strings.NewReader(_depositRewardInterfaceABI)) + if err != nil { + panic(err) + } + var ok bool + _depositRewardMethod, ok = rewardingInterface.Methods["deposit"] + if !ok { + panic("fail to load the deposit method") + } +} + // DepositToRewardingFund is the action to deposit to the rewarding fund type DepositToRewardingFund struct { AbstractAction @@ -74,7 +115,8 @@ func (d *DepositToRewardingFund) Cost() (*big.Int, error) { if err != nil { return nil, errors.Wrap(err, "error when getting intrinsic gas for the deposit action") } - return big.NewInt(0).Mul(d.GasPrice(), big.NewInt(0).SetUint64(intrinsicGas)), nil + fee := big.NewInt(0).Mul(d.GasPrice(), big.NewInt(0).SetUint64(intrinsicGas)) + return new(big.Int).Add(d.Amount(), fee), nil } // SanityCheck validates the variables in the action @@ -109,3 +151,49 @@ func (b *DepositToRewardingFundBuilder) Build() DepositToRewardingFund { b.deposit.AbstractAction = b.Builder.Build() return b.deposit } + +// EncodeABIBinary encodes data in abi encoding +func (r *DepositToRewardingFund) EncodeABIBinary() ([]byte, error) { + data, err := _depositRewardMethod.Inputs.Pack(r.Amount(), r.Data()) + if err != nil { + return nil, err + } + return append(_depositRewardMethod.ID, data...), nil +} + +// ToEthTx converts action to eth-compatible tx +func (r *DepositToRewardingFund) ToEthTx() (*types.Transaction, error) { + addr, err := address.FromString(address.RewardingProtocol) + if err != nil { + return nil, err + } + ethAddr := common.BytesToAddress(addr.Bytes()) + data, err := r.EncodeABIBinary() + if err != nil { + return nil, err + } + return types.NewTransaction(r.Nonce(), ethAddr, r.Amount(), r.GasLimit(), r.GasPrice(), data), nil +} + +// NewDepositToRewardingFundFromABIBinary decodes data into action +func NewDepositToRewardingFundFromABIBinary(data []byte) (*DepositToRewardingFund, error) { + var ( + paramsMap = map[string]interface{}{} + ok bool + ac DepositToRewardingFund + ) + // sanity check + if len(data) <= 4 || !bytes.Equal(_depositRewardMethod.ID[:], data[:4]) { + return nil, errDecodeFailure + } + if err := _depositRewardMethod.Inputs.UnpackIntoMap(paramsMap, data[4:]); err != nil { + return nil, err + } + if ac.amount, ok = paramsMap["amount"].(*big.Int); !ok { + return nil, errDecodeFailure + } + if ac.data, ok = paramsMap["data"].([]byte); !ok { + return nil, errDecodeFailure + } + return &ac, nil +} diff --git a/action/depositreward_test.go b/action/depositreward_test.go new file mode 100644 index 0000000000..35112f04ae --- /dev/null +++ b/action/depositreward_test.go @@ -0,0 +1,156 @@ +package action + +import ( + "encoding/hex" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/iotexproject/iotex-address/address" + "github.com/iotexproject/iotex-proto/golang/iotextypes" + "github.com/stretchr/testify/require" +) + +func TestDepositRewardProto(t *testing.T) { + r := require.New(t) + + rp := &DepositToRewardingFund{} + + p := rp.Proto() + r.NotNil(p) + r.IsType(&iotextypes.DepositToRewardingFund{}, p) + r.Nil(p.Data) + + rp.amount = big.NewInt(100) + rp.data = []byte{1} + p = rp.Proto() + r.NotNil(p) + r.EqualValues([]byte{1}, p.Data) + r.EqualValues("100", p.Amount) +} + +func TestDepositRewardSerialize(t *testing.T) { + r := require.New(t) + + rp := &DepositToRewardingFund{} + data := rp.Serialize() + r.NotNil(data) + + rp.amount = big.NewInt(100) + rp.data = []byte{1} + data = rp.Serialize() + r.NotNil(data) + r.EqualValues("0a03313030120101", hex.EncodeToString(data)) +} + +func TestDepositRewardIntrinsicGas(t *testing.T) { + r := require.New(t) + + rp := &DepositToRewardingFund{} + gas, err := rp.IntrinsicGas() + r.Nil(err) + r.EqualValues(10000, gas) + + rp.amount = big.NewInt(100000000) + gas, err = rp.IntrinsicGas() + r.Nil(err) + r.EqualValues(10000, gas) + + rp.data = []byte{1} + gas, err = rp.IntrinsicGas() + r.Nil(err) + r.EqualValues(10100, gas) +} + +func TestDepositRewardSanityCheck(t *testing.T) { + r := require.New(t) + + rp := &DepositToRewardingFund{} + + rp.amount = big.NewInt(1) + err := rp.SanityCheck() + r.Nil(err) + + rp.amount = big.NewInt(-1) + err = rp.SanityCheck() + r.NotNil(err) + r.EqualValues(_errNegativeNumberMsg, err.Error()) +} + +func TestDepositRewardCost(t *testing.T) { + r := require.New(t) + + rp := &DepositToRewardingFund{} + rp.gasPrice = _defaultGasPrice + rp.amount = big.NewInt(100) + cost, err := rp.Cost() + r.Nil(err) + r.EqualValues("10000000000000100", cost.String()) + + rp.data = []byte{1} + cost, err = rp.Cost() + r.Nil(err) + r.EqualValues("10100000000000100", cost.String()) +} + +func TestDepositRewardEncodeABIBinary(t *testing.T) { + r := require.New(t) + + rp := &DepositToRewardingFund{} + + rp.amount = big.NewInt(101) + data, err := rp.EncodeABIBinary() + r.Nil(err) + r.EqualValues( + "27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", + hex.EncodeToString(data), + ) + + rp.data = []byte{1, 2, 3} + data, err = rp.EncodeABIBinary() + r.Nil(err) + r.EqualValues( + "27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", + hex.EncodeToString(data), + ) +} + +func TestDepositRewardToEthTx(t *testing.T) { + r := require.New(t) + + rewardingPool, _ := address.FromString(address.RewardingProtocol) + rewardEthAddr := common.BytesToAddress(rewardingPool.Bytes()) + + rp := &DepositToRewardingFund{} + rp.amount = big.NewInt(101) + tx, err := rp.ToEthTx() + r.Nil(err) + r.EqualValues(rewardEthAddr, *tx.To()) + r.EqualValues( + "27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", + hex.EncodeToString(tx.Data()), + ) + r.EqualValues("101", tx.Value().String()) + + rp.data = []byte{1, 2, 3} + tx, err = rp.ToEthTx() + r.Nil(err) + r.EqualValues(rewardEthAddr, *tx.To()) + r.EqualValues( + "27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", + hex.EncodeToString(tx.Data()), + ) + r.EqualValues("101", tx.Value().String()) +} + +func TestNewRewardingDepositFromABIBinary(t *testing.T) { + r := require.New(t) + + data, _ := hex.DecodeString("27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003") + + rp, err := NewDepositToRewardingFundFromABIBinary(data) + r.Nil(err) + r.IsType(&DepositToRewardingFund{}, rp) + r.EqualValues("101", rp.Amount().String()) + r.EqualValues([]byte{1, 2, 3}, rp.Data()) +} diff --git a/action/rewarding.go b/action/rewarding.go deleted file mode 100644 index 20fa0aa509..0000000000 --- a/action/rewarding.go +++ /dev/null @@ -1,360 +0,0 @@ -package action - -import ( - "bytes" - "math/big" - "strings" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/iotexproject/iotex-address/address" - "github.com/iotexproject/iotex-core/pkg/util/byteutil" - "github.com/iotexproject/iotex-core/pkg/version" - "github.com/iotexproject/iotex-proto/golang/iotextypes" - "github.com/pkg/errors" - "google.golang.org/protobuf/proto" -) - -const ( - // RewardingDataGas represents the rewarding data gas per uint - RewardingDataGas = uint64(100) - // RewardingBaseIntrinsicGas represents the base intrinsic gas for rewarding - RewardingBaseIntrinsicGas = uint64(10000) - - _rewardingInterfaceABI = `[ - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint8[]", - "name": "data", - "type": "uint8[]" - } - ], - "name": "claim", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint8[]", - "name": "data", - "type": "uint8[]" - } - ], - "name": "deposit", - "outputs": [], - "stateMutability": "payable", - "type": "function" - } - ]` -) - -var ( - _rewardingClaimMethod abi.Method - _rewardingDepositMethod abi.Method -) - -type ( - // Rewarding base struct for rewarding - Rewarding struct { - AbstractAction - - amount *big.Int - data []byte - } - - // RewardingClaim struct for rewarding claim - RewardingClaim struct { - Rewarding - } - - // RewardingDeposit struct for rewarding deposit - RewardingDeposit struct { - Rewarding - } -) - -func init() { - rewardingInterface, err := abi.JSON(strings.NewReader(_rewardingInterfaceABI)) - if err != nil { - panic(err) - } - var ok bool - _rewardingClaimMethod, ok = rewardingInterface.Methods["claim"] - if !ok { - panic("fail to load the claim method") - } - _rewardingDepositMethod, ok = rewardingInterface.Methods["deposit"] - if !ok { - panic("fail to load the deposit method") - } -} - -// Amount returns the amount -func (r *Rewarding) Amount() *big.Int { - if r.amount == nil { - return big.NewInt(0) - } - return r.amount -} - -// Data returns the data bytes -func (r *Rewarding) Data() []byte { return r.data } - -// IntrinsicGas returns the intrinsic gas -func (r *Rewarding) IntrinsicGas() (uint64, error) { - dataSize := uint64(len(r.Data())) - return CalculateIntrinsicGas(RewardingBaseIntrinsicGas, RewardingDataGas, dataSize) -} - -// SanityCheck validates the variables in the action -func (r *Rewarding) SanityCheck() error { - if r.Amount().Sign() <= 0 { - return errors.Wrap(ErrInvalidAmount, "negative value") - } - - return r.AbstractAction.SanityCheck() -} - -func (r *Rewarding) encodeABIBinary(method abi.Method) ([]byte, error) { - data, err := method.Inputs.Pack(r.Amount(), r.Data()) - if err != nil { - return nil, err - } - return append(method.ID, data...), nil -} - -// NewRewardingClaim returns a RewardingClaim instance -func NewRewardingClaim( - nonce uint64, - amount *big.Int, - data []byte, - gasLimit uint64, - gasPrice *big.Int, -) (*RewardingClaim, error) { - return &RewardingClaim{ - Rewarding{ - AbstractAction: AbstractAction{ - version: version.ProtocolVersion, - nonce: nonce, - gasLimit: gasLimit, - gasPrice: gasPrice, - }, - amount: amount, - data: data, - }, - }, nil -} - -// Serialize returns a raw byte stream of the RewardingClaim struct -func (r *RewardingClaim) Serialize() []byte { - return byteutil.Must(proto.Marshal(r.Proto())) -} - -// Proto converts to protobuf RewardingClaim Action -func (r *RewardingClaim) Proto() *iotextypes.ClaimFromRewardingFund { - act := &iotextypes.ClaimFromRewardingFund{ - Data: r.data, - } - - if r.amount != nil { - act.Amount = r.amount.String() - } - return act -} - -// LoadProto converts a protobuf's Action to RewardingClaim -func (r *RewardingClaim) LoadProto(pbAct *iotextypes.ClaimFromRewardingFund) error { - if pbAct == nil { - return ErrNilProto - } - - r.data = pbAct.GetData() - if pbAct.GetAmount() == "" { - r.amount = big.NewInt(0) - } else { - amount, ok := new(big.Int).SetString(pbAct.GetAmount(), 10) - if !ok { - return errors.Errorf("invalid amount %s", pbAct.GetAmount()) - } - r.amount = amount - } - - return nil -} - -// EncodeABIBinary encodes data in abi encoding -func (r *RewardingClaim) EncodeABIBinary() ([]byte, error) { - return r.encodeABIBinary(_rewardingClaimMethod) -} - -// ToEthTx converts action to eth-compatible tx -func (r *RewardingClaim) ToEthTx() (*types.Transaction, error) { - addr, err := address.FromString(address.RewardingProtocol) - if err != nil { - return nil, err - } - ethAddr := common.BytesToAddress(addr.Bytes()) - data, err := r.EncodeABIBinary() - if err != nil { - return nil, err - } - return types.NewTransaction(r.Nonce(), ethAddr, big.NewInt(0), r.GasLimit(), r.GasPrice(), data), nil -} - -// Cost returns the total cost -func (r *RewardingClaim) Cost() (*big.Int, error) { - intrinsicGas, err := r.IntrinsicGas() - if err != nil { - return nil, errors.Wrap(err, "failed to get intrinsic gas for rewarding claim") - } - fee := big.NewInt(0).Mul(r.GasPrice(), big.NewInt(0).SetUint64(intrinsicGas)) - return fee, nil -} - -// NewRewardingClaimFromABIBinary decodes data into action -func NewRewardingClaimFromABIBinary(data []byte) (*RewardingClaim, error) { - var ( - paramsMap = map[string]interface{}{} - ok bool - ac RewardingClaim - ) - // sanity check - if len(data) <= 4 || !bytes.Equal(_rewardingClaimMethod.ID[:], data[:4]) { - return nil, errDecodeFailure - } - if err := _rewardingClaimMethod.Inputs.UnpackIntoMap(paramsMap, data[4:]); err != nil { - return nil, err - } - if ac.amount, ok = paramsMap["amount"].(*big.Int); !ok { - return nil, errDecodeFailure - } - if ac.data, ok = paramsMap["data"].([]byte); !ok { - return nil, errDecodeFailure - } - return &ac, nil -} - -// NewRewardingDeposit returns a RewardingDeposit instance -func NewRewardingDeposit( - nonce uint64, - amount *big.Int, - data []byte, - gasLimit uint64, - gasPrice *big.Int, -) (*RewardingDeposit, error) { - return &RewardingDeposit{ - Rewarding{ - AbstractAction: AbstractAction{ - version: version.ProtocolVersion, - nonce: nonce, - gasLimit: gasLimit, - gasPrice: gasPrice, - }, - amount: amount, - data: data, - }, - }, nil -} - -// Serialize returns a raw byte stream of the RewardingDeposit struct -func (r *RewardingDeposit) Serialize() []byte { - return byteutil.Must(proto.Marshal(r.Proto())) -} - -// Proto converts to protobuf RewardingDeposit Action -func (r *RewardingDeposit) Proto() *iotextypes.DepositToRewardingFund { - act := &iotextypes.DepositToRewardingFund{ - Data: r.data, - } - - if r.amount != nil { - act.Amount = r.amount.String() - } - return act -} - -// LoadProto converts a protobuf's Action to RewardingDeposit -func (r *RewardingDeposit) LoadProto(pbAct *iotextypes.DepositToRewardingFund) error { - if pbAct == nil { - return ErrNilProto - } - - r.data = pbAct.GetData() - if pbAct.GetAmount() == "" { - r.amount = big.NewInt(0) - } else { - amount, ok := new(big.Int).SetString(pbAct.GetAmount(), 10) - if !ok { - return errors.Errorf("invalid amount %s", pbAct.GetAmount()) - } - r.amount = amount - } - - return nil -} - -// EncodeABIBinary encodes data in abi encoding -func (r *RewardingDeposit) EncodeABIBinary() ([]byte, error) { - return r.encodeABIBinary(_rewardingDepositMethod) -} - -// ToEthTx converts action to eth-compatible tx -func (r *RewardingDeposit) ToEthTx() (*types.Transaction, error) { - addr, err := address.FromString(address.RewardingProtocol) - if err != nil { - return nil, err - } - ethAddr := common.BytesToAddress(addr.Bytes()) - data, err := r.EncodeABIBinary() - if err != nil { - return nil, err - } - return types.NewTransaction(r.Nonce(), ethAddr, r.Amount(), r.GasLimit(), r.GasPrice(), data), nil -} - -// Cost returns the total cost -func (r *RewardingDeposit) Cost() (*big.Int, error) { - intrinsicGas, err := r.IntrinsicGas() - if err != nil { - return nil, errors.Wrap(err, "failed to get intrinsic gas for rewarding deposit") - } - fee := big.NewInt(0).Mul(r.GasPrice(), big.NewInt(0).SetUint64(intrinsicGas)) - return new(big.Int).Add(r.Amount(), fee), nil -} - -// NewRewardingDepositFromABIBinary decodes data into action -func NewRewardingDepositFromABIBinary(data []byte) (*RewardingDeposit, error) { - var ( - paramsMap = map[string]interface{}{} - ok bool - ac RewardingDeposit - ) - // sanity check - if len(data) <= 4 || !bytes.Equal(_rewardingDepositMethod.ID[:], data[:4]) { - return nil, errDecodeFailure - } - if err := _rewardingDepositMethod.Inputs.UnpackIntoMap(paramsMap, data[4:]); err != nil { - return nil, err - } - if ac.amount, ok = paramsMap["amount"].(*big.Int); !ok { - return nil, errDecodeFailure - } - if ac.data, ok = paramsMap["data"].([]byte); !ok { - return nil, errDecodeFailure - } - return &ac, nil -} diff --git a/action/rewarding_test.go b/action/rewarding_test.go deleted file mode 100644 index a68c2b9ecb..0000000000 --- a/action/rewarding_test.go +++ /dev/null @@ -1,355 +0,0 @@ -package action - -import ( - "encoding/hex" - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/iotexproject/iotex-address/address" - "github.com/iotexproject/iotex-proto/golang/iotextypes" - "github.com/stretchr/testify/require" -) - -var ( - _defaultGasPrice = big.NewInt(1000000000000) - _errNegativeNumberMsg = "negative value: invalid amount" -) - -func TestRewardingClaimProto(t *testing.T) { - r := require.New(t) - - rc := &RewardingClaim{} - r.EqualValues(big.NewInt(0), rc.Amount()) - - p := rc.Proto() - r.NotNil(p) - r.IsType(&iotextypes.ClaimFromRewardingFund{}, p) - r.Nil(p.Data) - r.EqualValues("", p.Amount) - - rc.amount = big.NewInt(100) - rc.data = []byte{1} - p = rc.Proto() - r.NotNil(p) - r.EqualValues([]byte{1}, p.Data) - r.EqualValues("100", p.Amount) -} - -func TestRewardingClaimSerialize(t *testing.T) { - r := require.New(t) - - rc := &RewardingClaim{} - data := rc.Serialize() - r.NotNil(data) - r.EqualValues([]byte{}, data) - - rc.amount = big.NewInt(100) - rc.data = []byte{1} - data = rc.Serialize() - r.NotNil(data) - r.EqualValues("0a03313030120101", hex.EncodeToString(data)) -} - -func TestRewardingClaimIntrinsicGas(t *testing.T) { - r := require.New(t) - - rc := &RewardingClaim{} - gas, err := rc.IntrinsicGas() - r.Nil(err) - r.EqualValues(10000, gas) - - rc.amount = big.NewInt(100000000) - gas, err = rc.IntrinsicGas() - r.Nil(err) - r.EqualValues(10000, gas) - - rc.data = []byte{1} - gas, err = rc.IntrinsicGas() - r.Nil(err) - r.EqualValues(10100, gas) -} - -func TestRewardingClaimSanityCheck(t *testing.T) { - r := require.New(t) - - rc := &RewardingClaim{} - err := rc.SanityCheck() - r.NotNil(err) - r.EqualValues(_errNegativeNumberMsg, err.Error()) - - rc.amount = big.NewInt(1) - err = rc.SanityCheck() - r.Nil(err) - - rc.amount = big.NewInt(-1) - err = rc.SanityCheck() - r.NotNil(err) - r.EqualValues(_errNegativeNumberMsg, err.Error()) -} - -func TestRewardingClaimCost(t *testing.T) { - r := require.New(t) - - rc := &RewardingClaim{} - rc.gasPrice = _defaultGasPrice - cost, err := rc.Cost() - r.Nil(err) - r.EqualValues("10000000000000000", cost.String()) - - rc.amount = big.NewInt(100) - cost, err = rc.Cost() - r.Nil(err) - r.EqualValues("10000000000000000", cost.String()) - - rc.data = []byte{1} - cost, err = rc.Cost() - r.Nil(err) - r.EqualValues("10100000000000000", cost.String()) -} - -func TestRewardingClaimEncodeABIBinary(t *testing.T) { - r := require.New(t) - - rc := &RewardingClaim{} - data, err := rc.EncodeABIBinary() - r.Nil(err) - r.EqualValues( - "2df163ef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", - hex.EncodeToString(data), - ) - - rc.amount = big.NewInt(101) - data, err = rc.EncodeABIBinary() - r.Nil(err) - r.EqualValues( - "2df163ef000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", - hex.EncodeToString(data), - ) - - rc.data = []byte{1, 2, 3} - data, err = rc.EncodeABIBinary() - r.Nil(err) - r.EqualValues( - "2df163ef000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", - hex.EncodeToString(data), - ) -} - -func TestRewardingClaimToEthTx(t *testing.T) { - r := require.New(t) - - rewardingPool, _ := address.FromString(address.RewardingProtocol) - rewardEthAddr := common.BytesToAddress(rewardingPool.Bytes()) - - rc := &RewardingClaim{} - tx, err := rc.ToEthTx() - r.Nil(err) - r.EqualValues(rewardEthAddr, *tx.To()) - r.EqualValues( - "2df163ef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", - hex.EncodeToString(tx.Data()), - ) - r.EqualValues("0", tx.Value().String()) - - rc.amount = big.NewInt(101) - tx, err = rc.ToEthTx() - r.Nil(err) - r.EqualValues(rewardEthAddr, *tx.To()) - r.EqualValues( - "2df163ef000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", - hex.EncodeToString(tx.Data()), - ) - r.EqualValues("0", tx.Value().String()) - - rc.data = []byte{1, 2, 3} - tx, err = rc.ToEthTx() - r.Nil(err) - r.EqualValues(rewardEthAddr, *tx.To()) - r.EqualValues( - "2df163ef000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", - hex.EncodeToString(tx.Data()), - ) - r.EqualValues("0", tx.Value().String()) -} - -func TestNewRewardingClaimFromABIBinary(t *testing.T) { - r := require.New(t) - - data, _ := hex.DecodeString("2df163ef000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003") - - rc, err := NewRewardingClaimFromABIBinary(data) - r.Nil(err) - r.IsType(&RewardingClaim{}, rc) - r.EqualValues("101", rc.Amount().String()) - r.EqualValues([]byte{1, 2, 3}, rc.Data()) -} - -func TestRewardingDepositProto(t *testing.T) { - r := require.New(t) - - rp := &RewardingDeposit{} - r.EqualValues(big.NewInt(0), rp.Amount()) - - p := rp.Proto() - r.NotNil(p) - r.IsType(&iotextypes.DepositToRewardingFund{}, p) - r.Nil(p.Data) - r.EqualValues("", p.Amount) - - rp.amount = big.NewInt(100) - rp.data = []byte{1} - p = rp.Proto() - r.NotNil(p) - r.EqualValues([]byte{1}, p.Data) - r.EqualValues("100", p.Amount) -} - -func TestRewardingDepositSerialize(t *testing.T) { - r := require.New(t) - - rp := &RewardingDeposit{} - data := rp.Serialize() - r.NotNil(data) - r.EqualValues([]byte{}, data) - - rp.amount = big.NewInt(100) - rp.data = []byte{1} - data = rp.Serialize() - r.NotNil(data) - r.EqualValues("0a03313030120101", hex.EncodeToString(data)) -} - -func TestRewardingDepositIntrinsicGas(t *testing.T) { - r := require.New(t) - - rp := &RewardingDeposit{} - gas, err := rp.IntrinsicGas() - r.Nil(err) - r.EqualValues(10000, gas) - - rp.amount = big.NewInt(100000000) - gas, err = rp.IntrinsicGas() - r.Nil(err) - r.EqualValues(10000, gas) - - rp.data = []byte{1} - gas, err = rp.IntrinsicGas() - r.Nil(err) - r.EqualValues(10100, gas) -} - -func TestRewardingDepositSanityCheck(t *testing.T) { - r := require.New(t) - - rp := &RewardingDeposit{} - err := rp.SanityCheck() - r.NotNil(err) - r.EqualValues(_errNegativeNumberMsg, err.Error()) - - rp.amount = big.NewInt(1) - err = rp.SanityCheck() - r.Nil(err) - - rp.amount = big.NewInt(-1) - err = rp.SanityCheck() - r.NotNil(err) - r.EqualValues(_errNegativeNumberMsg, err.Error()) -} - -func TestRewardingDepositCost(t *testing.T) { - r := require.New(t) - - rp := &RewardingDeposit{} - rp.gasPrice = _defaultGasPrice - cost, err := rp.Cost() - r.Nil(err) - r.EqualValues("10000000000000000", cost.String()) - - rp.amount = big.NewInt(100) - cost, err = rp.Cost() - r.Nil(err) - r.EqualValues("10000000000000100", cost.String()) - - rp.data = []byte{1} - cost, err = rp.Cost() - r.Nil(err) - r.EqualValues("10100000000000100", cost.String()) -} - -func TestRewardingDepositEncodeABIBinary(t *testing.T) { - r := require.New(t) - - rp := &RewardingDeposit{} - data, err := rp.EncodeABIBinary() - r.Nil(err) - r.EqualValues( - "27852a6b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", - hex.EncodeToString(data), - ) - - rp.amount = big.NewInt(101) - data, err = rp.EncodeABIBinary() - r.Nil(err) - r.EqualValues( - "27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", - hex.EncodeToString(data), - ) - - rp.data = []byte{1, 2, 3} - data, err = rp.EncodeABIBinary() - r.Nil(err) - r.EqualValues( - "27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", - hex.EncodeToString(data), - ) -} - -func TestRewardingDepositToEthTx(t *testing.T) { - r := require.New(t) - - rewardingPool, _ := address.FromString(address.RewardingProtocol) - rewardEthAddr := common.BytesToAddress(rewardingPool.Bytes()) - - rp := &RewardingDeposit{} - tx, err := rp.ToEthTx() - r.Nil(err) - r.EqualValues(rewardEthAddr, *tx.To()) - r.EqualValues( - "27852a6b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", - hex.EncodeToString(tx.Data()), - ) - r.EqualValues("0", tx.Value().String()) - - rp.amount = big.NewInt(101) - tx, err = rp.ToEthTx() - r.Nil(err) - r.EqualValues(rewardEthAddr, *tx.To()) - r.EqualValues( - "27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", - hex.EncodeToString(tx.Data()), - ) - r.EqualValues("101", tx.Value().String()) - - rp.data = []byte{1, 2, 3} - tx, err = rp.ToEthTx() - r.Nil(err) - r.EqualValues(rewardEthAddr, *tx.To()) - r.EqualValues( - "27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", - hex.EncodeToString(tx.Data()), - ) - r.EqualValues("101", tx.Value().String()) -} - -func TestNewRewardingDepositFromABIBinary(t *testing.T) { - r := require.New(t) - - data, _ := hex.DecodeString("27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003") - - rp, err := NewRewardingDepositFromABIBinary(data) - r.Nil(err) - r.IsType(&RewardingDeposit{}, rp) - r.EqualValues("101", rp.Amount().String()) - r.EqualValues([]byte{1, 2, 3}, rp.Data()) -} diff --git a/action/rlp_tx_test.go b/action/rlp_tx_test.go index f29497a795..99de01837c 100644 --- a/action/rlp_tx_test.go +++ b/action/rlp_tx_test.go @@ -260,6 +260,32 @@ func TestRlpDecodeVerify(t *testing.T) { "04dc4c548c3a478278a6a09ffa8b5c4b384368e49654b35a6961ee8288fc889cdc39e9f8194e41abdbfac248ef9dc3f37b131a36ee2c052d974c21c1d2cd56730b", "1e14d5373e1af9cc77f0032ad2cd0fba8be5ea2e", }, + { + "rewardingClaim", + "f8c6806482520894a576c141e5659137ddda4223d209d4744b2106be80b8642df163ef0000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000008224c6a03d62943431b8ca0e8ea0a9c79dc8f64df14c965ca5486da124804013778ed566a065956b185116b65cec0ec9bcf9539e924784a4b448190b0aa9d017f1719be921", + 0, + 21000, + "100", + "0", + "0xA576C141e5659137ddDa4223d209d4744b2106BE", + 100, + "4d26d0736ebd9e69bd5994f3730b05a2d48c810b3bb54818be65d02004cf4ff4", + "04830579b50e01602c2015c24e72fbc48bca1cca1e601b119ca73abe2e0b5bd61fcb7874567e091030d6b644f927445d80e00b3f9ca0c566c21c30615e94c343da", + "8d38efe45794d7fceea10b2262c23c12245959db", + }, + { + "rewardingDeposit", + "f8c6016482520894a576c141e5659137ddda4223d209d4744b2106be65b86427852a6b0000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000008224c5a0112ab2b0eea79a4377bb89a0452f0a6e414431160ba0f8536bb07e9eff7d51f5a01bcc21d24ac2c5c715675753e5db3a00d249c49fafbe9ac31ec0c7b293a9f2c2", + 1, + 21000, + "100", + "101", + "0xA576C141e5659137ddDa4223d209d4744b2106BE", + 100, + "2bc65273dfb59cbad42478dbdac2a3c1ac76a4b19c865eb186464b85deb02cca", + "04830579b50e01602c2015c24e72fbc48bca1cca1e601b119ca73abe2e0b5bd61fcb7874567e091030d6b644f927445d80e00b3f9ca0c566c21c30615e94c343da", + "8d38efe45794d7fceea10b2262c23c12245959db", + }, } for _, v := range rlpTests { @@ -346,6 +372,9 @@ func convertToNativeProto(tx *types.Transaction, actType string) *iotextypes.Act "transferStake", "candidateRegister", "candidateUpdate": elp, _ := elpBuilder.BuildStakingAction(tx) return elp.Proto() + case "rewardingClaim", "rewardingDeposit": + elp, _ := elpBuilder.BuildRewardingAction(tx) + return elp.Proto() default: panic("unsupported") } From f7295d87c83aa8c57566e547c0345d0faf3b0eb0 Mon Sep 17 00:00:00 2001 From: ququzone Date: Mon, 14 Nov 2022 15:46:15 +0800 Subject: [PATCH 09/12] change name --- action/claimreward.go | 10 +++++----- action/depositreward.go | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/action/claimreward.go b/action/claimreward.go index 69b7996961..0aa8ca591f 100644 --- a/action/claimreward.go +++ b/action/claimreward.go @@ -152,8 +152,8 @@ func (b *ClaimFromRewardingFundBuilder) Build() ClaimFromRewardingFund { } // EncodeABIBinary encodes data in abi encoding -func (r *ClaimFromRewardingFund) EncodeABIBinary() ([]byte, error) { - data, err := _claimRewardingMethod.Inputs.Pack(r.Amount(), r.Data()) +func (c *ClaimFromRewardingFund) EncodeABIBinary() ([]byte, error) { + data, err := _claimRewardingMethod.Inputs.Pack(c.Amount(), c.Data()) if err != nil { return nil, err } @@ -161,17 +161,17 @@ func (r *ClaimFromRewardingFund) EncodeABIBinary() ([]byte, error) { } // ToEthTx converts action to eth-compatible tx -func (r *ClaimFromRewardingFund) ToEthTx() (*types.Transaction, error) { +func (c *ClaimFromRewardingFund) ToEthTx() (*types.Transaction, error) { addr, err := address.FromString(address.RewardingProtocol) if err != nil { return nil, err } ethAddr := common.BytesToAddress(addr.Bytes()) - data, err := r.EncodeABIBinary() + data, err := c.EncodeABIBinary() if err != nil { return nil, err } - return types.NewTransaction(r.Nonce(), ethAddr, big.NewInt(0), r.GasLimit(), r.GasPrice(), data), nil + return types.NewTransaction(c.Nonce(), ethAddr, big.NewInt(0), c.GasLimit(), c.GasPrice(), data), nil } // NewClaimFromRewardingFundFromABIBinary decodes data into action diff --git a/action/depositreward.go b/action/depositreward.go index 75a2e21eca..53d515c07d 100644 --- a/action/depositreward.go +++ b/action/depositreward.go @@ -153,8 +153,8 @@ func (b *DepositToRewardingFundBuilder) Build() DepositToRewardingFund { } // EncodeABIBinary encodes data in abi encoding -func (r *DepositToRewardingFund) EncodeABIBinary() ([]byte, error) { - data, err := _depositRewardMethod.Inputs.Pack(r.Amount(), r.Data()) +func (d *DepositToRewardingFund) EncodeABIBinary() ([]byte, error) { + data, err := _depositRewardMethod.Inputs.Pack(d.Amount(), d.Data()) if err != nil { return nil, err } @@ -162,17 +162,17 @@ func (r *DepositToRewardingFund) EncodeABIBinary() ([]byte, error) { } // ToEthTx converts action to eth-compatible tx -func (r *DepositToRewardingFund) ToEthTx() (*types.Transaction, error) { +func (d *DepositToRewardingFund) ToEthTx() (*types.Transaction, error) { addr, err := address.FromString(address.RewardingProtocol) if err != nil { return nil, err } ethAddr := common.BytesToAddress(addr.Bytes()) - data, err := r.EncodeABIBinary() + data, err := d.EncodeABIBinary() if err != nil { return nil, err } - return types.NewTransaction(r.Nonce(), ethAddr, r.Amount(), r.GasLimit(), r.GasPrice(), data), nil + return types.NewTransaction(d.Nonce(), ethAddr, d.Amount(), d.GasLimit(), d.GasPrice(), data), nil } // NewDepositToRewardingFundFromABIBinary decodes data into action From f2681fc3016c9debc04a733ff4399113ed423846 Mon Sep 17 00:00:00 2001 From: ququzone Date: Thu, 17 Nov 2022 10:16:57 +0800 Subject: [PATCH 10/12] revert fix amount bug for deposit cost bug --- action/claimreward.go | 10 +++++----- action/claimreward_test.go | 23 ++--------------------- action/depositreward.go | 15 +++++++-------- action/depositreward_test.go | 31 ++++++------------------------- action/rlp_tx_test.go | 6 +++--- 5 files changed, 23 insertions(+), 62 deletions(-) diff --git a/action/claimreward.go b/action/claimreward.go index 0aa8ca591f..e2168e13db 100644 --- a/action/claimreward.go +++ b/action/claimreward.go @@ -53,12 +53,12 @@ var ( ) func init() { - rewardingInterface, err := abi.JSON(strings.NewReader(_claimRewardingInterfaceABI)) + claimRewardInterface, err := abi.JSON(strings.NewReader(_claimRewardingInterfaceABI)) if err != nil { panic(err) } var ok bool - _claimRewardingMethod, ok = rewardingInterface.Methods["claim"] + _claimRewardingMethod, ok = claimRewardInterface.Methods["claim"] if !ok { panic("fail to load the claim method") } @@ -151,8 +151,8 @@ func (b *ClaimFromRewardingFundBuilder) Build() ClaimFromRewardingFund { return b.claim } -// EncodeABIBinary encodes data in abi encoding -func (c *ClaimFromRewardingFund) EncodeABIBinary() ([]byte, error) { +// encodeABIBinary encodes data in abi encoding +func (c *ClaimFromRewardingFund) encodeABIBinary() ([]byte, error) { data, err := _claimRewardingMethod.Inputs.Pack(c.Amount(), c.Data()) if err != nil { return nil, err @@ -167,7 +167,7 @@ func (c *ClaimFromRewardingFund) ToEthTx() (*types.Transaction, error) { return nil, err } ethAddr := common.BytesToAddress(addr.Bytes()) - data, err := c.EncodeABIBinary() + data, err := c.encodeABIBinary() if err != nil { return nil, err } diff --git a/action/claimreward_test.go b/action/claimreward_test.go index b74c234e0f..447a049873 100644 --- a/action/claimreward_test.go +++ b/action/claimreward_test.go @@ -7,7 +7,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/iotexproject/iotex-address/address" - "github.com/iotexproject/iotex-proto/golang/iotextypes" "github.com/stretchr/testify/require" ) @@ -16,24 +15,6 @@ var ( _errNegativeNumberMsg = "negative value" ) -func TestClaimRewardProto(t *testing.T) { - r := require.New(t) - - rc := &ClaimFromRewardingFund{} - - p := rc.Proto() - r.NotNil(p) - r.IsType(&iotextypes.ClaimFromRewardingFund{}, p) - r.Nil(p.Data) - - rc.amount = big.NewInt(100) - rc.data = []byte{1} - p = rc.Proto() - r.NotNil(p) - r.EqualValues([]byte{1}, p.Data) - r.EqualValues("100", p.Amount) -} - func TestClaimRewardSerialize(t *testing.T) { r := require.New(t) @@ -107,7 +88,7 @@ func TestClaimRewardEncodeABIBinary(t *testing.T) { rc := &ClaimFromRewardingFund{} rc.amount = big.NewInt(101) - data, err := rc.EncodeABIBinary() + data, err := rc.encodeABIBinary() r.Nil(err) r.EqualValues( "2df163ef000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", @@ -115,7 +96,7 @@ func TestClaimRewardEncodeABIBinary(t *testing.T) { ) rc.data = []byte{1, 2, 3} - data, err = rc.EncodeABIBinary() + data, err = rc.encodeABIBinary() r.Nil(err) r.EqualValues( "2df163ef000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", diff --git a/action/depositreward.go b/action/depositreward.go index 53d515c07d..18a251d9c0 100644 --- a/action/depositreward.go +++ b/action/depositreward.go @@ -53,12 +53,12 @@ var ( ) func init() { - rewardingInterface, err := abi.JSON(strings.NewReader(_depositRewardInterfaceABI)) + depositRewardInterface, err := abi.JSON(strings.NewReader(_depositRewardInterfaceABI)) if err != nil { panic(err) } var ok bool - _depositRewardMethod, ok = rewardingInterface.Methods["deposit"] + _depositRewardMethod, ok = depositRewardInterface.Methods["deposit"] if !ok { panic("fail to load the deposit method") } @@ -115,8 +115,7 @@ func (d *DepositToRewardingFund) Cost() (*big.Int, error) { if err != nil { return nil, errors.Wrap(err, "error when getting intrinsic gas for the deposit action") } - fee := big.NewInt(0).Mul(d.GasPrice(), big.NewInt(0).SetUint64(intrinsicGas)) - return new(big.Int).Add(d.Amount(), fee), nil + return big.NewInt(0).Mul(d.GasPrice(), big.NewInt(0).SetUint64(intrinsicGas)), nil } // SanityCheck validates the variables in the action @@ -152,8 +151,8 @@ func (b *DepositToRewardingFundBuilder) Build() DepositToRewardingFund { return b.deposit } -// EncodeABIBinary encodes data in abi encoding -func (d *DepositToRewardingFund) EncodeABIBinary() ([]byte, error) { +// encodeABIBinary encodes data in abi encoding +func (d *DepositToRewardingFund) encodeABIBinary() ([]byte, error) { data, err := _depositRewardMethod.Inputs.Pack(d.Amount(), d.Data()) if err != nil { return nil, err @@ -168,11 +167,11 @@ func (d *DepositToRewardingFund) ToEthTx() (*types.Transaction, error) { return nil, err } ethAddr := common.BytesToAddress(addr.Bytes()) - data, err := d.EncodeABIBinary() + data, err := d.encodeABIBinary() if err != nil { return nil, err } - return types.NewTransaction(d.Nonce(), ethAddr, d.Amount(), d.GasLimit(), d.GasPrice(), data), nil + return types.NewTransaction(d.Nonce(), ethAddr, big.NewInt(0), d.GasLimit(), d.GasPrice(), data), nil } // NewDepositToRewardingFundFromABIBinary decodes data into action diff --git a/action/depositreward_test.go b/action/depositreward_test.go index 35112f04ae..ffc302f37d 100644 --- a/action/depositreward_test.go +++ b/action/depositreward_test.go @@ -7,28 +7,9 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/iotexproject/iotex-address/address" - "github.com/iotexproject/iotex-proto/golang/iotextypes" "github.com/stretchr/testify/require" ) -func TestDepositRewardProto(t *testing.T) { - r := require.New(t) - - rp := &DepositToRewardingFund{} - - p := rp.Proto() - r.NotNil(p) - r.IsType(&iotextypes.DepositToRewardingFund{}, p) - r.Nil(p.Data) - - rp.amount = big.NewInt(100) - rp.data = []byte{1} - p = rp.Proto() - r.NotNil(p) - r.EqualValues([]byte{1}, p.Data) - r.EqualValues("100", p.Amount) -} - func TestDepositRewardSerialize(t *testing.T) { r := require.New(t) @@ -85,12 +66,12 @@ func TestDepositRewardCost(t *testing.T) { rp.amount = big.NewInt(100) cost, err := rp.Cost() r.Nil(err) - r.EqualValues("10000000000000100", cost.String()) + r.EqualValues("10000000000000000", cost.String()) rp.data = []byte{1} cost, err = rp.Cost() r.Nil(err) - r.EqualValues("10100000000000100", cost.String()) + r.EqualValues("10100000000000000", cost.String()) } func TestDepositRewardEncodeABIBinary(t *testing.T) { @@ -99,7 +80,7 @@ func TestDepositRewardEncodeABIBinary(t *testing.T) { rp := &DepositToRewardingFund{} rp.amount = big.NewInt(101) - data, err := rp.EncodeABIBinary() + data, err := rp.encodeABIBinary() r.Nil(err) r.EqualValues( "27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", @@ -107,7 +88,7 @@ func TestDepositRewardEncodeABIBinary(t *testing.T) { ) rp.data = []byte{1, 2, 3} - data, err = rp.EncodeABIBinary() + data, err = rp.encodeABIBinary() r.Nil(err) r.EqualValues( "27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", @@ -130,7 +111,7 @@ func TestDepositRewardToEthTx(t *testing.T) { "27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", hex.EncodeToString(tx.Data()), ) - r.EqualValues("101", tx.Value().String()) + r.EqualValues("0", tx.Value().String()) rp.data = []byte{1, 2, 3} tx, err = rp.ToEthTx() @@ -140,7 +121,7 @@ func TestDepositRewardToEthTx(t *testing.T) { "27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", hex.EncodeToString(tx.Data()), ) - r.EqualValues("101", tx.Value().String()) + r.EqualValues("0", tx.Value().String()) } func TestNewRewardingDepositFromABIBinary(t *testing.T) { diff --git a/action/rlp_tx_test.go b/action/rlp_tx_test.go index 99de01837c..22798b6c19 100644 --- a/action/rlp_tx_test.go +++ b/action/rlp_tx_test.go @@ -275,14 +275,14 @@ func TestRlpDecodeVerify(t *testing.T) { }, { "rewardingDeposit", - "f8c6016482520894a576c141e5659137ddda4223d209d4744b2106be65b86427852a6b0000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000008224c5a0112ab2b0eea79a4377bb89a0452f0a6e414431160ba0f8536bb07e9eff7d51f5a01bcc21d24ac2c5c715675753e5db3a00d249c49fafbe9ac31ec0c7b293a9f2c2", + "f8c6016482520894a576c141e5659137ddda4223d209d4744b2106be80b86427852a6b0000000000000000000000000000000000000000000000000000000000000065000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000008224c6a013b7679dbabcb0f97b93942436f5072cca3c7fe43451a8fedcdf3c84c1344e1da02af4cc67594c0200b59f4e30ba149af15e546acbfc69fa31f14e8788ab063d85", 1, 21000, "100", - "101", + "0", "0xA576C141e5659137ddDa4223d209d4744b2106BE", 100, - "2bc65273dfb59cbad42478dbdac2a3c1ac76a4b19c865eb186464b85deb02cca", + "842fea9a292c0bc7a1e05a14a8255ed8dc945fdae7c01a6b70f5213ebe35583b", "04830579b50e01602c2015c24e72fbc48bca1cca1e601b119ca73abe2e0b5bd61fcb7874567e091030d6b644f927445d80e00b3f9ca0c566c21c30615e94c343da", "8d38efe45794d7fceea10b2262c23c12245959db", }, From f2210325ee48c8ed943c12653fb72182b04ac81f Mon Sep 17 00:00:00 2001 From: ququzone Date: Wed, 21 Dec 2022 15:51:29 +0800 Subject: [PATCH 11/12] change check error style --- action/claimreward_test.go | 8 ++++---- action/depositreward_test.go | 22 +++++++++++----------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/action/claimreward_test.go b/action/claimreward_test.go index 447a049873..22adbca18f 100644 --- a/action/claimreward_test.go +++ b/action/claimreward_test.go @@ -34,17 +34,17 @@ func TestClaimRewardIntrinsicGas(t *testing.T) { rc := &ClaimFromRewardingFund{} gas, err := rc.IntrinsicGas() - r.Nil(err) + r.NoError(err) r.EqualValues(10000, gas) rc.amount = big.NewInt(100000000) gas, err = rc.IntrinsicGas() - r.Nil(err) + r.NoError(err) r.EqualValues(10000, gas) rc.data = []byte{1} gas, err = rc.IntrinsicGas() - r.Nil(err) + r.NoError(err) r.EqualValues(10100, gas) } @@ -55,7 +55,7 @@ func TestClaimRewardSanityCheck(t *testing.T) { rc.amount = big.NewInt(1) err := rc.SanityCheck() - r.Nil(err) + r.NoError(err) rc.amount = big.NewInt(-1) err = rc.SanityCheck() diff --git a/action/depositreward_test.go b/action/depositreward_test.go index ffc302f37d..a08822dc63 100644 --- a/action/depositreward_test.go +++ b/action/depositreward_test.go @@ -29,17 +29,17 @@ func TestDepositRewardIntrinsicGas(t *testing.T) { rp := &DepositToRewardingFund{} gas, err := rp.IntrinsicGas() - r.Nil(err) + r.NoError(err) r.EqualValues(10000, gas) rp.amount = big.NewInt(100000000) gas, err = rp.IntrinsicGas() - r.Nil(err) + r.NoError(err) r.EqualValues(10000, gas) rp.data = []byte{1} gas, err = rp.IntrinsicGas() - r.Nil(err) + r.NoError(err) r.EqualValues(10100, gas) } @@ -50,7 +50,7 @@ func TestDepositRewardSanityCheck(t *testing.T) { rp.amount = big.NewInt(1) err := rp.SanityCheck() - r.Nil(err) + r.NoError(err) rp.amount = big.NewInt(-1) err = rp.SanityCheck() @@ -65,12 +65,12 @@ func TestDepositRewardCost(t *testing.T) { rp.gasPrice = _defaultGasPrice rp.amount = big.NewInt(100) cost, err := rp.Cost() - r.Nil(err) + r.NoError(err) r.EqualValues("10000000000000000", cost.String()) rp.data = []byte{1} cost, err = rp.Cost() - r.Nil(err) + r.NoError(err) r.EqualValues("10100000000000000", cost.String()) } @@ -81,7 +81,7 @@ func TestDepositRewardEncodeABIBinary(t *testing.T) { rp.amount = big.NewInt(101) data, err := rp.encodeABIBinary() - r.Nil(err) + r.NoError(err) r.EqualValues( "27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", hex.EncodeToString(data), @@ -89,7 +89,7 @@ func TestDepositRewardEncodeABIBinary(t *testing.T) { rp.data = []byte{1, 2, 3} data, err = rp.encodeABIBinary() - r.Nil(err) + r.NoError(err) r.EqualValues( "27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", hex.EncodeToString(data), @@ -105,7 +105,7 @@ func TestDepositRewardToEthTx(t *testing.T) { rp := &DepositToRewardingFund{} rp.amount = big.NewInt(101) tx, err := rp.ToEthTx() - r.Nil(err) + r.NoError(err) r.EqualValues(rewardEthAddr, *tx.To()) r.EqualValues( "27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", @@ -115,7 +115,7 @@ func TestDepositRewardToEthTx(t *testing.T) { rp.data = []byte{1, 2, 3} tx, err = rp.ToEthTx() - r.Nil(err) + r.NoError(err) r.EqualValues(rewardEthAddr, *tx.To()) r.EqualValues( "27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003", @@ -130,7 +130,7 @@ func TestNewRewardingDepositFromABIBinary(t *testing.T) { data, _ := hex.DecodeString("27852a6b000000000000000000000000000000000000000000000000000000000000006500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003") rp, err := NewDepositToRewardingFundFromABIBinary(data) - r.Nil(err) + r.NoError(err) r.IsType(&DepositToRewardingFund{}, rp) r.EqualValues("101", rp.Amount().String()) r.EqualValues([]byte{1, 2, 3}, rp.Data()) From ebafd6cef785a657723ea04078899ee4eae93b28 Mon Sep 17 00:00:00 2001 From: ququzone Date: Thu, 22 Dec 2022 09:30:32 +0800 Subject: [PATCH 12/12] add entrance for web3 rewarding --- api/web3server_utils.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/api/web3server_utils.go b/api/web3server_utils.go index 14374e9d31..047f7534b7 100644 --- a/api/web3server_utils.go +++ b/api/web3server_utils.go @@ -176,6 +176,9 @@ func (svr *web3Handler) ethTxToEnvelope(tx *types.Transaction) (action.Envelope, if to == address.StakingProtocolAddr { return elpBuilder.BuildStakingAction(tx) } + if to == address.RewardingProtocol { + return elpBuilder.BuildRewardingAction(tx) + } isContract, err := svr.checkContractAddr(to) if err != nil { return nil, err