Split test in to multiple parts
This commit is contained in:
parent
cb51e03587
commit
9e8729113c
|
@ -73,7 +73,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
TEST(TransactionBuilder, Invoke)
|
||||
TEST(TransactionBuilder, TransparentToSapling)
|
||||
{
|
||||
auto consensusParams = RegtestActivateSapling();
|
||||
|
||||
|
@ -91,106 +91,121 @@ TEST(TransactionBuilder, Invoke)
|
|||
libzcash::diversifier_t d = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
auto pk = *ivk.address(d);
|
||||
|
||||
auto sproutSk = libzcash::SproutSpendingKey::random();
|
||||
ZCNoteDecryption sproutDecryptor(sproutSk.receiving_key());
|
||||
auto sproutAddr = sproutSk.address();
|
||||
|
||||
// Create a shielding transaction from transparent to Sapling
|
||||
// 0.0005 t-ZEC in, 0.0004 z-ZEC out, 0.0001 t-ZEC fee
|
||||
auto builder1 = TransactionBuilder(consensusParams, 1, &keystore);
|
||||
builder1.AddTransparentInput(COutPoint(), scriptPubKey, 50000);
|
||||
builder1.AddSaplingOutput(fvk_from.ovk, pk, 40000, {});
|
||||
auto tx1 = builder1.Build().GetTxOrThrow();
|
||||
auto builder = TransactionBuilder(consensusParams, 1, &keystore);
|
||||
builder.AddTransparentInput(COutPoint(), scriptPubKey, 50000);
|
||||
builder.AddSaplingOutput(fvk_from.ovk, pk, 40000, {});
|
||||
auto tx = builder.Build().GetTxOrThrow();
|
||||
|
||||
EXPECT_EQ(tx1.vin.size(), 1);
|
||||
EXPECT_EQ(tx1.vout.size(), 0);
|
||||
EXPECT_EQ(tx1.vjoinsplit.size(), 0);
|
||||
EXPECT_EQ(tx1.vShieldedSpend.size(), 0);
|
||||
EXPECT_EQ(tx1.vShieldedOutput.size(), 1);
|
||||
EXPECT_EQ(tx1.valueBalance, -40000);
|
||||
EXPECT_EQ(tx.vin.size(), 1);
|
||||
EXPECT_EQ(tx.vout.size(), 0);
|
||||
EXPECT_EQ(tx.vjoinsplit.size(), 0);
|
||||
EXPECT_EQ(tx.vShieldedSpend.size(), 0);
|
||||
EXPECT_EQ(tx.vShieldedOutput.size(), 1);
|
||||
EXPECT_EQ(tx.valueBalance, -40000);
|
||||
|
||||
CValidationState state;
|
||||
EXPECT_TRUE(ContextualCheckTransaction(tx1, state, 2, 0));
|
||||
EXPECT_TRUE(ContextualCheckTransaction(tx, state, 2, 0));
|
||||
EXPECT_EQ(state.GetRejectReason(), "");
|
||||
|
||||
// Prepare to spend the note that was just created
|
||||
auto maybe_pt = libzcash::SaplingNotePlaintext::decrypt(
|
||||
tx1.vShieldedOutput[0].encCiphertext, ivk, tx1.vShieldedOutput[0].ephemeralKey, tx1.vShieldedOutput[0].cm);
|
||||
ASSERT_EQ(static_cast<bool>(maybe_pt), true);
|
||||
auto maybe_note = maybe_pt.get().note(ivk);
|
||||
ASSERT_EQ(static_cast<bool>(maybe_note), true);
|
||||
auto note = maybe_note.get();
|
||||
SaplingMerkleTree tree;
|
||||
tree.append(tx1.vShieldedOutput[0].cm);
|
||||
auto anchor = tree.root();
|
||||
auto witness = tree.witness();
|
||||
// Revert to default
|
||||
RegtestDeactivateSapling();
|
||||
}
|
||||
|
||||
TEST(TransactionBuilder, SaplingToSapling) {
|
||||
auto consensusParams = RegtestActivateSapling();
|
||||
|
||||
auto sk = libzcash::SaplingSpendingKey::random();
|
||||
auto expsk = sk.expanded_spending_key();
|
||||
auto fvk = sk.full_viewing_key();
|
||||
auto pa = sk.default_address();
|
||||
|
||||
auto testNote = GetTestSaplingNote(pa, 40000);
|
||||
|
||||
// Create a Sapling-only transaction
|
||||
// 0.0004 z-ZEC in, 0.00025 z-ZEC out, 0.0001 t-ZEC fee, 0.00005 z-ZEC change
|
||||
auto builder2 = TransactionBuilder(consensusParams, 2);
|
||||
builder2.AddSaplingSpend(expsk, note, anchor, witness);
|
||||
auto builder = TransactionBuilder(consensusParams, 2);
|
||||
builder.AddSaplingSpend(expsk, testNote.note, testNote.tree.root(), testNote.tree.witness());
|
||||
|
||||
// Check that trying to add a different anchor fails
|
||||
// TODO: the following check can be split out in to another test
|
||||
ASSERT_THROW(builder2.AddSaplingSpend(expsk, note, uint256(), witness), UniValue);
|
||||
ASSERT_THROW(builder.AddSaplingSpend(expsk, testNote.note, uint256(), testNote.tree.witness()), UniValue);
|
||||
|
||||
builder2.AddSaplingOutput(fvk.ovk, pk, 25000, {});
|
||||
auto tx2 = builder2.Build().GetTxOrThrow();
|
||||
builder.AddSaplingOutput(fvk.ovk, pa, 25000, {});
|
||||
auto tx = builder.Build().GetTxOrThrow();
|
||||
|
||||
EXPECT_EQ(tx2.vin.size(), 0);
|
||||
EXPECT_EQ(tx2.vout.size(), 0);
|
||||
EXPECT_EQ(tx2.vjoinsplit.size(), 0);
|
||||
EXPECT_EQ(tx2.vShieldedSpend.size(), 1);
|
||||
EXPECT_EQ(tx2.vShieldedOutput.size(), 2);
|
||||
EXPECT_EQ(tx2.valueBalance, 10000);
|
||||
EXPECT_EQ(tx.vin.size(), 0);
|
||||
EXPECT_EQ(tx.vout.size(), 0);
|
||||
EXPECT_EQ(tx.vjoinsplit.size(), 0);
|
||||
EXPECT_EQ(tx.vShieldedSpend.size(), 1);
|
||||
EXPECT_EQ(tx.vShieldedOutput.size(), 2);
|
||||
EXPECT_EQ(tx.valueBalance, 10000);
|
||||
|
||||
EXPECT_TRUE(ContextualCheckTransaction(tx2, state, 3, 0));
|
||||
CValidationState state;
|
||||
EXPECT_TRUE(ContextualCheckTransaction(tx, state, 3, 0));
|
||||
EXPECT_EQ(state.GetRejectReason(), "");
|
||||
|
||||
// Revert to default
|
||||
RegtestDeactivateSapling();
|
||||
}
|
||||
|
||||
TEST(TransactionBuilder, SaplingToSprout) {
|
||||
auto consensusParams = RegtestActivateSapling();
|
||||
|
||||
auto sk = libzcash::SaplingSpendingKey::random();
|
||||
auto expsk = sk.expanded_spending_key();
|
||||
auto pa = sk.default_address();
|
||||
|
||||
auto testNote = GetTestSaplingNote(pa, 40000);
|
||||
|
||||
auto sproutSk = libzcash::SproutSpendingKey::random();
|
||||
auto sproutAddr = sproutSk.address();
|
||||
|
||||
// Create a Sapling-to-Sprout transaction (reusing the note from above)
|
||||
// - 0.0004 Sapling-ZEC in - 0.00025 Sprout-ZEC out
|
||||
// - 0.00005 Sapling-ZEC change
|
||||
// - 0.0001 t-ZEC fee
|
||||
auto builder3 = TransactionBuilder(consensusParams, 2, nullptr, params);
|
||||
builder3.AddSaplingSpend(expsk, note, anchor, witness);
|
||||
builder3.AddSproutOutput(sproutAddr, 25000);
|
||||
auto tx3 = builder3.Build().GetTxOrThrow();
|
||||
auto builder = TransactionBuilder(consensusParams, 2, nullptr, params);
|
||||
builder.AddSaplingSpend(expsk, testNote.note, testNote.tree.root(), testNote.tree.witness());
|
||||
builder.AddSproutOutput(sproutAddr, 25000);
|
||||
auto tx = builder.Build().GetTxOrThrow();
|
||||
|
||||
EXPECT_EQ(tx3.vin.size(), 0);
|
||||
EXPECT_EQ(tx3.vout.size(), 0);
|
||||
EXPECT_EQ(tx3.vjoinsplit.size(), 1);
|
||||
EXPECT_EQ(tx3.vjoinsplit[0].vpub_old, 25000);
|
||||
EXPECT_EQ(tx3.vjoinsplit[0].vpub_new, 0);
|
||||
EXPECT_EQ(tx3.vShieldedSpend.size(), 1);
|
||||
EXPECT_EQ(tx3.vShieldedOutput.size(), 1);
|
||||
EXPECT_EQ(tx3.valueBalance, 35000);
|
||||
EXPECT_EQ(tx.vin.size(), 0);
|
||||
EXPECT_EQ(tx.vout.size(), 0);
|
||||
EXPECT_EQ(tx.vjoinsplit.size(), 1);
|
||||
EXPECT_EQ(tx.vjoinsplit[0].vpub_old, 25000);
|
||||
EXPECT_EQ(tx.vjoinsplit[0].vpub_new, 0);
|
||||
EXPECT_EQ(tx.vShieldedSpend.size(), 1);
|
||||
EXPECT_EQ(tx.vShieldedOutput.size(), 1);
|
||||
EXPECT_EQ(tx.valueBalance, 35000);
|
||||
|
||||
EXPECT_TRUE(ContextualCheckTransaction(tx3, state, 3, 0));
|
||||
CValidationState state;
|
||||
EXPECT_TRUE(ContextualCheckTransaction(tx, state, 3, 0));
|
||||
EXPECT_EQ(state.GetRejectReason(), "");
|
||||
|
||||
// Prepare to spend the Sprout note that was just created
|
||||
// Revert to default
|
||||
RegtestDeactivateSapling();
|
||||
}
|
||||
|
||||
TEST(TransactionBuilder, SproutToSproutAndSapling) {
|
||||
auto consensusParams = RegtestActivateSapling();
|
||||
|
||||
auto sk = libzcash::SaplingSpendingKey::random();
|
||||
auto fvk = sk.full_viewing_key();
|
||||
auto pa = sk.default_address();
|
||||
|
||||
auto sproutSk = libzcash::SproutSpendingKey::random();
|
||||
auto sproutAddr = sproutSk.address();
|
||||
|
||||
auto wtx = GetValidSproutReceive(*params, sproutSk, 25000, true);
|
||||
auto sproutNote = GetSproutNote(*params, sproutSk, wtx, 0, 1);
|
||||
|
||||
SproutMerkleTree sproutTree;
|
||||
libzcash::SproutNote sproutNote;
|
||||
SproutWitness sproutWitness;
|
||||
for (int i = 0; i < ZC_NUM_JS_OUTPUTS; i++) {
|
||||
sproutTree.append(tx3.vjoinsplit[0].commitments[i]);
|
||||
|
||||
auto hSig = tx3.vjoinsplit[0].h_sig(*params, tx3.joinSplitPubKey);
|
||||
try {
|
||||
auto pt = libzcash::SproutNotePlaintext::decrypt(
|
||||
sproutDecryptor,
|
||||
tx3.vjoinsplit[0].ciphertexts[i],
|
||||
tx3.vjoinsplit[0].ephemeralKey,
|
||||
hSig,
|
||||
(unsigned char)i);
|
||||
sproutNote = pt.note(sproutAddr);
|
||||
sproutWitness = sproutTree.witness();
|
||||
break;
|
||||
} catch (const std::exception& e) {
|
||||
// One of the outputs must be ours
|
||||
assert(i + 1 < ZC_NUM_JS_OUTPUTS);
|
||||
}
|
||||
sproutTree.append(wtx.vjoinsplit[0].commitments[i]);
|
||||
}
|
||||
|
||||
SproutWitness sproutWitness = sproutTree.witness();
|
||||
// Fake a view with the Sprout note in it
|
||||
auto rt = sproutTree.root();
|
||||
TransactionBuilderCoinsViewDB fakeDB;
|
||||
|
@ -203,30 +218,31 @@ TEST(TransactionBuilder, Invoke)
|
|||
// - 0.00005 Sprout-ZEC change
|
||||
// - 0.00005 Sapling-ZEC out
|
||||
// - 0.00005 t-ZEC fee
|
||||
auto builder4 = TransactionBuilder(consensusParams, 2, nullptr, params, &view);
|
||||
builder4.SetFee(5000);
|
||||
builder4.AddSproutInput(sproutSk, sproutNote, sproutWitness);
|
||||
builder4.AddSproutOutput(sproutAddr, 6000);
|
||||
builder4.AddSproutOutput(sproutAddr, 4000);
|
||||
builder4.AddSaplingOutput(fvk.ovk, pk, 5000);
|
||||
auto tx4 = builder4.Build().GetTxOrThrow();
|
||||
auto builder = TransactionBuilder(consensusParams, 2, nullptr, params, &view);
|
||||
builder.SetFee(5000);
|
||||
builder.AddSproutInput(sproutSk, sproutNote, sproutWitness);
|
||||
builder.AddSproutOutput(sproutAddr, 6000);
|
||||
builder.AddSproutOutput(sproutAddr, 4000);
|
||||
builder.AddSaplingOutput(fvk.ovk, pa, 5000);
|
||||
auto tx = builder.Build().GetTxOrThrow();
|
||||
|
||||
EXPECT_EQ(tx4.vin.size(), 0);
|
||||
EXPECT_EQ(tx4.vout.size(), 0);
|
||||
EXPECT_EQ(tx.vin.size(), 0);
|
||||
EXPECT_EQ(tx.vout.size(), 0);
|
||||
// TODO: This should be doable in two JoinSplits.
|
||||
// There's an inefficiency in the implementation.
|
||||
EXPECT_EQ(tx4.vjoinsplit.size(), 3);
|
||||
EXPECT_EQ(tx4.vjoinsplit[0].vpub_old, 0);
|
||||
EXPECT_EQ(tx4.vjoinsplit[0].vpub_new, 0);
|
||||
EXPECT_EQ(tx4.vjoinsplit[1].vpub_old, 0);
|
||||
EXPECT_EQ(tx4.vjoinsplit[1].vpub_new, 0);
|
||||
EXPECT_EQ(tx4.vjoinsplit[2].vpub_old, 0);
|
||||
EXPECT_EQ(tx4.vjoinsplit[2].vpub_new, 10000);
|
||||
EXPECT_EQ(tx4.vShieldedSpend.size(), 0);
|
||||
EXPECT_EQ(tx4.vShieldedOutput.size(), 1);
|
||||
EXPECT_EQ(tx4.valueBalance, -5000);
|
||||
EXPECT_EQ(tx.vjoinsplit.size(), 3);
|
||||
EXPECT_EQ(tx.vjoinsplit[0].vpub_old, 0);
|
||||
EXPECT_EQ(tx.vjoinsplit[0].vpub_new, 0);
|
||||
EXPECT_EQ(tx.vjoinsplit[1].vpub_old, 0);
|
||||
EXPECT_EQ(tx.vjoinsplit[1].vpub_new, 0);
|
||||
EXPECT_EQ(tx.vjoinsplit[2].vpub_old, 0);
|
||||
EXPECT_EQ(tx.vjoinsplit[2].vpub_new, 10000);
|
||||
EXPECT_EQ(tx.vShieldedSpend.size(), 0);
|
||||
EXPECT_EQ(tx.vShieldedOutput.size(), 1);
|
||||
EXPECT_EQ(tx.valueBalance, -5000);
|
||||
|
||||
EXPECT_TRUE(ContextualCheckTransaction(tx4, state, 4, 0));
|
||||
CValidationState state;
|
||||
EXPECT_TRUE(ContextualCheckTransaction(tx, state, 4, 0));
|
||||
EXPECT_EQ(state.GetRejectReason(), "");
|
||||
|
||||
// Revert to default
|
||||
|
|
Loading…
Reference in New Issue