OutputDescriptionInfo::Build()

This commit is contained in:
Jack Grigg 2019-05-17 17:39:30 +01:00
parent 95e446bf69
commit 17b2af94f6
2 changed files with 54 additions and 38 deletions

View File

@ -22,6 +22,52 @@ SpendDescriptionInfo::SpendDescriptionInfo(
librustzcash_sapling_generate_r(alpha.begin());
}
boost::optional<OutputDescription> OutputDescriptionInfo::Build(void* ctx) {
auto cmu = this->note.cmu();
if (!cmu) {
return boost::none;
}
libzcash::SaplingNotePlaintext notePlaintext(this->note, this->memo);
auto res = notePlaintext.encrypt(this->note.pk_d);
if (!res) {
return boost::none;
}
auto enc = res.get();
auto encryptor = enc.second;
libzcash::SaplingPaymentAddress address(this->note.d, this->note.pk_d);
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << address;
std::vector<unsigned char> addressBytes(ss.begin(), ss.end());
OutputDescription odesc;
if (!librustzcash_sapling_output_proof(
ctx,
encryptor.get_esk().begin(),
addressBytes.data(),
this->note.r.begin(),
this->note.value(),
odesc.cv.begin(),
odesc.zkproof.begin())) {
return boost::none;
}
odesc.cmu = *cmu;
odesc.ephemeralKey = encryptor.get_epk();
odesc.encCiphertext = enc.first;
libzcash::SaplingOutgoingPlaintext outPlaintext(this->note.pk_d, encryptor.get_esk());
odesc.outCiphertext = outPlaintext.encrypt(
this->ovk,
odesc.cv,
odesc.cmu,
encryptor);
return odesc;
}
TransactionBuilderResult::TransactionBuilderResult(const CTransaction& tx) : maybeTx(tx) {}
TransactionBuilderResult::TransactionBuilderResult(const std::string& error) : maybeError(error) {}
@ -302,51 +348,19 @@ TransactionBuilderResult TransactionBuilder::Build()
// Create Sapling OutputDescriptions
for (auto output : outputs) {
auto cmu = output.note.cmu();
if (!cmu) {
// Check this out here as well to provide better logging.
if (!output.note.cmu()) {
librustzcash_sapling_proving_ctx_free(ctx);
return TransactionBuilderResult("Output is invalid");
}
libzcash::SaplingNotePlaintext notePlaintext(output.note, output.memo);
auto res = notePlaintext.encrypt(output.note.pk_d);
if (!res) {
auto odesc = output.Build(ctx);
if (!odesc) {
librustzcash_sapling_proving_ctx_free(ctx);
return TransactionBuilderResult("Failed to encrypt note");
}
auto enc = res.get();
auto encryptor = enc.second;
libzcash::SaplingPaymentAddress address(output.note.d, output.note.pk_d);
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << address;
std::vector<unsigned char> addressBytes(ss.begin(), ss.end());
OutputDescription odesc;
if (!librustzcash_sapling_output_proof(
ctx,
encryptor.get_esk().begin(),
addressBytes.data(),
output.note.r.begin(),
output.note.value(),
odesc.cv.begin(),
odesc.zkproof.begin())) {
librustzcash_sapling_proving_ctx_free(ctx);
return TransactionBuilderResult("Output proof failed");
return TransactionBuilderResult("Failed to create output description");
}
odesc.cmu = *cmu;
odesc.ephemeralKey = encryptor.get_epk();
odesc.encCiphertext = enc.first;
libzcash::SaplingOutgoingPlaintext outPlaintext(output.note.pk_d, encryptor.get_esk());
odesc.outCiphertext = outPlaintext.encrypt(
output.ovk,
odesc.cv,
odesc.cmu,
encryptor);
mtx.vShieldedOutput.push_back(odesc);
mtx.vShieldedOutput.push_back(odesc.get());
}
//

View File

@ -43,6 +43,8 @@ struct OutputDescriptionInfo {
uint256 ovk,
libzcash::SaplingNote note,
std::array<unsigned char, ZC_MEMO_SIZE> memo) : ovk(ovk), note(note), memo(memo) {}
boost::optional<OutputDescription> Build(void* ctx);
};
struct TransparentInputInfo {