From 8285d2562fe04c021390b45cf406ffdd8fc3d7c5 Mon Sep 17 00:00:00 2001 From: Ragot Geoffrey Date: Thu, 14 Sep 2023 18:00:40 +0200 Subject: [PATCH] feat: add 'disableChecks' query param on revert endpoint (#459) --- pkg/api/controllers/swagger.yaml | 6 ++ pkg/api/controllers/transaction_controller.go | 8 ++- .../transaction_controller_test.go | 47 ++++++++++++++- pkg/api/internal/testing.go | 7 ++- pkg/ledger/benchmarks_test.go | 6 +- pkg/ledger/execute_script_test.go | 18 +++--- pkg/ledger/execute_txsdata.go | 60 ++++++++++--------- pkg/ledger/execute_txsdata_test.go | 12 ++-- pkg/ledger/ledger.go | 4 +- pkg/ledger/ledger_test.go | 40 ++++++------- 10 files changed, 132 insertions(+), 76 deletions(-) diff --git a/pkg/api/controllers/swagger.yaml b/pkg/api/controllers/swagger.yaml index 0f1f677f1..27a01ae3f 100644 --- a/pkg/api/controllers/swagger.yaml +++ b/pkg/api/controllers/swagger.yaml @@ -829,6 +829,12 @@ paths: format: int64 minimum: 0 example: 1234 + - name: disableChecks + in: query + description: Allow to disable balances checks + required: false + schema: + type: boolean responses: "200": description: OK diff --git a/pkg/api/controllers/transaction_controller.go b/pkg/api/controllers/transaction_controller.go index 674368739..4bf9c7410 100644 --- a/pkg/api/controllers/transaction_controller.go +++ b/pkg/api/controllers/transaction_controller.go @@ -274,7 +274,7 @@ func (ctl *TransactionController) PostTransaction(c *gin.Context) { Reference: payload.Reference, Metadata: payload.Metadata, } - res, err := l.(*ledger.Ledger).ExecuteTxsData(c.Request.Context(), preview, txData) + res, err := l.(*ledger.Ledger).ExecuteTxsData(c.Request.Context(), preview, true, txData) if err != nil { apierrors.ResponseError(c, err) return @@ -326,7 +326,9 @@ func (ctl *TransactionController) RevertTransaction(c *gin.Context) { return } - tx, err := l.(*ledger.Ledger).RevertTransaction(c.Request.Context(), txId) + disableChecks := c.Query("disableChecks") == "1" || c.Query("disableChecks") == "true" + + tx, err := l.(*ledger.Ledger).RevertTransaction(c.Request.Context(), txId, !disableChecks) if err != nil { apierrors.ResponseError(c, err) return @@ -392,7 +394,7 @@ func (ctl *TransactionController) PostTransactionsBatch(c *gin.Context) { } } - res, err := l.(*ledger.Ledger).ExecuteTxsData(c.Request.Context(), false, txs.Transactions...) + res, err := l.(*ledger.Ledger).ExecuteTxsData(c.Request.Context(), false, true, txs.Transactions...) if err != nil { apierrors.ResponseError(c, err) return diff --git a/pkg/api/controllers/transaction_controller_test.go b/pkg/api/controllers/transaction_controller_test.go index 10b25c996..be40bece8 100644 --- a/pkg/api/controllers/transaction_controller_test.go +++ b/pkg/api/controllers/transaction_controller_test.go @@ -877,6 +877,47 @@ func TestPostTransactionsOverdraft(t *testing.T) { })) } +func TestRevertWithDisableChecks(t *testing.T) { + internal.RunTest(t, fx.Invoke(func(lc fx.Lifecycle, api *api.API, driver storage.Driver[ledger.Store]) { + lc.Append(fx.Hook{ + OnStart: func(ctx context.Context) error { + + rsp := internal.PostTransaction(t, api, controllers.PostTransaction{ + Script: core.Script{ + Plain: ` + send [USD/2 100] ( + source = @world + destination = @users:43 + ) + `, + }, + }, false) + require.Equal(t, http.StatusOK, rsp.Result().StatusCode) + txs, ok := internal.DecodeSingleResponse[[]core.ExpandedTransaction](t, rsp.Body) + require.True(t, ok) + require.Len(t, txs, 1) + + rsp = internal.PostTransaction(t, api, controllers.PostTransaction{ + Script: core.Script{ + Plain: ` + send [USD/2 100] ( + source = @users:43 + destination = @blackhole + ) + `, + }, + }, false) + require.Equal(t, http.StatusOK, rsp.Result().StatusCode) + + rsp = internal.RevertTransaction(api, txs[0].ID, true) + require.Equal(t, http.StatusOK, rsp.Result().StatusCode) + + return nil + }, + }) + })) +} + func TestPostTransactionInvalidBody(t *testing.T) { internal.RunTest(t, fx.Invoke(func(lc fx.Lifecycle, api *api.API) { lc.Append(fx.Hook{ @@ -2064,7 +2105,7 @@ func TestRevertTransaction(t *testing.T) { revertedTxID := cursor.Data[0].ID t.Run("first revert should succeed", func(t *testing.T) { - rsp := internal.RevertTransaction(api, revertedTxID) + rsp := internal.RevertTransaction(api, revertedTxID, false) require.Equal(t, http.StatusOK, rsp.Result().StatusCode) res, _ := internal.DecodeSingleResponse[core.ExpandedTransaction](t, rsp.Body) require.Equal(t, revertedTxID+1, res.ID) @@ -2090,7 +2131,7 @@ func TestRevertTransaction(t *testing.T) { }) t.Run("transaction not found", func(t *testing.T) { - rsp := internal.RevertTransaction(api, uint64(42)) + rsp := internal.RevertTransaction(api, uint64(42), false) require.Equal(t, http.StatusNotFound, rsp.Result().StatusCode, rsp.Body.String()) err := sharedapi.ErrorResponse{} internal.Decode(t, rsp.Body, &err) @@ -2103,7 +2144,7 @@ func TestRevertTransaction(t *testing.T) { }) t.Run("second revert should fail", func(t *testing.T) { - rsp := internal.RevertTransaction(api, revertedTxID) + rsp := internal.RevertTransaction(api, revertedTxID, false) require.Equal(t, http.StatusBadRequest, rsp.Result().StatusCode, rsp.Body.String()) err := sharedapi.ErrorResponse{} diff --git a/pkg/api/internal/testing.go b/pkg/api/internal/testing.go index 99c6de564..b98aea88c 100644 --- a/pkg/api/internal/testing.go +++ b/pkg/api/internal/testing.go @@ -119,8 +119,13 @@ func GetTransaction(handler http.Handler, id uint64) *httptest.ResponseRecorder return rec } -func RevertTransaction(handler http.Handler, id uint64) *httptest.ResponseRecorder { +func RevertTransaction(handler http.Handler, id uint64, disableChecks bool) *httptest.ResponseRecorder { req, rec := NewRequest(http.MethodPost, fmt.Sprintf("/"+testingLedger+"/transactions/%d/revert", id), nil) + if disableChecks { + query := req.URL.Query() + query.Set("disableChecks", "1") + req.URL.RawQuery = query.Encode() + } handler.ServeHTTP(rec, req) return rec } diff --git a/pkg/ledger/benchmarks_test.go b/pkg/ledger/benchmarks_test.go index 33d31e756..8bfbff536 100644 --- a/pkg/ledger/benchmarks_test.go +++ b/pkg/ledger/benchmarks_test.go @@ -68,7 +68,7 @@ func BenchmarkLedger_PostTransactions_Postings_Single_FixedAccounts(b *testing.B for n := 0; n < b.N; n++ { _, err := txData.Postings.Validate() require.NoError(b, err) - res, err = l.ExecuteTxsData(context.Background(), true, txData) + res, err = l.ExecuteTxsData(context.Background(), true, true, txData) require.NoError(b, err) require.Len(b, res, 1) require.Len(b, res[0].Postings, nbPostings) @@ -96,7 +96,7 @@ func BenchmarkLedger_PostTransactions_Postings_Batch_FixedAccounts(b *testing.B) _, err := txData.Postings.Validate() require.NoError(b, err) } - res, err = l.ExecuteTxsData(context.Background(), true, txsData...) + res, err = l.ExecuteTxsData(context.Background(), true, true, txsData...) require.NoError(b, err) require.Len(b, res, 7) require.Len(b, res[0].Postings, 1) @@ -137,7 +137,7 @@ func BenchmarkLedger_PostTransactions_Postings_Batch_VaryingAccounts(b *testing. _, err := txData.Postings.Validate() require.NoError(b, err) } - res, err = l.ExecuteTxsData(context.Background(), true, txsData...) + res, err = l.ExecuteTxsData(context.Background(), true, true, txsData...) require.NoError(b, err) require.Len(b, res, 7) require.Len(b, res[0].Postings, 1) diff --git a/pkg/ledger/execute_script_test.go b/pkg/ledger/execute_script_test.go index ad45f266c..ce4282130 100644 --- a/pkg/ledger/execute_script_test.go +++ b/pkg/ledger/execute_script_test.go @@ -56,7 +56,7 @@ func TestMappingIgnoreDestinations(t *testing.T) { _, err := l.ExecuteScript(context.Background(), false, script) require.NoError(t, err) - _, err = l.ExecuteTxsData(context.Background(), false, core.TransactionData{ + _, err = l.ExecuteTxsData(context.Background(), false, true, core.TransactionData{ Postings: []core.Posting{{ Source: "B", Destination: "A", @@ -66,7 +66,7 @@ func TestMappingIgnoreDestinations(t *testing.T) { }) require.NoError(t, err) - _, err = l.ExecuteTxsData(context.Background(), false, core.TransactionData{ + _, err = l.ExecuteTxsData(context.Background(), false, true, core.TransactionData{ Postings: []core.Posting{{ Source: "B", Destination: "A", @@ -278,7 +278,7 @@ func TestEnoughFunds(t *testing.T) { }, } - _, err := l.ExecuteTxsData(context.Background(), false, tx) + _, err := l.ExecuteTxsData(context.Background(), false, true, tx) require.NoError(t, err) script := core.ScriptData{ @@ -309,7 +309,7 @@ func TestNotEnoughFunds(t *testing.T) { }, } - _, err := l.ExecuteTxsData(context.Background(), false, tx) + _, err := l.ExecuteTxsData(context.Background(), false, true, tx) require.NoError(t, err) script := core.ScriptData{ @@ -366,7 +366,7 @@ func TestMetadata(t *testing.T) { }, } - _, err := l.ExecuteTxsData(context.Background(), false, tx) + _, err := l.ExecuteTxsData(context.Background(), false, true, tx) require.NoError(t, err) err = l.SaveMeta(context.Background(), core.MetaTargetTypeAccount, @@ -624,7 +624,7 @@ func TestMonetaryVariableBalance(t *testing.T) { }, }, } - _, err := l.ExecuteTxsData(context.Background(), false, tx) + _, err := l.ExecuteTxsData(context.Background(), false, true, tx) require.NoError(t, err) script := core.ScriptData{ @@ -665,7 +665,7 @@ func TestMonetaryVariableBalance(t *testing.T) { }, }, } - _, err := l.ExecuteTxsData(context.Background(), false, tx) + _, err := l.ExecuteTxsData(context.Background(), false, true, tx) require.NoError(t, err) script := core.ScriptData{ @@ -706,7 +706,7 @@ func TestMonetaryVariableBalance(t *testing.T) { }, }, } - _, err := l.ExecuteTxsData(context.Background(), false, tx) + _, err := l.ExecuteTxsData(context.Background(), false, true, tx) require.NoError(t, err) script := core.ScriptData{ @@ -742,7 +742,7 @@ func TestMonetaryVariableBalance(t *testing.T) { }, }, } - _, err := l.ExecuteTxsData(context.Background(), false, tx) + _, err := l.ExecuteTxsData(context.Background(), false, true, tx) require.NoError(t, err) script := core.ScriptData{ diff --git a/pkg/ledger/execute_txsdata.go b/pkg/ledger/execute_txsdata.go index 856b2b0b1..1f0e218a4 100644 --- a/pkg/ledger/execute_txsdata.go +++ b/pkg/ledger/execute_txsdata.go @@ -11,7 +11,7 @@ import ( "github.com/pkg/errors" ) -func (l *Ledger) ExecuteTxsData(ctx context.Context, preview bool, txsData ...core.TransactionData) ([]core.ExpandedTransaction, error) { +func (l *Ledger) ExecuteTxsData(ctx context.Context, preview, checkBalances bool, txsData ...core.TransactionData) ([]core.ExpandedTransaction, error) { ctx, span := opentelemetry.Start(ctx, "ExecuteTxsData") defer span.End() @@ -98,38 +98,40 @@ func (l *Ledger) ExecuteTxsData(ctx context.Context, preview bool, txsData ...co } } - for account, volumes := range txVolumeAggr.PostCommitVolumes { - if _, ok := accs[account]; !ok { - accs[account], err = l.GetAccount(ctx, account) - if err != nil { - return []core.ExpandedTransaction{}, NewTransactionCommitError(i, - errors.Wrap(err, fmt.Sprintf("get account '%s'", account))) - } - } - for asset, vol := range volumes { - accs[account].Volumes[asset] = vol - } - accs[account].Balances = accs[account].Volumes.Balances() - for asset, volume := range volumes { - if account == core.WORLD { - continue + if checkBalances { + for account, volumes := range txVolumeAggr.PostCommitVolumes { + if _, ok := accs[account]; !ok { + accs[account], err = l.GetAccount(ctx, account) + if err != nil { + return []core.ExpandedTransaction{}, NewTransactionCommitError(i, + errors.Wrap(err, fmt.Sprintf("get account '%s'", account))) + } } - if volume.Balance().Gte(txVolumeAggr.PreCommitVolumes[account][asset].Balance()) { - continue + for asset, vol := range volumes { + accs[account].Volumes[asset] = vol } + accs[account].Balances = accs[account].Volumes.Balances() + for asset, volume := range volumes { + if account == core.WORLD { + continue + } + if volume.Balance().Gte(txVolumeAggr.PreCommitVolumes[account][asset].Balance()) { + continue + } - for _, contract := range contracts { - if contract.Match(account) { - if ok := contract.Expr.Eval(core.EvalContext{ - Variables: map[string]interface{}{ - "balance": volume.Balance(), - }, - Metadata: accs[account].Metadata, - Asset: asset, - }); !ok { - return []core.ExpandedTransaction{}, NewInsufficientFundError(asset) + for _, contract := range contracts { + if contract.Match(account) { + if ok := contract.Expr.Eval(core.EvalContext{ + Variables: map[string]interface{}{ + "balance": volume.Balance(), + }, + Metadata: accs[account].Metadata, + Asset: asset, + }); !ok { + return []core.ExpandedTransaction{}, NewInsufficientFundError(asset) + } + break } - break } } } diff --git a/pkg/ledger/execute_txsdata_test.go b/pkg/ledger/execute_txsdata_test.go index 6b5fb8d6f..aac62d90a 100644 --- a/pkg/ledger/execute_txsdata_test.go +++ b/pkg/ledger/execute_txsdata_test.go @@ -135,7 +135,7 @@ func TestLedger_ExecuteTxsData(t *testing.T) { }, } - res, err := l.ExecuteTxsData(context.Background(), true, txsData...) + res, err := l.ExecuteTxsData(context.Background(), true, true, txsData...) assert.NoError(t, err) assert.Equal(t, len(txsData), len(res)) @@ -185,7 +185,7 @@ func TestLedger_ExecuteTxsData(t *testing.T) { }, } - res, err := l.ExecuteTxsData(context.Background(), true, txsData...) + res, err := l.ExecuteTxsData(context.Background(), true, true, txsData...) require.NoError(t, err) require.Equal(t, len(txsData), len(res)) @@ -307,19 +307,19 @@ func TestLedger_ExecuteTxsData(t *testing.T) { }) t.Run("no transaction data", func(t *testing.T) { - _, err := l.ExecuteTxsData(context.Background(), true) + _, err := l.ExecuteTxsData(context.Background(), true, true) assert.Error(t, err) assert.ErrorContains(t, err, "no transaction data to execute") }) t.Run("no postings", func(t *testing.T) { - _, err := l.ExecuteTxsData(context.Background(), true, core.TransactionData{}) + _, err := l.ExecuteTxsData(context.Background(), true, true, core.TransactionData{}) assert.Error(t, err) assert.ErrorContains(t, err, "executing transaction data 0: no postings") }) t.Run("amount zero", func(t *testing.T) { - res, err := l.ExecuteTxsData(context.Background(), true, core.TransactionData{ + res, err := l.ExecuteTxsData(context.Background(), true, true, core.TransactionData{ Postings: core.Postings{ { Source: "world", @@ -347,7 +347,7 @@ func TestLedger_ExecuteTxsData(t *testing.T) { }, })) - _, err := l.ExecuteTxsData(context.Background(), true, + _, err := l.ExecuteTxsData(context.Background(), true, true, core.TransactionData{ Postings: []core.Posting{{ Source: "world", diff --git a/pkg/ledger/ledger.go b/pkg/ledger/ledger.go index 6b6d54fa9..4cc5f7597 100644 --- a/pkg/ledger/ledger.go +++ b/pkg/ledger/ledger.go @@ -97,7 +97,7 @@ func (l *Ledger) LoadMapping(ctx context.Context) (*core.Mapping, error) { return l.store.LoadMapping(ctx) } -func (l *Ledger) RevertTransaction(ctx context.Context, id uint64) (*core.ExpandedTransaction, error) { +func (l *Ledger) RevertTransaction(ctx context.Context, id uint64, checkBalances bool) (*core.ExpandedTransaction, error) { revertedTx, err := l.store.GetTransaction(ctx, id) if err != nil { return nil, errors.Wrap(err, fmt.Sprintf("getting transaction %d", id)) @@ -119,7 +119,7 @@ func (l *Ledger) RevertTransaction(ctx context.Context, id uint64) (*core.Expand Reference: rt.Reference, Metadata: rt.Metadata, } - res, err := l.ExecuteTxsData(ctx, false, txData) + res, err := l.ExecuteTxsData(ctx, false, checkBalances, txData) if err != nil { return nil, errors.Wrap(err, fmt.Sprintf( "executing revert script for transaction %d", id)) diff --git a/pkg/ledger/ledger_test.go b/pkg/ledger/ledger_test.go index bb78ec83c..7e1b6b052 100644 --- a/pkg/ledger/ledger_test.go +++ b/pkg/ledger/ledger_test.go @@ -137,7 +137,7 @@ func TestTransaction(t *testing.T) { continue } - _, err := l.ExecuteTxsData(context.Background(), false, batch...) + _, err := l.ExecuteTxsData(context.Background(), false, true, batch...) require.NoError(t, err) batch = []core.TransactionData{} @@ -195,7 +195,7 @@ func TestTransactionBatchWithConflictingReference(t *testing.T) { }, } - _, err := l.ExecuteTxsData(context.Background(), false, batch...) + _, err := l.ExecuteTxsData(context.Background(), false, true, batch...) assert.Error(t, err) assert.IsType(t, new(ledger.ConflictError), err) }) @@ -213,10 +213,10 @@ func TestTransactionBatchWithConflictingReference(t *testing.T) { }, Reference: "ref1", } - _, err := l.ExecuteTxsData(context.Background(), false, txData) + _, err := l.ExecuteTxsData(context.Background(), false, true, txData) require.NoError(t, err) - _, err = l.ExecuteTxsData(context.Background(), false, txData) + _, err = l.ExecuteTxsData(context.Background(), false, true, txData) assert.Error(t, err) assert.IsType(t, new(ledger.ConflictError), err) }) @@ -254,7 +254,7 @@ func TestTransactionBatchTimestamps(t *testing.T) { Timestamp: timestamp1, }, } - _, err := l.ExecuteTxsData(context.Background(), false, batch...) + _, err := l.ExecuteTxsData(context.Background(), false, true, batch...) require.True(t, ledger.IsValidationError(err), err) require.ErrorContains(t, err, "cannot pass a timestamp prior to the last transaction") }) @@ -283,7 +283,7 @@ func TestTransactionBatchTimestamps(t *testing.T) { Timestamp: timestamp3, }, } - _, err := l.ExecuteTxsData(context.Background(), false, batch...) + _, err := l.ExecuteTxsData(context.Background(), false, true, batch...) assert.NoError(t, err) }) t.Run("ascending order but before last inserted should fail", func(t *testing.T) { @@ -311,7 +311,7 @@ func TestTransactionBatchTimestamps(t *testing.T) { Timestamp: timestamp4, }, } - _, err := l.ExecuteTxsData(context.Background(), false, batch...) + _, err := l.ExecuteTxsData(context.Background(), false, true, batch...) require.True(t, ledger.IsValidationError(err)) require.ErrorContains(t, err, "cannot pass a timestamp prior to the last transaction") }) @@ -363,7 +363,7 @@ func TestTransactionExpectedVolumes(t *testing.T) { }, } - res, err := l.ExecuteTxsData(context.Background(), false, txsData...) + res, err := l.ExecuteTxsData(context.Background(), false, true, txsData...) assert.NoError(t, err) postCommitVolumes := core.AggregatePostCommitVolumes(res...) @@ -413,10 +413,10 @@ func TestReference(t *testing.T) { }, } - _, err := l.ExecuteTxsData(context.Background(), false, tx) + _, err := l.ExecuteTxsData(context.Background(), false, true, tx) require.NoError(t, err) - _, err = l.ExecuteTxsData(context.Background(), false, tx) + _, err = l.ExecuteTxsData(context.Background(), false, true, tx) assert.Error(t, err) }) } @@ -447,7 +447,7 @@ func TestAccountMetadata(t *testing.T) { { // We have to create at least one transaction to retrieve an account from GetAccounts store method - _, err := l.ExecuteTxsData(context.Background(), false, core.TransactionData{ + _, err := l.ExecuteTxsData(context.Background(), false, true, core.TransactionData{ Postings: core.Postings{ { Source: "world", @@ -473,7 +473,7 @@ func TestAccountMetadata(t *testing.T) { func TestTransactionMetadata(t *testing.T) { runOnLedger(func(l *ledger.Ledger) { - _, err := l.ExecuteTxsData(context.Background(), false, + _, err := l.ExecuteTxsData(context.Background(), false, true, core.TransactionData{ Postings: []core.Posting{ { @@ -512,7 +512,7 @@ func TestTransactionMetadata(t *testing.T) { func TestSaveTransactionMetadata(t *testing.T) { runOnLedger(func(l *ledger.Ledger) { - _, err := l.ExecuteTxsData(context.Background(), false, + _, err := l.ExecuteTxsData(context.Background(), false, true, core.TransactionData{ Postings: []core.Posting{ { @@ -541,7 +541,7 @@ func TestSaveTransactionMetadata(t *testing.T) { func TestGetTransaction(t *testing.T) { runOnLedger(func(l *ledger.Ledger) { - _, err := l.ExecuteTxsData(context.Background(), false, + _, err := l.ExecuteTxsData(context.Background(), false, true, core.TransactionData{ Reference: "bar", Postings: []core.Posting{ @@ -578,7 +578,7 @@ func TestGetTransactions(t *testing.T) { }, } - _, err := l.ExecuteTxsData(context.Background(), false, tx) + _, err := l.ExecuteTxsData(context.Background(), false, true, tx) require.NoError(t, err) res, err := l.GetTransactions(context.Background(), *ledger.NewTransactionsQuery()) @@ -592,7 +592,7 @@ func TestRevertTransaction(t *testing.T) { runOnLedger(func(l *ledger.Ledger) { revertAmt := core.NewMonetaryInt(100) - res, err := l.ExecuteTxsData(context.Background(), false, + res, err := l.ExecuteTxsData(context.Background(), false, true, core.TransactionData{ Reference: "foo", Postings: []core.Posting{ @@ -611,7 +611,7 @@ func TestRevertTransaction(t *testing.T) { originalBal := world.Balances["COIN"] - revertTx, err := l.RevertTransaction(context.Background(), res[0].ID) + revertTx, err := l.RevertTransaction(context.Background(), res[0].ID, true) require.NoError(t, err) require.Equal(t, core.Postings{ @@ -651,7 +651,7 @@ func TestVeryBigTransaction(t *testing.T) { "199999999999999999992919191919192929292939847477171818284637291884661818183647392936472918836161728274766266161728493736383838") require.NoError(t, err) - res, err := l.ExecuteTxsData(context.Background(), false, + res, err := l.ExecuteTxsData(context.Background(), false, true, core.TransactionData{ Postings: []core.Posting{{ Source: "world", @@ -684,7 +684,7 @@ func BenchmarkTransaction1(b *testing.B) { }, }) - _, err := l.ExecuteTxsData(context.Background(), false, txs...) + _, err := l.ExecuteTxsData(context.Background(), false, true, txs...) require.NoError(b, err) } }) @@ -709,7 +709,7 @@ func BenchmarkTransaction_20_1k(b *testing.B) { }) } - _, err := l.ExecuteTxsData(context.Background(), false, txs...) + _, err := l.ExecuteTxsData(context.Background(), false, true, txs...) require.NoError(b, err) } }