diff --git a/proto/confidentialtransfers/params.proto b/proto/confidentialtransfers/params.proto index 1823caeb4..159b22e93 100644 --- a/proto/confidentialtransfers/params.proto +++ b/proto/confidentialtransfers/params.proto @@ -6,5 +6,5 @@ option go_package = "github.com/sei-protocol/sei-chain/x/confidentialtransfers/t // Params defines the parameters for the confidential tokens module. message Params { bool enable_ct_module = 1; - uint32 range_proof_gas_multiplier = 2; + uint64 range_proof_gas_cost = 2; } diff --git a/x/confidentialtransfers/keeper/keeper.go b/x/confidentialtransfers/keeper/keeper.go index 9822cb05f..0a01a01fc 100644 --- a/x/confidentialtransfers/keeper/keeper.go +++ b/x/confidentialtransfers/keeper/keeper.go @@ -29,7 +29,7 @@ type Keeper interface { SetParams(ctx sdk.Context, params types.Params) IsCtModuleEnabled(ctx sdk.Context) bool - GetRangeProofGasMultiplier(ctx sdk.Context) uint32 + GetRangeProofGasCost(ctx sdk.Context) uint64 BankKeeper() types.BankKeeper @@ -153,9 +153,9 @@ func (k BaseKeeper) IsCtModuleEnabled(ctx sdk.Context) bool { return isCtModuleEnabled } -// GetRangeProofGasMultiplier retrieves the value of the RangeProofGasMultiplier param from the parameter store -func (k BaseKeeper) GetRangeProofGasMultiplier(ctx sdk.Context) uint32 { - var rangeProofGas uint32 +// GetRangeProofGasCost retrieves the value of the RangeProofGasCost param from the parameter store +func (k BaseKeeper) GetRangeProofGasCost(ctx sdk.Context) uint64 { + var rangeProofGas uint64 k.paramSpace.Get(ctx, types.KeyRangeProofGas, &rangeProofGas) return rangeProofGas } diff --git a/x/confidentialtransfers/keeper/msg_server.go b/x/confidentialtransfers/keeper/msg_server.go index 862641019..71e21a1b1 100644 --- a/x/confidentialtransfers/keeper/msg_server.go +++ b/x/confidentialtransfers/keeper/msg_server.go @@ -220,6 +220,13 @@ func (m msgServer) Withdraw(goCtx context.Context, req *types.MsgWithdraw) (*typ // Verify that the account has sufficient funds (Remaining balance after making the transfer is greater than or equal to zero.) // This range proof verification is performed on the RemainingBalanceCommitment sent by the user. // An additional check is required to ensure that this matches the remaining balance calculated by the server. + + // Consume additional gas as range proofs are computationally expensive. + cost := m.Keeper.GetRangeProofGasCost(ctx) + if cost > 0 { + ctx.GasMeter().ConsumeGas(cost, "range proof verification") + } + verified, _ := zkproofs.VerifyRangeProof(instruction.Proofs.RemainingBalanceRangeProof, instruction.RemainingBalanceCommitment, 128, m.CachedRangeVerifierFactory) if !verified { return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "range proof verification failed") @@ -257,14 +264,6 @@ func (m msgServer) Withdraw(goCtx context.Context, req *types.MsgWithdraw) (*typ return nil, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "insufficient funds to withdraw %s %s", req.Amount, req.Denom) } - gasSoFar := ctx.GasMeter().GasConsumed() - multiplier := m.Keeper.GetRangeProofGasMultiplier(ctx) - - // Consume additional gas according to the multiplier as range proofs are computationally expensive. - if multiplier > 1 { - ctx.GasMeter().ConsumeGas(gasSoFar*uint64(multiplier-1), "range proof verification") - } - // Emit any required events //TODO: Look into whether we can use EmitTypedEvents instead since EmitEvents is deprecated ctx.EventManager().EmitEvents(sdk.Events{ @@ -444,6 +443,13 @@ func (m msgServer) Transfer(goCtx context.Context, req *types.MsgTransfer) (*typ } // Validate proofs + rangeProofGasCost := m.Keeper.GetRangeProofGasCost(ctx) + + // Consume additional gas as range proofs are computationally expensive. + if rangeProofGasCost > 0 { + ctx.GasMeter().ConsumeGas(rangeProofGasCost, "range proof verification") + } + err = types.VerifyTransferProofs(instruction, &senderAccount.PublicKey, &recipientAccount.PublicKey, newSenderBalanceCiphertext, m.CachedRangeVerifierFactory) if err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error()) @@ -498,15 +504,6 @@ func (m msgServer) Transfer(goCtx context.Context, req *types.MsgTransfer) (*typ return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "error setting recipient account") } - gasSoFar := ctx.GasMeter().GasConsumed() - multiplier := m.Keeper.GetRangeProofGasMultiplier(ctx) - - // Consume additional gas according to the multiplier as range proofs are computationally expensive. - // gasSoFar + ((multiplier-1) x gasSoFar) = multiplier x gasSoFar - if multiplier > 1 { - ctx.GasMeter().ConsumeGas(gasSoFar*uint64(multiplier-1), "range proof verification") - } - // Emit any required events ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( diff --git a/x/confidentialtransfers/types/keys.go b/x/confidentialtransfers/types/keys.go index 1d993330d..f70321a80 100644 --- a/x/confidentialtransfers/types/keys.go +++ b/x/confidentialtransfers/types/keys.go @@ -24,7 +24,7 @@ const ( var ( AccountsKeyPrefix = []byte{0x01} KeyEnableCtModule = []byte("EnableCtModule") - KeyRangeProofGas = []byte("RangeProofGasMultiplier") + KeyRangeProofGas = []byte("RangeProofGasCost") ) // GetAddressPrefix generates the prefix for all accounts under a specific address diff --git a/x/confidentialtransfers/types/params.go b/x/confidentialtransfers/types/params.go index 65845c7a3..d02d84358 100644 --- a/x/confidentialtransfers/types/params.go +++ b/x/confidentialtransfers/types/params.go @@ -9,8 +9,8 @@ import ( // DefaultEnableCtModule is the default value for the EnableCtModule flag. const DefaultEnableCtModule = true -// DefaultRangeProofGasMultiplier is the default value for RangeProofGasMultiplier param. -const DefaultRangeProofGasMultiplier = uint32(10) +// DefaultRangeProofGasCost is the default value for RangeProofGasCost param. +const DefaultRangeProofGasCost = uint64(1000000) // ParamKeyTable ParamTable for confidential transfers module. func ParamKeyTable() paramtypes.KeyTable { @@ -20,8 +20,8 @@ func ParamKeyTable() paramtypes.KeyTable { // DefaultParams default confidential transfers module parameters. func DefaultParams() Params { return Params{ - EnableCtModule: DefaultEnableCtModule, - RangeProofGasMultiplier: DefaultRangeProofGasMultiplier, + EnableCtModule: DefaultEnableCtModule, + RangeProofGasCost: DefaultRangeProofGasCost, } } @@ -31,7 +31,7 @@ func (p *Params) Validate() error { return err } - if err := validateRangeProofGasMultiplier(p.RangeProofGasMultiplier); err != nil { + if err := validateRangeProofGasCost(p.RangeProofGasCost); err != nil { return err } @@ -42,7 +42,7 @@ func (p *Params) Validate() error { func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { return paramtypes.ParamSetPairs{ paramtypes.NewParamSetPair(KeyEnableCtModule, &p.EnableCtModule, validateEnableCtModule), - paramtypes.NewParamSetPair(KeyRangeProofGas, &p.RangeProofGasMultiplier, validateRangeProofGasMultiplier), + paramtypes.NewParamSetPair(KeyRangeProofGas, &p.RangeProofGasCost, validateRangeProofGasCost), } } @@ -56,14 +56,11 @@ func validateEnableCtModule(i interface{}) error { } // Validator for the parameter. -func validateRangeProofGasMultiplier(i interface{}) error { - multiplier, ok := i.(uint32) +func validateRangeProofGasCost(i interface{}) error { + _, ok := i.(uint64) if !ok { return fmt.Errorf("invalid parameter type: %T", i) } - if multiplier < 1 { - return fmt.Errorf("range proof gas multiplier must be greater than 0") - } return nil } diff --git a/x/confidentialtransfers/types/params.pb.go b/x/confidentialtransfers/types/params.pb.go index 7f6bf6f06..9dddab2af 100644 --- a/x/confidentialtransfers/types/params.pb.go +++ b/x/confidentialtransfers/types/params.pb.go @@ -24,8 +24,8 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // Params defines the parameters for the confidential tokens module. type Params struct { - EnableCtModule bool `protobuf:"varint,1,opt,name=enable_ct_module,json=enableCtModule,proto3" json:"enable_ct_module,omitempty"` - RangeProofGasMultiplier uint32 `protobuf:"varint,2,opt,name=range_proof_gas_multiplier,json=rangeProofGasMultiplier,proto3" json:"range_proof_gas_multiplier,omitempty"` + EnableCtModule bool `protobuf:"varint,1,opt,name=enable_ct_module,json=enableCtModule,proto3" json:"enable_ct_module,omitempty"` + RangeProofGasCost uint64 `protobuf:"varint,2,opt,name=range_proof_gas_cost,json=rangeProofGasCost,proto3" json:"range_proof_gas_cost,omitempty"` } func (m *Params) Reset() { *m = Params{} } @@ -68,9 +68,9 @@ func (m *Params) GetEnableCtModule() bool { return false } -func (m *Params) GetRangeProofGasMultiplier() uint32 { +func (m *Params) GetRangeProofGasCost() uint64 { if m != nil { - return m.RangeProofGasMultiplier + return m.RangeProofGasCost } return 0 } @@ -84,22 +84,22 @@ func init() { } var fileDescriptor_9a45744da1db817b = []byte{ - // 237 bytes of a gzipped FileDescriptorProto + // 232 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x8f, 0xb1, 0x4a, 0xc4, 0x40, - 0x10, 0x86, 0xb3, 0x16, 0x87, 0x04, 0x14, 0x49, 0xe3, 0x61, 0xb1, 0x1c, 0x57, 0x05, 0xc1, 0xa4, - 0xb0, 0xb4, 0x10, 0xb4, 0xb0, 0x3a, 0x38, 0xae, 0xd3, 0x66, 0xd9, 0xec, 0x4d, 0x72, 0x03, 0x9b, - 0x9d, 0x65, 0x67, 0x03, 0xfa, 0x16, 0x3e, 0x96, 0xe5, 0x95, 0x96, 0x92, 0xbc, 0x88, 0xb8, 0xa2, - 0x55, 0xba, 0x99, 0xff, 0xff, 0xbf, 0xe2, 0xcb, 0xd7, 0x86, 0x5c, 0x8b, 0x7b, 0x70, 0x11, 0xb5, - 0x8d, 0x41, 0x3b, 0x6e, 0x21, 0x70, 0xed, 0x75, 0xd0, 0x3d, 0x57, 0x3e, 0x50, 0xa4, 0xe2, 0x9a, - 0x01, 0xd3, 0x65, 0xc8, 0x56, 0x0c, 0x68, 0x0e, 0x1a, 0x5d, 0x35, 0x0b, 0xae, 0x29, 0x5f, 0x6c, - 0x13, 0x5b, 0x94, 0xf9, 0x05, 0x38, 0xdd, 0x58, 0x50, 0x26, 0xaa, 0x9e, 0xf6, 0x83, 0x85, 0xa5, - 0x58, 0x89, 0xf2, 0x74, 0x77, 0xfe, 0x9b, 0x3f, 0xc6, 0x4d, 0x4a, 0x8b, 0xbb, 0xfc, 0x2a, 0x68, - 0xd7, 0x81, 0xf2, 0x81, 0xa8, 0x55, 0x9d, 0x66, 0xd5, 0x0f, 0x36, 0xa2, 0xb7, 0x08, 0x61, 0x79, - 0xb2, 0x12, 0xe5, 0xd9, 0xee, 0x32, 0x2d, 0xb6, 0x3f, 0x83, 0x27, 0xcd, 0x9b, 0xff, 0xfa, 0xe1, - 0xf9, 0x63, 0x94, 0xe2, 0x38, 0x4a, 0xf1, 0x35, 0x4a, 0xf1, 0x3e, 0xc9, 0xec, 0x38, 0xc9, 0xec, - 0x73, 0x92, 0xd9, 0xcb, 0x7d, 0x87, 0xf1, 0x30, 0x34, 0x95, 0xa1, 0xbe, 0x66, 0xc0, 0x9b, 0x3f, - 0x85, 0xf4, 0x24, 0x87, 0xfa, 0xb5, 0x9e, 0xd7, 0x8f, 0x6f, 0x1e, 0xb8, 0x59, 0x24, 0xe2, 0xf6, - 0x3b, 0x00, 0x00, 0xff, 0xff, 0x6e, 0x49, 0x79, 0xce, 0x24, 0x01, 0x00, 0x00, + 0x10, 0x86, 0xb3, 0x22, 0x87, 0xa4, 0x10, 0x0d, 0x16, 0x57, 0x2d, 0xc7, 0x55, 0x41, 0x30, 0x5b, + 0xf8, 0x00, 0x82, 0x57, 0x58, 0x09, 0xc7, 0x75, 0xda, 0x2c, 0x93, 0xbd, 0x49, 0x6e, 0x21, 0xd9, + 0x09, 0x3b, 0x73, 0xa0, 0x6f, 0xe1, 0x63, 0x59, 0x5e, 0x69, 0x29, 0xc9, 0x8b, 0x88, 0x2b, 0x76, + 0xe9, 0x66, 0xfe, 0x9f, 0x0f, 0xbe, 0x3f, 0x5f, 0x3b, 0x0a, 0x8d, 0xdf, 0x63, 0x10, 0x0f, 0x9d, + 0x44, 0x08, 0xdc, 0x60, 0x64, 0x33, 0x40, 0x84, 0x9e, 0xab, 0x21, 0x92, 0x50, 0x71, 0xcb, 0xe8, + 0xd3, 0xe5, 0xa8, 0xab, 0x18, 0xbd, 0x3b, 0x80, 0x0f, 0xd5, 0x2c, 0xb8, 0x76, 0xf9, 0x62, 0x9b, + 0xd8, 0xa2, 0xcc, 0xaf, 0x30, 0x40, 0xdd, 0xa1, 0x75, 0x62, 0x7b, 0xda, 0x1f, 0x3b, 0x5c, 0xaa, + 0x95, 0x2a, 0x2f, 0x76, 0x97, 0x7f, 0xf9, 0x46, 0x9e, 0x53, 0x5a, 0x98, 0xfc, 0x26, 0x42, 0x68, + 0xd1, 0x0e, 0x91, 0xa8, 0xb1, 0x2d, 0xb0, 0x75, 0xc4, 0xb2, 0x3c, 0x5b, 0xa9, 0xf2, 0x7c, 0x77, + 0x9d, 0xba, 0xed, 0x6f, 0xf5, 0x04, 0xbc, 0x21, 0x96, 0xc7, 0x97, 0xcf, 0x51, 0xab, 0xd3, 0xa8, + 0xd5, 0xf7, 0xa8, 0xd5, 0xc7, 0xa4, 0xb3, 0xd3, 0xa4, 0xb3, 0xaf, 0x49, 0x67, 0xaf, 0x0f, 0xad, + 0x97, 0xc3, 0xb1, 0xae, 0x1c, 0xf5, 0x86, 0xd1, 0xdf, 0xfd, 0x6b, 0xa7, 0x27, 0x79, 0x9b, 0x37, + 0x33, 0x3f, 0x59, 0xde, 0x07, 0xe4, 0x7a, 0x91, 0x88, 0xfb, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x9c, 0xe5, 0x14, 0x12, 0x18, 0x01, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -122,8 +122,8 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.RangeProofGasMultiplier != 0 { - i = encodeVarintParams(dAtA, i, uint64(m.RangeProofGasMultiplier)) + if m.RangeProofGasCost != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.RangeProofGasCost)) i-- dAtA[i] = 0x10 } @@ -160,8 +160,8 @@ func (m *Params) Size() (n int) { if m.EnableCtModule { n += 2 } - if m.RangeProofGasMultiplier != 0 { - n += 1 + sovParams(uint64(m.RangeProofGasMultiplier)) + if m.RangeProofGasCost != 0 { + n += 1 + sovParams(uint64(m.RangeProofGasCost)) } return n } @@ -223,9 +223,9 @@ func (m *Params) Unmarshal(dAtA []byte) error { m.EnableCtModule = bool(v != 0) case 2: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field RangeProofGasMultiplier", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field RangeProofGasCost", wireType) } - m.RangeProofGasMultiplier = 0 + m.RangeProofGasCost = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowParams @@ -235,7 +235,7 @@ func (m *Params) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.RangeProofGasMultiplier |= uint32(b&0x7F) << shift + m.RangeProofGasCost |= uint64(b&0x7F) << shift if b < 0x80 { break } diff --git a/x/confidentialtransfers/types/params_test.go b/x/confidentialtransfers/types/params_test.go index 513511020..d56232bdc 100644 --- a/x/confidentialtransfers/types/params_test.go +++ b/x/confidentialtransfers/types/params_test.go @@ -17,8 +17,8 @@ func TestDefaultParams(t *testing.T) { { name: "default params", want: Params{ - EnableCtModule: DefaultEnableCtModule, - RangeProofGasMultiplier: DefaultRangeProofGasMultiplier, + EnableCtModule: DefaultEnableCtModule, + RangeProofGasCost: DefaultRangeProofGasCost, }, }, } @@ -33,8 +33,8 @@ func TestDefaultParams(t *testing.T) { func TestParams_Validate(t *testing.T) { type fields struct { - EnableCtModule bool - RangeProofGasMultiplier uint32 + EnableCtModule bool + RangeProofGasCost uint64 } tests := []struct { name string @@ -45,26 +45,17 @@ func TestParams_Validate(t *testing.T) { { name: "valid params", fields: fields{ - EnableCtModule: true, - RangeProofGasMultiplier: 10, + EnableCtModule: true, + RangeProofGasCost: 1000000, }, wantErr: false, }, - { - name: "invalid params", - fields: fields{ - EnableCtModule: true, - RangeProofGasMultiplier: 0, - }, - wantErr: true, - errMsg: "range proof gas multiplier must be greater than 0", - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { p := Params{ - EnableCtModule: tt.fields.EnableCtModule, - RangeProofGasMultiplier: tt.fields.RangeProofGasMultiplier, + EnableCtModule: tt.fields.EnableCtModule, + RangeProofGasCost: tt.fields.RangeProofGasCost, } err := p.Validate() if (err != nil) != tt.wantErr { @@ -91,34 +82,34 @@ func TestValidateEnableCtModule(t *testing.T) { }) } -func TestValidateRangeProofGasMultiplier(t *testing.T) { - t.Run("valid multiplier", func(t *testing.T) { - multiplier := uint32(10) - err := validateRangeProofGasMultiplier(multiplier) +func TestValidateRangeProofGasCost(t *testing.T) { + t.Run("valid cost", func(t *testing.T) { + cost := uint64(1000000) + err := validateRangeProofGasCost(cost) assert.Nil(t, err) }) - t.Run("valid but useless multiplier value", func(t *testing.T) { - flag := uint32(1) - err := validateRangeProofGasMultiplier(flag) + t.Run("valid but useless gas cost", func(t *testing.T) { + flag := uint64(0) + err := validateRangeProofGasCost(flag) assert.Nil(t, err) }) - t.Run("invalid multiplier value", func(t *testing.T) { - flag := uint32(0) - err := validateRangeProofGasMultiplier(flag) + t.Run("invalid gas cost", func(t *testing.T) { + flag := -1 + err := validateRangeProofGasCost(flag) assert.Error(t, err) }) - t.Run("invalid multiplier type", func(t *testing.T) { + t.Run("invalid gas cost type", func(t *testing.T) { flag := "True" - err := validateRangeProofGasMultiplier(flag) + err := validateRangeProofGasCost(flag) assert.Error(t, err) }) } func TestParams_ParamSetPairs(t *testing.T) { - params := &Params{EnableCtModule: DefaultEnableCtModule, RangeProofGasMultiplier: DefaultRangeProofGasMultiplier} + params := &Params{EnableCtModule: DefaultEnableCtModule, RangeProofGasCost: DefaultRangeProofGasCost} tests := []struct { name string want types.ParamSetPairs @@ -127,7 +118,7 @@ func TestParams_ParamSetPairs(t *testing.T) { name: "valid param set pairs", want: types.ParamSetPairs{ types.NewParamSetPair(KeyEnableCtModule, ¶ms.EnableCtModule, validateEnableCtModule), - types.NewParamSetPair(KeyRangeProofGas, ¶ms.RangeProofGasMultiplier, validateRangeProofGasMultiplier), + types.NewParamSetPair(KeyRangeProofGas, ¶ms.RangeProofGasCost, validateRangeProofGasCost), }, }, }