Skip to content

Commit 65b14a7

Browse files
authored
Fee pooling SDK change (#216)
* update setfee to support fee pooling * update unit test * update unit tests * update cucumber unit test and fee descriptions * typo fix
1 parent ab9ad13 commit 65b14a7

File tree

8 files changed

+73
-19
lines changed

8 files changed

+73
-19
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ build: generate
1313

1414
unit:
1515
go test $(TEST_SOURCES_NO_CUCUMBER)
16-
cd test && go test --godog.strict=true --godog.format=pretty --godog.tags="@unit.offline,@unit.algod,@unit.indexer,@unit.rekey,@unit.tealsign,@unit.dryrun,@unit.responses,@unit.applications,@unit.transactions,@unit.indexer.rekey,@unit.responses.messagepack,@unit.responses.231,@unit.responses.messagepack.231,@unit.responses.genesis" --test.v .
16+
cd test && go test --godog.strict=true --godog.format=pretty --godog.tags="@unit.offline,@unit.algod,@unit.indexer,@unit.rekey,@unit.tealsign,@unit.dryrun,@unit.responses,@unit.applications,@unit.transactions,@unit.indexer.rekey,@unit.responses.messagepack,@unit.responses.231,@unit.responses.messagepack.231,@unit.responses.genesis,@unit.feetest" --test.v .
1717

1818
integration:
1919
go test $(TEST_SOURCES_NO_CUCUMBER)

client/algod/models/models.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -558,8 +558,8 @@ type AssetList struct {
558558
type TransactionFee struct {
559559
// Fee is transaction fee
560560
// Fee is in units of micro-Algos per byte.
561-
// Fee may fall to zero but transactions must still have a fee of
562-
// at least MinTxnFee for the current network protocol.
561+
// Fee may fall to zero but a group of N atomic transactions must
562+
// still have a fee of at least N*MinTxnFee for the current network protocol.
563563
//
564564
// required: true
565565
Fee uint64 `json:"fee"`
@@ -571,8 +571,8 @@ type TransactionFee struct {
571571
type TransactionParams struct {
572572
// Fee is the suggested transaction fee
573573
// Fee is in units of micro-Algos per byte.
574-
// Fee may fall to zero but transactions must still have a fee of
575-
// at least MinTxnFee for the current network protocol.
574+
// Fee may fall to zero but a group of N atomic transactions must
575+
// still have a fee of at least N*MinTxnFee for the current network protocol.
576576
//
577577
// required: true
578578
Fee uint64 `json:"fee"`

client/v2/common/models/transaction_parameters_response.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ type TransactionParametersResponse struct {
99

1010
// Fee fee is the suggested transaction fee
1111
// Fee is in units of micro-Algos per byte.
12-
// Fee may fall to zero but transactions must still have a fee of
13-
// at least MinTxnFee for the current network protocol.
12+
// Fee may fall to zero but a group of N atomic transactions must
13+
// still have a fee of at least N*MinTxnFee for the current network protocol.
1414
Fee uint64 `json:"fee,omitempty"`
1515

1616
// GenesisHash genesisHash is the hash of the genesis block.

future/transaction.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,13 @@ func setFee(tx types.Transaction, params types.SuggestedParams) (types.Transacti
1818
return types.Transaction{}, err
1919
}
2020
tx.Fee = types.MicroAlgos(eSize * uint64(params.Fee))
21+
if tx.Fee < MinTxnFee {
22+
tx.Fee = MinTxnFee
23+
}
2124
} else {
2225
tx.Fee = params.Fee
2326
}
2427

25-
if tx.Fee < MinTxnFee {
26-
tx.Fee = MinTxnFee
27-
}
28-
2928
return tx, nil
3029
}
3130

@@ -518,7 +517,6 @@ func byte32FromBase64(in string) (out [32]byte, err error) {
518517
// A page is 1024 bytes. This field enables execution of app programs
519518
// larger than the default maximum program size.
520519

521-
522520
// MakeApplicationCreateTx makes a transaction for creating an application (see above for args desc.)
523521
// - optIn: true for opting in on complete, false for no-op.
524522
func MakeApplicationCreateTx(

future/transaction_test.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ package future
22

33
import (
44
"encoding/base64"
5+
"testing"
6+
57
"github.com/algorand/go-algorand-sdk/crypto"
68
"github.com/algorand/go-algorand-sdk/encoding/msgpack"
79
"github.com/algorand/go-algorand-sdk/mnemonic"
810
"github.com/algorand/go-algorand-sdk/transaction"
911
"github.com/algorand/go-algorand-sdk/types"
1012
"github.com/stretchr/testify/require"
11-
"testing"
1213
)
1314

1415
func byteFromBase64(s string) []byte {
@@ -741,17 +742,23 @@ func TestFee(t *testing.T) {
741742
expected: 1001,
742743
},
743744
{
744-
name: "Flat fee overridden with min fee",
745+
name: "Flat fee does not get overridden with min fee",
745746
flatFee: true,
746747
fee: 999,
747-
expected: 1000,
748+
expected: 999,
748749
},
749750
{
750751
name: "Estimated fee overridden with min fee",
751752
flatFee: false,
752753
fee: 1,
753754
expected: 1000,
754755
},
756+
{
757+
name: "Flat fee set to 0",
758+
flatFee: true,
759+
fee: 0,
760+
expected: 0,
761+
},
755762
}
756763
addr := types.Address{}.String()
757764
for _, testcase := range testcases {

test/applications_unit_test.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/algorand/go-algorand-sdk/client/v2/algod"
1515
"github.com/algorand/go-algorand-sdk/client/v2/indexer"
1616
"github.com/algorand/go-algorand-sdk/crypto"
17+
"github.com/algorand/go-algorand-sdk/encoding/msgpack"
1718
"github.com/algorand/go-algorand-sdk/future"
1819
"github.com/algorand/go-algorand-sdk/mnemonic"
1920
"github.com/algorand/go-algorand-sdk/types"
@@ -145,6 +146,30 @@ func signTheTransaction() error {
145146
return err
146147
}
147148

149+
func feeFieldIsInTxn() error {
150+
var txn map[string]interface{}
151+
err := msgpack.Decode(stx, &txn)
152+
if err != nil {
153+
return fmt.Errorf("Error while decoding txn. %v", err)
154+
}
155+
if _, ok := txn["txn"].(map[interface{}]interface{})["fee"]; !ok {
156+
return fmt.Errorf("fee field missing. %v", err)
157+
}
158+
return nil
159+
}
160+
161+
func feeFieldNotInTxn() error {
162+
var txn map[string]interface{}
163+
err := msgpack.Decode(stx, &txn)
164+
if err != nil {
165+
return fmt.Errorf("Error while decoding txn. %v", err)
166+
}
167+
if _, ok := txn["txn"].(map[interface{}]interface{})["fee"]; ok {
168+
return fmt.Errorf("fee field found but it should have been omitted. %v", err)
169+
}
170+
return nil
171+
}
172+
148173
func theBaseEncodedSignedTransactionShouldEqual(base int, golden string) error {
149174
gold, err := base64.StdEncoding.DecodeString(golden)
150175
if err != nil {
@@ -211,12 +236,15 @@ func weMakeALookupApplicationsCall(applicationID int) error {
211236
}
212237

213238
func ApplicationsUnitContext(s *godog.Suite) {
214-
// @unit.transactiosn
239+
// @unit.transactions
215240
s.Step(`^a signing account with address "([^"]*)" and mnemonic "([^"]*)"$`, aSigningAccountWithAddressAndMnemonic)
216241
s.Step(`^I build an application transaction with operation "([^"]*)", application-id (\d+), sender "([^"]*)", approval-program "([^"]*)", clear-program "([^"]*)", global-bytes (\d+), global-ints (\d+), local-bytes (\d+), local-ints (\d+), app-args "([^"]*)", foreign-apps "([^"]*)", foreign-assets "([^"]*)", app-accounts "([^"]*)", fee (\d+), first-valid (\d+), last-valid (\d+), genesis-hash "([^"]*)", extra-pages (\d+)$`, iBuildAnApplicationTransactionUnit)
217242
s.Step(`^sign the transaction$`, signTheTransaction)
218243
s.Step(`^the base(\d+) encoded signed transaction should equal "([^"]*)"$`, theBaseEncodedSignedTransactionShouldEqual)
219244

245+
s.Step(`^fee field is in txn$`, feeFieldIsInTxn)
246+
s.Step(`^fee field not in txn$`, feeFieldNotInTxn)
247+
220248
//@unit.applications
221249
s.Step(`^we make a GetAssetByID call for assetID (\d+)$`, weMakeAGetAssetByIDCall)
222250
s.Step(`^we make a GetApplicationByID call for applicationID (\d+)$`, weMakeAGetApplicationByIDCall)

test/steps_test.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ func FeatureContext(s *godog.Suite) {
174174
s.Step(`mnemonic for private key "([^"]*)"`, mnForSk)
175175
s.Step("I create the payment transaction", createTxn)
176176
s.Step(`multisig addresses "([^"]*)"`, msigAddresses)
177-
s.Step("I create the multisig payment transaction", createMsigTxn)
177+
s.Step("I create the multisig payment transaction$", createMsigTxn)
178+
s.Step("I create the multisig payment transaction with zero fee", createMsigTxnZeroFee)
178179
s.Step("I sign the multisig transaction with the private key", signMsigTxn)
179180
s.Step("I sign the transaction with the private key", signTxn)
180181
s.Step(`^I add a rekeyTo field with address "([^"]*)"$`, iAddARekeyToFieldWithAddress)
@@ -508,6 +509,25 @@ func createMsigTxn() error {
508509

509510
}
510511

512+
func createMsigTxnZeroFee() error {
513+
var err error
514+
paramsToUse := types.SuggestedParams{
515+
Fee: types.MicroAlgos(fee),
516+
GenesisID: gen,
517+
GenesisHash: gh,
518+
FirstRoundValid: types.Round(fv),
519+
LastRoundValid: types.Round(lv),
520+
FlatFee: true,
521+
}
522+
msigaddr, _ := msig.Address()
523+
txn, err = future.MakePaymentTxn(msigaddr.String(), to, amt, note, close, paramsToUse)
524+
if err != nil {
525+
return err
526+
}
527+
return err
528+
529+
}
530+
511531
func signMsigTxn() error {
512532
var err error
513533
txid, stx, err = crypto.SignMultisigTransaction(account.PrivateKey, msig, txn)

types/transaction.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,8 @@ type TxGroup struct {
162162
type SuggestedParams struct {
163163
// Fee is the suggested transaction fee
164164
// Fee is in units of micro-Algos per byte.
165-
// Fee may fall to zero but transactions must still have a fee of
166-
// at least MinTxnFee for the current network protocol.
165+
// Fee may fall to zero but a group of N atomic transactions must
166+
// still have a fee of at least N*MinTxnFee for the current network protocol.
167167
Fee MicroAlgos
168168

169169
// Genesis ID
@@ -183,6 +183,7 @@ type SuggestedParams struct {
183183
ConsensusVersion string
184184

185185
// FlatFee indicates whether the passed fee is per-byte or per-transaction
186+
// If true, txn fee may fall below the MinTxnFee for the current network protocol.
186187
FlatFee bool
187188

188189
// The minimum transaction fee (not per byte) required for the

0 commit comments

Comments
 (0)