OutputDescriptionInfo::Build()
This commit is contained in:
parent
95e446bf69
commit
17b2af94f6
|
@ -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());
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue