Skip to content

Commit 1ba587c

Browse files
committed
Rpc coinbase outputs calculation fix & tests updates
1 parent 4029650 commit 1ba587c

File tree

8 files changed

+85
-17
lines changed

8 files changed

+85
-17
lines changed

zebra-chain/src/parameters/network/testnet.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ impl Parameters {
616616
nu5: nu5_activation_height,
617617
nu6: nu6_activation_height,
618618
#[cfg(zcash_unstable = "nsm")]
619-
zfuture: nu5_activation_height.map(|height| height + 101),
619+
zfuture: nu5_activation_height.map(|height| height + 1),
620620
..Default::default()
621621
})
622622
.with_halving_interval(PRE_BLOSSOM_REGTEST_HALVING_INTERVAL);

zebra-chain/src/parameters/network/tests/vectors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ fn activates_network_upgrades_correctly() {
147147
// TODO: Remove this once the testnet parameters are being serialized (#8920).
148148
(Height(100), NetworkUpgrade::Nu5),
149149
#[cfg(zcash_unstable = "nsm")]
150-
(Height(201), NetworkUpgrade::ZFuture),
150+
(Height(101), NetworkUpgrade::ZFuture),
151151
];
152152

153153
for (network, expected_activation_heights) in [

zebra-rpc/src/methods/get_block_template_rpcs.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ where
625625
let mempool = self.mempool.clone();
626626
let mut latest_chain_tip = self.latest_chain_tip.clone();
627627
let sync_status = self.sync_status.clone();
628-
let state = self.state.clone();
628+
let mut state = self.state.clone();
629629

630630
if let Some(HexData(block_proposal_bytes)) = parameters
631631
.as_ref()
@@ -901,6 +901,38 @@ where
901901
None
902902
};
903903

904+
#[cfg(zcash_unstable = "nsm")]
905+
let expected_block_subsidy = {
906+
let money_reserve = match state
907+
.ready()
908+
.await
909+
.map_err(|_| Error {
910+
code: ErrorCode::InternalError,
911+
message: "".into(),
912+
data: None,
913+
})?
914+
.call(ReadRequest::TipPoolValues)
915+
.await
916+
.map_err(|_| Error {
917+
code: ErrorCode::InternalError,
918+
message: "".into(),
919+
data: None,
920+
})? {
921+
ReadResponse::TipPoolValues {
922+
tip_hash: _,
923+
tip_height: _,
924+
value_balance,
925+
} => value_balance.money_reserve(),
926+
_ => unreachable!("wrong response to ReadRequest::TipPoolValues"),
927+
};
928+
general::block_subsidy(next_block_height, &network, money_reserve)
929+
.map_server_error()?
930+
};
931+
932+
#[cfg(not(zcash_unstable = "nsm"))]
933+
let expected_block_subsidy =
934+
general::block_subsidy_pre_nsm(next_block_height, &network).map_server_error()?;
935+
904936
// Randomly select some mempool transactions.
905937
let mempool_txs = zip317::select_mempool_transactions(
906938
&network,
@@ -909,6 +941,7 @@ where
909941
mempool_txs,
910942
debug_like_zcashd,
911943
extra_coinbase_data.clone(),
944+
expected_block_subsidy,
912945
#[cfg(zcash_unstable = "nsm")]
913946
burn_amount,
914947
)
@@ -932,6 +965,7 @@ where
932965
submit_old,
933966
debug_like_zcashd,
934967
extra_coinbase_data,
968+
expected_block_subsidy,
935969
#[cfg(zcash_unstable = "nsm")]
936970
burn_amount,
937971
);

zebra-rpc/src/methods/get_block_template_rpcs/get_block_template.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use jsonrpc_core::{Error, ErrorCode, Result};
66
use tower::{Service, ServiceExt};
77

88
use zebra_chain::{
9-
amount::{self, Amount, NegativeOrZero, NonNegative, MAX_MONEY},
9+
amount::{self, Amount, NegativeOrZero, NonNegative},
1010
block::{
1111
self,
1212
merkle::{self, AuthDataRoot},
@@ -297,6 +297,7 @@ pub fn generate_coinbase_and_roots(
297297
history_tree: Arc<zebra_chain::history_tree::HistoryTree>,
298298
like_zcashd: bool,
299299
extra_coinbase_data: Vec<u8>,
300+
expected_block_subsidy: Amount<NonNegative>,
300301
#[cfg(zcash_unstable = "nsm")] burn_amount: Option<Amount<NonNegative>>,
301302
) -> (TransactionTemplate<NegativeOrZero>, DefaultRoots) {
302303
// Generate the coinbase transaction
@@ -308,6 +309,7 @@ pub fn generate_coinbase_and_roots(
308309
miner_fee,
309310
like_zcashd,
310311
extra_coinbase_data,
312+
expected_block_subsidy,
311313
#[cfg(zcash_unstable = "nsm")]
312314
burn_amount,
313315
);
@@ -336,16 +338,25 @@ pub fn generate_coinbase_and_roots(
336338
///
337339
/// If `like_zcashd` is true, try to match the coinbase transactions generated by `zcashd`
338340
/// in the `getblocktemplate` RPC.
341+
#[allow(clippy::too_many_arguments)]
339342
pub fn generate_coinbase_transaction(
340343
network: &Network,
341344
height: Height,
342345
miner_address: &transparent::Address,
343346
miner_fee: Amount<NonNegative>,
344347
like_zcashd: bool,
345348
extra_coinbase_data: Vec<u8>,
349+
expected_block_subsidy: Amount<NonNegative>,
346350
#[cfg(zcash_unstable = "nsm")] burn_amount: Option<Amount<NonNegative>>,
347351
) -> UnminedTx {
348-
let outputs = standard_coinbase_outputs(network, height, miner_address, miner_fee, like_zcashd);
352+
let outputs = standard_coinbase_outputs(
353+
network,
354+
height,
355+
miner_address,
356+
miner_fee,
357+
like_zcashd,
358+
expected_block_subsidy,
359+
);
349360

350361
if like_zcashd {
351362
#[cfg(zcash_unstable = "nsm")]
@@ -424,17 +435,8 @@ pub fn standard_coinbase_outputs(
424435
miner_address: &transparent::Address,
425436
miner_fee: Amount<NonNegative>,
426437
like_zcashd: bool,
438+
expected_block_subsidy: Amount<NonNegative>,
427439
) -> Vec<(Amount<NonNegative>, transparent::Script)> {
428-
#[cfg(zcash_unstable = "nsm")]
429-
let expected_block_subsidy = general::block_subsidy(
430-
height,
431-
network,
432-
MAX_MONEY.try_into().expect("MAX_MONEY is a valid amount"),
433-
)
434-
.expect("valid block subsidy");
435-
#[cfg(not(zcash_unstable = "nsm"))]
436-
let expected_block_subsidy =
437-
general::block_subsidy_pre_nsm(height, network).expect("valid block subsidy");
438440
let funding_streams =
439441
funding_streams::funding_stream_values(height, network, expected_block_subsidy)
440442
.expect("funding stream value calculations are valid for reasonable chain heights");

zebra-rpc/src/methods/get_block_template_rpcs/types/get_block_template.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ impl GetBlockTemplate {
231231
submit_old: Option<bool>,
232232
like_zcashd: bool,
233233
extra_coinbase_data: Vec<u8>,
234+
expected_block_subsidy: Amount<NonNegative>,
234235
#[cfg(zcash_unstable = "nsm")] burn_amount: Option<Amount<NonNegative>>,
235236
) -> Self {
236237
// Calculate the next block height.
@@ -272,6 +273,7 @@ impl GetBlockTemplate {
272273
chain_tip_and_local_time.history_tree.clone(),
273274
like_zcashd,
274275
extra_coinbase_data,
276+
expected_block_subsidy,
275277
#[cfg(zcash_unstable = "nsm")]
276278
burn_amount,
277279
);

zebra-rpc/src/methods/get_block_template_rpcs/zip317.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,15 @@ use crate::methods::get_block_template_rpcs::{
3636
/// Returns selected transactions from `mempool_txs`.
3737
///
3838
/// [ZIP-317]: https://zips.z.cash/zip-0317#block-production
39+
#[allow(clippy::too_many_arguments)]
3940
pub async fn select_mempool_transactions(
4041
network: &Network,
4142
next_block_height: Height,
4243
miner_address: &transparent::Address,
4344
mempool_txs: Vec<VerifiedUnminedTx>,
4445
like_zcashd: bool,
4546
extra_coinbase_data: Vec<u8>,
47+
expected_block_subsidy: Amount<NonNegative>,
4648
#[cfg(zcash_unstable = "nsm")] burn_amount: Option<Amount<NonNegative>>,
4749
) -> Vec<VerifiedUnminedTx> {
4850
// Use a fake coinbase transaction to break the dependency between transaction
@@ -53,6 +55,7 @@ pub async fn select_mempool_transactions(
5355
miner_address,
5456
like_zcashd,
5557
extra_coinbase_data,
58+
expected_block_subsidy,
5659
#[cfg(zcash_unstable = "nsm")]
5760
burn_amount,
5861
);
@@ -123,6 +126,7 @@ pub fn fake_coinbase_transaction(
123126
miner_address: &transparent::Address,
124127
like_zcashd: bool,
125128
extra_coinbase_data: Vec<u8>,
129+
expected_block_subsidy: Amount<NonNegative>,
126130
#[cfg(zcash_unstable = "nsm")] burn_amount: Option<Amount<NonNegative>>,
127131
) -> TransactionTemplate<NegativeOrZero> {
128132
// Block heights are encoded as variable-length (script) and `u32` (lock time, expiry height).
@@ -143,6 +147,7 @@ pub fn fake_coinbase_transaction(
143147
miner_fee,
144148
like_zcashd,
145149
extra_coinbase_data,
150+
expected_block_subsidy,
146151
#[cfg(zcash_unstable = "nsm")]
147152
burn_amount,
148153
);

zebra-rpc/src/methods/tests/vectors.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,6 +1246,7 @@ async fn rpc_getblocktemplate_mining_address(use_p2pkh: bool) {
12461246
parameters::NetworkKind,
12471247
serialization::DateTime32,
12481248
transaction::{zip317, VerifiedUnminedTx},
1249+
value_balance::ValueBalance,
12491250
work::difficulty::{CompactDifficulty, ExpandedDifficulty, U256},
12501251
};
12511252
use zebra_consensus::MAX_BLOCK_SIGOPS;
@@ -1337,6 +1338,16 @@ async fn rpc_getblocktemplate_mining_address(use_p2pkh: bool) {
13371338
max_time: fake_max_time,
13381339
history_tree: fake_history_tree(&Mainnet),
13391340
}));
1341+
1342+
#[cfg(zcash_unstable = "nsm")]
1343+
read_state
1344+
.expect_request_that(|req| matches!(req, ReadRequest::TipPoolValues))
1345+
.await
1346+
.respond(ReadResponse::TipPoolValues {
1347+
tip_height: fake_tip_height,
1348+
tip_hash: fake_tip_hash,
1349+
value_balance: ValueBalance::zero(),
1350+
});
13401351
}
13411352
};
13421353

zebrad/tests/acceptance.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3247,6 +3247,8 @@ async fn trusted_chain_sync_handles_forks_correctly() -> Result<()> {
32473247
#[cfg(feature = "getblocktemplate-rpcs")]
32483248
async fn nu6_funding_streams_and_coinbase_balance() -> Result<()> {
32493249
use zebra_chain::{
3250+
amount::MAX_MONEY,
3251+
block::subsidy::general,
32503252
chain_sync_status::MockSyncStatus,
32513253
parameters::{
32523254
subsidy::{FundingStreamReceiver, FUNDING_STREAM_MG_ADDRESSES_TESTNET},
@@ -3287,7 +3289,7 @@ async fn nu6_funding_streams_and_coinbase_balance() -> Result<()> {
32873289
.with_activation_heights(ConfiguredActivationHeights {
32883290
nu6: Some(1),
32893291
#[cfg(zcash_unstable = "nsm")]
3290-
zfuture: Some(10),
3292+
zfuture: Some(2),
32913293
..Default::default()
32923294
});
32933295

@@ -3444,14 +3446,25 @@ async fn nu6_funding_streams_and_coinbase_balance() -> Result<()> {
34443446
})
34453447
.to_network();
34463448

3449+
let block_height = Height(block_template.height);
3450+
#[cfg(zcash_unstable = "nsm")]
3451+
let expected_block_subsidy = general::block_subsidy(
3452+
block_height,
3453+
&network,
3454+
MAX_MONEY.try_into().expect("MAX_MONEY is a valid amount"),
3455+
)?;
3456+
#[cfg(not(zcash_unstable = "nsm"))]
3457+
let expected_block_subsidy = general::block_subsidy_pre_nsm(block_height, &network)?;
3458+
34473459
let (coinbase_txn, default_roots) = generate_coinbase_and_roots(
34483460
&network,
3449-
Height(block_template.height),
3461+
block_height,
34503462
&miner_address,
34513463
&[],
34523464
history_tree.clone(),
34533465
true,
34543466
vec![],
3467+
expected_block_subsidy,
34553468
#[cfg(zcash_unstable = "nsm")]
34563469
None,
34573470
);
@@ -3497,6 +3510,7 @@ async fn nu6_funding_streams_and_coinbase_balance() -> Result<()> {
34973510
history_tree.clone(),
34983511
true,
34993512
vec![],
3513+
expected_block_subsidy,
35003514
#[cfg(zcash_unstable = "nsm")]
35013515
None,
35023516
);

0 commit comments

Comments
 (0)