Skip to content

Commit

Permalink
txnbuild: Add support for new CAP-21 preconditions. (#4303)
Browse files Browse the repository at this point in the history
Adds support for new CAP-21 preconditions with a simple, but breaking API
change:

TransactionParams.Timebounds -> TransactionParams.Preconditions.TimeBounds

You can now pass a lot more preconditions to a Transaction (including
timebounds), and these are managed by the new Preconditions object. All of the
XDR abstractions are hidden away behind this object.
  • Loading branch information
Shaptic authored Mar 25, 2022
1 parent 67f991f commit 649016c
Show file tree
Hide file tree
Showing 44 changed files with 834 additions and 428 deletions.
4 changes: 2 additions & 2 deletions clients/horizonclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
10 changes: 5 additions & 5 deletions clients/horizonclient/examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down
18 changes: 9 additions & 9 deletions clients/horizonclient/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
8 changes: 5 additions & 3 deletions exp/services/webauth/internal/serve/token_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion services/friendbot/init_friendbot.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion services/friendbot/internal/minion.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion services/horizon/internal/integration/sponsorship_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion services/horizon/internal/test/integration/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
Loading

0 comments on commit 649016c

Please sign in to comment.