Skip to content

Commit ff2dec2

Browse files
random-zebraFuzzbawls
authored andcommitted
Sapling: Decouple ProveAndSign from Build
Github-Pull: #2065 Rebased-From: efd7139
1 parent 5b7e86d commit ff2dec2

File tree

2 files changed

+76
-69
lines changed

2 files changed

+76
-69
lines changed

src/sapling/transaction_builder.cpp

Lines changed: 74 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -209,66 +209,31 @@ void TransactionBuilder::SendChangeTo(CTxDestination& changeAddr)
209209
saplingChangeAddr = nullopt;
210210
}
211211

212-
TransactionBuilderResult TransactionBuilder::Build()
212+
TransactionBuilderResult TransactionBuilder::ProveAndSign()
213213
{
214214
//
215-
// Consistency checks
215+
// Sapling spend descriptions
216216
//
217-
// Valid fee
218-
if (fee < 0) {
219-
return TransactionBuilderResult("Fee cannot be negative");
220-
}
221-
222-
// Valid change
223-
CAmount change = mtx.sapData->valueBalance - fee;
224-
for (auto& tIn : tIns) {
225-
change += tIn.value;
226-
}
227-
for (auto& tOut : mtx.vout) {
228-
change -= tOut.nValue;
229-
}
230-
if (change < 0) {
231-
return TransactionBuilderResult("Change cannot be negative");
232-
}
217+
if (!spends.empty() || !outputs.empty()) {
233218

234-
//
235-
// Change output
236-
//
219+
auto ctx = librustzcash_sapling_proving_ctx_init();
237220

238-
if (change > 0) {
239-
// If we get here and the change is dust, add it to the fee
240-
CAmount dustThreshold = (spends.empty() && outputs.empty()) ? GetDustThreshold(minRelayTxFee) :
241-
GetShieldedDustThreshold(minRelayTxFee);
242-
if (change > dustThreshold) {
243-
// Send change to the specified change address. If no change address
244-
// was set, send change to the first Sapling address given as input
245-
// (A t-address can only be used as the change address if explicitly set.)
246-
if (saplingChangeAddr) {
247-
AddSaplingOutput(saplingChangeAddr->first, saplingChangeAddr->second, change);
248-
} else if (tChangeAddr) {
249-
// tChangeAddr has already been validated.
250-
AddTransparentOutput(*tChangeAddr, change);
251-
} else if (!spends.empty()) {
252-
auto fvk = spends[0].expsk.full_viewing_key();
253-
auto note = spends[0].note;
254-
libzcash::SaplingPaymentAddress changeAddr(note.d, note.pk_d);
255-
AddSaplingOutput(fvk.ovk, changeAddr, change);
256-
} else {
257-
return TransactionBuilderResult("Could not determine change address");
221+
// Create Sapling OutputDescriptions
222+
for (auto output : outputs) {
223+
// Check this out here as well to provide better logging.
224+
if (!output.note.cmu()) {
225+
librustzcash_sapling_proving_ctx_free(ctx);
226+
return TransactionBuilderResult("Output is invalid");
258227
}
259-
} else {
260-
// Not used after, but update for consistency
261-
fee += change;
262-
change = 0;
263-
}
264-
}
265228

266-
//
267-
// Sapling spends and outputs
268-
//
269-
if (!spends.empty() || !outputs.empty()) {
229+
auto odesc = output.Build(ctx);
230+
if (!odesc) {
231+
librustzcash_sapling_proving_ctx_free(ctx);
232+
return TransactionBuilderResult("Failed to create output description");
233+
}
270234

271-
auto ctx = librustzcash_sapling_proving_ctx_init();
235+
mtx.sapData->vShieldedOutput.push_back(odesc.get());
236+
}
272237

273238
// Create Sapling SpendDescriptions
274239
for (auto spend : spends) {
@@ -307,23 +272,6 @@ TransactionBuilderResult TransactionBuilder::Build()
307272
mtx.sapData->vShieldedSpend.push_back(sdesc);
308273
}
309274

310-
// Create Sapling OutputDescriptions
311-
for (auto output : outputs) {
312-
// Check this out here as well to provide better logging.
313-
if (!output.note.cmu()) {
314-
librustzcash_sapling_proving_ctx_free(ctx);
315-
return TransactionBuilderResult("Output is invalid");
316-
}
317-
318-
auto odesc = output.Build(ctx);
319-
if (!odesc) {
320-
librustzcash_sapling_proving_ctx_free(ctx);
321-
return TransactionBuilderResult("Failed to create output description");
322-
}
323-
324-
mtx.sapData->vShieldedOutput.push_back(odesc.get());
325-
}
326-
327275
//
328276
// Signatures
329277
//
@@ -375,3 +323,60 @@ TransactionBuilderResult TransactionBuilder::Build()
375323

376324
return TransactionBuilderResult(CTransaction(mtx));
377325
}
326+
327+
TransactionBuilderResult TransactionBuilder::Build()
328+
{
329+
//
330+
// Consistency checks
331+
//
332+
// Valid fee
333+
if (fee < 0) {
334+
return TransactionBuilderResult("Fee cannot be negative");
335+
}
336+
337+
// Valid change
338+
CAmount change = mtx.sapData->valueBalance - fee;
339+
for (auto& tIn : tIns) {
340+
change += tIn.value;
341+
}
342+
for (auto& tOut : mtx.vout) {
343+
change -= tOut.nValue;
344+
}
345+
if (change < 0) {
346+
return TransactionBuilderResult("Change cannot be negative");
347+
}
348+
349+
//
350+
// Change output
351+
//
352+
353+
if (change > 0) {
354+
// If we get here and the change is dust, add it to the fee
355+
CAmount dustThreshold = (spends.empty() && outputs.empty()) ? GetDustThreshold(minRelayTxFee) :
356+
GetShieldedDustThreshold(minRelayTxFee);
357+
if (change > dustThreshold) {
358+
// Send change to the specified change address. If no change address
359+
// was set, send change to the first Sapling address given as input
360+
// (A t-address can only be used as the change address if explicitly set.)
361+
if (saplingChangeAddr) {
362+
AddSaplingOutput(saplingChangeAddr->first, saplingChangeAddr->second, change);
363+
} else if (tChangeAddr) {
364+
// tChangeAddr has already been validated.
365+
AddTransparentOutput(*tChangeAddr, change);
366+
} else if (!spends.empty()) {
367+
auto fvk = spends[0].expsk.full_viewing_key();
368+
auto note = spends[0].note;
369+
libzcash::SaplingPaymentAddress changeAddr(note.d, note.pk_d);
370+
AddSaplingOutput(fvk.ovk, changeAddr, change);
371+
} else {
372+
return TransactionBuilderResult("Could not determine change address");
373+
}
374+
} else {
375+
// Not used after, but update for consistency
376+
fee += change;
377+
change = 0;
378+
}
379+
}
380+
381+
return ProveAndSign();
382+
}

src/sapling/transaction_builder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ class TransactionBuilder
121121
void SendChangeTo(CTxDestination& changeAddr);
122122

123123
TransactionBuilderResult Build();
124+
// Add Sapling Spend/Output descriptions, binding sig, and transparent signatures
125+
TransactionBuilderResult ProveAndSign();
124126
};
125127

126128
#endif /* TRANSACTION_BUILDER_H */

0 commit comments

Comments
 (0)