diff --git a/clients/horizonclient/client.go b/clients/horizonclient/client.go index 105c37fc7f..c35f3267ca 100644 --- a/clients/horizonclient/client.go +++ b/clients/horizonclient/client.go @@ -653,10 +653,10 @@ func (c *Client) StreamOrderBooks(ctx context.Context, request OrderBookRequest, // It defaults to localtime when the server time is not available. // Note that this will generate your timebounds when you init the transaction, not when you build or submit // the transaction! So give yourself enough time to get the transaction built and signed before submitting. -func (c *Client) FetchTimebounds(seconds int64) (txnbuild.Timebounds, error) { +func (c *Client) FetchTimebounds(seconds int64) (txnbuild.TimeBounds, error) { serverURL, err := url.Parse(c.HorizonURL) if err != nil { - return txnbuild.Timebounds{}, errors.Wrap(err, "unable to parse horizon url") + return txnbuild.TimeBounds{}, errors.Wrap(err, "unable to parse horizon url") } currentTime := currentServerTime(serverURL.Hostname(), c.clock.Now().UTC().Unix()) if currentTime != 0 { diff --git a/clients/horizonclient/examples_test.go b/clients/horizonclient/examples_test.go index 146bba681e..3494014fab 100644 --- a/clients/horizonclient/examples_test.go +++ b/clients/horizonclient/examples_test.go @@ -1100,7 +1100,7 @@ func ExampleClient_SubmitFeeBumpTransaction() { IncrementSequenceNum: false, Operations: []txnbuild.Operation{&op}, BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewInfiniteTimeout()}, // Use a real timeout in production! }, ) if err != nil { @@ -1154,7 +1154,7 @@ func ExampleClient_SubmitFeeBumpTransactionWithOptions() { IncrementSequenceNum: false, Operations: []txnbuild.Operation{&op}, BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewInfiniteTimeout()}, // Use a real timeout in production! }, ) if err != nil { @@ -1211,7 +1211,7 @@ func ExampleClient_SubmitTransaction() { IncrementSequenceNum: false, Operations: []txnbuild.Operation{&op}, BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewInfiniteTimeout()}, // Use a real timeout in production! }, ) if err != nil { @@ -1253,7 +1253,7 @@ func ExampleClient_SubmitTransactionWithOptions() { IncrementSequenceNum: false, Operations: []txnbuild.Operation{&op}, BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewInfiniteTimeout()}, // Use a real timeout in production! }, ) if err != nil { @@ -1295,7 +1295,7 @@ func ExampleClient_SubmitTransactionWithOptions_skip_memo_required_check() { IncrementSequenceNum: false, Operations: []txnbuild.Operation{&op}, BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewInfiniteTimeout()}, // Use a real timeout in production! }, ) if err != nil { diff --git a/clients/horizonclient/main_test.go b/clients/horizonclient/main_test.go index 9bd0d6f5ea..b1119def12 100644 --- a/clients/horizonclient/main_test.go +++ b/clients/horizonclient/main_test.go @@ -146,7 +146,7 @@ func TestCheckMemoRequired(t *testing.T) { IncrementSequenceNum: true, Operations: tc.operations, BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimebounds(0, 10), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimebounds(0, 10)}, }, ) tt.NoError(err) @@ -878,7 +878,7 @@ func TestSubmitTransactionRequest(t *testing.T) { IncrementSequenceNum: true, Operations: []txnbuild.Operation{&payment}, BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimebounds(0, 10), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimebounds(0, 10)}, }, ) assert.NoError(t, err) @@ -946,7 +946,7 @@ func TestSubmitTransactionRequestMuxedAccounts(t *testing.T) { IncrementSequenceNum: true, Operations: []txnbuild.Operation{&payment}, BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimebounds(0, 10), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimebounds(0, 10)}, }, ) assert.NoError(t, err) @@ -1006,7 +1006,7 @@ func TestSubmitFeeBumpTransaction(t *testing.T) { IncrementSequenceNum: true, Operations: []txnbuild.Operation{&payment}, BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimebounds(0, 10), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimebounds(0, 10)}, }, ) assert.NoError(t, err) @@ -1075,7 +1075,7 @@ func TestSubmitTransactionWithOptionsRequest(t *testing.T) { IncrementSequenceNum: true, Operations: []txnbuild.Operation{&payment}, BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimebounds(0, 10), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimebounds(0, 10)}, }, ) assert.NoError(t, err) @@ -1168,7 +1168,7 @@ func TestSubmitTransactionWithOptionsRequest(t *testing.T) { Operations: []txnbuild.Operation{&payment}, BaseFee: txnbuild.MinBaseFee, Memo: txnbuild.MemoText("HelloWorld"), - Timebounds: txnbuild.NewTimebounds(0, 10), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimebounds(0, 10)}, }, ) assert.NoError(t, err) @@ -1202,7 +1202,7 @@ func TestSubmitFeeBumpTransactionWithOptions(t *testing.T) { IncrementSequenceNum: true, Operations: []txnbuild.Operation{&payment}, BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimebounds(0, 10), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimebounds(0, 10)}, }, ) assert.NoError(t, err) @@ -1293,7 +1293,7 @@ func TestSubmitFeeBumpTransactionWithOptions(t *testing.T) { Operations: []txnbuild.Operation{&payment}, BaseFee: txnbuild.MinBaseFee, Memo: txnbuild.MemoText("HelloWorld"), - Timebounds: txnbuild.NewTimebounds(0, 10), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimebounds(0, 10)}, }, ) assert.NoError(t, err) @@ -1483,7 +1483,7 @@ func TestFetchTimebounds(t *testing.T) { ServerTimeMap["localhost"] = newRecord st, err = client.FetchTimebounds(100) assert.NoError(t, err) - assert.IsType(t, st, txnbuild.Timebounds{}) + assert.IsType(t, st, txnbuild.TimeBounds{}) assert.Equal(t, st.MinTime, int64(0)) // time should be 200, serverTime + 100seconds assert.Equal(t, st.MaxTime, int64(200)) diff --git a/exp/services/recoverysigner/internal/serve/account_sign_signing_address_test.go b/exp/services/recoverysigner/internal/serve/account_sign_signing_address_test.go index 7246653230..c7b3289610 100644 --- a/exp/services/recoverysigner/internal/serve/account_sign_signing_address_test.go +++ b/exp/services/recoverysigner/internal/serve/account_sign_signing_address_test.go @@ -349,8 +349,8 @@ func TestAccountSign_signingAddressAccountAuthenticatedButSigningAddressInvalid( }, }, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimebounds(0, 1), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimebounds(0, 1)}, }, ) require.NoError(t, err) @@ -411,8 +411,8 @@ func TestAccountSign_signingAddressAccountAuthenticatedOtherSignerSelected(t *te }, }, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimebounds(0, 1), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimebounds(0, 1)}, }, ) require.NoError(t, err) @@ -477,8 +477,8 @@ func TestAccountSign_signingAddressAccountAuthenticatedTxSourceAccountValid(t *t }, }, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimebounds(0, 1), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimebounds(0, 1)}, }, ) require.NoError(t, err) @@ -544,8 +544,8 @@ func TestAccountSign_signingAddressAccountAuthenticatedTxAndOpSourceAccountValid }, }, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimebounds(0, 1), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimebounds(0, 1)}, }, ) require.NoError(t, err) @@ -610,8 +610,8 @@ func TestAccountSign_signingAddressAccountAuthenticatedTxSourceAccountInvalid(t }, }, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimebounds(0, 1), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimebounds(0, 1)}, }, ) require.NoError(t, err) @@ -673,8 +673,8 @@ func TestAccountSign_signingAddressAccountAuthenticatedOpSourceAccountInvalid(t }, }, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimebounds(0, 1), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimebounds(0, 1)}, }, ) require.NoError(t, err) @@ -737,8 +737,8 @@ func TestAccountSign_signingAddressAccountAuthenticatedTxAndOpSourceAccountInval }, }, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimebounds(0, 1), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimebounds(0, 1)}, }, ) require.NoError(t, err) @@ -806,8 +806,8 @@ func TestAccountSign_signingAddressPhoneNumberOwnerAuthenticated(t *testing.T) { }, }, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimebounds(0, 1), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimebounds(0, 1)}, }, ) require.NoError(t, err) @@ -878,8 +878,8 @@ func TestAccountSign_signingAddressPhoneNumberOtherAuthenticated(t *testing.T) { }, }, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimebounds(0, 1), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimebounds(0, 1)}, }, ) require.NoError(t, err) @@ -950,8 +950,8 @@ func TestAccountSign_signingAddressEmailOwnerAuthenticated(t *testing.T) { }, }, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimebounds(0, 1), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimebounds(0, 1)}, }, ) require.NoError(t, err) @@ -1031,8 +1031,8 @@ func TestAccountSign_signingAddressEmailOwnerAuthenticatedOpSourceAccountIsAllow }, &txnbuild.EndSponsoringFutureReserves{}, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimebounds(0, 1), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimebounds(0, 1)}, }, ) require.NoError(t, err) @@ -1108,8 +1108,8 @@ func TestAccountSign_signingAddressEmailOwnerAuthenticatedOpSourceAccountInvalid }, &txnbuild.EndSponsoringFutureReserves{}, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimebounds(0, 1), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimebounds(0, 1)}, }, ) require.NoError(t, err) @@ -1175,8 +1175,8 @@ func TestAccountSign_signingAddressEmailOtherAuthenticated(t *testing.T) { }, }, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimebounds(0, 1), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimebounds(0, 1)}, }, ) require.NoError(t, err) @@ -1281,8 +1281,8 @@ func TestAccountSign_signingAddressRejectsFeeBumpTx(t *testing.T) { }, }, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimebounds(0, 1), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimebounds(0, 1)}, }, ) require.NoError(t, err) @@ -1351,8 +1351,8 @@ func TestAccountSign_signingAddressValidContentTypeForm(t *testing.T) { }, }, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimebounds(0, 1), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimebounds(0, 1)}, }, ) require.NoError(t, err) diff --git a/exp/services/webauth/internal/serve/token_test.go b/exp/services/webauth/internal/serve/token_test.go index ceb1c1e771..367c941b56 100644 --- a/exp/services/webauth/internal/serve/token_test.go +++ b/exp/services/webauth/internal/serve/token_test.go @@ -1136,9 +1136,11 @@ func TestToken_jsonInputNoWebAuthDomainSuccess(t *testing.T) { Value: []byte("ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg"), }, }, - BaseFee: txnbuild.MinBaseFee, - Memo: nil, - Timebounds: txnbuild.NewTimebounds(txMinTimebounds, txMaxTimebounds), + BaseFee: txnbuild.MinBaseFee, + Memo: nil, + Preconditions: txnbuild.Preconditions{ + Timebounds: txnbuild.NewTimebounds(txMinTimebounds, txMaxTimebounds), + }, }, ) require.NoError(t, err) diff --git a/services/friendbot/init_friendbot.go b/services/friendbot/init_friendbot.go index ec8d1051cc..19c45f96b2 100644 --- a/services/friendbot/init_friendbot.go +++ b/services/friendbot/init_friendbot.go @@ -120,7 +120,7 @@ func createMinionAccounts(botAccount internal.Account, botKeypair *keypair.Full, IncrementSequenceNum: true, Operations: ops, BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimeout(300), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimeout(300)}, }, ) if err != nil { diff --git a/services/friendbot/internal/minion.go b/services/friendbot/internal/minion.go index 826826728e..a27e5a3296 100644 --- a/services/friendbot/internal/minion.go +++ b/services/friendbot/internal/minion.go @@ -117,7 +117,7 @@ func (minion *Minion) makeTx(destAddress string) (string, error) { IncrementSequenceNum: true, Operations: []txnbuild.Operation{&createAccountOp}, BaseFee: minion.BaseFee, - Timebounds: txnbuild.NewInfiniteTimeout(), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewInfiniteTimeout()}, }, ) if err != nil { diff --git a/services/horizon/internal/integration/negative_seq_txsub_test.go b/services/horizon/internal/integration/negative_seq_txsub_test.go index 0abf2c7bcb..572a682e52 100644 --- a/services/horizon/internal/integration/negative_seq_txsub_test.go +++ b/services/horizon/internal/integration/negative_seq_txsub_test.go @@ -55,7 +55,7 @@ func TestNegativeSequenceTxSubmission(t *testing.T) { SourceAccount: account, Operations: []txnbuild.Operation{&op2}, BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewInfiniteTimeout(), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewInfiniteTimeout()}, IncrementSequenceNum: false, } tx, err := txnbuild.NewTransaction(txParams) diff --git a/services/horizon/internal/integration/sponsorship_test.go b/services/horizon/internal/integration/sponsorship_test.go index 74a21dd385..af2ae7ea10 100644 --- a/services/horizon/internal/integration/sponsorship_test.go +++ b/services/horizon/internal/integration/sponsorship_test.go @@ -311,7 +311,7 @@ func TestSponsorships(t *testing.T) { SourceAccount: newAccount, Operations: []txnbuild.Operation{preAuthOp}, BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewInfiniteTimeout(), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewInfiniteTimeout()}, IncrementSequenceNum: true, } preaAuthTx, err := txnbuild.NewTransaction(txParams) diff --git a/services/horizon/internal/test/integration/integration.go b/services/horizon/internal/test/integration/integration.go index bd7de611a9..1a485d2a94 100644 --- a/services/horizon/internal/test/integration/integration.go +++ b/services/horizon/internal/test/integration/integration.go @@ -694,7 +694,7 @@ func (i *Test) CreateSignedTransaction( SourceAccount: source, Operations: ops, BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewInfiniteTimeout(), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewInfiniteTimeout()}, IncrementSequenceNum: true, } diff --git a/services/regulated-assets-approval-server/internal/configureissuer/configureissuer.go b/services/regulated-assets-approval-server/internal/configureissuer/configureissuer.go index 611c92448d..ba3cdb8050 100644 --- a/services/regulated-assets-approval-server/internal/configureissuer/configureissuer.go +++ b/services/regulated-assets-approval-server/internal/configureissuer/configureissuer.go @@ -119,8 +119,8 @@ func setup(opts Options, hClient horizonclient.ClientInterface) error { SourceAccount: trustorKP.Address(), }, }, - BaseFee: 300, - Timebounds: txnbuild.NewTimeout(300), + BaseFee: 300, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimeout(300)}, }) if err != nil { return errors.Wrap(err, "building transaction") diff --git a/services/regulated-assets-approval-server/internal/serve/api_tx_approve_test.go b/services/regulated-assets-approval-server/internal/serve/api_tx_approve_test.go index bdba6a9825..47f0af2f13 100644 --- a/services/regulated-assets-approval-server/internal/serve/api_tx_approve_test.go +++ b/services/regulated-assets-approval-server/internal/serve/api_tx_approve_test.go @@ -114,8 +114,8 @@ func TestAPI_txApprove_revised(t *testing.T) { Asset: assetGOAT, }, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewInfiniteTimeout(), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewInfiniteTimeout()}, }, ) require.NoError(t, err) @@ -234,8 +234,8 @@ func TestAPI_txAprove_actionRequired(t *testing.T) { Asset: assetGOAT, }, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewInfiniteTimeout(), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewInfiniteTimeout()}, }, ) require.NoError(t, err) @@ -327,8 +327,8 @@ func TestAPI_txAprove_actionRequiredFlow(t *testing.T) { Asset: assetGOAT, }, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewInfiniteTimeout(), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewInfiniteTimeout()}, }, ) require.NoError(t, err) @@ -538,8 +538,8 @@ func TestAPI_txApprove_success(t *testing.T) { SourceAccount: issuerKP.Address(), }, }, - BaseFee: 300, - Timebounds: txnbuild.NewTimeout(300), + BaseFee: 300, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimeout(300)}, }) require.NoError(t, err) txe, err := tx.Base64() diff --git a/services/regulated-assets-approval-server/internal/serve/friendbot.go b/services/regulated-assets-approval-server/internal/serve/friendbot.go index 6da2936461..9adc1b56c2 100644 --- a/services/regulated-assets-approval-server/internal/serve/friendbot.go +++ b/services/regulated-assets-approval-server/internal/serve/friendbot.go @@ -157,8 +157,8 @@ func (h friendbotHandler) topUpAccountWithRegulatedAsset(ctx context.Context, in Authorize: false, }, }, - BaseFee: 300, - Timebounds: txnbuild.NewTimeout(300), + BaseFee: 300, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimeout(300)}, }) if err != nil { err = errors.Wrap(err, "building transaction") diff --git a/services/regulated-assets-approval-server/internal/serve/tx_approve.go b/services/regulated-assets-approval-server/internal/serve/tx_approve.go index 47b82ae83c..ff1f9dee00 100644 --- a/services/regulated-assets-approval-server/internal/serve/tx_approve.go +++ b/services/regulated-assets-approval-server/internal/serve/tx_approve.go @@ -231,7 +231,7 @@ func (h txApproveHandler) txApprove(ctx context.Context, in txApproveRequest) (r IncrementSequenceNum: true, Operations: revisedOperations, BaseFee: 300, - Timebounds: txnbuild.NewTimeout(300), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimeout(300)}, }) if err != nil { return nil, errors.Wrap(err, "building transaction") diff --git a/services/regulated-assets-approval-server/internal/serve/tx_approve_test.go b/services/regulated-assets-approval-server/internal/serve/tx_approve_test.go index 1b8a19aa94..fcdb548f45 100644 --- a/services/regulated-assets-approval-server/internal/serve/tx_approve_test.go +++ b/services/regulated-assets-approval-server/internal/serve/tx_approve_test.go @@ -143,7 +143,7 @@ func TestTxApproveHandler_validateInput(t *testing.T) { Sequence: "1", }, IncrementSequenceNum: true, - Timebounds: txnbuild.NewInfiniteTimeout(), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewInfiniteTimeout()}, BaseFee: 300, Operations: []txnbuild.Operation{ &txnbuild.Payment{ @@ -169,7 +169,7 @@ func TestTxApproveHandler_validateInput(t *testing.T) { Sequence: "1", }, IncrementSequenceNum: true, - Timebounds: txnbuild.NewInfiniteTimeout(), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewInfiniteTimeout()}, BaseFee: 300, Operations: []txnbuild.Operation{ &txnbuild.BumpSequence{}, @@ -197,7 +197,7 @@ func TestTxApproveHandler_validateInput(t *testing.T) { Sequence: "1", }, IncrementSequenceNum: true, - Timebounds: txnbuild.NewInfiniteTimeout(), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewInfiniteTimeout()}, BaseFee: 300, Operations: []txnbuild.Operation{ &txnbuild.Payment{ @@ -371,8 +371,8 @@ func TestTxApproveHandler_txApprove_rejected(t *testing.T) { Asset: assetGOAT, }, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewInfiniteTimeout(), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewInfiniteTimeout()}, }, ) require.NoError(t, err) @@ -394,8 +394,8 @@ func TestTxApproveHandler_txApprove_rejected(t *testing.T) { Operations: []txnbuild.Operation{ &txnbuild.BumpSequence{}, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewInfiniteTimeout(), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewInfiniteTimeout()}, }, ) require.NoError(t, err) @@ -424,8 +424,8 @@ func TestTxApproveHandler_txApprove_rejected(t *testing.T) { }, }, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewInfiniteTimeout(), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewInfiniteTimeout()}, }, ) require.NoError(t, err) @@ -454,8 +454,8 @@ func TestTxApproveHandler_txApprove_rejected(t *testing.T) { }, }, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewInfiniteTimeout(), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewInfiniteTimeout()}, }, ) require.NoError(t, err) @@ -481,8 +481,8 @@ func TestTxApproveHandler_txApprove_rejected(t *testing.T) { Asset: assetGOAT, }, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewInfiniteTimeout(), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewInfiniteTimeout()}, }, ) require.NoError(t, err) @@ -568,8 +568,8 @@ func TestTxApproveHandler_txApprove_success(t *testing.T) { SourceAccount: issuerKP.Address(), }, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewInfiniteTimeout(), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewInfiniteTimeout()}, }, ) require.NoError(t, err) @@ -630,8 +630,8 @@ func TestTxApproveHandler_txApprove_actionRequired(t *testing.T) { Asset: assetGOAT, }, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewInfiniteTimeout(), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewInfiniteTimeout()}, }, ) require.NoError(t, err) @@ -706,8 +706,8 @@ func TestTxApproveHandler_txApprove_revised(t *testing.T) { Asset: assetGOAT, }, }, - BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewInfiniteTimeout(), + BaseFee: txnbuild.MinBaseFee, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewInfiniteTimeout()}, }, ) require.NoError(t, err) @@ -784,8 +784,8 @@ func TestValidateTransactionOperationsForSuccess(t *testing.T) { Asset: assetGOAT, }, }, - BaseFee: 300, - Timebounds: txnbuild.NewTimeout(300), + BaseFee: 300, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimeout(300)}, }) require.NoError(t, err) @@ -808,8 +808,8 @@ func TestValidateTransactionOperationsForSuccess(t *testing.T) { &txnbuild.BumpSequence{}, &txnbuild.BumpSequence{}, }, - BaseFee: 300, - Timebounds: txnbuild.NewTimeout(300), + BaseFee: 300, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimeout(300)}, }) require.NoError(t, err) @@ -837,8 +837,8 @@ func TestValidateTransactionOperationsForSuccess(t *testing.T) { &txnbuild.BumpSequence{}, &txnbuild.BumpSequence{}, }, - BaseFee: 300, - Timebounds: txnbuild.NewTimeout(300), + BaseFee: 300, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimeout(300)}, }) require.NoError(t, err) @@ -886,8 +886,8 @@ func TestValidateTransactionOperationsForSuccess(t *testing.T) { SourceAccount: issuerKP.Address(), }, }, - BaseFee: 300, - Timebounds: txnbuild.NewTimeout(300), + BaseFee: 300, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimeout(300)}, }) require.NoError(t, err) @@ -935,8 +935,8 @@ func TestValidateTransactionOperationsForSuccess(t *testing.T) { SourceAccount: issuerKP.Address(), }, }, - BaseFee: 300, - Timebounds: txnbuild.NewTimeout(300), + BaseFee: 300, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimeout(300)}, }) require.NoError(t, err) @@ -1001,8 +1001,8 @@ func TestTxApproveHandler_handleSuccessResponseIfNeeded_revisable(t *testing.T) Asset: assetGOAT, }, }, - BaseFee: 300, - Timebounds: txnbuild.NewTimeout(300), + BaseFee: 300, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimeout(300)}, }) require.NoError(t, err) @@ -1065,8 +1065,8 @@ func TestTxApproveHandler_handleSuccessResponseIfNeeded_rejected(t *testing.T) { &txnbuild.BumpSequence{}, &txnbuild.BumpSequence{}, }, - BaseFee: 300, - Timebounds: txnbuild.NewTimeout(300), + BaseFee: 300, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimeout(300)}, }) require.NoError(t, err) @@ -1113,8 +1113,8 @@ func TestTxApproveHandler_handleSuccessResponseIfNeeded_rejected(t *testing.T) { SourceAccount: issuerKP.Address(), }, }, - BaseFee: 300, - Timebounds: txnbuild.NewTimeout(300), + BaseFee: 300, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimeout(300)}, }) require.NoError(t, err) @@ -1163,7 +1163,7 @@ func TestTxApproveHandler_handleSuccessResponseIfNeeded_rejected(t *testing.T) { IncrementSequenceNum: true, Operations: compliantOps, BaseFee: 300, - Timebounds: txnbuild.NewTimeout(300), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimeout(300)}, }) require.NoError(t, err) @@ -1246,8 +1246,8 @@ func TestTxApproveHandler_handleSuccessResponseIfNeeded_actionRequired(t *testin SourceAccount: issuerKP.Address(), }, }, - BaseFee: 300, - Timebounds: txnbuild.NewTimeout(300), + BaseFee: 300, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimeout(300)}, }) require.NoError(t, err) @@ -1385,8 +1385,8 @@ func TestTxApproveHandler_handleSuccessResponseIfNeeded_success(t *testing.T) { SourceAccount: issuerKP.Address(), }, }, - BaseFee: 300, - Timebounds: txnbuild.NewTimeout(300), + BaseFee: 300, + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimeout(300)}, }) require.NoError(t, err) diff --git a/txnbuild/CHANGELOG.md b/txnbuild/CHANGELOG.md index 8f5f88a083..40435f9594 100644 --- a/txnbuild/CHANGELOG.md +++ b/txnbuild/CHANGELOG.md @@ -4,6 +4,26 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## Unreleased + +### Breaking changes + +* Adds support for Protocol 19 transaction preconditions ([CAP-21](https://stellar.org/protocol/cap-21)). There are many new ways for a transaction to be (in)valid (see the new `Preconditions` structure), and the corresponding breaking change is in how transactions are built: + +```diff + tx, err := NewTransaction(TransactionParams{ + SourceAccount: someAccount, + // ... other parameters ... +- Timebounds: NewTimeout(5), ++ Preconditions: Preconditions{TimeBounds: NewTimeout(5)}, + }) +``` + +* `Timebounds` has been renamed to `TimeBounds`, though a type alias remains. + +* A `*TimeBounds` structure is no longer considered valid (via `Validate()`) if it's `nil`. This further reinforces the fact that transactions need timebounds. + + ## [9.0.0](https://github.com/stellar/go/releases/tag/horizonclient-v9.0.0) - 2022-01-10 * Enable Muxed Accounts ([SEP-23](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0023.md)) by default ([#4169](https://github.com/stellar/go/pull/4169)): diff --git a/txnbuild/account_merge_test.go b/txnbuild/account_merge_test.go index 72cf9027ce..7ee237acf4 100644 --- a/txnbuild/account_merge_test.go +++ b/txnbuild/account_merge_test.go @@ -18,7 +18,7 @@ func TestAccountMergeValidate(t *testing.T) { TransactionParams{ SourceAccount: &sourceAccount, Operations: []Operation{&accountMerge}, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, BaseFee: MinBaseFee, }, ) diff --git a/txnbuild/allow_trust_test.go b/txnbuild/allow_trust_test.go index 607e58a81b..7bb0f68979 100644 --- a/txnbuild/allow_trust_test.go +++ b/txnbuild/allow_trust_test.go @@ -22,7 +22,7 @@ func TestAllowTrustValidateAsset(t *testing.T) { TransactionParams{ SourceAccount: &sourceAccount, Operations: []Operation{&allowTrust}, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, BaseFee: MinBaseFee, }, ) @@ -48,7 +48,7 @@ func TestAllowTrustValidateTrustor(t *testing.T) { TransactionParams{ SourceAccount: &sourceAccount, Operations: []Operation{&allowTrust}, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, BaseFee: MinBaseFee, }, ) diff --git a/txnbuild/bump_sequence_test.go b/txnbuild/bump_sequence_test.go index 067cdd0b8f..844a7200fc 100644 --- a/txnbuild/bump_sequence_test.go +++ b/txnbuild/bump_sequence_test.go @@ -18,7 +18,7 @@ func TestBumpSequenceValidate(t *testing.T) { TransactionParams{ SourceAccount: &sourceAccount, Operations: []Operation{&bumpSequence}, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, BaseFee: MinBaseFee, }, ) diff --git a/txnbuild/change_trust_test.go b/txnbuild/change_trust_test.go index 9ba0c38ec4..8d56b05ede 100644 --- a/txnbuild/change_trust_test.go +++ b/txnbuild/change_trust_test.go @@ -21,7 +21,7 @@ func TestChangeTrustMaxLimit(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&changeTrust}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, @@ -46,7 +46,7 @@ func TestChangeTrustValidateInvalidAsset(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&changeTrust}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -70,7 +70,7 @@ func TestChangeTrustValidateInvalidLimit(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&changeTrust}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { diff --git a/txnbuild/clawback_test.go b/txnbuild/clawback_test.go index dab757c5a3..a8e020f1ef 100644 --- a/txnbuild/clawback_test.go +++ b/txnbuild/clawback_test.go @@ -22,7 +22,7 @@ func TestClawbackValidateFrom(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&clawback}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -47,7 +47,7 @@ func TestClawbackValidateAmount(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&clawback}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -72,7 +72,7 @@ func TestClawbackValidateAsset(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&clawback}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { diff --git a/txnbuild/cmd/demo/operations/demo.go b/txnbuild/cmd/demo/operations/demo.go index 9621773603..2b8fa49462 100644 --- a/txnbuild/cmd/demo/operations/demo.go +++ b/txnbuild/cmd/demo/operations/demo.go @@ -215,7 +215,7 @@ func bumpSequence(source *hProtocol.Account, seqNum int64, signer Account) (stri IncrementSequenceNum: true, Operations: []txnbuild.Operation{&bumpSequenceOp}, BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimeout(300), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimeout(300)}, }, ) if err != nil { @@ -245,7 +245,7 @@ func createAccount(source *hProtocol.Account, dest string, signer Account) (stri IncrementSequenceNum: true, Operations: []txnbuild.Operation{&createAccountOp}, BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimeout(300), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimeout(300)}, }, ) if err != nil { @@ -274,7 +274,7 @@ func deleteData(source *hProtocol.Account, dataKey string, signer Account) (stri IncrementSequenceNum: true, Operations: []txnbuild.Operation{&manageDataOp}, BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimeout(300), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimeout(300)}, }, ) if err != nil { @@ -305,7 +305,7 @@ func payment(source *hProtocol.Account, dest, amount string, asset txnbuild.Asse IncrementSequenceNum: true, Operations: []txnbuild.Operation{&paymentOp}, BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimeout(300), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimeout(300)}, }, ) if err != nil { @@ -332,7 +332,7 @@ func deleteTrustline(source *hProtocol.Account, asset txnbuild.ChangeTrustAsset, IncrementSequenceNum: true, Operations: []txnbuild.Operation{&deleteTrustline}, BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimeout(300), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimeout(300)}, }, ) if err != nil { @@ -362,7 +362,7 @@ func deleteOffer(source *hProtocol.Account, offerID int64, signer Account) (stri IncrementSequenceNum: true, Operations: []txnbuild.Operation{&deleteOffer}, BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimeout(300), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimeout(300)}, }, ) if err != nil { @@ -391,7 +391,7 @@ func mergeAccount(source *hProtocol.Account, destAddress string, signer Account) IncrementSequenceNum: true, Operations: []txnbuild.Operation{&accountMerge}, BaseFee: txnbuild.MinBaseFee, - Timebounds: txnbuild.NewTimeout(300), + Preconditions: txnbuild.Preconditions{Timebounds: txnbuild.NewTimeout(300)}, }, ) if err != nil { diff --git a/txnbuild/create_account_test.go b/txnbuild/create_account_test.go index b715dca70d..a8a9003705 100644 --- a/txnbuild/create_account_test.go +++ b/txnbuild/create_account_test.go @@ -21,7 +21,7 @@ func TestCreateAccountValidateDestination(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&createAccount}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -45,7 +45,7 @@ func TestCreateAccountValidateAmount(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&createAccount}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) diff --git a/txnbuild/create_claimable_balance_test.go b/txnbuild/create_claimable_balance_test.go index d6516c7983..46e2e94cbf 100644 --- a/txnbuild/create_claimable_balance_test.go +++ b/txnbuild/create_claimable_balance_test.go @@ -78,7 +78,7 @@ func TestClaimableBalanceID(t *testing.T) { SourceAccount: &aAccount, IncrementSequenceNum: true, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, Operations: []Operation{&claimableBalanceEntry}, }, ) diff --git a/txnbuild/create_passive_offer_test.go b/txnbuild/create_passive_offer_test.go index d4d0efbea4..b09b05b74e 100644 --- a/txnbuild/create_passive_offer_test.go +++ b/txnbuild/create_passive_offer_test.go @@ -1,9 +1,10 @@ package txnbuild import ( - "github.com/stellar/go/xdr" "testing" + "github.com/stellar/go/xdr" + "github.com/stretchr/testify/assert" ) @@ -24,7 +25,7 @@ func TestCreatePassiveSellOfferValidateBuyingAsset(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&createPassiveOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -51,7 +52,7 @@ func TestCreatePassiveSellOfferValidateSellingAsset(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&createPassiveOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -78,7 +79,7 @@ func TestCreatePassiveSellOfferValidateAmount(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&createPassiveOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -105,7 +106,7 @@ func TestCreatePassiveSellOfferValidatePrice(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&createPassiveOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { diff --git a/txnbuild/example_test.go b/txnbuild/example_test.go index eea43fb3e0..614240125c 100644 --- a/txnbuild/example_test.go +++ b/txnbuild/example_test.go @@ -2,9 +2,10 @@ package txnbuild import ( "fmt" + "time" + "github.com/stellar/go/price" "github.com/stellar/go/xdr" - "time" "github.com/stellar/go/keypair" "github.com/stellar/go/network" @@ -26,7 +27,7 @@ func ExampleInflation() { IncrementSequenceNum: true, Operations: []Operation{&op}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, // Use a real timeout in production! }, ) check(err) @@ -59,7 +60,7 @@ func ExampleCreateAccount() { IncrementSequenceNum: true, Operations: []Operation{&op}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, // Use a real timeout in production! }, ) check(err) @@ -93,7 +94,7 @@ func ExamplePayment() { IncrementSequenceNum: true, Operations: []Operation{&op}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, // Use a real timeout in production! }, ) check(err) @@ -137,7 +138,7 @@ func ExamplePayment_setBaseFee() { IncrementSequenceNum: true, Operations: []Operation{&op1, &op2}, BaseFee: feeStats.MaxFee.P50, - Timebounds: NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, // Use a real timeout in production! }, ) check(err) @@ -169,7 +170,7 @@ func ExampleBumpSequence() { IncrementSequenceNum: true, Operations: []Operation{&op}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, // Use a real timeout in production! }, ) check(err) @@ -201,7 +202,7 @@ func ExampleAccountMerge() { IncrementSequenceNum: true, Operations: []Operation{&op}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, // Use a real timeout in production! }, ) check(err) @@ -234,7 +235,7 @@ func ExampleManageData() { IncrementSequenceNum: true, Operations: []Operation{&op}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, // Use a real timeout in production! }, ) check(err) @@ -266,7 +267,7 @@ func ExampleManageData_removeDataEntry() { IncrementSequenceNum: true, Operations: []Operation{&op}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, // Use a real timeout in production! }, ) check(err) @@ -306,7 +307,7 @@ func ExampleSetOptions() { IncrementSequenceNum: true, Operations: []Operation{&op}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, // Use a real timeout in production! }, ) check(err) @@ -342,7 +343,7 @@ func ExampleChangeTrust() { IncrementSequenceNum: true, Operations: []Operation{&op}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, // Use a real timeout in production! }, ) check(err) @@ -372,7 +373,7 @@ func ExampleChangeTrust_removeTrustline() { IncrementSequenceNum: true, Operations: []Operation{&op}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, // Use a real timeout in production! }, ) check(err) @@ -406,7 +407,7 @@ func ExampleAllowTrust() { IncrementSequenceNum: true, Operations: []Operation{&op}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, // Use a real timeout in production! }, ) check(err) @@ -440,7 +441,7 @@ func ExampleManageSellOffer() { IncrementSequenceNum: true, Operations: []Operation{&op}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, // Use a real timeout in production! }, ) check(err) @@ -472,7 +473,7 @@ func ExampleManageSellOffer_deleteOffer() { IncrementSequenceNum: true, Operations: []Operation{&op}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, // Use a real timeout in production! }, ) check(err) @@ -507,7 +508,7 @@ func ExampleManageSellOffer_updateOffer() { IncrementSequenceNum: true, Operations: []Operation{&op}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, // Use a real timeout in production! }, ) check(err) @@ -542,7 +543,7 @@ func ExampleCreatePassiveSellOffer() { IncrementSequenceNum: true, Operations: []Operation{&op}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, // Use a real timeout in production! }, ) check(err) @@ -580,7 +581,7 @@ func ExamplePathPayment() { IncrementSequenceNum: true, Operations: []Operation{&op}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, // Use a real timeout in production! }, ) check(err) @@ -618,7 +619,7 @@ func ExamplePathPaymentStrictReceive() { IncrementSequenceNum: true, Operations: []Operation{&op}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, // Use a real timeout in production! }, ) check(err) @@ -656,7 +657,7 @@ func ExamplePathPaymentStrictSend() { IncrementSequenceNum: true, Operations: []Operation{&op}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, // Use a real timeout in production! }, ) check(err) @@ -692,7 +693,7 @@ func ExampleManageBuyOffer() { IncrementSequenceNum: true, Operations: []Operation{&buyOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, // Use a real timeout in production! }, ) check(err) @@ -725,7 +726,7 @@ func ExampleFeeBumpTransaction() { IncrementSequenceNum: true, Operations: []Operation{&op}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), // Use a real timeout in production! + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, // Use a real timeout in production! }, ) check(err) @@ -799,7 +800,7 @@ func ExampleCreateClaimableBalance() { SourceAccount: &aAccount, IncrementSequenceNum: true, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, Operations: []Operation{&claimableBalanceEntry}, }, ) @@ -827,7 +828,7 @@ func ExampleClaimClaimableBalance() { SourceAccount: &aAccount, // or Account B, depending on the condition! IncrementSequenceNum: true, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, Operations: []Operation{&claimBalance}, }, network.TestNetworkPassphrase, @@ -893,7 +894,7 @@ func ExampleBeginSponsoringFutureReserves() { TransactionParams{ SourceAccount: &test.Aaccount, Operations: sponsorTrustline, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, BaseFee: MinBaseFee, IncrementSequenceNum: true, }, @@ -934,7 +935,7 @@ func ExampleBeginSponsoringFutureReserves_transfer() { TransactionParams{ SourceAccount: &test.S1account, Operations: transferOps, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, BaseFee: MinBaseFee, IncrementSequenceNum: true, }, @@ -981,7 +982,7 @@ func ExampleRevokeSponsorship() { TransactionParams{ SourceAccount: &test.S2account, Operations: revokeOps, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, BaseFee: MinBaseFee, IncrementSequenceNum: true, }, @@ -1050,7 +1051,7 @@ func ExampleLiquidityPoolDeposit() { TransactionParams{ SourceAccount: &test.AAccount, Operations: depositOps, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, BaseFee: MinBaseFee, IncrementSequenceNum: true, }, @@ -1085,7 +1086,7 @@ func ExampleLiquidityPoolWithdraw() { TransactionParams{ SourceAccount: &test.AAccount, Operations: withdrawOps, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, BaseFee: MinBaseFee, IncrementSequenceNum: true, }, diff --git a/txnbuild/fee_bump_test.go b/txnbuild/fee_bump_test.go index 1a4915041a..d9b2d64f4c 100644 --- a/txnbuild/fee_bump_test.go +++ b/txnbuild/fee_bump_test.go @@ -25,7 +25,7 @@ func TestFeeBumpInvalidFeeSource(t *testing.T) { SourceAccount: &sourceAccount, Operations: []Operation{&Inflation{}}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -51,7 +51,7 @@ func TestFeeBumpUpgradesV0Transaction(t *testing.T) { Operations: []Operation{&Inflation{}}, BaseFee: 2 * MinBaseFee, Memo: MemoText("test-memo"), - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -105,7 +105,7 @@ func TestFeeBumpInvalidInnerTransactionType(t *testing.T) { Operations: []Operation{&Inflation{}}, BaseFee: 2 * MinBaseFee, Memo: MemoText("test-memo"), - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -143,7 +143,7 @@ func TestFeeBumpAllowsFeeAccountToEqualInnerSourceAccount(t *testing.T) { SourceAccount: &sourceAccount, Operations: []Operation{&Inflation{}}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -202,7 +202,7 @@ func TestFeeBumpSignWithKeyString(t *testing.T) { SourceAccount: &sourceAccount, Operations: []Operation{&Inflation{}}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -257,7 +257,7 @@ func TestFeeBumpSignHashX(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&payment}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -300,7 +300,7 @@ func TestFeeBumpAddSignatureBase64(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&createAccount}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -363,7 +363,7 @@ func TestFeeBumpMuxedAccounts(t *testing.T) { SourceAccount: &sourceAccount, Operations: []Operation{&Inflation{}}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) diff --git a/txnbuild/ledgerbounds.go b/txnbuild/ledgerbounds.go new file mode 100644 index 0000000000..49c4a1501a --- /dev/null +++ b/txnbuild/ledgerbounds.go @@ -0,0 +1,23 @@ +package txnbuild + +import "github.com/stellar/go/support/errors" + +// LedgerBounds represent a transaction precondition that controls the ledger +// range for which a transaction is valid. Setting MaxLedger = 0 indicates there +// is no maximum ledger. +type LedgerBounds struct { + MinLedger uint32 + MaxLedger uint32 +} + +func (lb *LedgerBounds) Validate() error { + if lb == nil { + return nil + } + + if lb.MaxLedger > 0 && lb.MaxLedger < lb.MinLedger { + return errors.New("invalid ledgerbound: max ledger < min ledger") + } + + return nil +} diff --git a/txnbuild/manage_buy_offer_test.go b/txnbuild/manage_buy_offer_test.go index 4bd49f5a86..d244dfde4d 100644 --- a/txnbuild/manage_buy_offer_test.go +++ b/txnbuild/manage_buy_offer_test.go @@ -1,9 +1,10 @@ package txnbuild import ( + "testing" + "github.com/stellar/go/price" "github.com/stellar/go/xdr" - "testing" "github.com/stretchr/testify/assert" ) @@ -27,7 +28,7 @@ func TestManageBuyOfferValidateSellingAsset(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&buyOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -55,7 +56,7 @@ func TestManageBuyOfferValidateBuyingAsset(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&buyOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -83,7 +84,7 @@ func TestManageBuyOfferValidateAmount(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&buyOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -111,7 +112,7 @@ func TestManageBuyOfferValidatePrice(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&buyOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -139,7 +140,7 @@ func TestManageBuyOfferValidateOfferID(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&buyOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { diff --git a/txnbuild/manage_data_test.go b/txnbuild/manage_data_test.go index 9c8074371a..f4b4b0049c 100644 --- a/txnbuild/manage_data_test.go +++ b/txnbuild/manage_data_test.go @@ -22,7 +22,7 @@ func TestManageDataValidateName(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&manageData}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -46,7 +46,7 @@ func TestManageDataValidateValue(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&manageData}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -88,7 +88,7 @@ func TestManageDataRoundTrip(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&manageData}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) diff --git a/txnbuild/manage_offer_test.go b/txnbuild/manage_offer_test.go index d8b7504209..2c77eaa193 100644 --- a/txnbuild/manage_offer_test.go +++ b/txnbuild/manage_offer_test.go @@ -1,9 +1,10 @@ package txnbuild import ( + "testing" + "github.com/stellar/go/price" "github.com/stellar/go/xdr" - "testing" "github.com/stretchr/testify/assert" ) @@ -25,7 +26,7 @@ func TestManageSellOfferValidateSellingAsset(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&createOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -51,7 +52,7 @@ func TestManageSellOfferValidateBuyingAsset(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&createOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -77,7 +78,7 @@ func TestManageSellOfferValidateAmount(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&createOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -103,7 +104,7 @@ func TestManageSellOfferValidatePrice(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&createOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -131,7 +132,7 @@ func TestManageSellOfferValidateOfferID(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&mso}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { diff --git a/txnbuild/operation_test.go b/txnbuild/operation_test.go index d462e3a9c5..3922817a85 100644 --- a/txnbuild/operation_test.go +++ b/txnbuild/operation_test.go @@ -56,7 +56,7 @@ func TestZeroBalanceAccount(t *testing.T) { Operations: ops, IncrementSequenceNum: true, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) @@ -466,7 +466,7 @@ func testOperationsMarshallingRoundtrip(t *testing.T, operations []Operation, wi TransactionParams{ SourceAccount: &sourceAccount, Operations: operations, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, BaseFee: MinBaseFee, }, ) diff --git a/txnbuild/path_payment_strict_send_test.go b/txnbuild/path_payment_strict_send_test.go index 3e3d73a01a..c06dc2f129 100644 --- a/txnbuild/path_payment_strict_send_test.go +++ b/txnbuild/path_payment_strict_send_test.go @@ -27,7 +27,7 @@ func TestPathPaymentStrictSendValidateSendAsset(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&pathPayment}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -57,7 +57,7 @@ func TestPathPaymentStrictSendValidateDestAsset(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&pathPayment}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -87,7 +87,7 @@ func TestPathPaymentStrictSendValidateDestination(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&pathPayment}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -117,7 +117,7 @@ func TestPathPaymentStrictSendValidateSendMax(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&pathPayment}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) @@ -148,7 +148,7 @@ func TestPathPaymentStrictSendValidateDestAmount(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&pathPayment}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { diff --git a/txnbuild/path_payment_test.go b/txnbuild/path_payment_test.go index f5f78fafa7..0bc7155892 100644 --- a/txnbuild/path_payment_test.go +++ b/txnbuild/path_payment_test.go @@ -27,7 +27,7 @@ func TestPathPaymentValidateSendAsset(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&pathPayment}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) @@ -58,7 +58,7 @@ func TestPathPaymentValidateDestAsset(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&pathPayment}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -88,7 +88,7 @@ func TestPathPaymentValidateDestination(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&pathPayment}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -118,7 +118,7 @@ func TestPathPaymentValidateSendMax(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&pathPayment}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -148,7 +148,7 @@ func TestPathPaymentValidateDestAmount(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&pathPayment}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { diff --git a/txnbuild/payment_test.go b/txnbuild/payment_test.go index e82cd7b499..95eb6ad792 100644 --- a/txnbuild/payment_test.go +++ b/txnbuild/payment_test.go @@ -22,7 +22,7 @@ func TestPaymentValidateDestination(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&payment}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -47,7 +47,7 @@ func TestPaymentValidateAmount(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&payment}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { @@ -72,7 +72,7 @@ func TestPaymentValidateAsset(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&payment}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) if assert.Error(t, err) { diff --git a/txnbuild/preconditions.go b/txnbuild/preconditions.go new file mode 100644 index 0000000000..1251785d3a --- /dev/null +++ b/txnbuild/preconditions.go @@ -0,0 +1,143 @@ +package txnbuild + +import ( + "github.com/stellar/go/support/errors" + "github.com/stellar/go/xdr" +) + +// Preconditions is a container for all transaction preconditions. +type Preconditions struct { + // Transaction is only valid during a certain time range. + Timebounds TimeBounds + // Transaction is valid for ledger numbers n such that minLedger <= n < + // maxLedger (if maxLedger == 0, then only minLedger is checked) + Ledgerbounds *LedgerBounds + // If nil, the transaction is only valid when sourceAccount's sequence + // number "N" is seqNum - 1. Otherwise, valid when N satisfies minSeqNum <= + // N < tx.seqNum. + MinSequenceNumber *int64 + // Transaction is valid if the current ledger time is at least + // minSequenceNumberAge greater than the source account's seqTime. + MinSequenceNumberAge xdr.Duration + // Transaction is valid if the current ledger number is at least + // minSequenceNumberLedgerGap greater than the source account's seqLedger. + MinSequenceNumberLedgerGap uint32 + // Transaction is valid if there is a signature corresponding to every + // Signer in this array, even if the signature is not otherwise required by + // the source account or operations. + ExtraSigners []xdr.SignerKey +} + +// Validate ensures that all enabled preconditions are valid. +func (cond *Preconditions) Validate() error { + var err error + + if err = cond.Timebounds.Validate(); err != nil { + return err + } + + if err = cond.Ledgerbounds.Validate(); err != nil { + return err + } + + if len(cond.ExtraSigners) > 2 { + return errors.New("only 2 extra signers allowed") + } + + return nil +} + +// BuildXDR will create a precondition structure that varies depending on +// whether or not there are additional preconditions besides timebounds (which +// are required). +func (cond *Preconditions) BuildXDR() xdr.Preconditions { + xdrCond := xdr.Preconditions{} + xdrTimeBounds := xdr.TimeBounds{ + MinTime: xdr.TimePoint(cond.Timebounds.MinTime), + MaxTime: xdr.TimePoint(cond.Timebounds.MaxTime), + } + + // Only build PRECOND_V2 structure if we need to + if cond.hasV2Conditions() { + xdrPrecond := xdr.PreconditionsV2{ + TimeBounds: &xdrTimeBounds, + MinSeqAge: cond.MinSequenceNumberAge, + MinSeqLedgerGap: xdr.Uint32(cond.MinSequenceNumberLedgerGap), + ExtraSigners: cond.ExtraSigners, // should we copy? + } + + // micro-optimization: if the ledgerbounds will always succeed, omit them + if cond.Ledgerbounds != nil && !(cond.Ledgerbounds.MinLedger == 0 && + cond.Ledgerbounds.MaxLedger == 0) { + xdrPrecond.LedgerBounds = &xdr.LedgerBounds{ + MinLedger: xdr.Uint32(cond.Ledgerbounds.MinLedger), + MaxLedger: xdr.Uint32(cond.Ledgerbounds.MaxLedger), + } + } + + if cond.MinSequenceNumber != nil { + seqNum := xdr.SequenceNumber(*cond.MinSequenceNumber) + xdrPrecond.MinSeqNum = &seqNum + } + + xdrCond.Type = xdr.PreconditionTypePrecondV2 + xdrCond.V2 = &xdrPrecond + } else { + xdrCond.Type = xdr.PreconditionTypePrecondTime + xdrCond.TimeBounds = &xdrTimeBounds + } + + return xdrCond +} + +// FromXDR fills in the precondition structure from an xdr.Precondition. +func (cond *Preconditions) FromXDR(precondXdr xdr.Preconditions) { + *cond = Preconditions{} // reset existing values + + switch precondXdr.Type { + case xdr.PreconditionTypePrecondTime: + cond.Timebounds = NewTimebounds( + int64(precondXdr.MustTimeBounds().MinTime), + int64(precondXdr.MustTimeBounds().MaxTime), + ) + + case xdr.PreconditionTypePrecondV2: + inner := precondXdr.MustV2() + + if inner.TimeBounds != nil { + cond.Timebounds = NewTimebounds( + int64(inner.TimeBounds.MinTime), + int64(inner.TimeBounds.MaxTime), + ) + } + + if inner.LedgerBounds != nil { + cond.Ledgerbounds = &LedgerBounds{ + MinLedger: uint32(inner.LedgerBounds.MinLedger), + MaxLedger: uint32(inner.LedgerBounds.MaxLedger), + } + } + + if inner.MinSeqNum != nil { + minSeqNum := int64(*inner.MinSeqNum) + cond.MinSequenceNumber = &minSeqNum + } + + cond.MinSequenceNumberAge = inner.MinSeqAge + cond.MinSequenceNumberLedgerGap = uint32(inner.MinSeqLedgerGap) + cond.ExtraSigners = append(cond.ExtraSigners, inner.ExtraSigners...) + + case xdr.PreconditionTypePrecondNone: + default: // panic? + } +} + +// hasV2Conditions determines whether or not this has conditions on top of +// the (required) timebound precondition. +func (cond *Preconditions) hasV2Conditions() bool { + return (cond.Ledgerbounds != nil || + cond.MinSequenceNumber != nil || + cond.MinSequenceNumberAge > xdr.Duration(0) || + cond.MinSequenceNumberLedgerGap > 0 || + len(cond.ExtraSigners) > 0) +} diff --git a/txnbuild/preconditions_test.go b/txnbuild/preconditions_test.go new file mode 100644 index 0000000000..9757f1317f --- /dev/null +++ b/txnbuild/preconditions_test.go @@ -0,0 +1,168 @@ +package txnbuild + +import ( + "testing" + + "github.com/stellar/go/xdr" + "github.com/stretchr/testify/assert" +) + +var signers = []xdr.SignerKey{ + xdr.MustSigner("GAOQJGUAB7NI7K7I62ORBXMN3J4SSWQUQ7FOEPSDJ322W2HMCNWPHXFB"), + xdr.MustSigner("GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZ"), + xdr.MustSigner("PA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAQACAQDAQCQMBYIBEFAWDANBYHRAEISCMKBKFQXDAMRUGY4DUPB6IBZGM"), +} + +// TestPreconditionClassification ensures that Preconditions will correctly +// differentiate V1 (timebounds-only) or V2 (all other) preconditions correctly. +func TestPreconditionClassification(t *testing.T) { + tbpc := Preconditions{Timebounds: NewTimebounds(1, 2)} + assert.False(t, (&Preconditions{}).hasV2Conditions()) + assert.False(t, tbpc.hasV2Conditions()) + + tbpc.MinSequenceNumberLedgerGap = 2 + assert.True(t, tbpc.hasV2Conditions()) +} + +// TestPreconditionValidation ensures that validation fails when necessary. +func TestPreconditionValidation(t *testing.T) { + t.Run("too many signers", func(t *testing.T) { + pc := Preconditions{ + Timebounds: NewTimebounds(27, 42), + ExtraSigners: signers, + } + + assert.Error(t, pc.Validate()) + }) + + t.Run("nonsense ledgerbounds", func(t *testing.T) { + pc := Preconditions{Timebounds: NewTimebounds(27, 42)} + pc.Ledgerbounds = &LedgerBounds{MinLedger: 42, MaxLedger: 1} + assert.Error(t, pc.Validate()) + }) +} + +// TestPreconditionEncoding ensures correct XDR is generated for a +// (non-exhaustive) handful of precondition combinations. It generates XDR and +// txnbuild structures that match semantically, then makes sure they translate +// between each other (encode/decode round trips, etc.). +func TestPreconditionEncoding(t *testing.T) { + modifiers := []struct { + Name string + Modifier func() (xdr.Preconditions, Preconditions) + }{ + { + "unchanged", + func() (xdr.Preconditions, Preconditions) { + return createPreconditionFixtures() + }, + }, + { + "only timebounds", + func() (xdr.Preconditions, Preconditions) { + return xdr.Preconditions{ + Type: xdr.PreconditionTypePrecondTime, + TimeBounds: &xdr.TimeBounds{ + MinTime: xdr.TimePoint(1), + MaxTime: xdr.TimePoint(2), + }, + }, Preconditions{Timebounds: NewTimebounds(1, 2)} + }, + }, + { + "unbounded ledgerbounds", + func() (xdr.Preconditions, Preconditions) { + xdrPc, pc := createPreconditionFixtures() + xdrPc.V2.LedgerBounds.MaxLedger = 0 + pc.Ledgerbounds.MaxLedger = 0 + return xdrPc, pc + }, + }, + { + "nil ledgerbounds", + func() (xdr.Preconditions, Preconditions) { + xdrPc, pc := createPreconditionFixtures() + xdrPc.V2.LedgerBounds = nil + pc.Ledgerbounds = nil + return xdrPc, pc + }, + }, + { + "nil minSeq", + func() (xdr.Preconditions, Preconditions) { + xdrPc, pc := createPreconditionFixtures() + xdrPc.V2.MinSeqNum = nil + pc.MinSequenceNumber = nil + return xdrPc, pc + }, + }, + { + "no signers", + func() (xdr.Preconditions, Preconditions) { + xdrPc, pc := createPreconditionFixtures() + xdrPc.V2.ExtraSigners = nil + pc.ExtraSigners = nil + return xdrPc, pc + }, + }, + } + for _, testCase := range modifiers { + t.Run(testCase.Name, func(t *testing.T) { + xdrPrecond, precond := testCase.Modifier() + + assert.NoError(t, precond.Validate()) + + expectedBytes, err := xdrPrecond.MarshalBinary() + assert.NoError(t, err) + actualBytes, err := precond.BuildXDR().MarshalBinary() + assert.NoError(t, err) + + // building the struct should result in identical XDR! + assert.Equal(t, expectedBytes, actualBytes) + + // unpacking the XDR should result in identical structs! + roundTripXdr := xdr.Preconditions{} + err = roundTripXdr.UnmarshalBinary(actualBytes) + assert.NoError(t, err) + assert.Equal(t, xdrPrecond, roundTripXdr) + + roundTripPrecond := Preconditions{} + roundTripPrecond.FromXDR(roundTripXdr) + assert.Equal(t, precond, roundTripPrecond) + }) + } +} + +// createPreconditionFixtures returns some initial, sensible XDR and txnbuild +// precondition structures with all fields set and matching semantics. +func createPreconditionFixtures() (xdr.Preconditions, Preconditions) { + seqNum := int64(42) + xdrSeqNum := xdr.SequenceNumber(seqNum) + xdrCond := xdr.Preconditions{ + Type: xdr.PreconditionTypePrecondV2, + V2: &xdr.PreconditionsV2{ + TimeBounds: &xdr.TimeBounds{ + MinTime: xdr.TimePoint(27), + MaxTime: xdr.TimePoint(42), + }, + LedgerBounds: &xdr.LedgerBounds{ + MinLedger: xdr.Uint32(27), + MaxLedger: xdr.Uint32(42), + }, + MinSeqNum: &xdrSeqNum, + MinSeqAge: xdr.Duration(27), + MinSeqLedgerGap: xdr.Uint32(42), + ExtraSigners: []xdr.SignerKey{signers[0]}, + }, + } + pc := Preconditions{ + Timebounds: NewTimebounds(27, 42), + Ledgerbounds: &LedgerBounds{27, 42}, + MinSequenceNumber: &seqNum, + MinSequenceNumberAge: xdr.Duration(27), + MinSequenceNumberLedgerGap: 42, + ExtraSigners: []xdr.SignerKey{signers[0]}, + } + + return xdrCond, pc +} diff --git a/txnbuild/signers_test.go b/txnbuild/signers_test.go index 6dd98792cf..35f1d28667 100644 --- a/txnbuild/signers_test.go +++ b/txnbuild/signers_test.go @@ -1,9 +1,10 @@ package txnbuild import ( - "github.com/stellar/go/price" "testing" + "github.com/stellar/go/price" + "github.com/stellar/go/keypair" "github.com/stellar/go/xdr" @@ -28,7 +29,7 @@ func TestAccountMergeMultSigners(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&accountMerge}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, kp1, @@ -59,7 +60,7 @@ func TestAllowTrustMultSigners(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&allowTrust}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, kp1, @@ -87,7 +88,7 @@ func TestBumpSequenceMultSigners(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&bumpSequence}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, kp1, @@ -116,7 +117,7 @@ func TestChangeTrustMultSigners(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&changeTrust}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, kp1, @@ -145,7 +146,7 @@ func TestCreateAccountMultSigners(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&createAccount}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, kp1, @@ -176,7 +177,7 @@ func TestCreatePassiveSellOfferMultSigners(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&createPassiveOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, kp1, @@ -203,7 +204,7 @@ func TestInflationMultSigners(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&inflation}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, kp1, @@ -232,7 +233,7 @@ func TestManageDataMultSigners(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&manageData}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, kp1, @@ -261,7 +262,7 @@ func TestManageOfferCreateMultSigners(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&createOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, kp1, @@ -288,7 +289,7 @@ func TestManageOfferDeleteMultSigners(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&deleteOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, kp1, @@ -318,7 +319,7 @@ func TestManageOfferUpdateMultSigners(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&updateOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, kp1, @@ -352,7 +353,7 @@ func TestPathPaymentMultSigners(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&pathPayment}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, kp1, @@ -383,7 +384,7 @@ func TestPaymentMultSigners(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&payment}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, kp1, @@ -411,7 +412,7 @@ func TestSetOptionsMultSigners(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&setOptions}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, kp1, @@ -461,7 +462,7 @@ func TestSigningImmutability(t *testing.T) { SourceAccount: &sourceAccount, Operations: []Operation{&Inflation{}}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, } root, err := NewTransaction(params) assert.NoError(t, err) @@ -512,7 +513,7 @@ func TestFeeBumpSigningImmutability(t *testing.T) { SourceAccount: &sourceAccount, Operations: []Operation{&Inflation{}}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, } inner, err := NewTransaction(innerParams) assert.NoError(t, err) diff --git a/txnbuild/timebounds.go b/txnbuild/timebounds.go index ce1a0b66e7..1019497c2e 100644 --- a/txnbuild/timebounds.go +++ b/txnbuild/timebounds.go @@ -9,7 +9,7 @@ import ( // what you want. const TimeoutInfinite = int64(0) -// Timebounds represents the time window during which a Stellar transaction is considered valid. +// TimeBounds represents the time window during which a Stellar transaction is considered valid. // // MinTime and MaxTime represent Stellar timebounds - a window of time over which the Transaction will be // considered valid. In general, almost all Transactions benefit from setting an upper timebound, because once submitted, @@ -17,18 +17,20 @@ const TimeoutInfinite = int64(0) // With an upper timebound, the submitter has a guaranteed time at which the Transaction is known to have either // succeeded or failed, and can then take appropriate action (e.g. to resubmit or mark as resolved). // -// Create a Timebounds struct using one of NewTimebounds(), NewTimeout(), or NewInfiniteTimeout(). -type Timebounds struct { +// Create a TimeBounds struct using one of NewTimebounds(), NewTimeout(), or NewInfiniteTimeout(). +type TimeBounds struct { MinTime int64 MaxTime int64 wasBuilt bool } -// Validate for Timebounds sanity-checks the configured Timebound limits, and confirms the object was built +type Timebounds = TimeBounds + +// Validate for TimeBounds sanity-checks the configured Timebound limits, and confirms the object was built // using a factory method. This is done to ensure that default Timebound structs (which have no limits) are not // valid - you must explicitly specifiy the Timebound you require. -func (tb *Timebounds) Validate() error { - if !tb.wasBuilt { +func (tb *TimeBounds) Validate() error { + if tb == nil || !tb.wasBuilt { return errors.New("timebounds must be constructed using NewTimebounds(), NewTimeout(), or NewInfiniteTimeout()") } if tb.MinTime < 0 { @@ -48,24 +50,24 @@ func (tb *Timebounds) Validate() error { return nil } -// NewTimebounds is a factory method that constructs a Timebounds object from a min and max time. -// A Transaction cannot be built unless a Timebounds object is provided through a factory method. -func NewTimebounds(minTime, maxTime int64) Timebounds { - return Timebounds{minTime, maxTime, true} +// NewTimebounds is a factory method that constructs a TimeBounds object from a min and max time. +// A Transaction cannot be built unless a TimeBounds object is provided through a factory method. +func NewTimebounds(minTime, maxTime int64) TimeBounds { + return TimeBounds{minTime, maxTime, true} } // NewTimeout is a factory method that sets the MaxTime to be the duration in seconds in the // future specified by 'timeout'. -// A Transaction cannot be built unless a Timebounds object is provided through a factory method. +// A Transaction cannot be built unless a TimeBounds object is provided through a factory method. // This method uses the provided system time - make sure it is accurate. -func NewTimeout(timeout int64) Timebounds { - return Timebounds{0, time.Now().UTC().Unix() + timeout, true} +func NewTimeout(timeout int64) TimeBounds { + return TimeBounds{0, time.Now().UTC().Unix() + timeout, true} } // NewInfiniteTimeout is a factory method that sets the MaxTime to a value representing an indefinite // upper time bound. This is rarely needed, but is helpful for certain smart contracts, and for -// deterministic testing. A Transaction cannot be built unless a Timebounds object is provided through +// deterministic testing. A Transaction cannot be built unless a TimeBounds object is provided through // a factory method. -func NewInfiniteTimeout() Timebounds { - return Timebounds{0, TimeoutInfinite, true} +func NewInfiniteTimeout() TimeBounds { + return TimeBounds{0, TimeoutInfinite, true} } diff --git a/txnbuild/timebounds_test.go b/txnbuild/timebounds_test.go index b852242e66..96a6517531 100644 --- a/txnbuild/timebounds_test.go +++ b/txnbuild/timebounds_test.go @@ -8,7 +8,7 @@ import ( ) func TestTimeboundsRequireConstructor(t *testing.T) { - tb := Timebounds{MinTime: -1, MaxTime: 300} + tb := TimeBounds{MinTime: -1, MaxTime: 300} err := tb.Validate() expectedErrMsg := "timebounds must be constructed using NewTimebounds(), NewTimeout(), or NewInfiniteTimeout()" diff --git a/txnbuild/transaction.go b/txnbuild/transaction.go index d1e9c2dcd1..8c861bd430 100644 --- a/txnbuild/transaction.go +++ b/txnbuild/transaction.go @@ -212,7 +212,7 @@ type Transaction struct { sourceAccount SimpleAccount operations []Operation memo Memo - timebounds Timebounds + preconditions Preconditions } // BaseFee returns the per operation fee for this transaction. @@ -241,8 +241,8 @@ func (t *Transaction) Memo() Memo { } // Timebounds returns the Timebounds configured for this transaction. -func (t *Transaction) Timebounds() Timebounds { - return t.timebounds +func (t *Transaction) Timebounds() TimeBounds { + return t.preconditions.Timebounds } // Operations returns the list of operations included in this transaction. @@ -770,13 +770,9 @@ func transactionFromParsedXDR(xdrEnv xdr.TransactionEnvelope) (*GenericTransacti }, operations: nil, memo: nil, - timebounds: Timebounds{}, - } - - if timeBounds := xdrEnv.TimeBounds(); timeBounds != nil { - newTx.simple.timebounds = NewTimebounds(int64(timeBounds.MinTime), int64(timeBounds.MaxTime)) } + newTx.simple.preconditions.FromXDR(xdrEnv.Preconditions()) newTx.simple.memo, err = memoFromXDR(xdrEnv.Memo()) if err != nil { return nil, errors.Wrap(err, "unable to parse memo") @@ -794,26 +790,25 @@ func transactionFromParsedXDR(xdrEnv xdr.TransactionEnvelope) (*GenericTransacti return newTx, nil } -// TransactionParams is a container for parameters -// which are used to construct new Transaction instances +// TransactionParams is a container for parameters which are used to construct +// new Transaction instances type TransactionParams struct { SourceAccount Account IncrementSequenceNum bool Operations []Operation BaseFee int64 Memo Memo - Timebounds Timebounds + Preconditions Preconditions } // NewTransaction returns a new Transaction instance func NewTransaction(params TransactionParams) (*Transaction, error) { - var sequence int64 - var err error - if params.SourceAccount == nil { return nil, errors.New("transaction has no source account") } + var sequence int64 + var err error if params.IncrementSequenceNum { sequence, err = params.SourceAccount.IncrementSequenceNumber() } else { @@ -829,9 +824,9 @@ func NewTransaction(params TransactionParams) (*Transaction, error) { AccountID: params.SourceAccount.GetAccountID(), Sequence: sequence, }, - operations: params.Operations, - memo: params.Memo, - timebounds: params.Timebounds, + operations: params.Operations, + memo: params.Memo, + preconditions: params.Preconditions, } var sourceAccount xdr.MuxedAccount if err = sourceAccount.SetAddress(tx.sourceAccount.AccountID); err != nil { @@ -850,14 +845,14 @@ func NewTransaction(params TransactionParams) (*Transaction, error) { // if maxFee is negative then there must have been an int overflow hi, lo := bits.Mul64(uint64(params.BaseFee), uint64(len(params.Operations))) if hi > 0 || lo > math.MaxUint32 { - return nil, errors.Errorf("base fee %d results in an overflow of max fee", params.BaseFee) + return nil, errors.Errorf( + "base fee %d results in an overflow of max fee", params.BaseFee) } tx.maxFee = int64(lo) - // Check and set the timebounds - err = tx.timebounds.Validate() - if err != nil { - return nil, errors.Wrap(err, "invalid time bounds") + // Check that all preconditions are valid + if err = tx.preconditions.Validate(); err != nil { + return nil, errors.Wrap(err, "invalid preconditions") } envelope := xdr.TransactionEnvelope{ @@ -867,13 +862,7 @@ func NewTransaction(params TransactionParams) (*Transaction, error) { SourceAccount: sourceAccount, Fee: xdr.Uint32(tx.maxFee), SeqNum: xdr.SequenceNumber(sequence), - Cond: xdr.Preconditions{ - Type: xdr.PreconditionTypePrecondTime, - TimeBounds: &xdr.TimeBounds{ - MinTime: xdr.TimePoint(tx.timebounds.MinTime), - MaxTime: xdr.TimePoint(tx.timebounds.MaxTime), - }, - }, + Cond: tx.preconditions.BuildXDR(), }, Signatures: nil, }, @@ -920,7 +909,7 @@ func convertToV1(tx *Transaction) (*Transaction, error) { Operations: tx.Operations(), BaseFee: tx.BaseFee(), Memo: tx.Memo(), - Timebounds: tx.Timebounds(), + Preconditions: Preconditions{Timebounds: tx.Timebounds()}, }) if err != nil { return tx, err @@ -1056,9 +1045,11 @@ func BuildChallengeTx(serverSignerSecret, clientAccountID, webAuthDomain, homeDo Value: []byte(webAuthDomain), }, }, - BaseFee: MinBaseFee, - Memo: nil, - Timebounds: NewTimebounds(currentTime.Unix(), maxTime.Unix()), + BaseFee: MinBaseFee, + Memo: nil, + Preconditions: Preconditions{ + Timebounds: NewTimebounds(currentTime.Unix(), maxTime.Unix()), + }, }, ) if err != nil { diff --git a/txnbuild/transaction_fee_test.go b/txnbuild/transaction_fee_test.go index 888f8a2483..b1d1114b3c 100644 --- a/txnbuild/transaction_fee_test.go +++ b/txnbuild/transaction_fee_test.go @@ -16,7 +16,7 @@ func TestBaseFeeCanBeZeroOrPositive(t *testing.T) { SourceAccount: &SimpleAccount{keypair.MustRandom().Address(), 1}, Operations: []Operation{&Inflation{}}, BaseFee: bf, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -30,7 +30,7 @@ func TestBaseFeeErrorWhenNegative(t *testing.T) { SourceAccount: &SimpleAccount{keypair.MustRandom().Address(), 1}, Operations: []Operation{&Inflation{}}, BaseFee: -1, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.EqualError(t, err, "base fee cannot be negative") @@ -45,7 +45,7 @@ func TestFeeBumpMinBaseFee(t *testing.T) { SourceAccount: &sourceAccount, Operations: []Operation{&Inflation{}}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -70,7 +70,7 @@ func TestFeeOverflow(t *testing.T) { SourceAccount: &sourceAccount, Operations: []Operation{&Inflation{}, &Inflation{}}, BaseFee: math.MaxUint32 / 2, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -80,7 +80,7 @@ func TestFeeOverflow(t *testing.T) { SourceAccount: &sourceAccount, Operations: []Operation{&Inflation{}, &Inflation{}, &Inflation{}}, BaseFee: math.MaxUint32 / 2, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.EqualError(t, err, "base fee 2147483647 results in an overflow of max fee") @@ -95,7 +95,7 @@ func TestFeeBumpOverflow(t *testing.T) { SourceAccount: &sourceAccount, Operations: []Operation{&Inflation{}}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -128,7 +128,7 @@ func TestFeeBumpFeeGreaterThanOrEqualInner(t *testing.T) { SourceAccount: &sourceAccount, Operations: []Operation{&Inflation{}}, BaseFee: 2 * MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) diff --git a/txnbuild/transaction_test.go b/txnbuild/transaction_test.go index 24518ebcd3..70f5d366a7 100644 --- a/txnbuild/transaction_test.go +++ b/txnbuild/transaction_test.go @@ -26,25 +26,59 @@ func TestMissingTimebounds(t *testing.T) { BaseFee: MinBaseFee, }, ) - assert.EqualError(t, err, "invalid time bounds: timebounds must be constructed using NewTimebounds(), NewTimeout(), or NewInfiniteTimeout()") + assert.EqualError(t, err, "invalid preconditions: timebounds must be constructed using NewTimebounds(), NewTimeout(), or NewInfiniteTimeout()") } func TestTimebounds(t *testing.T) { kp0 := newKeypair0() - tb := NewTimeout(300) - tx, err := NewTransaction( - TransactionParams{ - SourceAccount: &SimpleAccount{AccountID: kp0.Address(), Sequence: 1}, - Operations: []Operation{&BumpSequence{BumpTo: 0}}, - BaseFee: MinBaseFee, - Timebounds: tb, - }, - ) + + tp := TransactionParams{ + SourceAccount: &SimpleAccount{AccountID: kp0.Address(), Sequence: 1}, + Operations: []Operation{&BumpSequence{BumpTo: 0}}, + BaseFee: MinBaseFee, + } + + tp.Preconditions.Timebounds = tb + tx, err := NewTransaction(tp) assert.NoError(t, err) - assert.Equal(t, tb, tx.timebounds) - assert.Equal(t, xdr.TimePoint(tb.MinTime), tx.envelope.V1.Tx.Cond.TimeBounds.MinTime) - assert.Equal(t, xdr.TimePoint(tb.MaxTime), tx.envelope.V1.Tx.Cond.TimeBounds.MaxTime) + assert.Equal(t, tb, tx.preconditions.Timebounds) + assert.Equal(t, xdr.TimePoint(tb.MinTime), tx.envelope.TimeBounds().MinTime) + assert.Equal(t, xdr.TimePoint(tb.MaxTime), tx.envelope.TimeBounds().MaxTime) +} + +func TestV2Preconditions(t *testing.T) { + kp0 := newKeypair0() + + cond := Preconditions{ + Timebounds: NewTimeout(300), + Ledgerbounds: &LedgerBounds{0, 1}, + MinSequenceNumber: nil, + MinSequenceNumberAge: xdr.Duration(10), + MinSequenceNumberLedgerGap: 2, + } + assert.True(t, cond.hasV2Conditions()) + + tp := TransactionParams{ + SourceAccount: &SimpleAccount{AccountID: kp0.Address(), Sequence: 1}, + Operations: []Operation{&BumpSequence{BumpTo: 0}}, + BaseFee: MinBaseFee, + Preconditions: cond, + } + + tx, err := NewTransaction(tp) + assert.NoError(t, err) + assert.Equal(t, cond, tx.preconditions) + + b64, err := tx.Base64() + assert.NoError(t, err) + + unpackedTx, err := TransactionFromXDR(b64) + assert.NoError(t, err) + if !assert.NotNil(t, unpackedTx.simple) { + t.FailNow() + } + assert.Equal(t, cond, unpackedTx.simple.preconditions) } func TestMissingSourceAccount(t *testing.T) { @@ -63,7 +97,7 @@ func TestIncrementSequenceNum(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&inflation}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -75,7 +109,7 @@ func TestIncrementSequenceNum(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&inflation}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -87,7 +121,7 @@ func TestIncrementSequenceNum(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&inflation}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -99,7 +133,7 @@ func TestIncrementSequenceNum(t *testing.T) { IncrementSequenceNum: false, Operations: []Operation{&inflation}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -115,7 +149,7 @@ func TestFeeNoOperations(t *testing.T) { SourceAccount: &sourceAccount, Operations: []Operation{}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.EqualError(t, err, "transaction has no operations") @@ -133,7 +167,7 @@ func TestInflation(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&inflation}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, @@ -159,7 +193,7 @@ func TestCreateAccount(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&createAccount}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, @@ -186,7 +220,7 @@ func TestPayment(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&payment}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, @@ -222,7 +256,7 @@ func TestPaymentMuxedAccounts(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&payment}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, @@ -248,7 +282,7 @@ func TestPaymentFailsIfNoAssetSpecified(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&payment}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) expectedErrMsg := "validation failed for *txnbuild.Payment operation: Field: Asset, Error: asset is undefined" @@ -269,7 +303,7 @@ func TestBumpSequence(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&bumpSequence}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp1, @@ -294,7 +328,7 @@ func TestAccountMerge(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&accountMerge}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, @@ -320,7 +354,7 @@ func TestManageData(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&manageData}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, @@ -345,7 +379,7 @@ func TestManageDataRemoveDataEntry(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&manageData}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, @@ -371,7 +405,7 @@ func TestSetOptionsInflationDestination(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&setOptions}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, @@ -396,7 +430,7 @@ func TestSetOptionsSetFlags(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&setOptions}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, @@ -421,7 +455,7 @@ func TestSetOptionsClearFlags(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&setOptions}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, @@ -446,7 +480,7 @@ func TestSetOptionsMasterWeight(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&setOptions}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, @@ -473,7 +507,7 @@ func TestSetOptionsThresholds(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&setOptions}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, @@ -498,7 +532,7 @@ func TestSetOptionsHomeDomain(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&setOptions}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, @@ -523,7 +557,7 @@ func TestSetOptionsHomeDomainTooLong(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&setOptions}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) @@ -545,7 +579,7 @@ func TestSetOptionsSigner(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&setOptions}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, @@ -571,7 +605,7 @@ func TestMultipleOperations(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&inflation, &bumpSequence}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp1, @@ -598,7 +632,7 @@ func TestChangeTrust(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&changeTrust}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, @@ -624,7 +658,7 @@ func TestChangeTrustNativeAssetNotAllowed(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&changeTrust}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) @@ -646,7 +680,7 @@ func TestChangeTrustDeleteTrustline(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&removeTrust}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, @@ -675,7 +709,7 @@ func TestAllowTrust(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&allowTrust}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, @@ -704,7 +738,7 @@ func TestAllowTrustNoIssuer(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&allowTrust}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, @@ -732,7 +766,7 @@ func TestManageSellOfferNewOffer(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&createOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp1, @@ -757,7 +791,7 @@ func TestManageSellOfferDeleteOffer(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&deleteOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp1, @@ -786,7 +820,7 @@ func TestManageSellOfferUpdateOffer(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&updateOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp1, @@ -815,7 +849,7 @@ func TestCreatePassiveSellOffer(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&createPassiveOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp1, @@ -847,7 +881,7 @@ func TestPathPayment(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&pathPayment}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp2, @@ -869,7 +903,7 @@ func TestMemoText(t *testing.T) { Operations: []Operation{&BumpSequence{BumpTo: 1}}, Memo: MemoText("Twas brillig"), BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp2, @@ -891,7 +925,7 @@ func TestMemoID(t *testing.T) { Operations: []Operation{&BumpSequence{BumpTo: 1}}, Memo: MemoID(314159), BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp2, @@ -913,7 +947,7 @@ func TestMemoHash(t *testing.T) { Operations: []Operation{&BumpSequence{BumpTo: 1}}, Memo: MemoHash([32]byte{0x01}), BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp2, @@ -935,7 +969,7 @@ func TestMemoReturn(t *testing.T) { Operations: []Operation{&BumpSequence{BumpTo: 1}}, Memo: MemoReturn([32]byte{0x01}), BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp2, @@ -965,7 +999,7 @@ func TestManageBuyOfferNewOffer(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&buyOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp1, @@ -994,7 +1028,7 @@ func TestManageBuyOfferDeleteOffer(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&buyOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp1, @@ -1023,7 +1057,7 @@ func TestManageBuyOfferUpdateOffer(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&buyOffer}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp1, @@ -1108,7 +1142,7 @@ func TestHashHex(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&createAccount}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -1152,7 +1186,7 @@ func TestTransactionFee(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&createAccount}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -1166,7 +1200,7 @@ func TestTransactionFee(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&createAccount}, BaseFee: 500, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -1200,7 +1234,7 @@ func TestPreAuthTransaction(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&createAccount}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -1238,7 +1272,7 @@ func TestPreAuthTransaction(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&setOptions}, BaseFee: 500, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -1279,7 +1313,7 @@ func TestHashXTransaction(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&setOptions}, BaseFee: 500, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -1309,7 +1343,7 @@ func TestHashXTransaction(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&payment}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -1415,7 +1449,7 @@ func TestBuild(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&createAccount}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -1475,7 +1509,7 @@ func TestFromXDRBuildSignEncode(t *testing.T) { Operations: newTx.Operations(), BaseFee: newTx.BaseFee(), Memo: MemoText("newtx"), - Timebounds: newTx.Timebounds(), + Preconditions: Preconditions{Timebounds: newTx.Timebounds()}, }, network.TestNetworkPassphrase, kp0, @@ -1501,7 +1535,7 @@ func TestSignWithSecretKey(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&createAccount}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, kp1, @@ -1514,7 +1548,7 @@ func TestSignWithSecretKey(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&createAccount}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -1548,7 +1582,7 @@ func TestAddSignatureDecorated(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&createAccount}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, kp1, @@ -1561,7 +1595,7 @@ func TestAddSignatureDecorated(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&createAccount}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -1649,8 +1683,8 @@ func TestFeeBumpTransaction_AddSignatureDecorated(t *testing.T) { Amount: "10", SourceAccount: kp1.Address(), }}, - BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + BaseFee: MinBaseFee, + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }) require.NoError(t, err) tx, err = tx.Sign(network.TestNetworkPassphrase, kp0, kp1) @@ -1700,7 +1734,7 @@ func TestAddSignatureBase64(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&createAccount}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, network.TestNetworkPassphrase, kp0, kp1, @@ -1713,7 +1747,7 @@ func TestAddSignatureBase64(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&createAccount}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -1749,8 +1783,8 @@ func TestTransaction_ClearSignatures(t *testing.T) { Amount: "10", SourceAccount: kp1.Address(), }}, - BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + BaseFee: MinBaseFee, + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) require.NoError(t, err) @@ -1782,8 +1816,8 @@ func TestFeeBumpTransaction_ClearSignatures(t *testing.T) { Amount: "10", SourceAccount: kp1.Address(), }}, - BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + BaseFee: MinBaseFee, + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }) require.NoError(t, err) require.Len(t, tx.Signatures(), 0) @@ -1835,7 +1869,7 @@ func TestReadChallengeTx_validSignedByServerAndClient(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, ) assert.NoError(t, err) @@ -1870,7 +1904,7 @@ func TestReadChallengeTx_validSignedByServer(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, ) assert.NoError(t, err) @@ -1905,7 +1939,7 @@ func TestReadChallengeTx_invalidNotSignedByServer(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, ) assert.NoError(t, err) @@ -1938,7 +1972,7 @@ func TestReadChallengeTx_invalidCorrupted(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, ) assert.NoError(t, err) @@ -1979,7 +2013,7 @@ func TestReadChallengeTx_invalidServerAccountIDMismatch(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, ) assert.NoError(t, err) @@ -2014,7 +2048,7 @@ func TestReadChallengeTx_invalidSeqNoNotZero(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, ) assert.NoError(t, err) @@ -2049,7 +2083,7 @@ func TestReadChallengeTx_invalidTimeboundsInfinite(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -2084,7 +2118,7 @@ func TestReadChallengeTx_invalidTimeboundsOutsideRange(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimebounds(0, 100), + Preconditions: Preconditions{Timebounds: NewTimebounds(0, 100)}, }, ) assert.NoError(t, err) @@ -2121,7 +2155,7 @@ func TestReadChallengeTx_validTimeboundsWithGracePeriod(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimebounds(unixNow+5*59, unixNow+60*60), + Preconditions: Preconditions{Timebounds: NewTimebounds(unixNow+5*59, unixNow+60*60)}, }, ) assert.NoError(t, err) @@ -2157,7 +2191,7 @@ func TestReadChallengeTx_invalidTimeboundsWithGracePeriod(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimebounds(unixNow+5*61, unixNow+60*60), + Preconditions: Preconditions{Timebounds: NewTimebounds(unixNow+5*61, unixNow+60*60)}, }, ) assert.NoError(t, err) @@ -2187,7 +2221,7 @@ func TestReadChallengeTx_invalidOperationWrongType(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(300), + Preconditions: Preconditions{Timebounds: NewTimeout(300)}, }, ) assert.NoError(t, err) @@ -2215,7 +2249,7 @@ func TestReadChallengeTx_invalidOperationNoSourceAccount(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(300), + Preconditions: Preconditions{Timebounds: NewTimeout(300)}, }, ) assert.NoError(t, err) @@ -2248,7 +2282,7 @@ func TestReadChallengeTx_invalidDataValueWrongEncodedLength(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(300), + Preconditions: Preconditions{Timebounds: NewTimeout(300)}, }, ) assert.NoError(t, err) @@ -2283,7 +2317,7 @@ func TestReadChallengeTx_invalidDataValueCorruptBase64(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(300), + Preconditions: Preconditions{Timebounds: NewTimeout(300)}, }, ) assert.NoError(t, err) @@ -2318,7 +2352,7 @@ func TestReadChallengeTx_invalidDataValueWrongByteLength(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, ) assert.NoError(t, err) @@ -2468,7 +2502,7 @@ func TestReadChallengeTx_doesVerifyHomeDomainFailure(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, ) assert.NoError(t, err) @@ -2501,7 +2535,7 @@ func TestReadChallengeTx_doesVerifyHomeDomainSuccess(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, ) assert.NoError(t, err) @@ -2539,7 +2573,7 @@ func TestReadChallengeTx_allowsAdditionalManageDataOpsWithSourceAccountSetToServ IncrementSequenceNum: true, Operations: []Operation{&op1, &op2, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, ) assert.NoError(t, err) @@ -2579,7 +2613,7 @@ func TestReadChallengeTx_disallowsAdditionalManageDataOpsWithoutSourceAccountSet IncrementSequenceNum: true, Operations: []Operation{&op1, &op2, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, ) assert.NoError(t, err) @@ -2616,7 +2650,7 @@ func TestReadChallengeTx_disallowsAdditionalOpsOfOtherTypes(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op1, &op2, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(300), + Preconditions: Preconditions{Timebounds: NewTimeout(300)}, }, ) assert.NoError(t, err) @@ -2651,7 +2685,7 @@ func TestReadChallengeTx_matchesHomeDomain(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op1, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(300), + Preconditions: Preconditions{Timebounds: NewTimeout(300)}, }, ) assert.NoError(t, err) @@ -2684,7 +2718,7 @@ func TestReadChallengeTx_doesNotMatchHomeDomain(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op1, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(300), + Preconditions: Preconditions{Timebounds: NewTimeout(300)}, }, ) assert.NoError(t, err) @@ -2712,7 +2746,7 @@ func TestReadChallengeTx_validWhenWebAuthDomainMissing(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op1}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(300), + Preconditions: Preconditions{Timebounds: NewTimeout(300)}, }, ) assert.NoError(t, err) @@ -2744,7 +2778,7 @@ func TestReadChallengeTx_invalidWebAuthDomainSourceAccount(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op1, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(300), + Preconditions: Preconditions{Timebounds: NewTimeout(300)}, }, ) assert.NoError(t, err) @@ -2776,7 +2810,7 @@ func TestReadChallengeTx_invalidWebAuthDomain(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op1, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(300), + Preconditions: Preconditions{Timebounds: NewTimeout(300)}, }, ) assert.NoError(t, err) @@ -2809,7 +2843,7 @@ func TestVerifyChallengeTxThreshold_invalidServer(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, clientKP, @@ -2845,7 +2879,7 @@ func TestVerifyChallengeTxThreshold_validServerAndClientKeyMeetingThreshold(t *t IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP, @@ -2886,7 +2920,7 @@ func TestVerifyChallengeTxThreshold_validServerAndMultipleClientKeyMeetingThresh IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP1, clientKP2, @@ -2941,7 +2975,7 @@ func TestVerifyChallengeTxThreshold_validServerAndMultipleClientKeyMeetingThresh IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP1, clientKP2, @@ -2992,7 +3026,7 @@ func TestVerifyChallengeTxThreshold_validServerAndMultipleClientKeyMeetingThresh IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP1, clientKP2, @@ -3033,7 +3067,7 @@ func TestVerifyChallengeTxThreshold_invalidServerAndMultipleClientKeyNotMeetingT IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP1, clientKP2, @@ -3072,7 +3106,7 @@ func TestVerifyChallengeTxThreshold_invalidClientKeyUnrecognized(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP1, clientKP2, clientKP3, @@ -3108,7 +3142,7 @@ func TestVerifyChallengeTxThreshold_invalidNoSigners(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP1, clientKP2, clientKP3, @@ -3140,7 +3174,7 @@ func TestVerifyChallengeTxThreshold_weightsAddToMoreThan8Bits(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP1, clientKP2, @@ -3182,7 +3216,7 @@ func TestVerifyChallengeTxThreshold_matchesHomeDomain(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op1, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(300), + Preconditions: Preconditions{Timebounds: NewTimeout(300)}, }, ) assert.NoError(t, err) @@ -3225,7 +3259,7 @@ func TestVerifyChallengeTxThreshold_doesNotMatchHomeDomain(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op1, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(300), + Preconditions: Preconditions{Timebounds: NewTimeout(300)}, }, ) assert.NoError(t, err) @@ -3263,7 +3297,7 @@ func TestVerifyChallengeTxThreshold_doesVerifyHomeDomainFailure(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP, @@ -3299,7 +3333,7 @@ func TestVerifyChallengeTxThreshold_doesVerifyHomeDomainSuccess(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP, @@ -3345,7 +3379,7 @@ func TestVerifyChallengeTxThreshold_allowsAdditionalManageDataOpsWithSourceAccou IncrementSequenceNum: true, Operations: []Operation{&op1, &op2, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP, @@ -3391,7 +3425,7 @@ func TestVerifyChallengeTxThreshold_disallowsAdditionalManageDataOpsWithoutSourc IncrementSequenceNum: true, Operations: []Operation{&op1, &op2, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP, @@ -3433,7 +3467,7 @@ func TestVerifyChallengeTxThreshold_disallowsAdditionalOpsOfOtherTypes(t *testin IncrementSequenceNum: true, Operations: []Operation{&op1, &op2, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP, @@ -3466,7 +3500,7 @@ func TestVerifyChallengeTxThreshold_validWhenWebAuthDomainMissing(t *testing.T) IncrementSequenceNum: true, Operations: []Operation{&op}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP, @@ -3506,7 +3540,7 @@ func TestVerifyChallengeTxThreshold_invalidWebAuthDomainSourceAccount(t *testing IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP, @@ -3542,7 +3576,7 @@ func TestVerifyChallengeTxThreshold_invalidWebAuthDomain(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP, @@ -3578,7 +3612,7 @@ func TestVerifyChallengeTxSigners_invalidServer(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, clientKP, @@ -3611,7 +3645,7 @@ func TestVerifyChallengeTxSigners_validServerAndClientMasterKey(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP, @@ -3644,7 +3678,7 @@ func TestVerifyChallengeTxSigners_invalidServerAndNoClient(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, @@ -3678,7 +3712,7 @@ func TestVerifyChallengeTxSigners_invalidServerAndUnrecognizedClient(t *testing. IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, unrecognizedKP, @@ -3712,7 +3746,7 @@ func TestVerifyChallengeTxSigners_validServerAndMultipleClientSigners(t *testing IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP, clientKP2, @@ -3746,7 +3780,7 @@ func TestVerifyChallengeTxSigners_validServerAndMultipleClientSignersReverseOrde IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP2, clientKP, @@ -3780,7 +3814,7 @@ func TestVerifyChallengeTxSigners_validServerAndClientSignersNotMasterKey(t *tes IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP2, @@ -3814,7 +3848,7 @@ func TestVerifyChallengeTxSigners_validServerAndClientSignersIgnoresServerSigner IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP2, @@ -3848,7 +3882,7 @@ func TestVerifyChallengeTxSigners_invalidServerNoClientSignersIgnoresServerSigne IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, @@ -3882,7 +3916,7 @@ func TestVerifyChallengeTxSigners_validServerAndClientSignersIgnoresDuplicateSig IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP2, @@ -3919,7 +3953,7 @@ func TestVerifyChallengeTxSigners_validIgnorePreauthTxHashAndXHash(t *testing.T) IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP2, @@ -3953,7 +3987,7 @@ func TestVerifyChallengeTxSigners_invalidServerAndClientSignersIgnoresDuplicateS IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP2, @@ -3987,7 +4021,7 @@ func TestVerifyChallengeTxSigners_invalidServerAndClientSignersFailsDuplicateSig IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP2, clientKP2, @@ -4021,7 +4055,7 @@ func TestVerifyChallengeTxSigners_invalidServerAndClientSignersFailsSignerSeed(t IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP2, @@ -4054,7 +4088,7 @@ func TestVerifyChallengeTxSigners_invalidNoSigners(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP, @@ -4086,7 +4120,7 @@ func TestVerifyChallengeTxSigners_doesVerifyHomeDomainFailure(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP, @@ -4118,7 +4152,7 @@ func TestVerifyChallengeTxSigners_matchesHomeDomain(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op1, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(300), + Preconditions: Preconditions{Timebounds: NewTimeout(300)}, }, ) assert.NoError(t, err) @@ -4158,7 +4192,7 @@ func TestVerifyChallengeTxSigners_doesNotMatchHomeDomain(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op1, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(300), + Preconditions: Preconditions{Timebounds: NewTimeout(300)}, }, ) assert.NoError(t, err) @@ -4198,7 +4232,7 @@ func TestVerifyChallengeTxSigners_doesVerifyHomeDomainSuccess(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP, @@ -4235,7 +4269,7 @@ func TestVerifyChallengeTxSigners_allowsAdditionalManageDataOpsWithSourceAccount IncrementSequenceNum: true, Operations: []Operation{&op1, &op2, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP, @@ -4273,7 +4307,7 @@ func TestVerifyChallengeTxSigners_disallowsAdditionalManageDataOpsWithoutSourceA IncrementSequenceNum: true, Operations: []Operation{&op1, &op2, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP, @@ -4310,7 +4344,7 @@ func TestVerifyChallengeTxSigners_disallowsAdditionalOpsOfOtherTypes(t *testing. IncrementSequenceNum: true, Operations: []Operation{&op1, &op2, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP, @@ -4337,7 +4371,7 @@ func TestVerifyChallengeTxSigners_validWhenWebAuthDomainMissing(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP, @@ -4371,7 +4405,7 @@ func TestVerifyChallengeTxSigners_invalidWebAuthDomainSourceAccount(t *testing.T IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP, @@ -4402,7 +4436,7 @@ func TestVerifyChallengeTxSigners_invalidWebAuthDomain(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&op, &webAuthDomainOp}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, network.TestNetworkPassphrase, serverKP, clientKP, @@ -4428,7 +4462,7 @@ func TestVerifyTxSignatureUnsignedTx(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&createAccount}, BaseFee: MinBaseFee, - Timebounds: NewTimeout(1000), + Preconditions: Preconditions{Timebounds: NewTimeout(1000)}, }, ) assert.NoError(t, err) @@ -4454,7 +4488,7 @@ func TestVerifyTxSignatureSingle(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&createAccount}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -4480,7 +4514,7 @@ func TestVerifyTxSignatureMultiple(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&createAccount}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -4508,7 +4542,7 @@ func TestVerifyTxSignatureInvalid(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&createAccount}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) @@ -4543,7 +4577,7 @@ func TestClaimableBalanceIds(t *testing.T) { SourceAccount: &aMuxedAccount, IncrementSequenceNum: true, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, Operations: []Operation{&claimableBalanceEntry}, }, ) @@ -4578,7 +4612,7 @@ func TestTransaction_marshalUnmarshalText(t *testing.T) { SourceAccount: &SimpleAccount{AccountID: k.Address(), Sequence: 1}, IncrementSequenceNum: false, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, Operations: []Operation{&BumpSequence{BumpTo: 2}}, }, ) @@ -4612,7 +4646,7 @@ func TestFeeBumpTransaction_marshalUnmarshalText(t *testing.T) { SourceAccount: &SimpleAccount{AccountID: k.Address(), Sequence: 1}, IncrementSequenceNum: false, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, Operations: []Operation{&BumpSequence{BumpTo: 2}}, }, ) @@ -4652,7 +4686,7 @@ func TestNewGenericTransactionWithTransaction(t *testing.T) { SourceAccount: &SimpleAccount{AccountID: k.Address(), Sequence: 1}, IncrementSequenceNum: false, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, Operations: []Operation{&BumpSequence{BumpTo: 2}}, }, ) @@ -4671,7 +4705,7 @@ func TestNewGenericTransactionWithFeeBumpTransaction(t *testing.T) { SourceAccount: &SimpleAccount{AccountID: k.Address(), Sequence: 1}, IncrementSequenceNum: false, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, Operations: []Operation{&BumpSequence{BumpTo: 2}}, }, ) @@ -4703,7 +4737,7 @@ func TestGenericTransaction_marshalUnmarshalText(t *testing.T) { SourceAccount: &SimpleAccount{AccountID: k.Address(), Sequence: 1}, IncrementSequenceNum: false, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, Operations: []Operation{&BumpSequence{BumpTo: 2}}, }, ) @@ -4760,7 +4794,7 @@ func TestGenericTransaction_marshalBinary(t *testing.T) { SourceAccount: &SimpleAccount{AccountID: k.Address(), Sequence: 1}, IncrementSequenceNum: false, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, Operations: []Operation{&BumpSequence{BumpTo: 2}}, }, ) @@ -4806,7 +4840,7 @@ func TestGenericTransaction_HashHex(t *testing.T) { IncrementSequenceNum: true, Operations: []Operation{&createAccount}, BaseFee: MinBaseFee, - Timebounds: NewInfiniteTimeout(), + Preconditions: Preconditions{Timebounds: NewInfiniteTimeout()}, }, ) assert.NoError(t, err) diff --git a/xdr/transaction_envelope.go b/xdr/transaction_envelope.go index e9a4ce0a89..4f9b126996 100644 --- a/xdr/transaction_envelope.go +++ b/xdr/transaction_envelope.go @@ -103,6 +103,24 @@ func (e TransactionEnvelope) TimeBounds() *TimeBounds { } } +// Preconditions returns the preconditions on the transaction. If the +// transaction is a V0 envelope (aka before preconditions existed), this returns +// a new precondition (timebound if present, empty otherwise). If the +// transaction is a fee bump, it returns the preconditions of the *inner* +// transaction. +func (e TransactionEnvelope) Preconditions() Preconditions { + switch e.Type { + case EnvelopeTypeEnvelopeTypeTxFeeBump: + return e.FeeBump.Tx.InnerTx.V1.Tx.Cond + case EnvelopeTypeEnvelopeTypeTx: + return e.V1.Tx.Cond + case EnvelopeTypeEnvelopeTypeTxV0: + return NewPreconditionsWithTimeBounds(e.TimeBounds()) + default: + panic("unsupported transaction type: " + e.Type.String()) + } +} + // Operations returns the operations set in the transaction envelope // Note for fee bump transactions, Operations() returns the operations // of the inner transaction