Auto merge of #4986 - str4d:zcash-script-precompute, r=str4d

zcash_script: Add API to verify scripts with precomputed tx data

This enables users of libzcash_script to more efficiently verify transactions with multiple inputs.

Closes zcash/zcash#4876.
This commit is contained in:
Homu 2021-02-18 15:59:11 +00:00
commit 6f04751c49
2 changed files with 101 additions and 2 deletions

View File

@ -71,6 +71,69 @@ struct ECCryptoClosure
ECCryptoClosure instance_of_eccryptoclosure;
}
struct PrecomputedTransaction {
const CTransaction tx;
const PrecomputedTransactionData txdata;
PrecomputedTransaction(CTransaction txIn) : tx(txIn), txdata(txIn) {}
};
void* zcash_script_new_precomputed_tx(
const unsigned char* txTo,
unsigned int txToLen,
zcash_script_error* err)
{
try {
TxInputStream stream(SER_NETWORK, PROTOCOL_VERSION, txTo, txToLen);
CTransaction tx;
stream >> tx;
if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen) {
set_error(err, zcash_script_ERR_TX_SIZE_MISMATCH);
return nullptr;
}
// Regardless of the verification result, the tx did not error.
set_error(err, zcash_script_ERR_OK);
auto preTx = new PrecomputedTransaction(tx);
return preTx;
} catch (const std::exception&) {
set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing
return nullptr;
}
}
void zcash_script_free_precomputed_tx(void* pre_preTx)
{
PrecomputedTransaction* preTx = static_cast<PrecomputedTransaction*>(pre_preTx);
delete preTx;
preTx = nullptr;
}
int zcash_script_verify_precomputed(
const void* pre_preTx,
unsigned int nIn,
const unsigned char* scriptPubKey,
unsigned int scriptPubKeyLen,
int64_t amount,
unsigned int flags,
uint32_t consensusBranchId,
zcash_script_error* err)
{
const PrecomputedTransaction* preTx = static_cast<const PrecomputedTransaction*>(pre_preTx);
if (nIn >= preTx->tx.vin.size())
return set_error(err, zcash_script_ERR_TX_INDEX);
// Regardless of the verification result, the tx did not error.
set_error(err, zcash_script_ERR_OK);
return VerifyScript(
preTx->tx.vin[nIn].scriptSig,
CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen),
flags,
TransactionSignatureChecker(&preTx->tx, nIn, amount, preTx->txdata),
consensusBranchId,
NULL);
}
int zcash_script_verify(
const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen,
int64_t amount,

View File

@ -33,7 +33,7 @@
extern "C" {
#endif
#define ZCASH_SCRIPT_API_VER 0
#define ZCASH_SCRIPT_API_VER 1
typedef enum zcash_script_error_t
{
@ -51,10 +51,46 @@ enum
zcash_script_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), // enable CHECKLOCKTIMEVERIFY (BIP65)
};
/// Deserializes the given transaction and precomputes values to improve
/// script verification performance.
///
/// Returns a pointer to the precomputed transaction. Free this with
/// zcash_script_free_precomputed_tx once you are done.
///
/// If not NULL, err will contain an error/success code for the operation.
void* zcash_script_new_precomputed_tx(
const unsigned char* txTo,
unsigned int txToLen,
zcash_script_error* err);
/// Frees a precomputed transaction previously created with
/// zcash_script_new_precomputed_tx.
void zcash_script_free_precomputed_tx(void* preTx);
/// Returns 1 if the input nIn of the precomputed transaction pointed to by
/// preTx correctly spends the scriptPubKey pointed to by scriptPubKey under
/// the additional constraints specified by flags.
///
/// If not NULL, err will contain an error/success code for the operation.
/// Note that script verification failure is indicated by err being set to
/// zcash_script_ERR_OK and a return value of 0.
EXPORT_SYMBOL int zcash_script_verify_precomputed(
const void* preTx,
unsigned int nIn,
const unsigned char* scriptPubKey,
unsigned int scriptPubKeyLen,
int64_t amount,
unsigned int flags,
uint32_t consensusBranchId,
zcash_script_error* err);
/// Returns 1 if the input nIn of the serialized transaction pointed to by
/// txTo correctly spends the scriptPubKey pointed to by scriptPubKey under
/// the additional constraints specified by flags.
/// If not NULL, err will contain an error/success code for the operation
///
/// If not NULL, err will contain an error/success code for the operation.
/// Note that script verification failure is indicated by err being set to
/// zcash_script_ERR_OK and a return value of 0.
EXPORT_SYMBOL int zcash_script_verify(
const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen,
int64_t amount,