Merge pull request #5373 from ZcashFoundation/lib-zcash-script-sigops
Add legacy sigops counts to the zcash_script library API
This commit is contained in:
commit
f8e99e7ba5
|
@ -393,6 +393,7 @@ libbitcoin_common_a_SOURCES = \
|
||||||
netbase.cpp \
|
netbase.cpp \
|
||||||
primitives/block.cpp \
|
primitives/block.cpp \
|
||||||
primitives/transaction.cpp \
|
primitives/transaction.cpp \
|
||||||
|
primitives/tx_version_info.cpp \
|
||||||
proof_verifier.cpp \
|
proof_verifier.cpp \
|
||||||
protocol.cpp \
|
protocol.cpp \
|
||||||
pubkey.cpp \
|
pubkey.cpp \
|
||||||
|
@ -558,6 +559,7 @@ libzcash_script_la_SOURCES = \
|
||||||
crypto/sha512.cpp \
|
crypto/sha512.cpp \
|
||||||
hash.cpp \
|
hash.cpp \
|
||||||
primitives/transaction.cpp \
|
primitives/transaction.cpp \
|
||||||
|
primitives/tx_version_info.cpp \
|
||||||
pubkey.cpp \
|
pubkey.cpp \
|
||||||
script/zcash_script.cpp \
|
script/zcash_script.cpp \
|
||||||
script/interpreter.cpp \
|
script/interpreter.cpp \
|
||||||
|
|
|
@ -425,45 +425,3 @@ std::string CTransaction::ToString() const
|
||||||
str += " " + vout[i].ToString() + "\n";
|
str += " " + vout[i].ToString() + "\n";
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the most recent supported transaction version and version group id,
|
|
||||||
* as of the specified activation height and active features.
|
|
||||||
*/
|
|
||||||
TxVersionInfo CurrentTxVersionInfo(
|
|
||||||
const Consensus::Params& consensus,
|
|
||||||
int nHeight,
|
|
||||||
bool requireSprout)
|
|
||||||
{
|
|
||||||
if (consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_ZFUTURE)) {
|
|
||||||
return {
|
|
||||||
.fOverwintered = true,
|
|
||||||
.nVersionGroupId = ZFUTURE_VERSION_GROUP_ID,
|
|
||||||
.nVersion = ZFUTURE_TX_VERSION
|
|
||||||
};
|
|
||||||
} else if (consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_NU5) && !requireSprout) {
|
|
||||||
return {
|
|
||||||
.fOverwintered = true,
|
|
||||||
.nVersionGroupId = ZIP225_VERSION_GROUP_ID,
|
|
||||||
.nVersion = ZIP225_TX_VERSION
|
|
||||||
};
|
|
||||||
} else if (consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_SAPLING)) {
|
|
||||||
return {
|
|
||||||
.fOverwintered = true,
|
|
||||||
.nVersionGroupId = SAPLING_VERSION_GROUP_ID,
|
|
||||||
.nVersion = SAPLING_TX_VERSION
|
|
||||||
};
|
|
||||||
} else if (consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_OVERWINTER)) {
|
|
||||||
return {
|
|
||||||
.fOverwintered = true,
|
|
||||||
.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID,
|
|
||||||
.nVersion = OVERWINTER_TX_VERSION
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
.fOverwintered = false,
|
|
||||||
.nVersionGroupId = 0,
|
|
||||||
.nVersion = CTransaction::SPROUT_MIN_CURRENT_VERSION
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
// Copyright (c) 2021 The Zcash developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
|
||||||
|
|
||||||
|
#include "primitives/transaction.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the most recent supported transaction version and version group id,
|
||||||
|
* as of the specified activation height and active features.
|
||||||
|
*/
|
||||||
|
TxVersionInfo CurrentTxVersionInfo(
|
||||||
|
const Consensus::Params& consensus,
|
||||||
|
int nHeight,
|
||||||
|
bool requireSprout)
|
||||||
|
{
|
||||||
|
if (consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_ZFUTURE)) {
|
||||||
|
return {
|
||||||
|
.fOverwintered = true,
|
||||||
|
.nVersionGroupId = ZFUTURE_VERSION_GROUP_ID,
|
||||||
|
.nVersion = ZFUTURE_TX_VERSION
|
||||||
|
};
|
||||||
|
} else if (consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_NU5) && !requireSprout) {
|
||||||
|
return {
|
||||||
|
.fOverwintered = true,
|
||||||
|
.nVersionGroupId = ZIP225_VERSION_GROUP_ID,
|
||||||
|
.nVersion = ZIP225_TX_VERSION
|
||||||
|
};
|
||||||
|
} else if (consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_SAPLING)) {
|
||||||
|
return {
|
||||||
|
.fOverwintered = true,
|
||||||
|
.nVersionGroupId = SAPLING_VERSION_GROUP_ID,
|
||||||
|
.nVersion = SAPLING_TX_VERSION
|
||||||
|
};
|
||||||
|
} else if (consensus.NetworkUpgradeActive(nHeight, Consensus::UPGRADE_OVERWINTER)) {
|
||||||
|
return {
|
||||||
|
.fOverwintered = true,
|
||||||
|
.nVersionGroupId = OVERWINTER_VERSION_GROUP_ID,
|
||||||
|
.nVersion = OVERWINTER_TX_VERSION
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
.fOverwintered = false,
|
||||||
|
.nVersionGroupId = 0,
|
||||||
|
.nVersion = CTransaction::SPROUT_MIN_CURRENT_VERSION
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,13 +6,13 @@ use std::mem::size_of_val;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
use orchard::{bundle::Authorized, tree::MerkleHashOrchard};
|
use orchard::{bundle::Authorized, tree::MerkleHashOrchard};
|
||||||
|
use tracing::error;
|
||||||
use zcash_primitives::{
|
use zcash_primitives::{
|
||||||
merkle_tree::incremental::{read_frontier_v1, read_tree, write_frontier_v1, write_tree},
|
merkle_tree::incremental::{read_frontier_v1, read_tree, write_frontier_v1, write_tree},
|
||||||
transaction::components::Amount,
|
transaction::components::Amount,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::orchard_ffi::{error, CppStreamReader, CppStreamWriter, ReadCb, StreamObj, WriteCb};
|
use crate::streams_ffi::{CppStreamReader, CppStreamWriter, ReadCb, StreamObj, WriteCb};
|
||||||
|
|
||||||
pub const MERKLE_DEPTH: u8 = 32;
|
pub const MERKLE_DEPTH: u8 = 32;
|
||||||
pub const MAX_CHECKPOINTS: usize = 100;
|
pub const MAX_CHECKPOINTS: usize = 100;
|
|
@ -19,8 +19,6 @@ use zcash_primitives::transaction::{
|
||||||
|
|
||||||
use crate::streams_ffi::{CppStreamReader, CppStreamWriter, ReadCb, StreamObj, WriteCb};
|
use crate::streams_ffi::{CppStreamReader, CppStreamWriter, ReadCb, StreamObj, WriteCb};
|
||||||
|
|
||||||
mod incremental_sinsemilla_tree_ffi;
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn orchard_bundle_clone(
|
pub extern "C" fn orchard_bundle_clone(
|
||||||
bundle: *const Bundle<Authorized, Amount>,
|
bundle: *const Bundle<Authorized, Amount>,
|
||||||
|
|
|
@ -70,6 +70,7 @@ mod tracing_ffi;
|
||||||
|
|
||||||
mod address_ffi;
|
mod address_ffi;
|
||||||
mod history_ffi;
|
mod history_ffi;
|
||||||
|
mod incremental_sinsemilla_tree_ffi;
|
||||||
mod orchard_ffi;
|
mod orchard_ffi;
|
||||||
mod transaction_ffi;
|
mod transaction_ffi;
|
||||||
mod zip339_ffi;
|
mod zip339_ffi;
|
||||||
|
|
|
@ -69,6 +69,22 @@ struct ECCryptoClosure
|
||||||
};
|
};
|
||||||
|
|
||||||
ECCryptoClosure instance_of_eccryptoclosure;
|
ECCryptoClosure instance_of_eccryptoclosure;
|
||||||
|
|
||||||
|
// Copy of GetLegacySigOpCount from main.cpp commit c4b2ef7c4.
|
||||||
|
// Replace with the copy from src/consensus/tx_verify.{cpp,h} after backporting that refactor.
|
||||||
|
unsigned int GetLegacySigOpCount(const CTransaction& tx)
|
||||||
|
{
|
||||||
|
unsigned int nSigOps = 0;
|
||||||
|
for (const CTxIn& txin : tx.vin)
|
||||||
|
{
|
||||||
|
nSigOps += txin.scriptSig.GetSigOpCount(false);
|
||||||
|
}
|
||||||
|
for (const CTxOut& txout : tx.vout)
|
||||||
|
{
|
||||||
|
nSigOps += txout.scriptPubKey.GetSigOpCount(false);
|
||||||
|
}
|
||||||
|
return nSigOps;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PrecomputedTransaction {
|
struct PrecomputedTransaction {
|
||||||
|
@ -92,7 +108,7 @@ void* zcash_script_new_precomputed_tx(
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regardless of the verification result, the tx did not error.
|
// Deserializing the tx did not error.
|
||||||
set_error(err, zcash_script_ERR_OK);
|
set_error(err, zcash_script_ERR_OK);
|
||||||
auto preTx = new PrecomputedTransaction(tx);
|
auto preTx = new PrecomputedTransaction(tx);
|
||||||
return preTx;
|
return preTx;
|
||||||
|
@ -166,6 +182,42 @@ int zcash_script_verify(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int zcash_script_legacy_sigop_count_precomputed(
|
||||||
|
const void* pre_preTx,
|
||||||
|
zcash_script_error* err)
|
||||||
|
{
|
||||||
|
const PrecomputedTransaction* preTx = static_cast<const PrecomputedTransaction*>(pre_preTx);
|
||||||
|
|
||||||
|
// The current implementation of this method never errors.
|
||||||
|
set_error(err, zcash_script_ERR_OK);
|
||||||
|
|
||||||
|
return GetLegacySigOpCount(preTx->tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int zcash_script_legacy_sigop_count(
|
||||||
|
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 UINT_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deserializing the tx did not error.
|
||||||
|
set_error(err, zcash_script_ERR_OK);
|
||||||
|
|
||||||
|
return GetLegacySigOpCount(tx);
|
||||||
|
} catch (const std::exception&) {
|
||||||
|
set_error(err, zcash_script_ERR_TX_DESERIALIZE); // Error deserializing
|
||||||
|
return UINT_MAX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int zcash_script_version()
|
unsigned int zcash_script_version()
|
||||||
{
|
{
|
||||||
// Just use the API version for now
|
// Just use the API version for now
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ZCASH_SCRIPT_API_VER 1
|
#define ZCASH_SCRIPT_API_VER 2
|
||||||
|
|
||||||
typedef enum zcash_script_error_t
|
typedef enum zcash_script_error_t
|
||||||
{
|
{
|
||||||
|
@ -99,6 +99,28 @@ EXPORT_SYMBOL int zcash_script_verify(
|
||||||
uint32_t consensusBranchId,
|
uint32_t consensusBranchId,
|
||||||
zcash_script_error* err);
|
zcash_script_error* err);
|
||||||
|
|
||||||
|
/// Returns the number of transparent signature operations in the
|
||||||
|
/// transparent inputs and outputs of the precomputed transaction
|
||||||
|
/// pointed to by preTx.
|
||||||
|
///
|
||||||
|
/// Returns UINT_MAX on error, so that invalid transactions don't pass the Zcash consensus rules.
|
||||||
|
/// If not NULL, err will contain an error/success code for the operation.
|
||||||
|
EXPORT_SYMBOL unsigned int zcash_script_legacy_sigop_count_precomputed(
|
||||||
|
const void* preTx,
|
||||||
|
zcash_script_error* err);
|
||||||
|
|
||||||
|
/// Returns the number of transparent signature operations in the
|
||||||
|
/// transparent inputs and outputs of the serialized transaction
|
||||||
|
/// pointed to by txTo.
|
||||||
|
///
|
||||||
|
/// Returns UINT_MAX on error.
|
||||||
|
/// If not NULL, err will contain an error/success code for the operation.
|
||||||
|
EXPORT_SYMBOL unsigned int zcash_script_legacy_sigop_count(
|
||||||
|
const unsigned char *txTo,
|
||||||
|
unsigned int txToLen,
|
||||||
|
zcash_script_error* err);
|
||||||
|
|
||||||
|
/// Returns the current version of the zcash_script library.
|
||||||
EXPORT_SYMBOL unsigned int zcash_script_version();
|
EXPORT_SYMBOL unsigned int zcash_script_version();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
Loading…
Reference in New Issue