Split test in to multiple parts

This commit is contained in:
Eirik0 2019-02-26 15:09:55 -07:00
parent cb51e03587
commit 9e8729113c
1 changed files with 109 additions and 93 deletions

View File

@ -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