Update transaction size estimation to include V5 transactions
This commit is contained in:
parent
ffdc11c378
commit
a0740650c3
|
@ -27,6 +27,7 @@
|
|||
#include "primitives/transaction.h"
|
||||
#include "zcbenchmarks.h"
|
||||
#include "script/interpreter.h"
|
||||
#include "zcash/Zcash.h"
|
||||
#include "zcash/Address.hpp"
|
||||
#include "zcash/address/zip32.h"
|
||||
|
||||
|
@ -4352,43 +4353,16 @@ size_t EstimateTxSize(
|
|||
int nextBlockHeight) {
|
||||
CMutableTransaction mtx;
|
||||
mtx.fOverwintered = true;
|
||||
mtx.nVersionGroupId = SAPLING_VERSION_GROUP_ID;
|
||||
mtx.nVersion = SAPLING_TX_VERSION;
|
||||
mtx.nConsensusBranchId = CurrentEpochBranchId(nextBlockHeight, Params().GetConsensus());
|
||||
|
||||
bool fromTaddr = std::visit(match {
|
||||
[&](const AccountZTXOPattern& acct) {
|
||||
return
|
||||
acct.GetReceiverTypes().empty() ||
|
||||
acct.GetReceiverTypes().count(ReceiverType::P2PKH) > 0 ||
|
||||
acct.GetReceiverTypes().count(ReceiverType::P2SH) > 0;
|
||||
},
|
||||
[&](const CKeyID& keyId) {
|
||||
return true;
|
||||
},
|
||||
[&](const CScriptID& scriptId) {
|
||||
return true;
|
||||
},
|
||||
[&](const libzcash::UnifiedFullViewingKey& ufvk) {
|
||||
return ufvk.GetTransparentKey().has_value();
|
||||
},
|
||||
[&](const libzcash::SproutPaymentAddress& addr) {
|
||||
return false;
|
||||
},
|
||||
[&](const libzcash::SproutViewingKey& addr) {
|
||||
return false;
|
||||
},
|
||||
[&](const libzcash::SaplingPaymentAddress& addr) {
|
||||
return false;
|
||||
},
|
||||
[&](const libzcash::SaplingExtendedFullViewingKey& addr) {
|
||||
return false;
|
||||
}
|
||||
}, ztxoSelector.GetPattern());
|
||||
bool fromSprout = ztxoSelector.SelectsSprout();
|
||||
bool fromTaddr = ztxoSelector.SelectsTransparent();
|
||||
|
||||
// As a sanity check, estimate and verify that the size of the transaction will be valid.
|
||||
// Depending on the input notes, the actual tx size may turn out to be larger and perhaps invalid.
|
||||
size_t txsize = 0;
|
||||
size_t taddrRecipientCount = 0;
|
||||
size_t orchardRecipientCount = 0;
|
||||
for (const SendManyRecipient& recipient : recipients) {
|
||||
std::visit(match {
|
||||
[&](const CKeyID&) {
|
||||
|
@ -4405,13 +4379,27 @@ size_t EstimateTxSize(
|
|||
jsdesc.proof = GrothProof();
|
||||
mtx.vJoinSplit.push_back(jsdesc);
|
||||
},
|
||||
[&](const libzcash::UnifiedAddress& ua) {
|
||||
// FIXME
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Unified addresses not yet supported.");
|
||||
[&](const libzcash::OrchardRawAddress& addr) {
|
||||
if (fromSprout) {
|
||||
throw JSONRPCError(
|
||||
RPC_INVALID_PARAMETER,
|
||||
"Sending funds from a Sprout address to a Unified Address is not supported by z_sendmany");
|
||||
}
|
||||
orchardRecipientCount += 1;
|
||||
}
|
||||
}, recipient.address);
|
||||
}
|
||||
|
||||
bool nu5Active = Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_NU5);
|
||||
|
||||
if (fromSprout || !nu5Active) {
|
||||
mtx.nVersionGroupId = SAPLING_VERSION_GROUP_ID;
|
||||
mtx.nVersion = SAPLING_TX_VERSION;
|
||||
} else {
|
||||
mtx.nVersionGroupId = ZIP225_VERSION_GROUP_ID;
|
||||
mtx.nVersion = ZIP225_TX_VERSION;
|
||||
}
|
||||
|
||||
CTransaction tx(mtx);
|
||||
txsize += GetSerializeSize(tx, SER_NETWORK, tx.nVersion);
|
||||
if (fromTaddr) {
|
||||
|
@ -4420,6 +4408,12 @@ size_t EstimateTxSize(
|
|||
}
|
||||
txsize += CTXOUT_REGULAR_SIZE * taddrRecipientCount;
|
||||
|
||||
if (orchardRecipientCount > 0) {
|
||||
// - The Orchard transaction builder pads to a minimum of 2 actions.
|
||||
// - We subtract 1 because `GetSerializeSize(tx, ...)` already counts
|
||||
// `ZC_ZIP225_ORCHARD_NUM_ACTIONS_BASE_SIZE`.
|
||||
txsize += ZC_ZIP225_ORCHARD_BASE_SIZE - 1 + ZC_ZIP225_ORCHARD_MARGINAL_SIZE * std::max(2, (int) orchardRecipientCount);
|
||||
}
|
||||
return txsize;
|
||||
}
|
||||
|
||||
|
|
|
@ -6554,7 +6554,7 @@ std::optional<libzcash::UnifiedAddress> UnifiedAddressForReceiver::operator()(co
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool ZTXOSelector::SelectsTransparent() {
|
||||
bool ZTXOSelector::SelectsTransparent() const {
|
||||
return std::visit(match {
|
||||
[](const CKeyID& keyId) { return true; },
|
||||
[](const CScriptID& scriptId) { return true; },
|
||||
|
@ -6566,14 +6566,14 @@ bool ZTXOSelector::SelectsTransparent() {
|
|||
[](const AccountZTXOPattern& acct) { return acct.IncludesP2PKH() || acct.IncludesP2SH(); }
|
||||
}, this->pattern);
|
||||
}
|
||||
bool ZTXOSelector::SelectsSprout() {
|
||||
bool ZTXOSelector::SelectsSprout() const {
|
||||
return std::visit(match {
|
||||
[](const libzcash::SproutViewingKey& addr) { return true; },
|
||||
[](const libzcash::SproutPaymentAddress& extfvk) { return true; },
|
||||
[](const auto& addr) { return false; }
|
||||
}, this->pattern);
|
||||
}
|
||||
bool ZTXOSelector::SelectsSapling() {
|
||||
bool ZTXOSelector::SelectsSapling() const {
|
||||
return std::visit(match {
|
||||
[](const libzcash::SaplingPaymentAddress& addr) { return true; },
|
||||
[](const libzcash::SaplingExtendedSpendingKey& extfvk) { return true; },
|
||||
|
|
|
@ -762,9 +762,9 @@ public:
|
|||
return requireSpendingKeys;
|
||||
}
|
||||
|
||||
bool SelectsTransparent();
|
||||
bool SelectsSprout();
|
||||
bool SelectsSapling();
|
||||
bool SelectsTransparent() const;
|
||||
bool SelectsSprout() const;
|
||||
bool SelectsSapling() const;
|
||||
};
|
||||
|
||||
class SpendableInputs {
|
||||
|
|
|
@ -28,4 +28,20 @@
|
|||
#define ZC_SAPLING_ENCCIPHERTEXT_SIZE (ZC_SAPLING_ENCPLAINTEXT_SIZE + NOTEENCRYPTION_AUTH_BYTES)
|
||||
#define ZC_SAPLING_OUTCIPHERTEXT_SIZE (ZC_SAPLING_OUTPLAINTEXT_SIZE + NOTEENCRYPTION_AUTH_BYTES)
|
||||
|
||||
// - CompactSize is at least 1 byte
|
||||
#define ZC_ZIP225_ORCHARD_NUM_ACTIONS_SIZE 1
|
||||
#define ZC_ZIP225_ORCHARD_FLAGS_SIZE 1
|
||||
#define ZC_ZIP225_ORCHARD_VALUE_BALANCE_SIZE 8
|
||||
#define ZC_ZIP225_ORCHARD_ANCHOR_SIZE 32
|
||||
// - CompactSize is at least 2 bytes because sizeProofsOrchard >= 253
|
||||
#define ZC_ZIP225_ORCHARD_SIZE_PROOFS_BASE_SIZE 2
|
||||
#define ZC_ZIP225_ORCHARD_PROOF_BASE_SIZE 2720
|
||||
#define ZC_ZIP225_ORCHARD_BINDING_SIG_SIZE 64
|
||||
#define ZC_ZIP225_ORCHARD_BASE_SIZE (ZC_ZIP225_ORCHARD_NUM_ACTIONS_SIZE + ZC_ZIP225_ORCHARD_FLAGS_SIZE + ZC_ZIP225_ORCHARD_VALUE_BALANCE_SIZE + ZC_ZIP225_ORCHARD_ANCHOR_SIZE + ZC_ZIP225_ORCHARD_SIZE_PROOFS_BASE_SIZE + ZC_ZIP225_ORCHARD_PROOF_BASE_SIZE + ZC_ZIP225_ORCHARD_BINDING_SIG_SIZE)
|
||||
// Marginal transaction size per Orchard Action
|
||||
#define ZC_ZIP225_ORCHARD_ACTION_SIZE 820
|
||||
#define ZC_ZIP225_ORCHARD_SPEND_AUTH_SIG_SIZE 64
|
||||
#define ZC_ZIP225_ORCHARD_PROOF_MARGINAL_SIZE 2272
|
||||
#define ZC_ZIP225_ORCHARD_MARGINAL_SIZE (ZC_ZIP225_ORCHARD_ACTION_SIZE + ZC_ZIP225_ORCHARD_SPEND_AUTH_SIG_SIZE + ZC_ZIP225_ORCHARD_PROOF_MARGINAL_SIZE)
|
||||
|
||||
#endif // ZCASH_ZCASH_ZCASH_H
|
||||
|
|
Loading…
Reference in New Issue