Skip to content

Commit 055a2be

Browse files
committed
fix fee logic
1 parent 22804b8 commit 055a2be

File tree

2 files changed

+31
-29
lines changed

2 files changed

+31
-29
lines changed

txnbuild/transaction.go

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -847,16 +847,6 @@ func NewTransaction(params TransactionParams) (*Transaction, error) {
847847
return nil, errors.New("transaction has no operations")
848848
}
849849

850-
// check if maxFee fits in a uint32
851-
// 64 bit fees are only available in fee bump transactions
852-
// if maxFee is negative then there must have been an int overflow
853-
hi, lo := bits.Mul64(uint64(params.BaseFee), uint64(len(params.Operations)))
854-
if hi > 0 || lo > math.MaxUint32 {
855-
return nil, errors.Errorf(
856-
"base fee %d results in an overflow of max fee", params.BaseFee)
857-
}
858-
tx.maxFee = int64(lo)
859-
860850
// Check that all preconditions are valid
861851
if err = tx.preconditions.Validate(); err != nil {
862852
return nil, errors.Wrap(err, "invalid preconditions")
@@ -909,21 +899,32 @@ func NewTransaction(params TransactionParams) (*Transaction, error) {
909899
}
910900

911901
// In case it's a smart contract transaction, we need to include the Ext field within the envelope.
902+
var sorobanFee uint64
912903
if sorobanOp != nil {
913904
envelope.V1.Tx.Ext, err = sorobanOp.BuildTransactionExt()
914905
if err != nil {
915906
return nil, errors.Wrap(err, fmt.Sprintf("failed to build operation %T", sorobanOp))
916907
}
917908
if envelope.V1.Tx.Ext.SorobanData != nil {
918-
sorobanFee := int64(envelope.V1.Tx.Ext.SorobanData.ResourceFee)
919-
tx.maxFee += sorobanFee
920-
if tx.maxFee < 0 {
921-
return nil, fmt.Errorf("soroban fee: %v overflows transaction fee", sorobanFee)
922-
}
909+
sorobanFee = uint64(envelope.V1.Tx.Ext.SorobanData.ResourceFee)
923910
}
924911
}
925912

926-
envelope.V1.Tx.Fee = xdr.Uint32(tx.maxFee)
913+
// check if maxFee fits in a uint32
914+
// 64 bit fees are only available in fee bump transactions
915+
// if maxFee is negative then there must have been an int overflow
916+
hi, lo := bits.Mul64(uint64(params.BaseFee), uint64(len(params.Operations)))
917+
if hi > 0 || lo > math.MaxUint32 {
918+
return nil, errors.Errorf(
919+
"base fee %d results in an overflow of max fee", params.BaseFee)
920+
}
921+
totalFee := lo + sorobanFee
922+
if totalFee < 0 || totalFee > math.MaxUint32 {
923+
return nil, fmt.Errorf("soroban fee %v results in an overflow of max fee", sorobanFee)
924+
}
925+
tx.maxFee = int64(totalFee)
926+
envelope.V1.Tx.Fee = xdr.Uint32(totalFee)
927+
927928
tx.envelope = envelope
928929
return tx, nil
929930
}
@@ -983,18 +984,11 @@ func NewFeeBumpTransaction(params FeeBumpTransactionParams) (*FeeBumpTransaction
983984
// number of operations in the inner transaction. Correspondingly, the minimum fee for
984985
// the fee-bump transaction is one base fee more than the minimum fee for the inner
985986
// transaction.
986-
maxFee: params.BaseFee * int64(len(inner.operations)+1),
987987
feeAccount: params.FeeAccount,
988988
inner: new(Transaction),
989989
}
990990
*tx.inner = *inner
991991

992-
hi, lo := bits.Mul64(uint64(params.BaseFee), uint64(len(inner.operations)+1))
993-
if hi > 0 || lo > math.MaxInt64 {
994-
return nil, errors.Errorf("base fee %d results in an overflow of max fee", params.BaseFee)
995-
}
996-
tx.maxFee = int64(lo)
997-
998992
if tx.baseFee < tx.inner.baseFee {
999993
return tx, errors.New("base fee cannot be lower than provided inner transaction fee")
1000994
}
@@ -1004,13 +998,20 @@ func NewFeeBumpTransaction(params FeeBumpTransactionParams) (*FeeBumpTransaction
1004998
)
1005999
}
10061000

1001+
var sorobanFee uint64
10071002
if inner.envelope.V1 != nil && inner.envelope.V1.Tx.Ext.SorobanData != nil {
1008-
sorobanFee := int64(inner.envelope.V1.Tx.Ext.SorobanData.ResourceFee)
1009-
tx.maxFee += sorobanFee
1010-
if tx.maxFee < 0 {
1011-
return nil, fmt.Errorf("soroban fee: %v overflows transaction fee", sorobanFee)
1012-
}
1003+
sorobanFee = uint64(inner.envelope.V1.Tx.Ext.SorobanData.ResourceFee)
1004+
}
1005+
1006+
hi, lo := bits.Mul64(uint64(params.BaseFee), uint64(len(inner.operations)+1))
1007+
if hi > 0 || lo > math.MaxInt64 {
1008+
return nil, errors.Errorf("base fee %d results in an overflow of max fee", params.BaseFee)
10131009
}
1010+
totalFee := lo + sorobanFee
1011+
if totalFee < 0 || totalFee > math.MaxInt64 {
1012+
return nil, fmt.Errorf("soroban fee %v results in an overflow of max fee", sorobanFee)
1013+
}
1014+
tx.maxFee = int64(lo)
10141015

10151016
var feeSource xdr.MuxedAccount
10161017
if err := feeSource.SetAddress(tx.feeAccount); err != nil {

txnbuild/transaction_fee_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ import (
44
"math"
55
"testing"
66

7-
"github.com/stellar/go/keypair"
87
"github.com/stretchr/testify/assert"
8+
9+
"github.com/stellar/go/keypair"
910
)
1011

1112
func TestBaseFeeCanBeZeroOrPositive(t *testing.T) {

0 commit comments

Comments
 (0)