Skip to content

Commit

Permalink
feat(grpc): calculate fee for create-raw-transaction APIs (#1159)
Browse files Browse the repository at this point in the history
  • Loading branch information
b00f authored Mar 10, 2024
1 parent 40cf0d9 commit 3a4184b
Show file tree
Hide file tree
Showing 30 changed files with 763 additions and 595 deletions.
4 changes: 2 additions & 2 deletions cmd/gtk/dialog_transaction_unbond.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import (
)

//go:embed assets/ui/dialog_transaction_unbond.ui
var uiTransactionUnBondDialog []byte
var uiTransactionUnbondDialog []byte

func broadcastTransactionUnbond(wlt *wallet.Wallet) {
builder, err := gtk.BuilderNewFromString(string(uiTransactionUnBondDialog))
builder, err := gtk.BuilderNewFromString(string(uiTransactionUnbondDialog))
fatalErrorCheck(err)

dlg := getDialogObj(builder, "id_dialog_transaction_unbond")
Expand Down
3 changes: 1 addition & 2 deletions crypto/hash/hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import (
"fmt"

"golang.org/x/crypto/blake2b"
//nolint:staticcheck // use to hash the public key to get the address
"golang.org/x/crypto/ripemd160"
"golang.org/x/crypto/ripemd160" //nolint:staticcheck // use to hash the public key to get the address
)

const HashSize = 32
Expand Down
2 changes: 1 addition & 1 deletion state/facade.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ type Facade interface {
ValidatorAddresses() []crypto.Address
Params() *param.Params
Close() error
CalculateFee(amount int64, payloadType payload.Type) (int64, error)
CalculateFee(amount int64, payloadType payload.Type) int64
PublicKey(addr crypto.Address) (crypto.PublicKey, error)
AvailabilityScore(valNum int32) float64
}
18 changes: 2 additions & 16 deletions state/mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,22 +253,8 @@ func (m *MockState) Params() *param.Params {
return m.TestParams
}

func (m *MockState) CalculateFee(_ int64, payloadType payload.Type) (int64, error) {
switch payloadType {
case payload.TypeTransfer,
payload.TypeBond,
payload.TypeWithdraw:

return m.ts.RandInt64(1e9), nil

case payload.TypeUnbond,
payload.TypeSortition:

return 0, nil

default:
return 0, errors.Errorf(errors.ErrInvalidTx, "unexpected tx type: %v", payloadType)
}
func (m *MockState) CalculateFee(amount int64, _ payload.Type) int64 {
return amount / 10000
}

func (m *MockState) PublicKey(addr crypto.Address) (crypto.PublicKey, error) {
Expand Down
8 changes: 4 additions & 4 deletions state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -771,21 +771,21 @@ func (st *state) publishEvents(height uint32, blk *block.Block) {
}
}

func (st *state) CalculateFee(amount int64, payloadType payload.Type) (int64, error) {
func (st *state) CalculateFee(amount int64, payloadType payload.Type) int64 {
switch payloadType {
case payload.TypeTransfer,
payload.TypeBond,
payload.TypeWithdraw:

return execution.CalculateFee(amount, st.params), nil
return execution.CalculateFee(amount, st.params)

case payload.TypeUnbond,
payload.TypeSortition:

return 0, nil
return 0

default:
return 0, errors.Errorf(errors.ErrInvalidTx, "unexpected tx type: %v", payloadType)
return 0
}
}

Expand Down
50 changes: 27 additions & 23 deletions state/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"github.com/pactus-project/pactus/types/validator"
"github.com/pactus-project/pactus/types/vote"
"github.com/pactus-project/pactus/util"
"github.com/pactus-project/pactus/util/errors"
"github.com/pactus-project/pactus/util/testsuite"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -604,37 +603,42 @@ func TestCalcFee(t *testing.T) {
td := setup(t)

tests := []struct {
amount int64
pldType payload.Type
fee int64
expectedFee int64
expectedErrCode int
amount int64
pldType payload.Type
expectedFee int64
}{
{1, payload.TypeTransfer, 1, td.state.params.MinimumFee, errors.ErrInvalidFee},
{1, payload.TypeWithdraw, 1001, td.state.params.MinimumFee, errors.ErrInvalidFee},
{1, payload.TypeBond, 1000, td.state.params.MinimumFee, errors.ErrNone},
{0, payload.TypeTransfer, td.state.params.MinimumFee},
{0, payload.TypeWithdraw, td.state.params.MinimumFee},
{0, payload.TypeBond, td.state.params.MinimumFee},

{1 * 1e9, payload.TypeTransfer, 1, 100000, errors.ErrInvalidFee},
{1 * 1e9, payload.TypeWithdraw, 100001, 100000, errors.ErrInvalidFee},
{1 * 1e9, payload.TypeBond, 100000, 100000, errors.ErrNone},
{1, payload.TypeTransfer, td.state.params.MinimumFee},
{1, payload.TypeWithdraw, td.state.params.MinimumFee},
{1, payload.TypeBond, td.state.params.MinimumFee},

{1 * 1e12, payload.TypeTransfer, 1, 1000000, errors.ErrInvalidFee},
{1 * 1e12, payload.TypeWithdraw, 1000001, 1000000, errors.ErrInvalidFee},
{1 * 1e12, payload.TypeBond, 1000000, 1000000, errors.ErrNone},
{1 * 1e9, payload.TypeTransfer, 100000},
{1 * 1e9, payload.TypeWithdraw, 100000},
{1 * 1e9, payload.TypeBond, 100000},

{1 * 1e12, payload.TypeSortition, 0, 0, errors.ErrInvalidFee},
{1 * 1e12, payload.TypeUnbond, 0, 0, errors.ErrNone},
{1 * 1e12, payload.TypeTransfer, 1000000},
{1 * 1e12, payload.TypeWithdraw, 1000000},
{1 * 1e12, payload.TypeBond, 1000000},

{1 * 1e12, payload.TypeSortition, 0},
{1 * 1e12, payload.TypeUnbond, 0},
}
for _, test := range tests {
fee, err := td.state.CalculateFee(test.amount, test.pldType)
assert.NoError(t, err)
fee := td.state.CalculateFee(test.amount, test.pldType)
assert.Equal(t, test.expectedFee, fee)

_, err = td.state.CalculateFee(test.amount, 6)
assert.Error(t, err)
}
}

func TestInvalidPayloadFee(t *testing.T) {
td := setup(t)

fee := td.state.CalculateFee(td.RandAmount(), 6)
assert.Zero(t, fee)
}

func TestCheckMaximumTransactionPerBlock(t *testing.T) {
td := setup(t)

Expand All @@ -643,7 +647,7 @@ func TestCheckMaximumTransactionPerBlock(t *testing.T) {
senderAddr := td.genAccKey.PublicKeyNative().AccountAddress()
for i := 0; i < maxTransactionsPerBlock+2; i++ {
amt := td.RandInt64(1e6)
fee, _ := td.state.CalculateFee(amt, payload.TypeTransfer)
fee := td.state.CalculateFee(amt, payload.TypeTransfer)
trx := tx.NewTransferTx(lockTime, senderAddr, td.RandAccAddress(), amt, fee, "")
err := td.state.AddPendingTx(trx)
assert.NoError(t, err)
Expand Down
4 changes: 2 additions & 2 deletions wallet/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ func (s *transactionServer) GetRawTransferTransaction(_ context.Context,
}, nil
}

func (s *transactionServer) GetRawUnBondTransaction(_ context.Context,
_ *pactus.GetRawUnBondTransactionRequest,
func (s *transactionServer) GetRawUnbondTransaction(_ context.Context,
_ *pactus.GetRawUnbondTransactionRequest,
) (*pactus.GetRawTransactionResponse, error) {
return &pactus.GetRawTransactionResponse{
RawTransaction: make([]byte, 0),
Expand Down
1 change: 0 additions & 1 deletion www/grpc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ In order to compile [pactus.proto](./proto/pactus.proto) file, run this command:
make proto
```


## gRPC-gateway

Pactus utilizes the [gRPC-gateway](https://github.com/grpc-ecosystem/grpc-gateway) to transform gRPC services
Expand Down
2 changes: 1 addition & 1 deletion www/grpc/buf/grpc-gateway.config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ http:
- selector: pactus.Transaction.GetRawBondTransaction
get: "/pactus/transaction/get_raw_bond_transaction/sender/{sender}/receiver/{receiver}/stake/{stake}/lock_time/{lock_time}/public_key/{public_key}/fee/{fee}/memo/{memo}"

- selector: pactus.Transaction.GetRawUnBondTransaction
- selector: pactus.Transaction.GetRawUnbondTransaction
get: "/pactus/transaction/get_raw_unbond_transaction/validator_address/{validator_address}/lock_time/{lock_time}/memo/{memo}"

- selector: pactus.Transaction.GetRawWithdrawTransaction
Expand Down
58 changes: 29 additions & 29 deletions www/grpc/gen/dart/transaction.pb.dart
Original file line number Diff line number Diff line change
Expand Up @@ -631,16 +631,16 @@ class GetRawBondTransactionRequest extends $pb.GeneratedMessage {
void clearMemo() => clearField(7);
}

class GetRawUnBondTransactionRequest extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GetRawUnBondTransactionRequest', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'pactus'), createEmptyInstance: create)
class GetRawUnbondTransactionRequest extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'GetRawUnbondTransactionRequest', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'pactus'), createEmptyInstance: create)
..a<$core.int>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'lockTime', $pb.PbFieldType.OU3)
..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'validatorAddress')
..aOS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'memo')
..hasRequiredFields = false
;

GetRawUnBondTransactionRequest._() : super();
factory GetRawUnBondTransactionRequest({
GetRawUnbondTransactionRequest._() : super();
factory GetRawUnbondTransactionRequest({
$core.int? lockTime,
$core.String? validatorAddress,
$core.String? memo,
Expand All @@ -657,26 +657,26 @@ class GetRawUnBondTransactionRequest extends $pb.GeneratedMessage {
}
return _result;
}
factory GetRawUnBondTransactionRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory GetRawUnBondTransactionRequest.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
factory GetRawUnbondTransactionRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory GetRawUnbondTransactionRequest.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
GetRawUnBondTransactionRequest clone() => GetRawUnBondTransactionRequest()..mergeFromMessage(this);
GetRawUnbondTransactionRequest clone() => GetRawUnbondTransactionRequest()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
GetRawUnBondTransactionRequest copyWith(void Function(GetRawUnBondTransactionRequest) updates) => super.copyWith((message) => updates(message as GetRawUnBondTransactionRequest)) as GetRawUnBondTransactionRequest; // ignore: deprecated_member_use
GetRawUnbondTransactionRequest copyWith(void Function(GetRawUnbondTransactionRequest) updates) => super.copyWith((message) => updates(message as GetRawUnbondTransactionRequest)) as GetRawUnbondTransactionRequest; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static GetRawUnBondTransactionRequest create() => GetRawUnBondTransactionRequest._();
GetRawUnBondTransactionRequest createEmptyInstance() => create();
static $pb.PbList<GetRawUnBondTransactionRequest> createRepeated() => $pb.PbList<GetRawUnBondTransactionRequest>();
static GetRawUnbondTransactionRequest create() => GetRawUnbondTransactionRequest._();
GetRawUnbondTransactionRequest createEmptyInstance() => create();
static $pb.PbList<GetRawUnbondTransactionRequest> createRepeated() => $pb.PbList<GetRawUnbondTransactionRequest>();
@$core.pragma('dart2js:noInline')
static GetRawUnBondTransactionRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GetRawUnBondTransactionRequest>(create);
static GetRawUnBondTransactionRequest? _defaultInstance;
static GetRawUnbondTransactionRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<GetRawUnbondTransactionRequest>(create);
static GetRawUnbondTransactionRequest? _defaultInstance;

@$pb.TagNumber(1)
$core.int get lockTime => $_getIZ(0);
Expand Down Expand Up @@ -711,8 +711,8 @@ class GetRawWithdrawTransactionRequest extends $pb.GeneratedMessage {
..a<$core.int>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'lockTime', $pb.PbFieldType.OU3)
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'validatorAddress')
..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'accountAddress')
..aInt64(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fee')
..aInt64(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'amount')
..aInt64(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'amount')
..aInt64(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fee')
..aOS(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'memo')
..hasRequiredFields = false
;
Expand All @@ -722,8 +722,8 @@ class GetRawWithdrawTransactionRequest extends $pb.GeneratedMessage {
$core.int? lockTime,
$core.String? validatorAddress,
$core.String? accountAddress,
$fixnum.Int64? fee,
$fixnum.Int64? amount,
$fixnum.Int64? fee,
$core.String? memo,
}) {
final _result = create();
Expand All @@ -736,12 +736,12 @@ class GetRawWithdrawTransactionRequest extends $pb.GeneratedMessage {
if (accountAddress != null) {
_result.accountAddress = accountAddress;
}
if (fee != null) {
_result.fee = fee;
}
if (amount != null) {
_result.amount = amount;
}
if (fee != null) {
_result.fee = fee;
}
if (memo != null) {
_result.memo = memo;
}
Expand Down Expand Up @@ -796,22 +796,22 @@ class GetRawWithdrawTransactionRequest extends $pb.GeneratedMessage {
void clearAccountAddress() => clearField(3);

@$pb.TagNumber(4)
$fixnum.Int64 get fee => $_getI64(3);
$fixnum.Int64 get amount => $_getI64(3);
@$pb.TagNumber(4)
set fee($fixnum.Int64 v) { $_setInt64(3, v); }
set amount($fixnum.Int64 v) { $_setInt64(3, v); }
@$pb.TagNumber(4)
$core.bool hasFee() => $_has(3);
$core.bool hasAmount() => $_has(3);
@$pb.TagNumber(4)
void clearFee() => clearField(4);
void clearAmount() => clearField(4);

@$pb.TagNumber(5)
$fixnum.Int64 get amount => $_getI64(4);
$fixnum.Int64 get fee => $_getI64(4);
@$pb.TagNumber(5)
set amount($fixnum.Int64 v) { $_setInt64(4, v); }
set fee($fixnum.Int64 v) { $_setInt64(4, v); }
@$pb.TagNumber(5)
$core.bool hasAmount() => $_has(4);
$core.bool hasFee() => $_has(4);
@$pb.TagNumber(5)
void clearAmount() => clearField(5);
void clearFee() => clearField(5);

@$pb.TagNumber(6)
$core.String get memo => $_getSZ(5);
Expand Down Expand Up @@ -1501,9 +1501,9 @@ class TransactionApi {
var emptyResponse = GetRawTransactionResponse();
return _client.invoke<GetRawTransactionResponse>(ctx, 'Transaction', 'GetRawBondTransaction', request, emptyResponse);
}
$async.Future<GetRawTransactionResponse> getRawUnBondTransaction($pb.ClientContext? ctx, GetRawUnBondTransactionRequest request) {
$async.Future<GetRawTransactionResponse> getRawUnbondTransaction($pb.ClientContext? ctx, GetRawUnbondTransactionRequest request) {
var emptyResponse = GetRawTransactionResponse();
return _client.invoke<GetRawTransactionResponse>(ctx, 'Transaction', 'GetRawUnBondTransaction', request, emptyResponse);
return _client.invoke<GetRawTransactionResponse>(ctx, 'Transaction', 'GetRawUnbondTransaction', request, emptyResponse);
}
$async.Future<GetRawTransactionResponse> getRawWithdrawTransaction($pb.ClientContext? ctx, GetRawWithdrawTransactionRequest request) {
var emptyResponse = GetRawTransactionResponse();
Expand Down
Loading

0 comments on commit 3a4184b

Please sign in to comment.