From 720f9ff9c395b315351e76074f1ff8db824caab3 Mon Sep 17 00:00:00 2001 From: marta-lokhova Date: Mon, 26 Jun 2023 16:35:19 -0700 Subject: [PATCH 1/4] Test suite cleanup and audit of source account limit flag --- src/herder/TxSetFrame.cpp | 3 - src/herder/test/HerderTests.cpp | 484 ++++++------ src/herder/test/PendingEnvelopesTests.cpp | 14 +- src/herder/test/TransactionQueueTests.cpp | 816 ++++++++++----------- src/herder/test/TxSetTests.cpp | 21 +- src/history/test/HistoryTestsUtils.cpp | 38 +- src/main/Config.cpp | 7 +- src/simulation/test/LoadGeneratorTests.cpp | 3 - src/test/test.cpp | 5 - src/transactions/test/MergeTests.cpp | 22 +- src/transactions/test/PaymentTests.cpp | 4 +- src/transactions/test/TxEnvelopeTests.cpp | 27 +- 12 files changed, 679 insertions(+), 765 deletions(-) diff --git a/src/herder/TxSetFrame.cpp b/src/herder/TxSetFrame.cpp index 18a0371df8..b03246cfbe 100644 --- a/src/herder/TxSetFrame.cpp +++ b/src/herder/TxSetFrame.cpp @@ -641,9 +641,6 @@ TxSetFrame::checkValid(Application& app, uint64_t lowerBoundCloseTimeOffset, { // First, ensure the tx set does not contain multiple txs per source // account - // FIXME: Our test suite relies on tx chains per source account, so - // introducing this invariant causes a fallout. When the test suite is - // updated to accommodate 1 tx/source account, remove this flag. if (app.getConfig().LIMIT_TX_QUEUE_SOURCE_ACCOUNT) { std::unordered_set seenAccounts; diff --git a/src/herder/test/HerderTests.cpp b/src/herder/test/HerderTests.cpp index e00b7ca28c..9a18ae0f56 100644 --- a/src/herder/test/HerderTests.cpp +++ b/src/herder/test/HerderTests.cpp @@ -85,9 +85,10 @@ TEST_CASE_VERSIONS("standalone", "[herder][acceptance]") { VirtualTimer setupTimer(*app); - auto feedTx = [&](TransactionFramePtr& tx) { + auto feedTx = [&](TransactionFramePtr& tx, + TransactionQueue::AddResult expectedRes) { REQUIRE(app->getHerder().recvTransaction(tx, false) == - TransactionQueue::AddResult::ADD_STATUS_PENDING); + expectedRes); }; auto waitForExternalize = [&]() { @@ -115,13 +116,12 @@ TEST_CASE_VERSIONS("standalone", "[herder][acceptance]") auto setup = [&](asio::error_code const& error) { REQUIRE(!error); // create accounts - auto txFrameA = root.tx({createAccount(a1, startingBalance)}); - auto txFrameB = root.tx({createAccount(b1, startingBalance)}); - auto txFrameC = root.tx({createAccount(c1, startingBalance)}); + auto txFrame = root.tx({createAccount(a1, startingBalance), + createAccount(b1, startingBalance), + createAccount(c1, startingBalance)}); - feedTx(txFrameA); - feedTx(txFrameB); - feedTx(txFrameC); + feedTx(txFrame, + TransactionQueue::AddResult::ADD_STATUS_PENDING); }; setupTimer.expires_from_now(std::chrono::seconds(0)); @@ -136,42 +136,53 @@ TEST_CASE_VERSIONS("standalone", "[herder][acceptance]") SECTION("txset with valid txs - but failing later") { + bool hasC = false; + { + LedgerTxn ltx(app->getLedgerTxnRoot()); + hasC = protocolVersionStartsFrom( + ltx.loadHeader().current().ledgerVersion, + ProtocolVersion::V_10); + } + std::vector txAs, txBs, txCs; txAs.emplace_back(a1.tx({payment(root, paymentAmount)})); - txAs.emplace_back(a1.tx({payment(root, paymentAmount)})); - txAs.emplace_back(a1.tx({payment(root, paymentAmount)})); - - txBs.emplace_back(b1.tx({payment(root, paymentAmount)})); - txBs.emplace_back(b1.tx({accountMerge(root)})); - txBs.emplace_back(b1.tx({payment(a1, paymentAmount)})); - - auto expectedC1Seq = c1.getLastSequenceNumber() + 10; - txCs.emplace_back(c1.tx({payment(root, paymentAmount)})); - txCs.emplace_back(c1.tx({bumpSequence(expectedC1Seq)})); - txCs.emplace_back(c1.tx({payment(root, paymentAmount)})); + txAs.emplace_back(b1.tx({payment(root, paymentAmount)})); + if (hasC) + { + txAs.emplace_back(c1.tx({payment(root, paymentAmount)})); + } for (auto a : txAs) { - feedTx(a); + feedTx(a, TransactionQueue::AddResult::ADD_STATUS_PENDING); } - for (auto b : txBs) + waitForExternalize(); + + txBs.emplace_back(a1.tx({payment(root, paymentAmount)})); + txBs.emplace_back(b1.tx({accountMerge(root)})); + auto expectedC1Seq = c1.getLastSequenceNumber() + 10; + if (hasC) { - feedTx(b); + txBs.emplace_back(c1.tx({bumpSequence(expectedC1Seq)})); } - bool hasC = false; + for (auto b : txBs) { - LedgerTxn ltx(app->getLedgerTxnRoot()); - hasC = protocolVersionStartsFrom( - ltx.loadHeader().current().ledgerVersion, - ProtocolVersion::V_10); + feedTx(b, TransactionQueue::AddResult::ADD_STATUS_PENDING); } + waitForExternalize(); + + txCs.emplace_back(a1.tx({payment(root, paymentAmount)})); + txCs.emplace_back(b1.tx({payment(a1, paymentAmount)})); + txCs.emplace_back(c1.tx({payment(root, paymentAmount)})); + + feedTx(txCs[0], + TransactionQueue::AddResult::ADD_STATUS_PENDING); + feedTx(txCs[1], TransactionQueue::AddResult::ADD_STATUS_ERROR); if (hasC) { - for (auto c : txCs) - { - feedTx(c); - } + feedTx(txCs[2], + TransactionQueue::AddResult::ADD_STATUS_ERROR); } waitForExternalize(); @@ -188,7 +199,7 @@ TEST_CASE_VERSIONS("standalone", "[herder][acceptance]") { // c1's last transaction failed due to wrong sequence number int64 expectedCBalance = - startingBalance - paymentAmount - 3 * txfee; + startingBalance - paymentAmount - 2 * txfee; REQUIRE(c1.getBalance() == expectedCBalance); REQUIRE(c1.loadSequenceNumber() == expectedC1Seq); } @@ -280,17 +291,21 @@ static void testTxSet(uint32 protocolVersion) { Config cfg(getTestConfig()); - cfg.TESTING_UPGRADE_MAX_TX_SET_SIZE = 14; + cfg.TESTING_UPGRADE_MAX_TX_SET_SIZE = 15; cfg.LEDGER_PROTOCOL_VERSION = protocolVersion; cfg.TESTING_UPGRADE_LEDGER_PROTOCOL_VERSION = protocolVersion; VirtualClock clock; Application::pointer app = createTestApplication(clock, cfg); + bool uniqueAccounts = + protocolVersion >= + static_cast(GENERALIZED_TX_SET_PROTOCOL_VERSION); // set up world auto root = TestAccount::createRoot(*app); - const int nbAccounts = 2; - const int nbTransactions = 5; + const int nbAccounts = 3; + // Post protocol 20, multiple transactions per accounts aren't allowed + const int nbTransactions = uniqueAccounts ? 1 : 5; auto accounts = std::vector{}; @@ -318,7 +333,7 @@ testTxSet(uint32 protocolVersion) SECTION("valid set") { auto txSet = TxSetFrame::makeFromTransactions(txs, *app, 0, 0); - REQUIRE(txSet->sizeTxTotal() == (2 * nbTransactions)); + REQUIRE(txSet->sizeTxTotal() == (nbAccounts * nbTransactions)); } SECTION("too many txs") @@ -340,7 +355,7 @@ testTxSet(uint32 protocolVersion) auto txSet = TxSetFrame::makeFromTransactions(txs, *app, 0, 0, removed); REQUIRE(removed.size() == 1); - REQUIRE(txSet->sizeTxTotal() == (2 * nbTransactions)); + REQUIRE(txSet->sizeTxTotal() == (nbAccounts * nbTransactions)); } SECTION("sequence gap") { @@ -354,7 +369,7 @@ testTxSet(uint32 protocolVersion) auto txSet = TxSetFrame::makeFromTransactions(txs, *app, 0, 0, removed); REQUIRE(removed.size() == 1); - REQUIRE(txSet->sizeTxTotal() == (2 * nbTransactions)); + REQUIRE(txSet->sizeTxTotal() == (nbAccounts * nbTransactions)); } SECTION("gap begin") { @@ -366,23 +381,30 @@ testTxSet(uint32 protocolVersion) // one of the account lost all its transactions REQUIRE(removed.size() == (nbTransactions - 1)); - REQUIRE(txSet->sizeTxTotal() == nbTransactions); + REQUIRE(txSet->sizeTxTotal() == + nbTransactions * (nbAccounts - 1)); } SECTION("gap middle") { - int remIdx = 2; // 3rd transaction from the first account - txs.erase(txs.begin() + remIdx); + // Gap in the middle only makes sense if we allow multiple txs + // per account + if (!uniqueAccounts) + { + int remIdx = 2; // 3rd transaction from the first account + txs.erase(txs.begin() + remIdx); - TxSetFrame::Transactions removed; - auto txSet = - TxSetFrame::makeFromTransactions(txs, *app, 0, 0, removed); + TxSetFrame::Transactions removed; + auto txSet = TxSetFrame::makeFromTransactions(txs, *app, 0, + 0, removed); - // one account has all its transactions, - // the other, we removed transactions after remIdx - auto expectedRemoved = nbTransactions - remIdx - 1; - REQUIRE(removed.size() == expectedRemoved); - REQUIRE(txSet->sizeTxTotal() == - (nbTransactions * 2 - expectedRemoved - 1)); + // one account has all its transactions, + // the other, we removed transactions after remIdx + auto expectedRemoved = nbTransactions - remIdx - 1; + REQUIRE(removed.size() == expectedRemoved); + REQUIRE( + txSet->sizeTxTotal() == + (nbTransactions * nbAccounts - expectedRemoved - 1)); + } } } SECTION("insufficient balance") @@ -394,7 +416,7 @@ testTxSet(uint32 protocolVersion) auto txSet = TxSetFrame::makeFromTransactions(txs, *app, 0, 0, removed); REQUIRE(removed.size() == (nbTransactions + 1)); - REQUIRE(txSet->sizeTxTotal() == nbTransactions); + REQUIRE(txSet->sizeTxTotal() == nbTransactions * (nbAccounts - 1)); } SECTION("bad signature") { @@ -405,7 +427,7 @@ testTxSet(uint32 protocolVersion) auto txSet = TxSetFrame::makeFromTransactions(txs, *app, 0, 0, removed); REQUIRE(removed.size() == nbTransactions); - REQUIRE(txSet->sizeTxTotal() == nbTransactions); + REQUIRE(txSet->sizeTxTotal() == nbTransactions * (nbAccounts - 1)); } } } @@ -708,6 +730,14 @@ TEST_CASE_VERSIONS("txset with PreconditionsV2", "[herder][txset]") SECTION("minSeqNum gap") { + { + LedgerTxn ltx(app->getLedgerTxnRoot()); + if (ltx.loadHeader().current().ledgerVersion >= + static_cast(GENERALIZED_TX_SET_PROTOCOL_VERSION)) + { + return; + } + } auto minSeqNumCond = [](SequenceNumber seqNum) { PreconditionsV2 cond; cond.minSeqNum.activate() = seqNum; @@ -735,6 +765,14 @@ TEST_CASE_VERSIONS("txset with PreconditionsV2", "[herder][txset]") } SECTION("minSeqLedgerGap") { + { + LedgerTxn ltx(app->getLedgerTxnRoot()); + if (ltx.loadHeader().current().ledgerVersion >= + static_cast(GENERALIZED_TX_SET_PROTOCOL_VERSION)) + { + return; + } + } auto minSeqLedgerGapCond = [](uint32_t minSeqLedgerGap) { PreconditionsV2 cond; cond.minSeqLedgerGap = minSeqLedgerGap; @@ -1370,6 +1408,11 @@ static void surgeTest(uint32 protocolVersion, uint32_t nbTxs, uint32_t maxTxSetSize, uint32_t expectedReduced) { + if (protocolVersion >= + static_cast(GENERALIZED_TX_SET_PROTOCOL_VERSION)) + { + throw std::runtime_error("Surge test does not apply post protocol 19"); + } Config cfg(getTestConfig()); cfg.TESTING_UPGRADE_MAX_TX_SET_SIZE = maxTxSetSize; cfg.TESTING_UPGRADE_LEDGER_PROTOCOL_VERSION = protocolVersion; @@ -1510,10 +1553,10 @@ surgeTest(uint32 protocolVersion, uint32_t nbTxs, uint32_t maxTxSetSize, TEST_CASE("surge pricing", "[herder][txset]") { - SECTION("protocol current") + SECTION("protocol 19") { // (1+..+4) + (1+2) = 10+3 = 13 - surgeTest(Config::CURRENT_LEDGER_PROTOCOL_VERSION, 5, 15, 13); + surgeTest(19, 5, 15, 13); } SECTION("max 0 ops per ledger") { @@ -1581,8 +1624,12 @@ TEST_CASE("surge pricing", "[herder][txset]") auto acc3 = root.create("account3", 500000000); auto acc4 = root.create("account4", 500000000); auto acc5 = root.create("account5", 500000000); - std::vector accounts = {root, acc1, acc2, - acc3, acc4, acc5}; + auto acc6 = root.create("account6", 500000000); + + // Ensure these accounts don't overlap with classic tx (with root source + // account) + std::vector accounts = {acc1, acc2, acc3, + acc4, acc5, acc6}; // Valid classic auto tx = makeMultiPayment(acc1, root, 1, 100, 0, 1); @@ -1837,17 +1884,20 @@ TEST_CASE("surge pricing with DEX separation", "[herder][txset]") auto accountA = root.create("accountA", 5000000000); auto accountB = root.create("accountB", 5000000000); auto accountC = root.create("accountC", 5000000000); + auto accountD = root.create("accountD", 5000000000); auto seqNumA = accountA.getLastSequenceNumber(); auto seqNumB = accountB.getLastSequenceNumber(); auto seqNumC = accountC.getLastSequenceNumber(); + auto seqNumD = accountD.getLastSequenceNumber(); auto runTest = [&](std::vector const& txs, size_t expectedTxsA, size_t expectedTxsB, - size_t expectedTxsC, int64_t expectedNonDexBaseFee, + size_t expectedTxsC, size_t expectedTxsD, + int64_t expectedNonDexBaseFee, int64_t expectedDexBaseFee) { auto txSet = TxSetFrame::makeFromTransactions(txs, *app, 0, 0); - size_t cntA = 0, cntB = 0, cntC = 0; + size_t cntA = 0, cntB = 0, cntC = 0, cntD = 0; auto resTxs = txSet->getTxsInApplyOrder(); for (auto const& tx : resTxs) { @@ -1869,6 +1919,13 @@ TEST_CASE("surge pricing with DEX separation", "[herder][txset]") ++seqNumC; REQUIRE(seqNumC == tx->getSeqNum()); } + if (tx->getSourceID() == accountD.getPublicKey()) + { + ++cntD; + ++seqNumD; + REQUIRE(seqNumD == tx->getSeqNum()); + } + auto baseFee = txSet->getTxBaseFee(tx, lhCopy); REQUIRE(baseFee); if (tx->hasDexOperations()) @@ -1883,6 +1940,7 @@ TEST_CASE("surge pricing with DEX separation", "[herder][txset]") REQUIRE(cntA == expectedTxsA); REQUIRE(cntB == expectedTxsB); REQUIRE(cntC == expectedTxsC); + REQUIRE(cntD == expectedTxsD); }; auto nonDexTx = [](TestAccount& account, uint32 nbOps, uint32_t opFee) { @@ -1891,205 +1949,95 @@ TEST_CASE("surge pricing with DEX separation", "[herder][txset]") auto dexTx = [&](TestAccount& account, uint32 nbOps, uint32_t opFee) { return createSimpleDexTx(*app, account, nbOps, opFee * nbOps); }; - - SECTION("single account") + SECTION("only non-DEX txs") { - SECTION("only non DEX txs") - { - runTest({nonDexTx(accountA, 3, 200), nonDexTx(accountA, 4, 120), - nonDexTx(accountA, 2, 150), nonDexTx(accountA, 5, 250), - /* cutoff */ nonDexTx(accountA, 2, 300), - nonDexTx(accountA, 1, 500)}, - 4, 0, 0, 120, 0); - } - SECTION("only DEX txs") - { - runTest({dexTx(accountA, 3, 200), dexTx(accountA, 1, 120), - /* cutoff */ - dexTx(accountA, 2, 150), dexTx(accountA, 1, 300)}, - 2, 0, 0, 0, 120); - } - SECTION("mixed txs") + runTest({nonDexTx(accountA, 8, 200), nonDexTx(accountB, 4, 300), + nonDexTx(accountC, 2, 400), + /* cutoff */ + nonDexTx(accountD, 2, 100)}, + 1, 1, 1, 0, 200, 0); + } + SECTION("only DEX txs") + { + runTest({dexTx(accountA, 2, 200), dexTx(accountB, 1, 300), + dexTx(accountC, 2, 400), + /* cutoff */ + dexTx(accountD, 1, 100)}, + 1, 1, 1, 0, 0, 200); + } + SECTION("mixed txs") + { + SECTION("only DEX surge priced") { - SECTION("only DEX surge priced") + SECTION("DEX limit reached") { - SECTION("DEX limit reached") - { - runTest( - {/* 5 non-DEX ops + 4 DEX ops = 9 ops */ - nonDexTx(accountA, 2, 200), dexTx(accountA, 4, 250), - nonDexTx(accountA, 1, 150), - /* cutoff */ dexTx(accountA, 2, 150), - nonDexTx(accountA, 1, 500)}, - 3, 0, 0, 100, 250); - } - SECTION("both limits reached") - { - // DEX tx didn't fit into both DEX and global limits, but - // there are no remaining non-DEX txs to activate surge - // pricing for them. - runTest( - { - /* 10 non-DEX ops + 4 DEX ops = 14 ops */ - nonDexTx(accountA, 10, 200), - dexTx(accountA, 4, 250), - /* cutoff */ - dexTx(accountA, 2, 300), - nonDexTx(accountA, 1, 500), - }, - 2, 0, 0, 100, 250); - } + runTest( + { + /* 6 non-DEX ops + 5 DEX ops = 11 ops */ + nonDexTx(accountA, 6, 100), + dexTx(accountB, 5, 400), + /* cutoff */ + dexTx(accountC, 1, 200), + dexTx(accountD, 1, 399), + }, + 1, 1, 0, 0, 100, 400); } - SECTION("both DEX and non-dex surge priced") + SECTION("both limits reached, but only DEX evicted") { - SECTION("non-DEX fee is lowest") - { - runTest( - { - /* 8 non-DEX ops + 4 DEX ops = 12 ops */ - nonDexTx(accountA, 3, 200), - dexTx(accountA, 4, 250), - nonDexTx(accountA, 5, 150), - /* cutoff */ - nonDexTx(accountA, 4, 500), - dexTx(accountA, 2, 150), - }, - 3, 0, 0, 150, 150); - } - SECTION("DEX fee is lowest") - { - runTest( - { - /* 8 non-DEX ops + 4 DEX ops = 12 ops */ - nonDexTx(accountA, 3, 200), - dexTx(accountA, 4, 150), - nonDexTx(accountA, 5, 250), - /* cutoff */ - nonDexTx(accountA, 4, 500), - dexTx(accountA, 2, 150), - }, - 3, 0, 0, 150, 150); - } + runTest( + { + /* 10 non-DEX ops + 5 DEX ops = 15 ops */ + nonDexTx(accountA, 10, 100), + dexTx(accountB, 5, 400), + /* cutoff */ + dexTx(accountC, 1, 399), + dexTx(accountD, 1, 399), + }, + 1, 1, 0, 0, 100, 400); } } - } - - SECTION("multiple accounts") - { - SECTION("only non-DEX txs") - { - // Last 3 txs do not fit into limit and activate surge pricing. - runTest({nonDexTx(accountA, 3, 200), nonDexTx(accountA, 5, 250), - nonDexTx(accountB, 4, 300), nonDexTx(accountC, 2, 400), - /* cutoff */ - nonDexTx(accountA, 2, 500), nonDexTx(accountB, 2, 180), - nonDexTx(accountC, 2, 100)}, - 2, 1, 1, 200, 0); - } - SECTION("only DEX txs") + SECTION("all txs surge priced") { - // Last two txs do not fit into DEX ops limit and activate surge - // pricing. - runTest({dexTx(accountA, 1, 200), dexTx(accountA, 1, 250), - dexTx(accountB, 1, 300), dexTx(accountC, 2, 400), - /* cutoff */ - dexTx(accountA, 4, 500), dexTx(accountB, 1, 180), - dexTx(accountC, 1, 100)}, - 2, 1, 1, 0, 200); - } - SECTION("mixed txs") - { - SECTION("only DEX surge priced") + SECTION("only global limit reached") { - SECTION("DEX limit reached") - { - runTest( - { - /* 6 non-DEX ops + 5 DEX ops = 11 ops */ - nonDexTx(accountA, 1, 300), - dexTx(accountA, 2, 400), - dexTx(accountB, 1, 300), - nonDexTx(accountB, 2, 400), - dexTx(accountC, 2, 250), - nonDexTx(accountC, 3, 500), - /* cutoff */ - dexTx(accountA, 1, 200), - dexTx(accountB, 1, 200), - dexTx(accountC, 1, 249), - }, - 2, 2, 2, 100, 250); - } - SECTION("both limits reached, but only DEX evicted") + runTest( + { + /* 13 non-DEX ops + 2 DEX ops = 15 ops */ + nonDexTx(accountA, 13, 250), + dexTx(accountB, 2, 250), + /* cutoff */ + dexTx(accountC, 1, 200), + nonDexTx(accountD, 1, 249), + }, + 1, 1, 0, 0, 250, 250); + } + SECTION("both limits reached") + { + SECTION("non-DEX fee is lowest") { runTest( { /* 10 non-DEX ops + 5 DEX ops = 15 ops */ - nonDexTx(accountA, 2, 600), - dexTx(accountA, 3, 400), - nonDexTx(accountB, 3, 400), - dexTx(accountC, 2, 500), - nonDexTx(accountC, 5, 250), + nonDexTx(accountA, 10, 250), + dexTx(accountB, 5, 400), /* cutoff */ - dexTx(accountA, 1, 399), - dexTx(accountB, 1, 399), dexTx(accountC, 1, 399), + nonDexTx(accountD, 1, 249), }, - 2, 1, 2, 100, 400); + 1, 1, 0, 0, 250, 400); } - } - SECTION("all txs surge priced") - { - SECTION("only global limit reached") + SECTION("DEX fee is lowest") { runTest( { - /* 13 non-DEX ops + 2 DEX ops = 15 ops */ - nonDexTx(accountA, 6, 300), - dexTx(accountB, 1, 400), - nonDexTx(accountB, 3, 400), - nonDexTx(accountC, 4, 250), - dexTx(accountC, 1, 500), + /* 10 non-DEX ops + 5 DEX ops = 15 ops */ + nonDexTx(accountA, 10, 500), + dexTx(accountB, 5, 200), /* cutoff */ - dexTx(accountA, 1, 200), - nonDexTx(accountB, 1, 249), - dexTx(accountC, 1, 249), + dexTx(accountC, 1, 199), + nonDexTx(accountD, 1, 199), }, - 1, 2, 2, 250, 250); - } - SECTION("both limits reached") - { - SECTION("non-DEX fee is lowest") - { - runTest( - { - /* 10 non-DEX ops + 5 DEX ops = 15 ops */ - nonDexTx(accountA, 2, 600), - dexTx(accountA, 3, 400), - nonDexTx(accountB, 3, 400), - dexTx(accountC, 2, 500), - nonDexTx(accountC, 5, 250), - /* cutoff */ - dexTx(accountA, 1, 399), - nonDexTx(accountB, 1, 249), - }, - 2, 1, 2, 250, 400); - } - SECTION("DEX fee is lowest") - { - runTest( - { - /* 10 non-DEX ops + 5 DEX ops = 15 ops */ - dexTx(accountA, 3, 300), - nonDexTx(accountA, 2, 500), - nonDexTx(accountB, 3, 400), - dexTx(accountC, 2, 200), - nonDexTx(accountC, 5, 250), - /* cutoff */ - dexTx(accountA, 1, 199), - nonDexTx(accountB, 1, 199), - }, - 2, 1, 2, 200, 200); - } + 1, 1, 0, 0, 200, 200); } } } @@ -2345,7 +2293,7 @@ testSCPDriver(uint32 protocolVersion, uint32_t maxTxSetSize, size_t expectedOps) auto const& lcl = app->getLedgerManager().getLastClosedLedgerHeader(); auto root = TestAccount::createRoot(*app); - auto a1 = TestAccount{*app, getAccount("A")}; + std::vector accounts; using TxPair = std::pair; auto makeTxUpgradePair = [&](HerderImpl& herder, TxSetFrameConstPtr txSet, @@ -2383,10 +2331,18 @@ testSCPDriver(uint32 protocolVersion, uint32_t maxTxSetSize, size_t expectedOps) return envelope; }; auto makeTransactions = [&](int n, int nbOps, uint32 feeMulti) { - root.loadSequenceNumber(); std::vector txs(n); + while (accounts.size() < n) + { + std::string accountName = fmt::format("A{}", accounts.size()); + accounts.push_back(root.create(accountName.c_str(), 500000000)); + } + size_t index = 0; + std::generate(std::begin(txs), std::end(txs), [&]() { - return makeMultiPayment(root, root, nbOps, 1000, 0, feeMulti); + accounts[index].loadSequenceNumber(); + return makeMultiPayment(root, accounts[index++], nbOps, 1000, 0, + feeMulti); }); return TxSetFrame::makeFromTransactions(txs, *app, 0, 0); @@ -3361,10 +3317,7 @@ TEST_CASE("tx queue source account limit", "[herder][transactionqueue]") cfg.TESTING_UPGRADE_LEDGER_PROTOCOL_VERSION = mix ? static_cast(ProtocolVersion::V_19) : Config::CURRENT_LEDGER_PROTOCOL_VERSION; - if (!mix || i % 2 == 1) - { - cfg.LIMIT_TX_QUEUE_SOURCE_ACCOUNT = true; - } + cfg.LIMIT_TX_QUEUE_SOURCE_ACCOUNT = !mix || (i % 2 == 1); return cfg; }); @@ -4567,7 +4520,8 @@ TEST_CASE("do not flood too many transactions", "[herder][transactionqueue]") std::vector accs; // number of accounts to use - int const nbAccounts = 40; + size_t const maxOps = cfg.TESTING_UPGRADE_MAX_TX_SET_SIZE; + int const nbAccounts = maxOps; // number of transactions to generate per fee // groups are int const feeGroupMaxSize = 7; @@ -4576,6 +4530,7 @@ TEST_CASE("do not flood too many transactions", "[herder][transactionqueue]") uint32 curFeeOffset = 10000; accs.reserve(nbAccounts); + accs.emplace_back(root); for (int i = 0; i < nbAccounts; ++i) { accs.emplace_back( @@ -4615,18 +4570,20 @@ TEST_CASE("do not flood too many transactions", "[herder][transactionqueue]") return tx; }; - auto genTxRandAccount = [&](uint32_t numOps) { - genTx(rand_element(accs), numOps, false); + auto nextAccountIt = accs.begin(); + auto getNextAccountTx = [&](uint32_t numOps, bool highFee = false) { + REQUIRE(nextAccountIt != accs.end()); + auto tx = genTx(*nextAccountIt, numOps, highFee); + nextAccountIt++; + return tx; }; - size_t const maxOps = cfg.TESTING_UPGRADE_MAX_TX_SET_SIZE; - - auto tx1a = genTx(accs[0], numOps, false); - auto tx1r = genTx(root, numOps, false); + auto tx1a = getNextAccountTx(numOps); + auto tx1r = getNextAccountTx(numOps); size_t numTx = 2; for (; (numTx + 2) * numOps <= maxOps; ++numTx) { - genTxRandAccount(numOps); + getNextAccountTx(numOps); } std::map bcastTracker; @@ -4688,7 +4645,7 @@ TEST_CASE("do not flood too many transactions", "[herder][transactionqueue]") // from an account with no pending transactions // this transactions should be the next one to be broadcasted simulation->crankForAtLeast(std::chrono::milliseconds(500), false); - genTx(root, numOps, true); + getNextAccountTx(numOps, /* highFee */ true); simulation->crankForAtLeast(std::chrono::milliseconds(2000), false); REQUIRE(numBroadcast == (numTx - 1)); @@ -4754,7 +4711,8 @@ TEST_CASE("do not flood too many transactions with DEX separation", std::vector accs; // number of accounts to use - int const nbAccounts = 40; + int const nbAccounts = + app->getConfig().TESTING_UPGRADE_MAX_TX_SET_SIZE * 2; // number of transactions to generate per fee groups int const feeGroupMaxSize = 7; // used to track fee @@ -4822,9 +4780,11 @@ TEST_CASE("do not flood too many transactions with DEX separation", return tx; }; - auto genTxRandAccount = [&](bool isDex, uint32_t numOps) { - genTx(autocheck::generator()(nbAccounts - 3), isDex, numOps, - false); + auto nextAccountIdx = 0; + auto genNextAccountTx = [&](bool isDex, uint32_t numOps, + bool highFee = false) { + REQUIRE(nextAccountIdx < accs.size()); + return genTx(nextAccountIdx++, isDex, numOps, highFee); }; // Reserve 1 tx in each non-empty group to add in the middle of the @@ -4847,12 +4807,12 @@ TEST_CASE("do not flood too many transactions with DEX separation", (generatedNonDex >= nonDexTxs || boolGen()); if (isDex) { - genTxRandAccount(true, opsPerDexTx); + genNextAccountTx(true, opsPerDexTx); ++generatedDex; } else { - genTxRandAccount(false, opsPerNonDexTx); + genNextAccountTx(false, opsPerNonDexTx); ++generatedNonDex; } } @@ -4863,18 +4823,18 @@ TEST_CASE("do not flood too many transactions with DEX separation", { for (uint32_t i = 0; i < dexTxs; ++i) { - genTxRandAccount(true, opsPerDexTx); + genNextAccountTx(true, opsPerDexTx); } } for (uint32_t i = 0; i < nonDexTxs; ++i) { - genTxRandAccount(false, opsPerNonDexTx); + genNextAccountTx(false, opsPerNonDexTx); } if (!broadcastDexFirst) { for (uint32_t i = 0; i < dexTxs; ++i) { - genTxRandAccount(true, opsPerDexTx); + genNextAccountTx(true, opsPerDexTx); } } } @@ -4952,12 +4912,12 @@ TEST_CASE("do not flood too many transactions with DEX separation", if (dexTxs > 0) { ++dexTxs; - genTx(nbAccounts - 2, true, opsPerDexTx, true); + genNextAccountTx(true, opsPerDexTx, true); } if (nonDexTxs > 0) { ++nonDexTxs; - genTx(nbAccounts - 1, false, opsPerNonDexTx, true); + genNextAccountTx(false, opsPerNonDexTx, true); } } auto lastDexOpsBroadcasted = dexOpsBroadcasted; diff --git a/src/herder/test/PendingEnvelopesTests.cpp b/src/herder/test/PendingEnvelopesTests.cpp index ebd1045500..519c9a7141 100644 --- a/src/herder/test/PendingEnvelopesTests.cpp +++ b/src/herder/test/PendingEnvelopesTests.cpp @@ -35,7 +35,13 @@ TEST_CASE("PendingEnvelopes recvSCPEnvelope", "[herder]") auto& herder = static_cast(app->getHerder()); auto root = TestAccount::createRoot(*app); - auto a1 = TestAccount{*app, getAccount("A")}; + size_t numAccounts = 50; + std::vector accs; + for (size_t i = 0; i < numAccounts; i++) + { + accs.push_back(TestAccount{*app, getAccount("A" + std::to_string(i))}); + } + using TxPair = std::pair; auto makeTxPair = [&](TxSetFrameConstPtr txSet, uint64_t closeTime, StellarValueType svt) { @@ -61,10 +67,12 @@ TEST_CASE("PendingEnvelopes recvSCPEnvelope", "[herder]") herder.signEnvelope(s, envelope); return envelope; }; + size_t index = 0; auto makeTransactions = [&](Hash hash, int n) { + REQUIRE(n <= accs.size()); std::vector txs(n); std::generate(std::begin(txs), std::end(txs), - [&]() { return root.tx({createAccount(a1, 10000000)}); }); + [&]() { return accs[index++].tx({payment(root, 1)}); }); return TxSetFrame::makeFromTransactions(txs, *app, 0, 0); }; @@ -102,7 +110,7 @@ TEST_CASE("PendingEnvelopes recvSCPEnvelope", "[herder]") } auto bigQSetHash = sha256(xdr::xdr_to_opaque(bigQSet)); - auto txSet = makeTransactions(lcl.hash, 50); + auto txSet = makeTransactions(lcl.hash, numAccounts); auto p = makeTxPair(txSet, 10, STELLAR_VALUE_SIGNED); auto saneEnvelope = makeEnvelope(p, saneQSetHash, lcl.header.ledgerSeq + 1); auto bigEnvelope = makeEnvelope(p, bigQSetHash, lcl.header.ledgerSeq + 1); diff --git a/src/herder/test/TransactionQueueTests.cpp b/src/herder/test/TransactionQueueTests.cpp index a4ac05a70d..f9b6b1323a 100644 --- a/src/herder/test/TransactionQueueTests.cpp +++ b/src/herder/test/TransactionQueueTests.cpp @@ -804,6 +804,9 @@ TEST_CASE("TransactionQueue hitting the rate limit", auto account1 = root.create("a1", minBalance2); auto account2 = root.create("a2", minBalance2); auto account3 = root.create("a3", minBalance2); + auto account4 = root.create("a4", minBalance2); + auto account5 = root.create("a5", minBalance2); + auto account6 = root.create("a6", minBalance2); TransactionQueueTest testQueue{*app}; std::vector txs; @@ -814,46 +817,48 @@ TEST_CASE("TransactionQueue hitting the rate limit", // Fill the queue/limiter with 8 ops (2 * 4) - any further ops should result // in eviction (limit is 2 * 4=TESTING_UPGRADE_MAX_TX_SET_SIZE). addTx(transaction(*app, account1, 1, 1, 200 * 1, 1)); - addTx(transaction(*app, account1, 2, 1, 400 * 2, 2)); - addTx(transaction(*app, account1, 3, 1, 100 * 1, 1)); - addTx(transaction(*app, account2, 1, 1, 300 * 4, 4)); + addTx(transaction(*app, account2, 1, 1, 400 * 2, 2)); + addTx(transaction(*app, account3, 1, 1, 100 * 1, 1)); + addTx(transaction(*app, account4, 1, 1, 300 * 4, 4)); SECTION("cannot add low fee tx") { - auto tx = transaction(*app, account3, 1, 1, 300 * 3, 3); + auto tx = transaction(*app, account5, 1, 1, 300 * 3, 3); testQueue.add(tx, TransactionQueue::AddResult::ADD_STATUS_ERROR); REQUIRE(tx->getResult().result.code() == txINSUFFICIENT_FEE); REQUIRE(tx->getResult().feeCharged == 300 * 3 + 1); } SECTION("add high fee tx with eviction") { - auto tx = transaction(*app, account3, 1, 1, 300 * 3 + 1, 3); + auto tx = transaction(*app, account5, 1, 1, 300 * 3 + 1, 3); testQueue.add(tx, TransactionQueue::AddResult::ADD_STATUS_PENDING); - // Evict all txs from `account1` as `tx[2]` can't be applied - // after `tx[1]` is evicted. + // Evict txs from `account1`, `account3` and `account4` testQueue.check( - {{{account1}, {account2, 0, {txs[3]}}, {account3, 0, {tx}}}, - {{txs[0], txs[1], txs[2]}, {}}}); + {{{account1}, {account2, 0, {txs[1]}}, {account5, 0, {tx}}}, + {{txs[0], txs[2], txs[3]}, {}}}); SECTION("then cannot add tx with lower fee than evicted") { - auto nextTx = transaction(*app, account3, 2, 1, 200, 1); + auto nextTx = transaction(*app, account6, 1, 1, 300, 1); testQueue.add(nextTx, TransactionQueue::AddResult::ADD_STATUS_ERROR); REQUIRE(nextTx->getResult().result.code() == txINSUFFICIENT_FEE); - REQUIRE(nextTx->getResult().feeCharged == 201); + REQUIRE(nextTx->getResult().feeCharged == 301); } SECTION("then add tx with higher fee than evicted") { // The last evicted fee rate we accounted for was 200 (tx with fee // rate 400 is evicted due to seq num and is not accounted for). - auto nextTx = transaction(*app, account3, 2, 1, 201, 1); + auto nextTx = transaction(*app, account6, 1, 1, 301, 1); testQueue.add(nextTx, TransactionQueue::AddResult::ADD_STATUS_PENDING); testQueue.check({{{account1}, - {account2, 0, {txs[3]}}, - {account3, 0, {tx, nextTx}}}, - {{txs[0], txs[1], txs[2]}, {}}}); + {account2, 0, {txs[1]}}, + {account3}, + {account4}, + {account5, 0, {tx}}, + {account6, 0, {nextTx}}}, + {{txs[0], txs[2], txs[3]}, {}}}); } } } @@ -865,493 +870,459 @@ TEST_CASE_VERSIONS("TransactionQueue with PreconditionsV2", auto cfg = getTestConfig(); cfg.TESTING_UPGRADE_MAX_TX_SET_SIZE = 4; cfg.FLOOD_TX_PERIOD_MS = 100; + cfg.TESTING_UPGRADE_LEDGER_PROTOCOL_VERSION = 19; + cfg.LIMIT_TX_QUEUE_SOURCE_ACCOUNT = false; auto app = createTestApplication(clock, cfg); auto const minBalance2 = app->getLedgerManager().getLastMinBalance(2); + // Not applicable for version 20 and onwards due to source account limit in + // tx queue - for_versions_from(19, *app, [&] { - auto root = TestAccount::createRoot(*app); - auto account1 = root.create("a1", minBalance2); - auto account2 = root.create("a2", minBalance2); + auto root = TestAccount::createRoot(*app); + auto account1 = root.create("a1", minBalance2); + auto account2 = root.create("a2", minBalance2); - // use bumpSequence to update account1's seqLedger - account1.bumpSequence(1); + // use bumpSequence to update account1's seqLedger + account1.bumpSequence(1); - auto txSeqA1S1 = transaction(*app, account1, 1, 1, 200); - auto txSeqA1S2 = transaction(*app, account1, 2, 1, 200); - auto txSeqA1S6 = transaction(*app, account1, 6, 1, 200); + auto txSeqA1S1 = transaction(*app, account1, 1, 1, 200); + auto txSeqA1S2 = transaction(*app, account1, 2, 1, 200); + auto txSeqA1S6 = transaction(*app, account1, 6, 1, 200); - PreconditionsV2 condMinSeqNum; - condMinSeqNum.minSeqNum.activate() = 2; + PreconditionsV2 condMinSeqNum; + condMinSeqNum.minSeqNum.activate() = 2; - auto txSeqA1S5MinSeqNum = transactionWithV2Precondition( - *app, account1, 5, 200, condMinSeqNum); + auto txSeqA1S5MinSeqNum = + transactionWithV2Precondition(*app, account1, 5, 200, condMinSeqNum); - auto txSeqA1S4MinSeqNum = transactionWithV2Precondition( - *app, account1, 4, 200, condMinSeqNum); + auto txSeqA1S4MinSeqNum = + transactionWithV2Precondition(*app, account1, 4, 200, condMinSeqNum); - auto txSeqA1S8MinSeqNum = transactionWithV2Precondition( - *app, account1, 8, 200, condMinSeqNum); + auto txSeqA1S8MinSeqNum = + transactionWithV2Precondition(*app, account1, 8, 200, condMinSeqNum); - PreconditionsV2 condMinSeqAge; - condMinSeqAge.minSeqAge = 1; - auto txSeqA1S3MinSeqAge = transactionWithV2Precondition( - *app, account1, 3, 200, condMinSeqAge); + PreconditionsV2 condMinSeqAge; + condMinSeqAge.minSeqAge = 1; + auto txSeqA1S3MinSeqAge = + transactionWithV2Precondition(*app, account1, 3, 200, condMinSeqAge); - PreconditionsV2 condMinSeqLedgerGap; - condMinSeqLedgerGap.minSeqLedgerGap = 1; - auto txSeqA1S3MinSeqLedgerGap = transactionWithV2Precondition( - *app, account1, 3, 200, condMinSeqLedgerGap); + PreconditionsV2 condMinSeqLedgerGap; + condMinSeqLedgerGap.minSeqLedgerGap = 1; + auto txSeqA1S3MinSeqLedgerGap = transactionWithV2Precondition( + *app, account1, 3, 200, condMinSeqLedgerGap); + + SECTION("gap valid due to minSeqNum") + { + TransactionQueueTest test{*app}; + test.add(txSeqA1S1, TransactionQueue::AddResult::ADD_STATUS_PENDING); - SECTION("gap valid due to minSeqNum") { - TransactionQueueTest test{*app}; - test.add(txSeqA1S1, - TransactionQueue::AddResult::ADD_STATUS_PENDING); + // Try tx with a minSeqNum that's not low enough + PreconditionsV2 cond; + cond.minSeqNum.activate() = account1.getLastSequenceNumber() + 2; + auto tx = + transactionWithV2Precondition(*app, account1, 5, 200, cond); - { - // Try tx with a minSeqNum that's not low enough - PreconditionsV2 cond; - cond.minSeqNum.activate() = - account1.getLastSequenceNumber() + 2; - auto tx = - transactionWithV2Precondition(*app, account1, 5, 200, cond); + test.add(tx, TransactionQueue::AddResult::ADD_STATUS_ERROR); + } - test.add(tx, TransactionQueue::AddResult::ADD_STATUS_ERROR); - } + test.add(txSeqA1S5MinSeqNum, + TransactionQueue::AddResult::ADD_STATUS_PENDING); + test.add(txSeqA1S6, TransactionQueue::AddResult::ADD_STATUS_PENDING); - test.add(txSeqA1S5MinSeqNum, - TransactionQueue::AddResult::ADD_STATUS_PENDING); - test.add(txSeqA1S6, - TransactionQueue::AddResult::ADD_STATUS_PENDING); + // make sure duplicates are identified correctly + test.add(txSeqA1S1, TransactionQueue::AddResult::ADD_STATUS_DUPLICATE); + test.add(txSeqA1S5MinSeqNum, + TransactionQueue::AddResult::ADD_STATUS_DUPLICATE); + test.add(txSeqA1S6, TransactionQueue::AddResult::ADD_STATUS_DUPLICATE); - // make sure duplicates are identified correctly - test.add(txSeqA1S1, - TransactionQueue::AddResult::ADD_STATUS_DUPLICATE); - test.add(txSeqA1S5MinSeqNum, - TransactionQueue::AddResult::ADD_STATUS_DUPLICATE); - test.add(txSeqA1S6, - TransactionQueue::AddResult::ADD_STATUS_DUPLICATE); + // try to fill in gap with a tx + test.add(txSeqA1S2, TransactionQueue::AddResult::ADD_STATUS_ERROR); - // try to fill in gap with a tx - test.add(txSeqA1S2, TransactionQueue::AddResult::ADD_STATUS_ERROR); + // try to fill in gap with a minSeqNum tx + test.add(txSeqA1S4MinSeqNum, + TransactionQueue::AddResult::ADD_STATUS_ERROR); - // try to fill in gap with a minSeqNum tx - test.add(txSeqA1S4MinSeqNum, - TransactionQueue::AddResult::ADD_STATUS_ERROR); + test.check({{{account1, 0, {txSeqA1S1, txSeqA1S5MinSeqNum, txSeqA1S6}}, + {account2}}, + {}}); - test.check( - {{{account1, 0, {txSeqA1S1, txSeqA1S5MinSeqNum, txSeqA1S6}}, - {account2}}, - {}}); + // fee bump the existing minSeqNum tx + auto fb = feeBump(*app, account1, txSeqA1S5MinSeqNum, 4000); + test.add(fb, TransactionQueue::AddResult::ADD_STATUS_PENDING); - // fee bump the existing minSeqNum tx - auto fb = feeBump(*app, account1, txSeqA1S5MinSeqNum, 4000); - test.add(fb, TransactionQueue::AddResult::ADD_STATUS_PENDING); + test.check( + {{{account1, 0, {txSeqA1S1, fb, txSeqA1S6}}, {account2}}, {}}); - test.check( - {{{account1, 0, {txSeqA1S1, fb, txSeqA1S6}}, {account2}}, {}}); + // fee bump a new minSeqNum tx + auto fb2 = feeBump(*app, account1, txSeqA1S8MinSeqNum, 400); + test.add(fb2, TransactionQueue::AddResult::ADD_STATUS_PENDING); - // fee bump a new minSeqNum tx - auto fb2 = feeBump(*app, account1, txSeqA1S8MinSeqNum, 400); - test.add(fb2, TransactionQueue::AddResult::ADD_STATUS_PENDING); + test.check( + {{{account1, 0, {txSeqA1S1, fb, txSeqA1S6, fb2}}, {account2}}, {}}); - test.check( - {{{account1, 0, {txSeqA1S1, fb, txSeqA1S6, fb2}}, {account2}}, - {}}); + SECTION("removeApplied") + { + // seqNum=2 and below should be removed here + test.removeApplied({txSeqA1S2}); + test.check({{{account1, 0, {fb, txSeqA1S6, fb2}}, {account2}}, + {{txSeqA1S2}, {}}}); + + // seqNum=4. No change + test.removeApplied({txSeqA1S4MinSeqNum}, true); + test.check({{{account1, 0, {fb, txSeqA1S6, fb2}}, {account2}}, + {{txSeqA1S2, txSeqA1S4MinSeqNum}, {}}}); + + // seqNum=5 and below should be removed here + test.removeApplied({fb}); + test.check({{{account1, 0, {txSeqA1S6, fb2}}, {account2}}, + {{txSeqA1S2, txSeqA1S4MinSeqNum, fb}, {}}}); - SECTION("removeApplied") + SECTION("removeApplied last tx") { - // seqNum=2 and below should be removed here - test.removeApplied({txSeqA1S2}); - test.check({{{account1, 0, {fb, txSeqA1S6, fb2}}, {account2}}, - {{txSeqA1S2}, {}}}); - - // seqNum=4. No change - test.removeApplied({txSeqA1S4MinSeqNum}, true); - test.check({{{account1, 0, {fb, txSeqA1S6, fb2}}, {account2}}, - {{txSeqA1S2, txSeqA1S4MinSeqNum}, {}}}); - - // seqNum=5 and below should be removed here - test.removeApplied({fb}); - test.check({{{account1, 0, {txSeqA1S6, fb2}}, {account2}}, - {{txSeqA1S2, txSeqA1S4MinSeqNum, fb}, {}}}); - - SECTION("removeApplied last tx") - { - // seqNum=8 and below should be removed here - test.removeApplied({fb2}); - test.check( - {{{account1, 0, {}}, {account2}}, - {{txSeqA1S2, txSeqA1S4MinSeqNum, fb, fb2}, {}}}); - } - SECTION("removeApplied past last tx") - { - // seqNum=9 and below should be removed here - auto txSeqA1S9 = transaction(*app, account1, 9, 1, 200); - test.removeApplied({txSeqA1S9}); - test.check( - {{{account1, 0, {}}, {account2}}, - {{txSeqA1S2, txSeqA1S4MinSeqNum, fb, txSeqA1S9}, {}}}); - } + // seqNum=8 and below should be removed here + test.removeApplied({fb2}); + test.check({{{account1, 0, {}}, {account2}}, + {{txSeqA1S2, txSeqA1S4MinSeqNum, fb, fb2}, {}}}); } - SECTION("ban") + SECTION("removeApplied past last tx") { - SECTION("ban first tx") - { - test.ban({txSeqA1S1}); - test.check({{{account1, 0, {}}, {account2}}, - {{txSeqA1S1, fb, txSeqA1S6, fb2}}}); - } - SECTION("ban missing tx") - { - test.ban({txSeqA1S2}); - // no queue change - test.check({{{account1, 0, {txSeqA1S1, fb, txSeqA1S6, fb2}}, - {account2}}, - {{txSeqA1S2}}}); - } - SECTION("ban existing tx with larger seqnum first, missing tx " - "second") - { - test.ban({fb, txSeqA1S2}); - test.check({{{account1, 0, {txSeqA1S1}}, {account2}}, - {{txSeqA1S2, fb, txSeqA1S6, fb2}}}); - } + // seqNum=9 and below should be removed here + auto txSeqA1S9 = transaction(*app, account1, 9, 1, 200); + test.removeApplied({txSeqA1S9}); + test.check( + {{{account1, 0, {}}, {account2}}, + {{txSeqA1S2, txSeqA1S4MinSeqNum, fb, txSeqA1S9}, {}}}); } } - SECTION("fee bump new tx with minSeqNum past lastSeq") + SECTION("ban") { - PreconditionsV2 cond; - cond.minSeqNum.activate() = account1.getLastSequenceNumber() + 2; - auto tx = - transactionWithV2Precondition(*app, account1, 5, 200, cond); - - TransactionQueueTest test{*app}; - test.add(tx, TransactionQueue::AddResult::ADD_STATUS_ERROR); + SECTION("ban first tx") + { + test.ban({txSeqA1S1}); + test.check({{{account1, 0, {}}, {account2}}, + {{txSeqA1S1, fb, txSeqA1S6, fb2}}}); + } + SECTION("ban missing tx") + { + test.ban({txSeqA1S2}); + // no queue change + test.check({{{account1, 0, {txSeqA1S1, fb, txSeqA1S6, fb2}}, + {account2}}, + {{txSeqA1S2}}}); + } + SECTION("ban existing tx with larger seqnum first, missing tx " + "second") + { + test.ban({fb, txSeqA1S2}); + test.check({{{account1, 0, {txSeqA1S1}}, {account2}}, + {{txSeqA1S2, fb, txSeqA1S6, fb2}}}); + } } - SECTION("fee bump only existing tx") - { - PreconditionsV2 cond; - cond.minSeqNum.activate() = 2; - auto tx = - transactionWithV2Precondition(*app, account1, 5, 200, cond); + } + SECTION("fee bump new tx with minSeqNum past lastSeq") + { + PreconditionsV2 cond; + cond.minSeqNum.activate() = account1.getLastSequenceNumber() + 2; + auto tx = transactionWithV2Precondition(*app, account1, 5, 200, cond); - TransactionQueueTest test{*app}; - test.add(tx, TransactionQueue::AddResult::ADD_STATUS_PENDING); + TransactionQueueTest test{*app}; + test.add(tx, TransactionQueue::AddResult::ADD_STATUS_ERROR); + } + SECTION("fee bump only existing tx") + { + PreconditionsV2 cond; + cond.minSeqNum.activate() = 2; + auto tx = transactionWithV2Precondition(*app, account1, 5, 200, cond); - auto fb = feeBump(*app, account1, tx, 4000); - test.add(fb, TransactionQueue::AddResult::ADD_STATUS_PENDING); + TransactionQueueTest test{*app}; + test.add(tx, TransactionQueue::AddResult::ADD_STATUS_PENDING); - test.check({{{account1, 0, {fb}}, {account2}}, {}}); - } - SECTION("fee bump existing tx and add minSeqNum") + auto fb = feeBump(*app, account1, tx, 4000); + test.add(fb, TransactionQueue::AddResult::ADD_STATUS_PENDING); + + test.check({{{account1, 0, {fb}}, {account2}}, {}}); + } + SECTION("fee bump existing tx and add minSeqNum") + { + TransactionQueueTest test{*app}; + test.add(txSeqA1S1, TransactionQueue::AddResult::ADD_STATUS_PENDING); + + PreconditionsV2 cond; + cond.minSeqNum.activate() = 2; + + auto tx = transactionWithV2Precondition(*app, account1, 1, 200, cond); + auto fb = feeBump(*app, account1, tx, 4000); + test.add(fb, TransactionQueue::AddResult::ADD_STATUS_PENDING); + + test.check({{{account1, 0, {fb}}, {account2}}, {}}); + } + SECTION("fee bump existing tx and remove minSeqNum") + { + TransactionQueueTest test{*app}; + + PreconditionsV2 cond; + cond.minSeqNum.activate() = 2; + + auto tx = transactionWithV2Precondition(*app, account1, 1, 200, cond); + test.add(tx, TransactionQueue::AddResult::ADD_STATUS_PENDING); + + auto fb = feeBump(*app, account1, txSeqA1S1, 4000); + test.add(fb, TransactionQueue::AddResult::ADD_STATUS_PENDING); + + test.check({{{account1, 0, {fb}}, {account2}}, {}}); + } + SECTION("Try invalidating preconditions with fee bump") + { + TransactionQueueTest test{*app}; + test.add(txSeqA1S1, TransactionQueue::AddResult::ADD_STATUS_PENDING); + test.add(txSeqA1S5MinSeqNum, + TransactionQueue::AddResult::ADD_STATUS_PENDING); + + // try removing minSeqNum from second tx { - TransactionQueueTest test{*app}; - test.add(txSeqA1S1, - TransactionQueue::AddResult::ADD_STATUS_PENDING); + auto txS5 = transaction(*app, account1, 5, 1, 200); + auto fb = feeBump(*app, account1, txS5, 4000); + test.add(fb, TransactionQueue::AddResult::ADD_STATUS_ERROR); + } + // add minSeqLedgerGap to second tx + { PreconditionsV2 cond; cond.minSeqNum.activate() = 2; + cond.minSeqLedgerGap = 1; auto tx = - transactionWithV2Precondition(*app, account1, 1, 200, cond); - auto fb = feeBump(*app, account1, tx, 4000); - test.add(fb, TransactionQueue::AddResult::ADD_STATUS_PENDING); + transactionWithV2Precondition(*app, account1, 5, 200, cond); - test.check({{{account1, 0, {fb}}, {account2}}, {}}); + auto fb = feeBump(*app, account1, tx, 4000); + test.add(fb, + TransactionQueue::AddResult::ADD_STATUS_TRY_AGAIN_LATER); } - SECTION("fee bump existing tx and remove minSeqNum") - { - TransactionQueueTest test{*app}; + // add minSeqAge to second tx + { PreconditionsV2 cond; cond.minSeqNum.activate() = 2; + cond.minSeqAge = 1; auto tx = - transactionWithV2Precondition(*app, account1, 1, 200, cond); - test.add(tx, TransactionQueue::AddResult::ADD_STATUS_PENDING); - - auto fb = feeBump(*app, account1, txSeqA1S1, 4000); - test.add(fb, TransactionQueue::AddResult::ADD_STATUS_PENDING); + transactionWithV2Precondition(*app, account1, 5, 200, cond); - test.check({{{account1, 0, {fb}}, {account2}}, {}}); + auto fb = feeBump(*app, account1, tx, 4000); + test.add(fb, + TransactionQueue::AddResult::ADD_STATUS_TRY_AGAIN_LATER); } - SECTION("Try invalidating preconditions with fee bump") - { - TransactionQueueTest test{*app}; - test.add(txSeqA1S1, - TransactionQueue::AddResult::ADD_STATUS_PENDING); - test.add(txSeqA1S5MinSeqNum, - TransactionQueue::AddResult::ADD_STATUS_PENDING); - - // try removing minSeqNum from second tx - { - auto txS5 = transaction(*app, account1, 5, 1, 200); - auto fb = feeBump(*app, account1, txS5, 4000); - test.add(fb, TransactionQueue::AddResult::ADD_STATUS_ERROR); - } - - // add minSeqLedgerGap to second tx - { - PreconditionsV2 cond; - cond.minSeqNum.activate() = 2; - cond.minSeqLedgerGap = 1; - auto tx = - transactionWithV2Precondition(*app, account1, 5, 200, cond); + test.check( + {{{account1, 0, {txSeqA1S1, txSeqA1S5MinSeqNum}}, {account2}}, {}}); + } + SECTION("remove unnecessary minSeqNum with feeBump") + { + TransactionQueueTest test{*app}; - auto fb = feeBump(*app, account1, tx, 4000); - test.add( - fb, - TransactionQueue::AddResult::ADD_STATUS_TRY_AGAIN_LATER); - } + test.add(txSeqA1S1, TransactionQueue::AddResult::ADD_STATUS_PENDING); - // add minSeqAge to second tx - { - PreconditionsV2 cond; - cond.minSeqNum.activate() = 2; - cond.minSeqAge = 1; + auto txSeqA1S2MinSeqNum = transactionWithV2Precondition( + *app, account1, 2, 200, condMinSeqNum); + test.add(txSeqA1S2MinSeqNum, + TransactionQueue::AddResult::ADD_STATUS_PENDING); - auto tx = - transactionWithV2Precondition(*app, account1, 5, 200, cond); + auto fb = feeBump(*app, account1, txSeqA1S2, 4000); + test.add(fb, TransactionQueue::AddResult::ADD_STATUS_PENDING); - auto fb = feeBump(*app, account1, tx, 4000); - test.add( - fb, - TransactionQueue::AddResult::ADD_STATUS_TRY_AGAIN_LATER); - } + test.check({{{account1, 0, {txSeqA1S1, fb}}, {account2}}, {}}); + } + SECTION("fee bump existing tx and add all preconditions") + { + // move lcl forward + closeLedgerOn(*app, 1, 1, 2022); + TransactionQueueTest test{*app}; + test.add(txSeqA1S1, TransactionQueue::AddResult::ADD_STATUS_PENDING); + test.add(txSeqA1S5MinSeqNum, + TransactionQueue::AddResult::ADD_STATUS_PENDING); - test.check( - {{{account1, 0, {txSeqA1S1, txSeqA1S5MinSeqNum}}, {account2}}, - {}}); - } - SECTION("remove unnecessary minSeqNum with feeBump") - { - TransactionQueueTest test{*app}; + PreconditionsV2 cond; + cond.minSeqAge = 1; + cond.minSeqLedgerGap = 1; + cond.minSeqNum.activate() = 1; - test.add(txSeqA1S1, - TransactionQueue::AddResult::ADD_STATUS_PENDING); + auto lclNum = app->getLedgerManager().getLastClosedLedgerNum(); + LedgerBounds bounds; + bounds.minLedger = lclNum + 1; + bounds.maxLedger = lclNum + 2; + cond.ledgerBounds.activate() = bounds; - auto txSeqA1S2MinSeqNum = transactionWithV2Precondition( - *app, account1, 2, 200, condMinSeqNum); - test.add(txSeqA1S2MinSeqNum, - TransactionQueue::AddResult::ADD_STATUS_PENDING); + auto tx = transactionWithV2Precondition(*app, account1, 1, 200, cond); - auto fb = feeBump(*app, account1, txSeqA1S2, 4000); - test.add(fb, TransactionQueue::AddResult::ADD_STATUS_PENDING); + auto fb = feeBump(*app, account1, tx, 4000); + test.add(fb, TransactionQueue::AddResult::ADD_STATUS_PENDING); - test.check({{{account1, 0, {txSeqA1S1, fb}}, {account2}}, {}}); - } - SECTION("fee bump existing tx and add all preconditions") - { - // move lcl forward - closeLedgerOn(*app, 1, 1, 2022); - TransactionQueueTest test{*app}; - test.add(txSeqA1S1, - TransactionQueue::AddResult::ADD_STATUS_PENDING); - test.add(txSeqA1S5MinSeqNum, - TransactionQueue::AddResult::ADD_STATUS_PENDING); + test.check({{{account1, 0, {fb, txSeqA1S5MinSeqNum}}, {account2}}, {}}); + } + SECTION("minSeqAge failed due to lower seqNum in queue") + { + TransactionQueueTest test{*app}; + test.add(txSeqA1S1, TransactionQueue::AddResult::ADD_STATUS_PENDING); + test.add(txSeqA1S2, TransactionQueue::AddResult::ADD_STATUS_PENDING); + test.add(txSeqA1S3MinSeqAge, + TransactionQueue::AddResult::ADD_STATUS_TRY_AGAIN_LATER); - PreconditionsV2 cond; - cond.minSeqAge = 1; - cond.minSeqLedgerGap = 1; - cond.minSeqNum.activate() = 1; + // submit as fee bump + auto fb = feeBump(*app, account1, txSeqA1S3MinSeqAge, 4000); + test.add(fb, TransactionQueue::AddResult::ADD_STATUS_TRY_AGAIN_LATER); - auto lclNum = app->getLedgerManager().getLastClosedLedgerNum(); - LedgerBounds bounds; - bounds.minLedger = lclNum + 1; - bounds.maxLedger = lclNum + 2; - cond.ledgerBounds.activate() = bounds; + test.check({{{account1, 0, {txSeqA1S1, txSeqA1S2}}, {account2}}, {}}); + } + SECTION("minSeqLedgerGap failed due to lower seqNum in queue") + { + TransactionQueueTest test{*app}; + test.add(txSeqA1S1, TransactionQueue::AddResult::ADD_STATUS_PENDING); + test.add(txSeqA1S2, TransactionQueue::AddResult::ADD_STATUS_PENDING); + test.add(txSeqA1S3MinSeqLedgerGap, + TransactionQueue::AddResult::ADD_STATUS_TRY_AGAIN_LATER); - auto tx = - transactionWithV2Precondition(*app, account1, 1, 200, cond); + // submit as fee bump + auto fb = feeBump(*app, account1, txSeqA1S3MinSeqLedgerGap, 4000); + test.add(fb, TransactionQueue::AddResult::ADD_STATUS_TRY_AGAIN_LATER); - auto fb = feeBump(*app, account1, tx, 4000); - test.add(fb, TransactionQueue::AddResult::ADD_STATUS_PENDING); + test.check({{{account1, 0, {txSeqA1S1, txSeqA1S2}}, {account2}}, {}}); + } + SECTION("minSeqLedgerGap uses next ledgerSeq for validation") + { + TransactionQueueTest test{*app}; + test.add(txSeqA1S1, TransactionQueue::AddResult::ADD_STATUS_PENDING); + test.add(txSeqA1S2, TransactionQueue::AddResult::ADD_STATUS_PENDING); + test.add(txSeqA1S3MinSeqLedgerGap, + TransactionQueue::AddResult::ADD_STATUS_TRY_AGAIN_LATER); + } + SECTION("first tx has minSeqAge set") + { + auto lastCloseTime = app->getLedgerManager() + .getLastClosedLedgerHeader() + .header.scpValue.closeTime; - test.check( - {{{account1, 0, {fb, txSeqA1S5MinSeqNum}}, {account2}}, {}}); - } - SECTION("minSeqAge failed due to lower seqNum in queue") - { - TransactionQueueTest test{*app}; - test.add(txSeqA1S1, - TransactionQueue::AddResult::ADD_STATUS_PENDING); - test.add(txSeqA1S2, - TransactionQueue::AddResult::ADD_STATUS_PENDING); - test.add(txSeqA1S3MinSeqAge, - TransactionQueue::AddResult::ADD_STATUS_TRY_AGAIN_LATER); + auto nextCloseTime = lastCloseTime + 100; + auto lclNum = app->getLedgerManager().getLastClosedLedgerNum(); - // submit as fee bump - auto fb = feeBump(*app, account1, txSeqA1S3MinSeqAge, 4000); - test.add(fb, - TransactionQueue::AddResult::ADD_STATUS_TRY_AGAIN_LATER); + PreconditionsV2 cond; + cond.minSeqAge = 100; + auto txPass = + transactionWithV2Precondition(*app, account1, 1, 200, cond); - test.check( - {{{account1, 0, {txSeqA1S1, txSeqA1S2}}, {account2}}, {}}); - } - SECTION("minSeqLedgerGap failed due to lower seqNum in queue") - { - TransactionQueueTest test{*app}; - test.add(txSeqA1S1, - TransactionQueue::AddResult::ADD_STATUS_PENDING); - test.add(txSeqA1S2, - TransactionQueue::AddResult::ADD_STATUS_PENDING); - test.add(txSeqA1S3MinSeqLedgerGap, - TransactionQueue::AddResult::ADD_STATUS_TRY_AGAIN_LATER); + ++cond.minSeqAge; + auto txFail = + transactionWithV2Precondition(*app, account1, 1, 200, cond); - // submit as fee bump - auto fb = feeBump(*app, account1, txSeqA1S3MinSeqLedgerGap, 4000); - test.add(fb, - TransactionQueue::AddResult::ADD_STATUS_TRY_AGAIN_LATER); + closeLedgerOn(*app, lclNum + 1, nextCloseTime); - test.check( - {{{account1, 0, {txSeqA1S1, txSeqA1S2}}, {account2}}, {}}); - } - SECTION("minSeqLedgerGap uses next ledgerSeq for validation") - { - TransactionQueueTest test{*app}; - test.add(txSeqA1S1, - TransactionQueue::AddResult::ADD_STATUS_PENDING); - test.add(txSeqA1S2, - TransactionQueue::AddResult::ADD_STATUS_PENDING); - test.add(txSeqA1S3MinSeqLedgerGap, - TransactionQueue::AddResult::ADD_STATUS_TRY_AGAIN_LATER); - } - SECTION("first tx has minSeqAge set") - { - auto lastCloseTime = app->getLedgerManager() - .getLastClosedLedgerHeader() - .header.scpValue.closeTime; + TransactionQueueTest test{*app}; + test.add(txFail, TransactionQueue::AddResult::ADD_STATUS_ERROR); + test.add(txPass, TransactionQueue::AddResult::ADD_STATUS_PENDING); + test.add(txSeqA1S2, TransactionQueue::AddResult::ADD_STATUS_PENDING); + test.check({{{account1, 0, {txPass, txSeqA1S2}}, {account2}}, {}}); + } + SECTION("first tx has minSeqLedgerGap set") + { + auto lastCloseTime = app->getLedgerManager() + .getLastClosedLedgerHeader() + .header.scpValue.closeTime; - auto nextCloseTime = lastCloseTime + 100; - auto lclNum = app->getLedgerManager().getLastClosedLedgerNum(); + auto lclNum = app->getLedgerManager().getLastClosedLedgerNum(); - PreconditionsV2 cond; - cond.minSeqAge = 100; - auto txPass = - transactionWithV2Precondition(*app, account1, 1, 200, cond); + PreconditionsV2 cond; + cond.minSeqLedgerGap = 3; + auto txPass = + transactionWithV2Precondition(*app, account1, 1, 200, cond); - ++cond.minSeqAge; - auto txFail = - transactionWithV2Precondition(*app, account1, 1, 200, cond); + ++cond.minSeqLedgerGap; + auto txFail = + transactionWithV2Precondition(*app, account1, 1, 200, cond); - closeLedgerOn(*app, lclNum + 1, nextCloseTime); + closeLedgerOn(*app, lclNum + 1, lastCloseTime); + closeLedgerOn(*app, lclNum + 2, lastCloseTime); - TransactionQueueTest test{*app}; - test.add(txFail, TransactionQueue::AddResult::ADD_STATUS_ERROR); - test.add(txPass, TransactionQueue::AddResult::ADD_STATUS_PENDING); - test.add(txSeqA1S2, - TransactionQueue::AddResult::ADD_STATUS_PENDING); - test.check({{{account1, 0, {txPass, txSeqA1S2}}, {account2}}, {}}); - } - SECTION("first tx has minSeqLedgerGap set") - { - auto lastCloseTime = app->getLedgerManager() - .getLastClosedLedgerHeader() - .header.scpValue.closeTime; + TransactionQueueTest test{*app}; + test.add(txFail, TransactionQueue::AddResult::ADD_STATUS_ERROR); + test.add(txPass, TransactionQueue::AddResult::ADD_STATUS_PENDING); + test.add(txSeqA1S2, TransactionQueue::AddResult::ADD_STATUS_PENDING); + test.check({{{account1, 0, {txPass, txSeqA1S2}}, {account2}}, {}}); + } + SECTION("extra signer") + { + TransactionQueueTest test{*app}; - auto lclNum = app->getLedgerManager().getLastClosedLedgerNum(); + SignerKey a2; + a2.type(SIGNER_KEY_TYPE_ED25519); + a2.ed25519() = account2.getPublicKey().ed25519(); - PreconditionsV2 cond; - cond.minSeqLedgerGap = 3; - auto txPass = - transactionWithV2Precondition(*app, account1, 1, 200, cond); + PreconditionsV2 cond; + cond.extraSigners.emplace_back(a2); - ++cond.minSeqLedgerGap; - auto txFail = + SECTION("one signer") + { + auto tx = transactionWithV2Precondition(*app, account1, 1, 200, cond); + test.add(tx, TransactionQueue::AddResult::ADD_STATUS_ERROR); - closeLedgerOn(*app, lclNum + 1, lastCloseTime); - closeLedgerOn(*app, lclNum + 2, lastCloseTime); - - TransactionQueueTest test{*app}; - test.add(txFail, TransactionQueue::AddResult::ADD_STATUS_ERROR); - test.add(txPass, TransactionQueue::AddResult::ADD_STATUS_PENDING); - test.add(txSeqA1S2, - TransactionQueue::AddResult::ADD_STATUS_PENDING); - test.check({{{account1, 0, {txPass, txSeqA1S2}}, {account2}}, {}}); + tx->addSignature(account2.getSecretKey()); + test.add(tx, TransactionQueue::AddResult::ADD_STATUS_PENDING); } - SECTION("extra signer") + + SECTION("two signers") { - TransactionQueueTest test{*app}; + SignerKey rootKey; + rootKey.type(SIGNER_KEY_TYPE_ED25519); + rootKey.ed25519() = root.getPublicKey().ed25519(); - SignerKey a2; - a2.type(SIGNER_KEY_TYPE_ED25519); - a2.ed25519() = account2.getPublicKey().ed25519(); + cond.extraSigners.emplace_back(rootKey); + auto tx = + transactionWithV2Precondition(*app, account1, 1, 200, cond); - PreconditionsV2 cond; - cond.extraSigners.emplace_back(a2); + // no signature + test.add(tx, TransactionQueue::AddResult::ADD_STATUS_ERROR); - SECTION("one signer") + SECTION("first signature missing") { - auto tx = - transactionWithV2Precondition(*app, account1, 1, 200, cond); + tx->addSignature(root.getSecretKey()); test.add(tx, TransactionQueue::AddResult::ADD_STATUS_ERROR); tx->addSignature(account2.getSecretKey()); test.add(tx, TransactionQueue::AddResult::ADD_STATUS_PENDING); } - SECTION("two signers") + SECTION("second signature missing") { - SignerKey rootKey; - rootKey.type(SIGNER_KEY_TYPE_ED25519); - rootKey.ed25519() = root.getPublicKey().ed25519(); - - cond.extraSigners.emplace_back(rootKey); - auto tx = - transactionWithV2Precondition(*app, account1, 1, 200, cond); - - // no signature + tx->addSignature(account2.getSecretKey()); test.add(tx, TransactionQueue::AddResult::ADD_STATUS_ERROR); - SECTION("first signature missing") - { - tx->addSignature(root.getSecretKey()); - test.add(tx, TransactionQueue::AddResult::ADD_STATUS_ERROR); - - tx->addSignature(account2.getSecretKey()); - test.add(tx, - TransactionQueue::AddResult::ADD_STATUS_PENDING); - } - - SECTION("second signature missing") - { - tx->addSignature(account2.getSecretKey()); - test.add(tx, TransactionQueue::AddResult::ADD_STATUS_ERROR); - - tx->addSignature(root.getSecretKey()); - test.add(tx, - TransactionQueue::AddResult::ADD_STATUS_PENDING); - } + tx->addSignature(root.getSecretKey()); + test.add(tx, TransactionQueue::AddResult::ADD_STATUS_PENDING); } } - SECTION("remove invalid ledger bound after close") - { - auto lclNum = app->getLedgerManager().getLastClosedLedgerNum(); - LedgerBounds bounds; - bounds.minLedger = 0; - bounds.maxLedger = lclNum + 2; + } + SECTION("remove invalid ledger bound after close") + { + auto lclNum = app->getLedgerManager().getLastClosedLedgerNum(); + LedgerBounds bounds; + bounds.minLedger = 0; + bounds.maxLedger = lclNum + 2; - PreconditionsV2 cond; - cond.ledgerBounds.activate() = bounds; + PreconditionsV2 cond; + cond.ledgerBounds.activate() = bounds; - auto tx = - transactionWithV2Precondition(*app, account1, 1, 200, cond); + auto tx = transactionWithV2Precondition(*app, account1, 1, 200, cond); - auto& herder = static_cast(app->getHerder()); - auto& tq = herder.getTransactionQueue(); + auto& herder = static_cast(app->getHerder()); + auto& tq = herder.getTransactionQueue(); - REQUIRE(herder.recvTransaction(tx, false) == - TransactionQueue::AddResult::ADD_STATUS_PENDING); + REQUIRE(herder.recvTransaction(tx, false) == + TransactionQueue::AddResult::ADD_STATUS_PENDING); - REQUIRE(tq.getTransactions({}).size() == 1); - closeLedger(*app); - REQUIRE(tq.getTransactions({}).size() == 0); - REQUIRE(tq.isBanned(tx->getFullHash())); - } - }); + REQUIRE(tq.getTransactions({}).size() == 1); + closeLedger(*app); + REQUIRE(tq.getTransactions({}).size() == 0); + REQUIRE(tq.isBanned(tx->getFullHash())); + } } TEST_CASE("TxQueueLimiter with limited source accounts", @@ -1360,7 +1331,6 @@ TEST_CASE("TxQueueLimiter with limited source accounts", VirtualClock clock; auto cfg = getTestConfig(); cfg.TESTING_UPGRADE_MAX_TX_SET_SIZE = 4; - cfg.LIMIT_TX_QUEUE_SOURCE_ACCOUNT = true; auto app = createTestApplication(clock, cfg); auto const minBalance2 = app->getLedgerManager().getLastMinBalance(2); auto root = TestAccount::createRoot(*app); @@ -1461,7 +1431,6 @@ TEST_CASE("Soroban TransactionQueue limits", cfg.TESTING_LEDGER_MAX_SOROBAN_TX_COUNT = 4; cfg.FLOOD_TX_PERIOD_MS = 100; - cfg.LIMIT_TX_QUEUE_SOURCE_ACCOUNT = true; auto app = createTestApplication(clock, cfg); auto const minBalance2 = app->getLedgerManager().getLastMinBalance(2); auto root = TestAccount::createRoot(*app); @@ -1702,6 +1671,7 @@ TEST_CASE("TransactionQueue limits", "[herder][transactionqueue]") VirtualClock clock; auto cfg = getTestConfig(); cfg.TESTING_UPGRADE_MAX_TX_SET_SIZE = 4; + cfg.LIMIT_TX_QUEUE_SOURCE_ACCOUNT = false; cfg.FLOOD_TX_PERIOD_MS = 100; auto app = createTestApplication(clock, cfg); auto const minBalance2 = app->getLedgerManager().getLastMinBalance(2); @@ -1950,6 +1920,7 @@ TEST_CASE("TransactionQueue limiter with DEX separation", cfg.TESTING_UPGRADE_MAX_TX_SET_SIZE = 3; cfg.FLOOD_TX_PERIOD_MS = 100; cfg.MAX_DEX_TX_OPERATIONS_IN_TX_SET = 1; + cfg.LIMIT_TX_QUEUE_SOURCE_ACCOUNT = false; auto app = createTestApplication(clock, cfg); auto const minBalance2 = app->getLedgerManager().getLastMinBalance(2); @@ -2221,37 +2192,6 @@ TEST_CASE("transaction queue starting sequence boundary", REQUIRE(!checkTxSet(3)); REQUIRE(checkTxSet(4)); } - - SECTION("check a chain of transactions") - { - int64_t startingSeq = static_cast(nextLedgerSeq) << 32; - REQUIRE(acc1.loadSequenceNumber() < startingSeq); - acc1.bumpSequence(startingSeq - 3); - REQUIRE(acc1.loadSequenceNumber() == startingSeq - 3); - - ClassicTransactionQueue tq(*app, 4, 10, 4); - for (size_t i = 1; i <= 4; ++i) - { - REQUIRE(tq.tryAdd(transaction(*app, acc1, i, 1, 100), false) == - TransactionQueue::AddResult::ADD_STATUS_PENDING); - } - - auto checkTxSet = [&](uint32_t ledgerSeq, size_t size) { - auto lcl = app->getLedgerManager().getLastClosedLedgerHeader(); - lcl.header.ledgerSeq = ledgerSeq; - auto txSet = tq.getTransactions(lcl.header); - REQUIRE(txSet.size() == size); - for (size_t i = 1; i <= size; ++i) - { - REQUIRE(txSet[i - 1]->getSeqNum() == - static_cast(startingSeq - 3 + i)); - } - }; - - checkTxSet(2, 4); - checkTxSet(3, 2); - checkTxSet(4, 4); - } } void @@ -2782,13 +2722,15 @@ TEST_CASE("remove applied", "[herder][transactionqueue]") auto root = TestAccount::createRoot(*app); auto acc = root.create("A", lm.getLastMinBalance(2)); + auto acc2 = root.create("B", lm.getLastMinBalance(2)); + auto acc3 = root.create("C", lm.getLastMinBalance(2)); auto tx1a = root.tx({payment(root, 1)}); root.loadSequenceNumber(); auto tx1b = root.tx({payment(root, 2)}); - auto tx2 = root.tx({payment(root, 3)}); - auto tx3 = root.tx({payment(root, 4)}); - auto tx4 = root.tx({payment(root, 5)}); + auto tx2 = acc.tx({payment(root, 1)}); + auto tx3 = acc2.tx({payment(root, 1)}); + auto tx4 = acc3.tx({payment(root, 1)}); herder.recvTransaction(tx1a, false); herder.recvTransaction(tx2, false); diff --git a/src/herder/test/TxSetTests.cpp b/src/herder/test/TxSetTests.cpp index b955cfe88f..488c3c200b 100644 --- a/src/herder/test/TxSetTests.cpp +++ b/src/herder/test/TxSetTests.cpp @@ -445,12 +445,16 @@ TEST_CASE("generalized tx set XDR conversion", "[txset]") static_cast(GENERALIZED_TX_SET_PROTOCOL_VERSION); Application::pointer app = createTestApplication(clock, cfg); auto root = TestAccount::createRoot(*app); + int accountId = 0; auto createTxs = [&](int cnt, int fee) { std::vector txs; for (int i = 0; i < cnt; ++i) { + auto source = + root.create("unique " + std::to_string(accountId++), + app->getLedgerManager().getLastMinBalance(2)); txs.emplace_back(transactionFromOperations( - *app, root.getSecretKey(), root.nextSequenceNumber(), + *app, source.getSecretKey(), source.nextSequenceNumber(), {createAccount(getAccount(std::to_string(i)).getPublicKey(), 1)}, fee)); @@ -547,12 +551,8 @@ TEST_CASE("generalized tx set XDR conversion", "[txset]") { auto const& lclHeader = app->getLedgerManager().getLastClosedLedgerHeader(); - std::vector txs; - for (int i = 0; i < 5; ++i) - { - txs.push_back(root.tx({createAccount( - getAccount(std::to_string(i)).getPublicKey(), 1)})); - } + std::vector txs = + createTxs(5, lclHeader.header.baseFee); auto txSet = TxSetFrame::makeFromTransactions(txs, *app, 0, 0); GeneralizedTransactionSet txSetXdr; @@ -655,8 +655,11 @@ TEST_CASE("generalized tx set fees", "[txset]") ops.emplace_back(createAccount( getAccount(std::to_string(accountId++)).getPublicKey(), 1)); } - return transactionFromOperations(*app, root.getSecretKey(), - root.nextSequenceNumber(), ops, fee); + // Create a new unique accounts to ensure there are no collisions + auto source = root.create("unique " + std::to_string(accountId), + app->getLedgerManager().getLastMinBalance(2)); + return transactionFromOperations(*app, source.getSecretKey(), + source.nextSequenceNumber(), ops, fee); }; SECTION("valid txset") diff --git a/src/history/test/HistoryTestsUtils.cpp b/src/history/test/HistoryTestsUtils.cpp index 5c4ffd0c3a..07f85f3149 100644 --- a/src/history/test/HistoryTestsUtils.cpp +++ b/src/history/test/HistoryTestsUtils.cpp @@ -423,35 +423,51 @@ CatchupSimulation::generateRandomLedger(uint32_t version) auto carol = TestAccount{mApp, getAccount("carol")}; std::vector txs; - // Root sends to alice every tx, bob every other tx, carol every 4rd tx. if (ledgerSeq < 5) { - txs.push_back(root.tx({createAccount(alice, big)})); - txs.push_back(root.tx({createAccount(bob, big)})); - txs.push_back(root.tx({createAccount(carol, big)})); + txs.push_back( + root.tx({createAccount(alice, big), createAccount(bob, big), + createAccount(carol, big)})); } // Allow an occasional empty ledger else if (rand_flip() || rand_flip()) { - txs.push_back(root.tx({payment(alice, big)})); - txs.push_back(root.tx({payment(bob, big)})); - txs.push_back(root.tx({payment(carol, big)})); - // They all randomly send a little to one another every ledger after #4 if (rand_flip()) - txs.push_back(alice.tx({payment(bob, small)})); + { + txs.push_back(root.tx({payment(alice, big)})); + } + else + { + txs.push_back(root.tx({payment(bob, big)})); + } + if (rand_flip()) + { + txs.push_back(alice.tx({payment(bob, small)})); + } + else + { txs.push_back(alice.tx({payment(carol, small)})); + } if (rand_flip()) + { txs.push_back(bob.tx({payment(alice, small)})); - if (rand_flip()) + } + else + { txs.push_back(bob.tx({payment(carol, small)})); + } if (rand_flip()) + { txs.push_back(carol.tx({payment(alice, small)})); - if (rand_flip()) + } + else + { txs.push_back(carol.tx({payment(bob, small)})); + } } TxSetFrameConstPtr txSet = TxSetFrame::makeFromTransactions(txs, mApp, 0, 0); diff --git a/src/main/Config.cpp b/src/main/Config.cpp index 5e590eec81..053e53ed34 100644 --- a/src/main/Config.cpp +++ b/src/main/Config.cpp @@ -167,12 +167,7 @@ Config::Config() : NODE_SEED(SecretKey::random()) USE_CONFIG_FOR_GENESIS = false; FAILURE_SAFETY = -1; UNSAFE_QUORUM = false; - LIMIT_TX_QUEUE_SOURCE_ACCOUNT = -#ifdef ENABLE_NEXT_PROTOCOL_VERSION_UNSAFE_FOR_PRODUCTION - true; -#else - false; -#endif + LIMIT_TX_QUEUE_SOURCE_ACCOUNT = true; DISABLE_BUCKET_GC = false; DISABLE_XDR_FSYNC = false; MAX_SLOTS_TO_REMEMBER = 12; diff --git a/src/simulation/test/LoadGeneratorTests.cpp b/src/simulation/test/LoadGeneratorTests.cpp index 309b32e1d9..6de22eda59 100644 --- a/src/simulation/test/LoadGeneratorTests.cpp +++ b/src/simulation/test/LoadGeneratorTests.cpp @@ -21,7 +21,6 @@ TEST_CASE("generate load with unique accounts", "[loadgen]") Simulation::pointer simulation = Topologies::pair(Simulation::OVER_LOOPBACK, networkID, [](int i) { auto cfg = getTestConfig(i); - cfg.LIMIT_TX_QUEUE_SOURCE_ACCOUNT = true; cfg.TESTING_UPGRADE_MAX_TX_SET_SIZE = 5000; return cfg; }); @@ -97,7 +96,6 @@ TEST_CASE("Multi-op pretend transactions are valid", "[loadgen]") Simulation::pointer simulation = Topologies::pair(Simulation::OVER_LOOPBACK, networkID, [](int i) { auto cfg = getTestConfig(i); - cfg.LIMIT_TX_QUEUE_SOURCE_ACCOUNT = true; // 50% of transactions contain 2 ops, // and 50% of transactions contain 3 ops. cfg.LOADGEN_OP_COUNT_FOR_TESTING = {2, 3}; @@ -170,7 +168,6 @@ TEST_CASE("Multi-op mixed transactions are valid", "[loadgen]") Simulation::pointer simulation = Topologies::pair(Simulation::OVER_LOOPBACK, networkID, [](int i) { auto cfg = getTestConfig(i); - cfg.LIMIT_TX_QUEUE_SOURCE_ACCOUNT = true; cfg.LOADGEN_OP_COUNT_FOR_TESTING = {3}; cfg.LOADGEN_OP_COUNT_DISTRIBUTION_FOR_TESTING = {1}; cfg.TESTING_UPGRADE_MAX_TX_SET_SIZE = 1000; diff --git a/src/test/test.cpp b/src/test/test.cpp index 651b00d0ad..de4f99c443 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -231,11 +231,6 @@ getTestConfig(int instanceNumber, Config::TestDbMode mode) thisConfig.INVARIANT_CHECKS = {".*"}; - // Enabling this config causes a major fallout in the test suite, as - // many test use account chains We'll deal with this later - tests that - // mix Soroban and classic txs enable this flag manually anyway - thisConfig.LIMIT_TX_QUEUE_SOURCE_ACCOUNT = false; - thisConfig.ALLOW_LOCALHOST_FOR_TESTING = true; // this forces to pick up any other potential upgrades diff --git a/src/transactions/test/MergeTests.cpp b/src/transactions/test/MergeTests.cpp index 92cb998a63..168889132f 100644 --- a/src/transactions/test/MergeTests.cpp +++ b/src/transactions/test/MergeTests.cpp @@ -623,9 +623,11 @@ TEST_CASE_VERSIONS("merge", "[tx][merge]") { for_versions_from(19, *app, [&]() { SequenceNumber curStartSeqNum; + uint32_t protocolVersion = 0; { LedgerTxn ltx(app->getLedgerTxnRoot()); ltx.loadHeader().current().ledgerSeq += 1; + protocolVersion = ltx.loadHeader().current().ledgerVersion; curStartSeqNum = getStartingSequenceNumber(ltx.loadHeader()); } @@ -652,17 +654,10 @@ TEST_CASE_VERSIONS("merge", "[tx][merge]") } SECTION("merge source account") { - auto tx1 = transactionFrameFromOps(app->getNetworkID(), a1, - {accountMerge(b1)}, {}); - - // Add some intermediate transactions between the merge and the - // gap tx so MAX_SEQ_NUM_TO_APPLY receives additional updates - auto tx2 = transactionFrameFromOps(app->getNetworkID(), a1, - {payment(root, 1)}, {}); - auto tx3 = transactionFrameFromOps(app->getNetworkID(), a1, - {payment(root, 1)}, {}); - - auto r = closeLedger(*app, {tx1, tx2, tx3, txMinSeqNumSrc}); + auto tx1 = + transactionFrameFromOps(app->getNetworkID(), gateway, + {a1.op(accountMerge(b1))}, {a1}); + auto r = closeLedger(*app, {tx1, txMinSeqNumSrc}, true); REQUIRE(r[0].first.result.result.results()[0] .tr() @@ -676,8 +671,9 @@ TEST_CASE_VERSIONS("merge", "[tx][merge]") auto tx1 = transactionFrameFromOps( app->getNetworkID(), root, {a1.op(bumpSequence(curStartSeqNum))}, {a1}); - auto tx2 = transactionFrameFromOps( - app->getNetworkID(), root, {a1.op(accountMerge(b1))}, {a1}); + auto tx2 = + transactionFrameFromOps(app->getNetworkID(), gateway, + {a1.op(accountMerge(b1))}, {a1}); auto r = closeLedger(*app, {tx1, tx2}, true); diff --git a/src/transactions/test/PaymentTests.cpp b/src/transactions/test/PaymentTests.cpp index 328ea20c6c..101a1e63bd 100644 --- a/src/transactions/test/PaymentTests.cpp +++ b/src/transactions/test/PaymentTests.cpp @@ -274,7 +274,7 @@ TEST_CASE_VERSIONS("payment", "[tx][payment]") REQUIRE(expectedrootBalance == root.getBalance()); }); - for_versions_from(9, *app, [&] { + for_versions(9, 19, *app, [&] { auto tx1 = b1.tx({payment(root, paymentAmount)}); auto tx2 = b1.tx({payment(root, 6)}); @@ -292,6 +292,8 @@ TEST_CASE_VERSIONS("payment", "[tx][payment]") REQUIRE(expectedb1Balance == b1.getBalance()); REQUIRE(expectedrootBalance == root.getBalance()); }); + // As of protocol 20, it is no longer possible to have multiple txs from + // the same source account in a single ledger } SECTION("create, merge, pay, 2 accounts") diff --git a/src/transactions/test/TxEnvelopeTests.cpp b/src/transactions/test/TxEnvelopeTests.cpp index 304c7d727c..7ef7fc7d7f 100644 --- a/src/transactions/test/TxEnvelopeTests.cpp +++ b/src/transactions/test/TxEnvelopeTests.cpp @@ -1304,9 +1304,9 @@ TEST_CASE_VERSIONS("txenvelope", "[tx][envelope]") tx1 = b.tx({setOptions( setMasterWeight(1) | setLowThreshold(1) | setMedThreshold(2) | setHighThreshold(3))}); - tx2 = b.tx( - {payment(root, 100), root.op(payment(b, 100))}, - b.getLastSequenceNumber() + 1); + tx2 = root.tx( + {b.op(payment(root, 100)), payment(b, 100)}, + root.getLastSequenceNumber() + 2); SignerKey sk = alternative.createSigner(*tx2); Signer sk1(sk, 100); // high rights account @@ -1316,12 +1316,12 @@ TEST_CASE_VERSIONS("txenvelope", "[tx][envelope]") }; for_versions(3, 9, *app, [&] { setup(); - closeLedgerOn(*app, 1, 1, 2010, {tx1, tx2}); + closeLedgerOn(*app, 1, 1, 2010, {tx1, tx2}, true); REQUIRE(getAccountSigners(root, *app).size() == 1); }); for_versions_from(10, *app, [&] { setup(); - closeLedgerOn(*app, 1, 1, 2010, {tx1, tx2}); + closeLedgerOn(*app, 1, 1, 2010, {tx1, tx2}, true); REQUIRE(getAccountSigners(root, *app).size() == (alternative.autoRemove ? 0 : 1)); }); @@ -1335,9 +1335,9 @@ TEST_CASE_VERSIONS("txenvelope", "[tx][envelope]") tx1 = b.tx({setOptions( setMasterWeight(1) | setLowThreshold(1) | setMedThreshold(2) | setHighThreshold(3))}); - tx2 = b.tx( - {root.op(payment(b, 100)), payment(root, 100)}, - b.getLastSequenceNumber() + 1); + tx2 = root.tx( + {payment(b, 100), b.op(payment(root, 100))}, + root.getLastSequenceNumber() + 2); SignerKey sk = alternative.createSigner(*tx2); Signer sk1(sk, 100); // high rights account @@ -1347,12 +1347,12 @@ TEST_CASE_VERSIONS("txenvelope", "[tx][envelope]") }; for_versions(3, 9, *app, [&] { setup(); - closeLedgerOn(*app, 1, 1, 2010, {tx1, tx2}); + closeLedgerOn(*app, 1, 1, 2010, {tx1, tx2}, true); REQUIRE(getAccountSigners(root, *app).size() == 1); }); for_versions_from(10, *app, [&] { setup(); - closeLedgerOn(*app, 1, 1, 2010, {tx1, tx2}); + closeLedgerOn(*app, 1, 1, 2010, {tx1, tx2}, true); REQUIRE(getAccountSigners(root, *app).size() == (alternative.autoRemove ? 0 : 1)); }); @@ -2382,13 +2382,16 @@ TEST_CASE_VERSIONS("txenvelope", "[tx][envelope]") SECTION("multiple tx") { for_versions_from(10, *app, [&] { - auto tx1 = a.tx({setOptions(setSigner(makeSigner(b, 1)))}); + auto tx1 = root.tx( + {a.op(setOptions(setSigner(makeSigner(b, 1))))}); + tx1->addSignature(a); tx1->addSignature(b); + auto tx2 = a.tx({payment(root, 1000), setOptions(setSigner(makeSigner(b, 2)))}); tx2->addSignature(b); - auto r = closeLedgerOn(*app, 1, 2, 2016, {tx1, tx2}); + auto r = closeLedgerOn(*app, 1, 2, 2016, {tx1, tx2}, true); checkTx(0, r, txSUCCESS); checkTx(1, r, txFAILED); From a58bd6dc752000c5249ceda6b2c47dc6e28d87b3 Mon Sep 17 00:00:00 2001 From: marta-lokhova Date: Fri, 14 Jul 2023 12:39:27 -0700 Subject: [PATCH 2/4] Address comment --- src/transactions/test/MergeTests.cpp | 2 -- src/transactions/test/PaymentTests.cpp | 19 +++++++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/transactions/test/MergeTests.cpp b/src/transactions/test/MergeTests.cpp index 168889132f..905fb8f989 100644 --- a/src/transactions/test/MergeTests.cpp +++ b/src/transactions/test/MergeTests.cpp @@ -623,11 +623,9 @@ TEST_CASE_VERSIONS("merge", "[tx][merge]") { for_versions_from(19, *app, [&]() { SequenceNumber curStartSeqNum; - uint32_t protocolVersion = 0; { LedgerTxn ltx(app->getLedgerTxnRoot()); ltx.loadHeader().current().ledgerSeq += 1; - protocolVersion = ltx.loadHeader().current().ledgerVersion; curStartSeqNum = getStartingSequenceNumber(ltx.loadHeader()); } diff --git a/src/transactions/test/PaymentTests.cpp b/src/transactions/test/PaymentTests.cpp index 101a1e63bd..fddb1f3beb 100644 --- a/src/transactions/test/PaymentTests.cpp +++ b/src/transactions/test/PaymentTests.cpp @@ -256,10 +256,9 @@ TEST_CASE_VERSIONS("payment", "[tx][payment]") int64 startingBalance = paymentAmount + 5 + app->getLedgerManager().getLastMinBalance(0) + txfee * 2; - auto b1 = root.create("B", startingBalance); - auto rootBalance = root.getBalance(); - for_versions_to(8, *app, [&] { + auto b1 = root.create("B", startingBalance); + auto rootBalance = root.getBalance(); auto tx1 = b1.tx({payment(root, paymentAmount)}); auto tx2 = b1.tx({payment(root, 6)}); @@ -274,11 +273,17 @@ TEST_CASE_VERSIONS("payment", "[tx][payment]") REQUIRE(expectedrootBalance == root.getBalance()); }); - for_versions(9, 19, *app, [&] { + for_versions_from(9, *app, [&] { + // Starting balance adjusted to have enough fees for 1 tx only + // (since tx1 and tx2 have different fee) + auto b1 = root.create("B", startingBalance - txfee); + auto b2 = root.create("B2", startingBalance - txfee); + auto rootBalance = root.getBalance(); auto tx1 = b1.tx({payment(root, paymentAmount)}); - auto tx2 = b1.tx({payment(root, 6)}); + auto tx2 = b2.tx({b1.op(payment(root, 6))}); + tx2->addSignature(b1); - auto r = closeLedger(*app, {tx1, tx2}); + auto r = closeLedger(*app, {tx1, tx2}, /* strictOrder */ true); checkTx(0, r, txSUCCESS); checkTx(1, r, txFAILED); REQUIRE(r[1].first.result.result.results()[0] @@ -292,8 +297,6 @@ TEST_CASE_VERSIONS("payment", "[tx][payment]") REQUIRE(expectedb1Balance == b1.getBalance()); REQUIRE(expectedrootBalance == root.getBalance()); }); - // As of protocol 20, it is no longer possible to have multiple txs from - // the same source account in a single ledger } SECTION("create, merge, pay, 2 accounts") From 25296ade077a04a46bdf28bd1722f9e64918e0a1 Mon Sep 17 00:00:00 2001 From: marta-lokhova Date: Fri, 14 Jul 2023 14:39:54 -0700 Subject: [PATCH 3/4] protocol next: update meta --- test-tx-meta-baseline-next/PaymentTests.json | 25 ++++--- .../TxEnvelopeTests.json | 72 +++++++++---------- 2 files changed, 48 insertions(+), 49 deletions(-) diff --git a/test-tx-meta-baseline-next/PaymentTests.json b/test-tx-meta-baseline-next/PaymentTests.json index 5e6ddbc58d..2f0a597fd0 100644 --- a/test-tx-meta-baseline-next/PaymentTests.json +++ b/test-tx-meta-baseline-next/PaymentTests.json @@ -497,7 +497,6 @@ "4Nbm1erruzc=", "vCmlwgzENn4=" ], - "payment|protocol version 0|two payments, first breaking second" : [ "ns4DM4E40Nw=" ], "payment|protocol version 1" : [ "c8f9ZedQpBg=", @@ -1041,7 +1040,7 @@ "sTOzapOWynI=" ], "payment|protocol version 10|simple credit|with trust|positive" : [ "4rxlhWSkAKI=", "OoCI2N0zqgo=" ], - "payment|protocol version 10|two payments, first breaking second" : [ "/0FvQZGicBI=" ], + "payment|protocol version 10|two payments, first breaking second" : [ "AhF9uMnbZQs=", "3vwjcQhOkrg=" ], "payment|protocol version 11" : [ "I474xQR5RsE=", @@ -1411,7 +1410,7 @@ "sTOzapOWynI=" ], "payment|protocol version 11|simple credit|with trust|positive" : [ "4rxlhWSkAKI=", "OoCI2N0zqgo=" ], - "payment|protocol version 11|two payments, first breaking second" : [ "/0FvQZGicBI=" ], + "payment|protocol version 11|two payments, first breaking second" : [ "AhF9uMnbZQs=", "3vwjcQhOkrg=" ], "payment|protocol version 12" : [ "I474xQR5RsE=", @@ -1781,7 +1780,7 @@ "sTOzapOWynI=" ], "payment|protocol version 12|simple credit|with trust|positive" : [ "4rxlhWSkAKI=", "OoCI2N0zqgo=" ], - "payment|protocol version 12|two payments, first breaking second" : [ "/0FvQZGicBI=" ], + "payment|protocol version 12|two payments, first breaking second" : [ "AhF9uMnbZQs=", "3vwjcQhOkrg=" ], "payment|protocol version 13" : [ "I474xQR5RsE=", @@ -2151,7 +2150,7 @@ "sTOzapOWynI=" ], "payment|protocol version 13|simple credit|with trust|positive" : [ "4rxlhWSkAKI=", "OoCI2N0zqgo=" ], - "payment|protocol version 13|two payments, first breaking second" : [ "/0FvQZGicBI=" ], + "payment|protocol version 13|two payments, first breaking second" : [ "AhF9uMnbZQs=", "3vwjcQhOkrg=" ], "payment|protocol version 14" : [ "I474xQR5RsE=", @@ -2521,7 +2520,7 @@ "sTOzapOWynI=" ], "payment|protocol version 14|simple credit|with trust|positive" : [ "4rxlhWSkAKI=", "OoCI2N0zqgo=" ], - "payment|protocol version 14|two payments, first breaking second" : [ "/0FvQZGicBI=" ], + "payment|protocol version 14|two payments, first breaking second" : [ "AhF9uMnbZQs=", "3vwjcQhOkrg=" ], "payment|protocol version 15" : [ "I474xQR5RsE=", @@ -2891,7 +2890,7 @@ "sTOzapOWynI=" ], "payment|protocol version 15|simple credit|with trust|positive" : [ "4rxlhWSkAKI=", "OoCI2N0zqgo=" ], - "payment|protocol version 15|two payments, first breaking second" : [ "/0FvQZGicBI=" ], + "payment|protocol version 15|two payments, first breaking second" : [ "AhF9uMnbZQs=", "3vwjcQhOkrg=" ], "payment|protocol version 16" : [ "I474xQR5RsE=", @@ -3261,7 +3260,7 @@ "sTOzapOWynI=" ], "payment|protocol version 16|simple credit|with trust|positive" : [ "4rxlhWSkAKI=", "OoCI2N0zqgo=" ], - "payment|protocol version 16|two payments, first breaking second" : [ "/0FvQZGicBI=" ], + "payment|protocol version 16|two payments, first breaking second" : [ "AhF9uMnbZQs=", "3vwjcQhOkrg=" ], "payment|protocol version 17" : [ "I474xQR5RsE=", @@ -3643,7 +3642,7 @@ "sTOzapOWynI=" ], "payment|protocol version 17|simple credit|with trust|positive" : [ "4rxlhWSkAKI=", "OoCI2N0zqgo=" ], - "payment|protocol version 17|two payments, first breaking second" : [ "/0FvQZGicBI=" ], + "payment|protocol version 17|two payments, first breaking second" : [ "AhF9uMnbZQs=", "3vwjcQhOkrg=" ], "payment|protocol version 18" : [ "I474xQR5RsE=", @@ -4025,7 +4024,7 @@ "sTOzapOWynI=" ], "payment|protocol version 18|simple credit|with trust|positive" : [ "4rxlhWSkAKI=", "OoCI2N0zqgo=" ], - "payment|protocol version 18|two payments, first breaking second" : [ "/0FvQZGicBI=" ], + "payment|protocol version 18|two payments, first breaking second" : [ "AhF9uMnbZQs=", "3vwjcQhOkrg=" ], "payment|protocol version 19" : [ "3s8wcHiLvNA=", @@ -4407,7 +4406,7 @@ "Fl0YuTtWNnc=" ], "payment|protocol version 19|simple credit|with trust|positive" : [ "Aazvdg1c5s0=", "iZ3l88UPpG8=" ], - "payment|protocol version 19|two payments, first breaking second" : [ "4+6eFQ1y63k=" ], + "payment|protocol version 19|two payments, first breaking second" : [ "j+xd3s6njXg=", "lcjxNT+ADQs=" ], "payment|protocol version 1|a pays b, then a merge into b" : [ "tC1VsNNRT18=", "6Cm6IY7Goqo=" ], "payment|protocol version 1|a pays b, then b merge into a" : [ "tC1VsNNRT18=", "L64XLnXWjLE=" ], "payment|protocol version 1|authorize flag|allow trust" : @@ -5152,7 +5151,7 @@ "2lx7DIngIoQ=" ], "payment|protocol version 20|simple credit|with trust|positive" : [ "ifcwmBT8wpE=", "r83zWmKpoYs=" ], - "payment|protocol version 20|two payments, first breaking second" : [ "yFzGkR1RSYk=" ], + "payment|protocol version 20|two payments, first breaking second" : [ "Z75hIE44Ckk=", "rmCICV/H4sg=" ], "payment|protocol version 2|a pays b, then a merge into b" : [ "tC1VsNNRT18=", "6Cm6IY7Goqo=" ], "payment|protocol version 2|a pays b, then b merge into a" : [ "tC1VsNNRT18=", "L64XLnXWjLE=" ], "payment|protocol version 2|authorize flag|allow trust" : @@ -7882,5 +7881,5 @@ "0V4+P1RNIZs=" ], "payment|protocol version 9|simple credit|with trust|positive" : [ "p11w2Nkvdy4=", "gAN2F1zKkyI=" ], - "payment|protocol version 9|two payments, first breaking second" : [ "ns4DM4E40Nw=" ] + "payment|protocol version 9|two payments, first breaking second" : [ "kT8fmYwcruU=", "EKQA2rm+C1U=" ] } diff --git a/test-tx-meta-baseline-next/TxEnvelopeTests.json b/test-tx-meta-baseline-next/TxEnvelopeTests.json index 0aaf2ed5fb..25ca1c52d3 100644 --- a/test-tx-meta-baseline-next/TxEnvelopeTests.json +++ b/test-tx-meta-baseline-next/TxEnvelopeTests.json @@ -243,8 +243,8 @@ "txenvelope|protocol version 10|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "jQdv6PguSbg=", "omQ241GgqMw=" ], "txenvelope|protocol version 10|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "1zX5tFpchB0=", "1nCk2dxc8QE=", "PAEjXSKadQk=" ], "txenvelope|protocol version 10|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "bWQV9RGGn10=", "r5eqRixNcho=" ], - "txenvelope|protocol version 10|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "rO4cTIocnyk=" ], - "txenvelope|protocol version 10|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "zYP8bRNgJbk=" ], + "txenvelope|protocol version 10|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "XNKsjU30KYM=" ], + "txenvelope|protocol version 10|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "WdGJfGQRfVI=" ], "txenvelope|protocol version 10|alternative signatures|hash tx|multisig|signatures removed from multiple accounts even though transaction failed" : [ "CGeRVB0d1kM=", "q3lBBUTjMmQ=", "N6wylrYbDuU=" ], "txenvelope|protocol version 10|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "IF5hGrjjLEM=", "PRnyBpYQT9Q=", "hICLaD2OLu4=" ], "txenvelope|protocol version 10|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "QX02OX53mlU=", "Ca3C4aHxJFM=", "YxhjmsesZcg=", "MeciNpbK/lA=" ], @@ -485,8 +485,8 @@ "txenvelope|protocol version 11|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "jQdv6PguSbg=", "omQ241GgqMw=" ], "txenvelope|protocol version 11|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "1zX5tFpchB0=", "1nCk2dxc8QE=", "PAEjXSKadQk=" ], "txenvelope|protocol version 11|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "bWQV9RGGn10=", "r5eqRixNcho=" ], - "txenvelope|protocol version 11|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "rO4cTIocnyk=" ], - "txenvelope|protocol version 11|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "zYP8bRNgJbk=" ], + "txenvelope|protocol version 11|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "XNKsjU30KYM=" ], + "txenvelope|protocol version 11|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "WdGJfGQRfVI=" ], "txenvelope|protocol version 11|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "IF5hGrjjLEM=", "PRnyBpYQT9Q=", "hICLaD2OLu4=" ], "txenvelope|protocol version 11|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "QX02OX53mlU=", "Ca3C4aHxJFM=", "YxhjmsesZcg=", "MeciNpbK/lA=" ], "txenvelope|protocol version 11|alternative signatures|hash tx|single signature|failing transaction" : [ "k8yMJlLL3B8=", "/RrjgGXPfMc=" ], @@ -725,8 +725,8 @@ "txenvelope|protocol version 12|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "jQdv6PguSbg=", "omQ241GgqMw=" ], "txenvelope|protocol version 12|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "1zX5tFpchB0=", "1nCk2dxc8QE=", "PAEjXSKadQk=" ], "txenvelope|protocol version 12|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "bWQV9RGGn10=", "r5eqRixNcho=" ], - "txenvelope|protocol version 12|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "rO4cTIocnyk=" ], - "txenvelope|protocol version 12|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "zYP8bRNgJbk=" ], + "txenvelope|protocol version 12|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "XNKsjU30KYM=" ], + "txenvelope|protocol version 12|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "WdGJfGQRfVI=" ], "txenvelope|protocol version 12|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "IF5hGrjjLEM=", "PRnyBpYQT9Q=", "hICLaD2OLu4=" ], "txenvelope|protocol version 12|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "QX02OX53mlU=", "Ca3C4aHxJFM=", "YxhjmsesZcg=", "MeciNpbK/lA=" ], "txenvelope|protocol version 12|alternative signatures|hash tx|single signature|failing transaction" : [ "k8yMJlLL3B8=", "/RrjgGXPfMc=" ], @@ -967,8 +967,8 @@ "txenvelope|protocol version 13|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "jQdv6PguSbg=", "H/Lb0TRUsHM=" ], "txenvelope|protocol version 13|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "1zX5tFpchB0=", "1nCk2dxc8QE=", "3N/IxV4kRf4=" ], "txenvelope|protocol version 13|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "bWQV9RGGn10=", "r5eqRixNcho=" ], - "txenvelope|protocol version 13|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "rO4cTIocnyk=" ], - "txenvelope|protocol version 13|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "zYP8bRNgJbk=" ], + "txenvelope|protocol version 13|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "XNKsjU30KYM=" ], + "txenvelope|protocol version 13|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "WdGJfGQRfVI=" ], "txenvelope|protocol version 13|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "IF5hGrjjLEM=", "PRnyBpYQT9Q=", "hICLaD2OLu4=" ], "txenvelope|protocol version 13|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "QX02OX53mlU=", "Ca3C4aHxJFM=", "YxhjmsesZcg=", "MeciNpbK/lA=" ], "txenvelope|protocol version 13|alternative signatures|hash tx|single signature|failing transaction" : [ "k8yMJlLL3B8=", "/RrjgGXPfMc=" ], @@ -1209,8 +1209,8 @@ "txenvelope|protocol version 14|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "jQdv6PguSbg=", "H/Lb0TRUsHM=" ], "txenvelope|protocol version 14|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "1zX5tFpchB0=", "1nCk2dxc8QE=", "3N/IxV4kRf4=" ], "txenvelope|protocol version 14|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "bWQV9RGGn10=", "r5eqRixNcho=" ], - "txenvelope|protocol version 14|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "rO4cTIocnyk=" ], - "txenvelope|protocol version 14|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "zYP8bRNgJbk=" ], + "txenvelope|protocol version 14|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "XNKsjU30KYM=" ], + "txenvelope|protocol version 14|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "WdGJfGQRfVI=" ], "txenvelope|protocol version 14|alternative signatures|hash tx|multisig|success complex sponsored signatures + hash tx" : [ "IF5hGrjjLEM=", "41CUe6MU20Y=", "GXulSaEBlsg=" ], "txenvelope|protocol version 14|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "IF5hGrjjLEM=", "PRnyBpYQT9Q=", "hICLaD2OLu4=" ], "txenvelope|protocol version 14|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "QX02OX53mlU=", "Ca3C4aHxJFM=", "YxhjmsesZcg=", "MeciNpbK/lA=" ], @@ -1453,8 +1453,8 @@ "txenvelope|protocol version 15|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "jQdv6PguSbg=", "H/Lb0TRUsHM=" ], "txenvelope|protocol version 15|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "1zX5tFpchB0=", "1nCk2dxc8QE=", "3N/IxV4kRf4=" ], "txenvelope|protocol version 15|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "bWQV9RGGn10=", "r5eqRixNcho=" ], - "txenvelope|protocol version 15|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "rO4cTIocnyk=" ], - "txenvelope|protocol version 15|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "zYP8bRNgJbk=" ], + "txenvelope|protocol version 15|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "XNKsjU30KYM=" ], + "txenvelope|protocol version 15|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "WdGJfGQRfVI=" ], "txenvelope|protocol version 15|alternative signatures|hash tx|multisig|success complex sponsored signatures + hash tx" : [ "IF5hGrjjLEM=", "41CUe6MU20Y=", "GXulSaEBlsg=" ], "txenvelope|protocol version 15|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "IF5hGrjjLEM=", "PRnyBpYQT9Q=", "hICLaD2OLu4=" ], "txenvelope|protocol version 15|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "QX02OX53mlU=", "Ca3C4aHxJFM=", "YxhjmsesZcg=", "MeciNpbK/lA=" ], @@ -1697,8 +1697,8 @@ "txenvelope|protocol version 16|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "jQdv6PguSbg=", "H/Lb0TRUsHM=" ], "txenvelope|protocol version 16|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "1zX5tFpchB0=", "1nCk2dxc8QE=", "3N/IxV4kRf4=" ], "txenvelope|protocol version 16|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "bWQV9RGGn10=", "r5eqRixNcho=" ], - "txenvelope|protocol version 16|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "rO4cTIocnyk=" ], - "txenvelope|protocol version 16|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "zYP8bRNgJbk=" ], + "txenvelope|protocol version 16|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "XNKsjU30KYM=" ], + "txenvelope|protocol version 16|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "WdGJfGQRfVI=" ], "txenvelope|protocol version 16|alternative signatures|hash tx|multisig|success complex sponsored signatures + hash tx" : [ "IF5hGrjjLEM=", "41CUe6MU20Y=", "GXulSaEBlsg=" ], "txenvelope|protocol version 16|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "IF5hGrjjLEM=", "PRnyBpYQT9Q=", "hICLaD2OLu4=" ], "txenvelope|protocol version 16|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "QX02OX53mlU=", "Ca3C4aHxJFM=", "YxhjmsesZcg=", "MeciNpbK/lA=" ], @@ -1941,8 +1941,8 @@ "txenvelope|protocol version 17|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "jQdv6PguSbg=", "H/Lb0TRUsHM=" ], "txenvelope|protocol version 17|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "1zX5tFpchB0=", "1nCk2dxc8QE=", "3N/IxV4kRf4=" ], "txenvelope|protocol version 17|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "bWQV9RGGn10=", "r5eqRixNcho=" ], - "txenvelope|protocol version 17|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "rO4cTIocnyk=" ], - "txenvelope|protocol version 17|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "zYP8bRNgJbk=" ], + "txenvelope|protocol version 17|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "XNKsjU30KYM=" ], + "txenvelope|protocol version 17|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "WdGJfGQRfVI=" ], "txenvelope|protocol version 17|alternative signatures|hash tx|multisig|success complex sponsored signatures + hash tx" : [ "IF5hGrjjLEM=", "41CUe6MU20Y=", "GXulSaEBlsg=" ], "txenvelope|protocol version 17|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "IF5hGrjjLEM=", "PRnyBpYQT9Q=", "hICLaD2OLu4=" ], "txenvelope|protocol version 17|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "QX02OX53mlU=", "Ca3C4aHxJFM=", "YxhjmsesZcg=", "MeciNpbK/lA=" ], @@ -2185,8 +2185,8 @@ "txenvelope|protocol version 18|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "jQdv6PguSbg=", "H/Lb0TRUsHM=" ], "txenvelope|protocol version 18|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "1zX5tFpchB0=", "1nCk2dxc8QE=", "3N/IxV4kRf4=" ], "txenvelope|protocol version 18|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "bWQV9RGGn10=", "r5eqRixNcho=" ], - "txenvelope|protocol version 18|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "rO4cTIocnyk=" ], - "txenvelope|protocol version 18|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "zYP8bRNgJbk=" ], + "txenvelope|protocol version 18|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "XNKsjU30KYM=" ], + "txenvelope|protocol version 18|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "WdGJfGQRfVI=" ], "txenvelope|protocol version 18|alternative signatures|hash tx|multisig|success complex sponsored signatures + hash tx" : [ "IF5hGrjjLEM=", "41CUe6MU20Y=", "GXulSaEBlsg=" ], "txenvelope|protocol version 18|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "IF5hGrjjLEM=", "PRnyBpYQT9Q=", "hICLaD2OLu4=" ], "txenvelope|protocol version 18|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "QX02OX53mlU=", "Ca3C4aHxJFM=", "YxhjmsesZcg=", "MeciNpbK/lA=" ], @@ -2448,8 +2448,8 @@ "txenvelope|protocol version 19|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "v5kdfUJlGY8=", "wAlV/bkB5bE=" ], "txenvelope|protocol version 19|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "h64WYB4k6L4=", "nnfRVzNRiSQ=", "3vBDTILWyNA=" ], "txenvelope|protocol version 19|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "seWgWQjP1KA=", "HD+KE2dv0J8=" ], - "txenvelope|protocol version 19|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "nrKK2E+HdPI=", "w//akLu+Pkg=" ], - "txenvelope|protocol version 19|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "nrKK2E+HdPI=", "qwQedgIt/vw=" ], + "txenvelope|protocol version 19|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "nrKK2E+HdPI=", "7xAxuX2koIU=" ], + "txenvelope|protocol version 19|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "nrKK2E+HdPI=", "od7ol9puDzI=" ], "txenvelope|protocol version 19|alternative signatures|hash tx|multisig|success complex sponsored signatures + hash tx" : [ "J1TPVPqVGng=", "5RyIOUuDPkA=", "n54lTWoqP6c=" ], "txenvelope|protocol version 19|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "J1TPVPqVGng=", "rrLhA7Z1UnA=", "oasdKqTDCOA=" ], "txenvelope|protocol version 19|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "82DS8lxCTyM=", "jamZv4a6NgY=", "Te+Mi7134UI=", "0NccSo9SKW8=" ], @@ -3041,8 +3041,8 @@ "txenvelope|protocol version 20|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "wkO9L2WRTU4=", "ixIIsq/p8x4=" ], "txenvelope|protocol version 20|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "291iX6Bi/WE=", "m9oo8QJcNNc=", "UkJ/ShqhwUE=" ], "txenvelope|protocol version 20|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "qLTnqcxy+xo=", "N+iiTVk5omg=" ], - "txenvelope|protocol version 20|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "TKa2oOWhDOI=", "P+Df4kF23ds=" ], - "txenvelope|protocol version 20|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "TKa2oOWhDOI=", "069V84hhbGQ=" ], + "txenvelope|protocol version 20|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "TKa2oOWhDOI=", "G3JwAbREreo=" ], + "txenvelope|protocol version 20|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "TKa2oOWhDOI=", "nKtmIwLzyCk=" ], "txenvelope|protocol version 20|alternative signatures|hash tx|multisig|success complex sponsored signatures + hash tx" : [ "tpVB4/R2ioo=", "Rf2ufAXxo8g=", "KWpwC8TLLW4=" ], "txenvelope|protocol version 20|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "tpVB4/R2ioo=", "imNuZ/IK8Q4=", "UgsnwzEAZ3w=" ], "txenvelope|protocol version 20|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "ii0zb5xK4bc=", "YKChBVF1dCM=", "Pld3yl+X6Z4=", "QOZr4TTgy7Y=" ], @@ -3614,8 +3614,8 @@ "txenvelope|protocol version 3|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "u9+v3WCdR1g=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 3|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "2KqgUWg0WKI=", "mW47t/SpELw=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 3|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "4OZy8mwlUE8=", "/lfj8xIFS8I=" ], - "txenvelope|protocol version 3|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "igIsVgN22Lg=" ], - "txenvelope|protocol version 3|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "T60pn7P7lQM=" ], + "txenvelope|protocol version 3|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "byEfOC7o1g8=" ], + "txenvelope|protocol version 3|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "s9pYrUN9NE0=" ], "txenvelope|protocol version 3|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "GjplIy5uwyM=", "+s8MVo+Psew=", "3UxGStVAee8=" ], "txenvelope|protocol version 3|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "88FTRJod/cs=", "KgW73jFjwso=", "k57krCbAQlU=", "9QjEYubfs84=" ], "txenvelope|protocol version 3|alternative signatures|hash tx|single signature|failing transaction" : [ "QJIb3iCC2G0=", "/lfj8xIFS8I=" ], @@ -3849,8 +3849,8 @@ "txenvelope|protocol version 4|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "u9+v3WCdR1g=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 4|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "2KqgUWg0WKI=", "mW47t/SpELw=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 4|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "4OZy8mwlUE8=", "/lfj8xIFS8I=" ], - "txenvelope|protocol version 4|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "igIsVgN22Lg=" ], - "txenvelope|protocol version 4|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "T60pn7P7lQM=" ], + "txenvelope|protocol version 4|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "byEfOC7o1g8=" ], + "txenvelope|protocol version 4|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "s9pYrUN9NE0=" ], "txenvelope|protocol version 4|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "GjplIy5uwyM=", "+s8MVo+Psew=", "3UxGStVAee8=" ], "txenvelope|protocol version 4|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "88FTRJod/cs=", "KgW73jFjwso=", "k57krCbAQlU=", "9QjEYubfs84=" ], "txenvelope|protocol version 4|alternative signatures|hash tx|single signature|failing transaction" : [ "QJIb3iCC2G0=", "/lfj8xIFS8I=" ], @@ -4084,8 +4084,8 @@ "txenvelope|protocol version 5|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "u9+v3WCdR1g=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 5|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "2KqgUWg0WKI=", "mW47t/SpELw=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 5|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "4OZy8mwlUE8=", "/lfj8xIFS8I=" ], - "txenvelope|protocol version 5|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "igIsVgN22Lg=" ], - "txenvelope|protocol version 5|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "T60pn7P7lQM=" ], + "txenvelope|protocol version 5|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "byEfOC7o1g8=" ], + "txenvelope|protocol version 5|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "s9pYrUN9NE0=" ], "txenvelope|protocol version 5|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "GjplIy5uwyM=", "+s8MVo+Psew=", "3UxGStVAee8=" ], "txenvelope|protocol version 5|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "88FTRJod/cs=", "KgW73jFjwso=", "k57krCbAQlU=", "9QjEYubfs84=" ], "txenvelope|protocol version 5|alternative signatures|hash tx|single signature|failing transaction" : [ "QJIb3iCC2G0=", "/lfj8xIFS8I=" ], @@ -4319,8 +4319,8 @@ "txenvelope|protocol version 6|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "u9+v3WCdR1g=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 6|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "2KqgUWg0WKI=", "mW47t/SpELw=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 6|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "4OZy8mwlUE8=", "/lfj8xIFS8I=" ], - "txenvelope|protocol version 6|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "igIsVgN22Lg=" ], - "txenvelope|protocol version 6|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "T60pn7P7lQM=" ], + "txenvelope|protocol version 6|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "byEfOC7o1g8=" ], + "txenvelope|protocol version 6|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "s9pYrUN9NE0=" ], "txenvelope|protocol version 6|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "GjplIy5uwyM=", "+s8MVo+Psew=", "3UxGStVAee8=" ], "txenvelope|protocol version 6|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "88FTRJod/cs=", "KgW73jFjwso=", "k57krCbAQlU=", "9QjEYubfs84=" ], "txenvelope|protocol version 6|alternative signatures|hash tx|single signature|failing transaction" : [ "QJIb3iCC2G0=", "/lfj8xIFS8I=" ], @@ -4554,8 +4554,8 @@ "txenvelope|protocol version 7|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "u9+v3WCdR1g=", "JzN9OQjS1us=" ], "txenvelope|protocol version 7|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "2KqgUWg0WKI=", "mW47t/SpELw=", "emQsdvX/DuE=" ], "txenvelope|protocol version 7|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "4OZy8mwlUE8=", "Qal5IZ05kyg=" ], - "txenvelope|protocol version 7|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "igIsVgN22Lg=" ], - "txenvelope|protocol version 7|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "T60pn7P7lQM=" ], + "txenvelope|protocol version 7|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "byEfOC7o1g8=" ], + "txenvelope|protocol version 7|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "s9pYrUN9NE0=" ], "txenvelope|protocol version 7|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "GjplIy5uwyM=", "+s8MVo+Psew=", "AVPoABIwlMA=" ], "txenvelope|protocol version 7|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "88FTRJod/cs=", "KgW73jFjwso=", "k57krCbAQlU=", "9QjEYubfs84=" ], "txenvelope|protocol version 7|alternative signatures|hash tx|single signature|failing transaction" : [ "QJIb3iCC2G0=", "/lfj8xIFS8I=" ], @@ -4789,8 +4789,8 @@ "txenvelope|protocol version 8|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "u9+v3WCdR1g=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 8|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "2KqgUWg0WKI=", "mW47t/SpELw=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 8|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "4OZy8mwlUE8=", "/lfj8xIFS8I=" ], - "txenvelope|protocol version 8|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "igIsVgN22Lg=" ], - "txenvelope|protocol version 8|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "T60pn7P7lQM=" ], + "txenvelope|protocol version 8|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "byEfOC7o1g8=" ], + "txenvelope|protocol version 8|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "s9pYrUN9NE0=" ], "txenvelope|protocol version 8|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "GjplIy5uwyM=", "+s8MVo+Psew=", "3UxGStVAee8=" ], "txenvelope|protocol version 8|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "88FTRJod/cs=", "KgW73jFjwso=", "k57krCbAQlU=", "9QjEYubfs84=" ], "txenvelope|protocol version 8|alternative signatures|hash tx|single signature|failing transaction" : [ "QJIb3iCC2G0=", "/lfj8xIFS8I=" ], @@ -5024,8 +5024,8 @@ "txenvelope|protocol version 9|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "u9+v3WCdR1g=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 9|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "2KqgUWg0WKI=", "mW47t/SpELw=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 9|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "4OZy8mwlUE8=", "/lfj8xIFS8I=" ], - "txenvelope|protocol version 9|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "igIsVgN22Lg=" ], - "txenvelope|protocol version 9|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "T60pn7P7lQM=" ], + "txenvelope|protocol version 9|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "byEfOC7o1g8=" ], + "txenvelope|protocol version 9|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "s9pYrUN9NE0=" ], "txenvelope|protocol version 9|alternative signatures|hash tx|multisig|signatures removed from multiple accounts even though transaction failed" : [ "anr6jnq7tf8=", "JiRu+TWpIHg=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 9|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "GjplIy5uwyM=", "+s8MVo+Psew=", "3UxGStVAee8=" ], "txenvelope|protocol version 9|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "88FTRJod/cs=", "KgW73jFjwso=", "k57krCbAQlU=", "9QjEYubfs84=" ], From 3f679a187f8724def96c11661049a678a81a2a62 Mon Sep 17 00:00:00 2001 From: marta-lokhova Date: Fri, 14 Jul 2023 15:30:14 -0700 Subject: [PATCH 4/4] protocol curr: update meta --- .../PaymentTests.json | 23 +++---- .../TxEnvelopeTests.json | 68 +++++++++---------- 2 files changed, 45 insertions(+), 46 deletions(-) diff --git a/test-tx-meta-baseline-current/PaymentTests.json b/test-tx-meta-baseline-current/PaymentTests.json index 4787f4e163..402f0766d1 100644 --- a/test-tx-meta-baseline-current/PaymentTests.json +++ b/test-tx-meta-baseline-current/PaymentTests.json @@ -458,7 +458,6 @@ "4Nbm1erruzc=", "vCmlwgzENn4=" ], - "payment|protocol version 0|two payments, first breaking second" : [ "ns4DM4E40Nw=" ], "payment|protocol version 1" : [ "c8f9ZedQpBg=", @@ -1002,7 +1001,7 @@ "sTOzapOWynI=" ], "payment|protocol version 10|simple credit|with trust|positive" : [ "4rxlhWSkAKI=", "OoCI2N0zqgo=" ], - "payment|protocol version 10|two payments, first breaking second" : [ "/0FvQZGicBI=" ], + "payment|protocol version 10|two payments, first breaking second" : [ "AhF9uMnbZQs=", "3vwjcQhOkrg=" ], "payment|protocol version 11" : [ "I474xQR5RsE=", @@ -1372,7 +1371,7 @@ "sTOzapOWynI=" ], "payment|protocol version 11|simple credit|with trust|positive" : [ "4rxlhWSkAKI=", "OoCI2N0zqgo=" ], - "payment|protocol version 11|two payments, first breaking second" : [ "/0FvQZGicBI=" ], + "payment|protocol version 11|two payments, first breaking second" : [ "AhF9uMnbZQs=", "3vwjcQhOkrg=" ], "payment|protocol version 12" : [ "I474xQR5RsE=", @@ -1742,7 +1741,7 @@ "sTOzapOWynI=" ], "payment|protocol version 12|simple credit|with trust|positive" : [ "4rxlhWSkAKI=", "OoCI2N0zqgo=" ], - "payment|protocol version 12|two payments, first breaking second" : [ "/0FvQZGicBI=" ], + "payment|protocol version 12|two payments, first breaking second" : [ "AhF9uMnbZQs=", "3vwjcQhOkrg=" ], "payment|protocol version 13" : [ "I474xQR5RsE=", @@ -2112,7 +2111,7 @@ "sTOzapOWynI=" ], "payment|protocol version 13|simple credit|with trust|positive" : [ "4rxlhWSkAKI=", "OoCI2N0zqgo=" ], - "payment|protocol version 13|two payments, first breaking second" : [ "/0FvQZGicBI=" ], + "payment|protocol version 13|two payments, first breaking second" : [ "AhF9uMnbZQs=", "3vwjcQhOkrg=" ], "payment|protocol version 14" : [ "I474xQR5RsE=", @@ -2482,7 +2481,7 @@ "sTOzapOWynI=" ], "payment|protocol version 14|simple credit|with trust|positive" : [ "4rxlhWSkAKI=", "OoCI2N0zqgo=" ], - "payment|protocol version 14|two payments, first breaking second" : [ "/0FvQZGicBI=" ], + "payment|protocol version 14|two payments, first breaking second" : [ "AhF9uMnbZQs=", "3vwjcQhOkrg=" ], "payment|protocol version 15" : [ "I474xQR5RsE=", @@ -2852,7 +2851,7 @@ "sTOzapOWynI=" ], "payment|protocol version 15|simple credit|with trust|positive" : [ "4rxlhWSkAKI=", "OoCI2N0zqgo=" ], - "payment|protocol version 15|two payments, first breaking second" : [ "/0FvQZGicBI=" ], + "payment|protocol version 15|two payments, first breaking second" : [ "AhF9uMnbZQs=", "3vwjcQhOkrg=" ], "payment|protocol version 16" : [ "I474xQR5RsE=", @@ -3222,7 +3221,7 @@ "sTOzapOWynI=" ], "payment|protocol version 16|simple credit|with trust|positive" : [ "4rxlhWSkAKI=", "OoCI2N0zqgo=" ], - "payment|protocol version 16|two payments, first breaking second" : [ "/0FvQZGicBI=" ], + "payment|protocol version 16|two payments, first breaking second" : [ "AhF9uMnbZQs=", "3vwjcQhOkrg=" ], "payment|protocol version 17" : [ "I474xQR5RsE=", @@ -3604,7 +3603,7 @@ "sTOzapOWynI=" ], "payment|protocol version 17|simple credit|with trust|positive" : [ "4rxlhWSkAKI=", "OoCI2N0zqgo=" ], - "payment|protocol version 17|two payments, first breaking second" : [ "/0FvQZGicBI=" ], + "payment|protocol version 17|two payments, first breaking second" : [ "AhF9uMnbZQs=", "3vwjcQhOkrg=" ], "payment|protocol version 18" : [ "I474xQR5RsE=", @@ -3986,7 +3985,7 @@ "sTOzapOWynI=" ], "payment|protocol version 18|simple credit|with trust|positive" : [ "4rxlhWSkAKI=", "OoCI2N0zqgo=" ], - "payment|protocol version 18|two payments, first breaking second" : [ "/0FvQZGicBI=" ], + "payment|protocol version 18|two payments, first breaking second" : [ "AhF9uMnbZQs=", "3vwjcQhOkrg=" ], "payment|protocol version 19" : [ "3s8wcHiLvNA=", @@ -4368,7 +4367,7 @@ "Fl0YuTtWNnc=" ], "payment|protocol version 19|simple credit|with trust|positive" : [ "Aazvdg1c5s0=", "iZ3l88UPpG8=" ], - "payment|protocol version 19|two payments, first breaking second" : [ "4+6eFQ1y63k=" ], + "payment|protocol version 19|two payments, first breaking second" : [ "j+xd3s6njXg=", "lcjxNT+ADQs=" ], "payment|protocol version 1|a pays b, then a merge into b" : [ "tC1VsNNRT18=", "6Cm6IY7Goqo=" ], "payment|protocol version 1|a pays b, then b merge into a" : [ "tC1VsNNRT18=", "L64XLnXWjLE=" ], "payment|protocol version 1|authorize flag|allow trust" : @@ -7461,5 +7460,5 @@ "0V4+P1RNIZs=" ], "payment|protocol version 9|simple credit|with trust|positive" : [ "p11w2Nkvdy4=", "gAN2F1zKkyI=" ], - "payment|protocol version 9|two payments, first breaking second" : [ "ns4DM4E40Nw=" ] + "payment|protocol version 9|two payments, first breaking second" : [ "kT8fmYwcruU=", "EKQA2rm+C1U=" ] } diff --git a/test-tx-meta-baseline-current/TxEnvelopeTests.json b/test-tx-meta-baseline-current/TxEnvelopeTests.json index 0a5772b029..567dc98c01 100644 --- a/test-tx-meta-baseline-current/TxEnvelopeTests.json +++ b/test-tx-meta-baseline-current/TxEnvelopeTests.json @@ -220,8 +220,8 @@ "txenvelope|protocol version 10|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "jQdv6PguSbg=", "omQ241GgqMw=" ], "txenvelope|protocol version 10|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "1zX5tFpchB0=", "1nCk2dxc8QE=", "PAEjXSKadQk=" ], "txenvelope|protocol version 10|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "bWQV9RGGn10=", "r5eqRixNcho=" ], - "txenvelope|protocol version 10|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "rO4cTIocnyk=" ], - "txenvelope|protocol version 10|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "zYP8bRNgJbk=" ], + "txenvelope|protocol version 10|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "XNKsjU30KYM=" ], + "txenvelope|protocol version 10|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "WdGJfGQRfVI=" ], "txenvelope|protocol version 10|alternative signatures|hash tx|multisig|signatures removed from multiple accounts even though transaction failed" : [ "CGeRVB0d1kM=", "q3lBBUTjMmQ=", "N6wylrYbDuU=" ], "txenvelope|protocol version 10|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "IF5hGrjjLEM=", "PRnyBpYQT9Q=", "hICLaD2OLu4=" ], "txenvelope|protocol version 10|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "QX02OX53mlU=", "Ca3C4aHxJFM=", "YxhjmsesZcg=", "MeciNpbK/lA=" ], @@ -462,8 +462,8 @@ "txenvelope|protocol version 11|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "jQdv6PguSbg=", "omQ241GgqMw=" ], "txenvelope|protocol version 11|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "1zX5tFpchB0=", "1nCk2dxc8QE=", "PAEjXSKadQk=" ], "txenvelope|protocol version 11|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "bWQV9RGGn10=", "r5eqRixNcho=" ], - "txenvelope|protocol version 11|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "rO4cTIocnyk=" ], - "txenvelope|protocol version 11|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "zYP8bRNgJbk=" ], + "txenvelope|protocol version 11|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "XNKsjU30KYM=" ], + "txenvelope|protocol version 11|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "WdGJfGQRfVI=" ], "txenvelope|protocol version 11|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "IF5hGrjjLEM=", "PRnyBpYQT9Q=", "hICLaD2OLu4=" ], "txenvelope|protocol version 11|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "QX02OX53mlU=", "Ca3C4aHxJFM=", "YxhjmsesZcg=", "MeciNpbK/lA=" ], "txenvelope|protocol version 11|alternative signatures|hash tx|single signature|failing transaction" : [ "k8yMJlLL3B8=", "/RrjgGXPfMc=" ], @@ -702,8 +702,8 @@ "txenvelope|protocol version 12|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "jQdv6PguSbg=", "omQ241GgqMw=" ], "txenvelope|protocol version 12|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "1zX5tFpchB0=", "1nCk2dxc8QE=", "PAEjXSKadQk=" ], "txenvelope|protocol version 12|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "bWQV9RGGn10=", "r5eqRixNcho=" ], - "txenvelope|protocol version 12|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "rO4cTIocnyk=" ], - "txenvelope|protocol version 12|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "zYP8bRNgJbk=" ], + "txenvelope|protocol version 12|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "XNKsjU30KYM=" ], + "txenvelope|protocol version 12|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "WdGJfGQRfVI=" ], "txenvelope|protocol version 12|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "IF5hGrjjLEM=", "PRnyBpYQT9Q=", "hICLaD2OLu4=" ], "txenvelope|protocol version 12|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "QX02OX53mlU=", "Ca3C4aHxJFM=", "YxhjmsesZcg=", "MeciNpbK/lA=" ], "txenvelope|protocol version 12|alternative signatures|hash tx|single signature|failing transaction" : [ "k8yMJlLL3B8=", "/RrjgGXPfMc=" ], @@ -944,8 +944,8 @@ "txenvelope|protocol version 13|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "jQdv6PguSbg=", "H/Lb0TRUsHM=" ], "txenvelope|protocol version 13|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "1zX5tFpchB0=", "1nCk2dxc8QE=", "3N/IxV4kRf4=" ], "txenvelope|protocol version 13|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "bWQV9RGGn10=", "r5eqRixNcho=" ], - "txenvelope|protocol version 13|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "rO4cTIocnyk=" ], - "txenvelope|protocol version 13|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "zYP8bRNgJbk=" ], + "txenvelope|protocol version 13|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "XNKsjU30KYM=" ], + "txenvelope|protocol version 13|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "WdGJfGQRfVI=" ], "txenvelope|protocol version 13|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "IF5hGrjjLEM=", "PRnyBpYQT9Q=", "hICLaD2OLu4=" ], "txenvelope|protocol version 13|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "QX02OX53mlU=", "Ca3C4aHxJFM=", "YxhjmsesZcg=", "MeciNpbK/lA=" ], "txenvelope|protocol version 13|alternative signatures|hash tx|single signature|failing transaction" : [ "k8yMJlLL3B8=", "/RrjgGXPfMc=" ], @@ -1186,8 +1186,8 @@ "txenvelope|protocol version 14|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "jQdv6PguSbg=", "H/Lb0TRUsHM=" ], "txenvelope|protocol version 14|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "1zX5tFpchB0=", "1nCk2dxc8QE=", "3N/IxV4kRf4=" ], "txenvelope|protocol version 14|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "bWQV9RGGn10=", "r5eqRixNcho=" ], - "txenvelope|protocol version 14|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "rO4cTIocnyk=" ], - "txenvelope|protocol version 14|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "zYP8bRNgJbk=" ], + "txenvelope|protocol version 14|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "XNKsjU30KYM=" ], + "txenvelope|protocol version 14|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "WdGJfGQRfVI=" ], "txenvelope|protocol version 14|alternative signatures|hash tx|multisig|success complex sponsored signatures + hash tx" : [ "IF5hGrjjLEM=", "41CUe6MU20Y=", "GXulSaEBlsg=" ], "txenvelope|protocol version 14|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "IF5hGrjjLEM=", "PRnyBpYQT9Q=", "hICLaD2OLu4=" ], "txenvelope|protocol version 14|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "QX02OX53mlU=", "Ca3C4aHxJFM=", "YxhjmsesZcg=", "MeciNpbK/lA=" ], @@ -1430,8 +1430,8 @@ "txenvelope|protocol version 15|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "jQdv6PguSbg=", "H/Lb0TRUsHM=" ], "txenvelope|protocol version 15|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "1zX5tFpchB0=", "1nCk2dxc8QE=", "3N/IxV4kRf4=" ], "txenvelope|protocol version 15|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "bWQV9RGGn10=", "r5eqRixNcho=" ], - "txenvelope|protocol version 15|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "rO4cTIocnyk=" ], - "txenvelope|protocol version 15|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "zYP8bRNgJbk=" ], + "txenvelope|protocol version 15|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "XNKsjU30KYM=" ], + "txenvelope|protocol version 15|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "WdGJfGQRfVI=" ], "txenvelope|protocol version 15|alternative signatures|hash tx|multisig|success complex sponsored signatures + hash tx" : [ "IF5hGrjjLEM=", "41CUe6MU20Y=", "GXulSaEBlsg=" ], "txenvelope|protocol version 15|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "IF5hGrjjLEM=", "PRnyBpYQT9Q=", "hICLaD2OLu4=" ], "txenvelope|protocol version 15|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "QX02OX53mlU=", "Ca3C4aHxJFM=", "YxhjmsesZcg=", "MeciNpbK/lA=" ], @@ -1674,8 +1674,8 @@ "txenvelope|protocol version 16|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "jQdv6PguSbg=", "H/Lb0TRUsHM=" ], "txenvelope|protocol version 16|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "1zX5tFpchB0=", "1nCk2dxc8QE=", "3N/IxV4kRf4=" ], "txenvelope|protocol version 16|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "bWQV9RGGn10=", "r5eqRixNcho=" ], - "txenvelope|protocol version 16|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "rO4cTIocnyk=" ], - "txenvelope|protocol version 16|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "zYP8bRNgJbk=" ], + "txenvelope|protocol version 16|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "XNKsjU30KYM=" ], + "txenvelope|protocol version 16|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "WdGJfGQRfVI=" ], "txenvelope|protocol version 16|alternative signatures|hash tx|multisig|success complex sponsored signatures + hash tx" : [ "IF5hGrjjLEM=", "41CUe6MU20Y=", "GXulSaEBlsg=" ], "txenvelope|protocol version 16|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "IF5hGrjjLEM=", "PRnyBpYQT9Q=", "hICLaD2OLu4=" ], "txenvelope|protocol version 16|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "QX02OX53mlU=", "Ca3C4aHxJFM=", "YxhjmsesZcg=", "MeciNpbK/lA=" ], @@ -1918,8 +1918,8 @@ "txenvelope|protocol version 17|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "jQdv6PguSbg=", "H/Lb0TRUsHM=" ], "txenvelope|protocol version 17|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "1zX5tFpchB0=", "1nCk2dxc8QE=", "3N/IxV4kRf4=" ], "txenvelope|protocol version 17|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "bWQV9RGGn10=", "r5eqRixNcho=" ], - "txenvelope|protocol version 17|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "rO4cTIocnyk=" ], - "txenvelope|protocol version 17|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "zYP8bRNgJbk=" ], + "txenvelope|protocol version 17|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "XNKsjU30KYM=" ], + "txenvelope|protocol version 17|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "WdGJfGQRfVI=" ], "txenvelope|protocol version 17|alternative signatures|hash tx|multisig|success complex sponsored signatures + hash tx" : [ "IF5hGrjjLEM=", "41CUe6MU20Y=", "GXulSaEBlsg=" ], "txenvelope|protocol version 17|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "IF5hGrjjLEM=", "PRnyBpYQT9Q=", "hICLaD2OLu4=" ], "txenvelope|protocol version 17|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "QX02OX53mlU=", "Ca3C4aHxJFM=", "YxhjmsesZcg=", "MeciNpbK/lA=" ], @@ -2162,8 +2162,8 @@ "txenvelope|protocol version 18|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "jQdv6PguSbg=", "H/Lb0TRUsHM=" ], "txenvelope|protocol version 18|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "1zX5tFpchB0=", "1nCk2dxc8QE=", "3N/IxV4kRf4=" ], "txenvelope|protocol version 18|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "bWQV9RGGn10=", "r5eqRixNcho=" ], - "txenvelope|protocol version 18|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "rO4cTIocnyk=" ], - "txenvelope|protocol version 18|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "zYP8bRNgJbk=" ], + "txenvelope|protocol version 18|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "VwP3r9J7ttc=", "XNKsjU30KYM=" ], + "txenvelope|protocol version 18|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "VwP3r9J7ttc=", "WdGJfGQRfVI=" ], "txenvelope|protocol version 18|alternative signatures|hash tx|multisig|success complex sponsored signatures + hash tx" : [ "IF5hGrjjLEM=", "41CUe6MU20Y=", "GXulSaEBlsg=" ], "txenvelope|protocol version 18|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "IF5hGrjjLEM=", "PRnyBpYQT9Q=", "hICLaD2OLu4=" ], "txenvelope|protocol version 18|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "QX02OX53mlU=", "Ca3C4aHxJFM=", "YxhjmsesZcg=", "MeciNpbK/lA=" ], @@ -2425,8 +2425,8 @@ "txenvelope|protocol version 19|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "v5kdfUJlGY8=", "wAlV/bkB5bE=" ], "txenvelope|protocol version 19|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "h64WYB4k6L4=", "nnfRVzNRiSQ=", "3vBDTILWyNA=" ], "txenvelope|protocol version 19|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "seWgWQjP1KA=", "HD+KE2dv0J8=" ], - "txenvelope|protocol version 19|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "nrKK2E+HdPI=", "w//akLu+Pkg=" ], - "txenvelope|protocol version 19|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "nrKK2E+HdPI=", "qwQedgIt/vw=" ], + "txenvelope|protocol version 19|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "nrKK2E+HdPI=", "7xAxuX2koIU=" ], + "txenvelope|protocol version 19|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "nrKK2E+HdPI=", "od7ol9puDzI=" ], "txenvelope|protocol version 19|alternative signatures|hash tx|multisig|success complex sponsored signatures + hash tx" : [ "J1TPVPqVGng=", "5RyIOUuDPkA=", "n54lTWoqP6c=" ], "txenvelope|protocol version 19|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "J1TPVPqVGng=", "rrLhA7Z1UnA=", "oasdKqTDCOA=" ], "txenvelope|protocol version 19|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "82DS8lxCTyM=", "jamZv4a6NgY=", "Te+Mi7134UI=", "0NccSo9SKW8=" ], @@ -3249,8 +3249,8 @@ "txenvelope|protocol version 3|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "u9+v3WCdR1g=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 3|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "2KqgUWg0WKI=", "mW47t/SpELw=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 3|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "4OZy8mwlUE8=", "/lfj8xIFS8I=" ], - "txenvelope|protocol version 3|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "igIsVgN22Lg=" ], - "txenvelope|protocol version 3|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "T60pn7P7lQM=" ], + "txenvelope|protocol version 3|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "byEfOC7o1g8=" ], + "txenvelope|protocol version 3|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "s9pYrUN9NE0=" ], "txenvelope|protocol version 3|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "GjplIy5uwyM=", "+s8MVo+Psew=", "3UxGStVAee8=" ], "txenvelope|protocol version 3|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "88FTRJod/cs=", "KgW73jFjwso=", "k57krCbAQlU=", "9QjEYubfs84=" ], "txenvelope|protocol version 3|alternative signatures|hash tx|single signature|failing transaction" : [ "QJIb3iCC2G0=", "/lfj8xIFS8I=" ], @@ -3484,8 +3484,8 @@ "txenvelope|protocol version 4|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "u9+v3WCdR1g=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 4|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "2KqgUWg0WKI=", "mW47t/SpELw=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 4|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "4OZy8mwlUE8=", "/lfj8xIFS8I=" ], - "txenvelope|protocol version 4|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "igIsVgN22Lg=" ], - "txenvelope|protocol version 4|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "T60pn7P7lQM=" ], + "txenvelope|protocol version 4|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "byEfOC7o1g8=" ], + "txenvelope|protocol version 4|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "s9pYrUN9NE0=" ], "txenvelope|protocol version 4|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "GjplIy5uwyM=", "+s8MVo+Psew=", "3UxGStVAee8=" ], "txenvelope|protocol version 4|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "88FTRJod/cs=", "KgW73jFjwso=", "k57krCbAQlU=", "9QjEYubfs84=" ], "txenvelope|protocol version 4|alternative signatures|hash tx|single signature|failing transaction" : [ "QJIb3iCC2G0=", "/lfj8xIFS8I=" ], @@ -3719,8 +3719,8 @@ "txenvelope|protocol version 5|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "u9+v3WCdR1g=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 5|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "2KqgUWg0WKI=", "mW47t/SpELw=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 5|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "4OZy8mwlUE8=", "/lfj8xIFS8I=" ], - "txenvelope|protocol version 5|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "igIsVgN22Lg=" ], - "txenvelope|protocol version 5|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "T60pn7P7lQM=" ], + "txenvelope|protocol version 5|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "byEfOC7o1g8=" ], + "txenvelope|protocol version 5|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "s9pYrUN9NE0=" ], "txenvelope|protocol version 5|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "GjplIy5uwyM=", "+s8MVo+Psew=", "3UxGStVAee8=" ], "txenvelope|protocol version 5|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "88FTRJod/cs=", "KgW73jFjwso=", "k57krCbAQlU=", "9QjEYubfs84=" ], "txenvelope|protocol version 5|alternative signatures|hash tx|single signature|failing transaction" : [ "QJIb3iCC2G0=", "/lfj8xIFS8I=" ], @@ -3954,8 +3954,8 @@ "txenvelope|protocol version 6|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "u9+v3WCdR1g=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 6|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "2KqgUWg0WKI=", "mW47t/SpELw=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 6|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "4OZy8mwlUE8=", "/lfj8xIFS8I=" ], - "txenvelope|protocol version 6|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "igIsVgN22Lg=" ], - "txenvelope|protocol version 6|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "T60pn7P7lQM=" ], + "txenvelope|protocol version 6|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "byEfOC7o1g8=" ], + "txenvelope|protocol version 6|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "s9pYrUN9NE0=" ], "txenvelope|protocol version 6|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "GjplIy5uwyM=", "+s8MVo+Psew=", "3UxGStVAee8=" ], "txenvelope|protocol version 6|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "88FTRJod/cs=", "KgW73jFjwso=", "k57krCbAQlU=", "9QjEYubfs84=" ], "txenvelope|protocol version 6|alternative signatures|hash tx|single signature|failing transaction" : [ "QJIb3iCC2G0=", "/lfj8xIFS8I=" ], @@ -4189,8 +4189,8 @@ "txenvelope|protocol version 7|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "u9+v3WCdR1g=", "JzN9OQjS1us=" ], "txenvelope|protocol version 7|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "2KqgUWg0WKI=", "mW47t/SpELw=", "emQsdvX/DuE=" ], "txenvelope|protocol version 7|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "4OZy8mwlUE8=", "Qal5IZ05kyg=" ], - "txenvelope|protocol version 7|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "igIsVgN22Lg=" ], - "txenvelope|protocol version 7|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "T60pn7P7lQM=" ], + "txenvelope|protocol version 7|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "byEfOC7o1g8=" ], + "txenvelope|protocol version 7|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "s9pYrUN9NE0=" ], "txenvelope|protocol version 7|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "GjplIy5uwyM=", "+s8MVo+Psew=", "AVPoABIwlMA=" ], "txenvelope|protocol version 7|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "88FTRJod/cs=", "KgW73jFjwso=", "k57krCbAQlU=", "9QjEYubfs84=" ], "txenvelope|protocol version 7|alternative signatures|hash tx|single signature|failing transaction" : [ "QJIb3iCC2G0=", "/lfj8xIFS8I=" ], @@ -4424,8 +4424,8 @@ "txenvelope|protocol version 8|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "u9+v3WCdR1g=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 8|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "2KqgUWg0WKI=", "mW47t/SpELw=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 8|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "4OZy8mwlUE8=", "/lfj8xIFS8I=" ], - "txenvelope|protocol version 8|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "igIsVgN22Lg=" ], - "txenvelope|protocol version 8|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "T60pn7P7lQM=" ], + "txenvelope|protocol version 8|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "byEfOC7o1g8=" ], + "txenvelope|protocol version 8|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "s9pYrUN9NE0=" ], "txenvelope|protocol version 8|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "GjplIy5uwyM=", "+s8MVo+Psew=", "3UxGStVAee8=" ], "txenvelope|protocol version 8|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "88FTRJod/cs=", "KgW73jFjwso=", "k57krCbAQlU=", "9QjEYubfs84=" ], "txenvelope|protocol version 8|alternative signatures|hash tx|single signature|failing transaction" : [ "QJIb3iCC2G0=", "/lfj8xIFS8I=" ], @@ -4659,8 +4659,8 @@ "txenvelope|protocol version 9|alternative signatures|hash tx|multisig|not enough rights (envelope)" : [ "u9+v3WCdR1g=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 9|alternative signatures|hash tx|multisig|not enough rights (envelope). Same pre auth signer on both tx and op source account" : [ "2KqgUWg0WKI=", "mW47t/SpELw=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 9|alternative signatures|hash tx|multisig|not enough rights (operation)" : [ "4OZy8mwlUE8=", "/lfj8xIFS8I=" ], - "txenvelope|protocol version 9|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "igIsVgN22Lg=" ], - "txenvelope|protocol version 9|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "T60pn7P7lQM=" ], + "txenvelope|protocol version 9|alternative signatures|hash tx|multisig|not enough rights on first operation" : [ "mQPm/1BcnSE=", "byEfOC7o1g8=" ], + "txenvelope|protocol version 9|alternative signatures|hash tx|multisig|not enough rights on second operation" : [ "mQPm/1BcnSE=", "s9pYrUN9NE0=" ], "txenvelope|protocol version 9|alternative signatures|hash tx|multisig|signatures removed from multiple accounts even though transaction failed" : [ "anr6jnq7tf8=", "JiRu+TWpIHg=", "/lfj8xIFS8I=" ], "txenvelope|protocol version 9|alternative signatures|hash tx|multisig|success signature + hash tx" : [ "GjplIy5uwyM=", "+s8MVo+Psew=", "3UxGStVAee8=" ], "txenvelope|protocol version 9|alternative signatures|hash tx|single signature|accountMerge signing account" : [ "88FTRJod/cs=", "KgW73jFjwso=", "k57krCbAQlU=", "9QjEYubfs84=" ],