Check nSpendsSapling, nOutputsSapling, and nActionsOrchard 2^16 limit (#3069)

* Check nSpendsSapling, nOutputsSapling, and nActionsOrchard 2^16 limit

* Apply suggestions from code review

Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>

* Removed not required #[macro_use]

Co-authored-by: Janito Vaqueiro Ferreira Filho <janito.vff@gmail.com>
This commit is contained in:
Conrado Gouvea 2021-11-18 15:06:07 -03:00 committed by GitHub
parent 3fc049e2eb
commit 88b09c812a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 28 additions and 3 deletions

1
Cargo.lock generated
View File

@ -4347,6 +4347,7 @@ dependencies = [
"serde-big-array",
"sha2",
"spandoc",
"static_assertions",
"subtle",
"thiserror",
"tracing",

View File

@ -40,6 +40,7 @@ secp256k1 = { version = "0.20.3", features = ["serde"] }
serde = { version = "1", features = ["serde_derive", "rc"] }
serde-big-array = "0.3.2"
sha2 = { version = "0.9.8", features=["compress"] }
static_assertions = "1.1.0"
subtle = "2.4"
thiserror = "1"
uint = "0.9.1"

View File

@ -182,7 +182,14 @@ impl TrustedPreallocate for Action {
// Since a serialized Vec<AuthorizedAction> uses at least one byte for its length,
// and the signature is required,
// a valid max allocation can never exceed this size
(MAX_BLOCK_BYTES - 1) / AUTHORIZED_ACTION_SIZE
const MAX: u64 = (MAX_BLOCK_BYTES - 1) / AUTHORIZED_ACTION_SIZE;
// > [NU5 onward] nSpendsSapling, nOutputsSapling, and nActionsOrchard MUST all be less than 2^16.
// https://zips.z.cash/protocol/protocol.pdf#txnencodingandconsensus
// This acts as nActionsOrchard and is therefore subject to the rule.
// The maximum value is actually smaller due to the block size limit,
// but we ensure the 2^16 limit with a static assertion.
static_assertions::const_assert!(MAX < (1 << 16));
MAX
}
}

View File

@ -217,7 +217,15 @@ impl TrustedPreallocate for OutputInTransactionV4 {
fn max_allocation() -> u64 {
// Since a serialized Vec<Output> uses at least one byte for its length,
// the max allocation can never exceed (MAX_BLOCK_BYTES - 1) / OUTPUT_SIZE
(MAX_BLOCK_BYTES - 1) / OUTPUT_SIZE
const MAX: u64 = (MAX_BLOCK_BYTES - 1) / OUTPUT_SIZE;
// > [NU5 onward] nSpendsSapling, nOutputsSapling, and nActionsOrchard MUST all be less than 2^16.
// https://zips.z.cash/protocol/protocol.pdf#txnencodingandconsensus
// This acts as nOutputsSapling and is therefore subject to the rule.
// The maximum value is actually smaller due to the block size limit,
// but we ensure the 2^16 limit with a static assertion.
// (The check is not required pre-NU5, but it doesn't cause problems.)
static_assertions::const_assert!(MAX < (1 << 16));
MAX
}
}

View File

@ -276,7 +276,15 @@ impl TrustedPreallocate for SpendPrefixInTransactionV5 {
// Since a serialized Vec<Spend> uses at least one byte for its length,
// and the associated fields are required,
// a valid max allocation can never exceed this size
(MAX_BLOCK_BYTES - 1) / SHARED_ANCHOR_SPEND_SIZE
const MAX: u64 = (MAX_BLOCK_BYTES - 1) / SHARED_ANCHOR_SPEND_SIZE;
// > [NU5 onward] nSpendsSapling, nOutputsSapling, and nActionsOrchard MUST all be less than 2^16.
// https://zips.z.cash/protocol/protocol.pdf#txnencodingandconsensus
// This acts as nSpendsSapling and is therefore subject to the rule.
// The maximum value is actually smaller due to the block size limit,
// but we ensure the 2^16 limit with a static assertion.
// (The check is not required pre-NU5, but it doesn't cause problems.)
static_assertions::const_assert!(MAX < (1 << 16));
MAX
}
}