Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(rpc): getblocktemplate coinbase outputs order #9272

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -394,24 +394,34 @@ fn combine_coinbase_outputs(
miner_reward: Amount<NonNegative>,
like_zcashd: bool,
) -> Vec<(Amount<NonNegative>, transparent::Script)> {
// Combine all the funding streams with the miner reward.
let mut coinbase_outputs: Vec<(Amount<NonNegative>, &transparent::Address)> = funding_streams
.into_iter()
.map(|(_receiver, (amount, address))| (amount, address))
.collect();
coinbase_outputs.push((miner_reward, miner_address));

let mut coinbase_outputs: Vec<(Amount<NonNegative>, transparent::Script)> = coinbase_outputs
.iter()
.map(|(amount, address)| (*amount, address.create_script_from_address()))
.collect();
// Collect all the funding streams and convert them to outputs.
let funding_streams_outputs: Vec<(Amount<NonNegative>, &transparent::Address)> =
funding_streams
.into_iter()
.map(|(_receiver, (amount, address))| (amount, address))
.collect();

let mut coinbase_outputs: Vec<(Amount<NonNegative>, transparent::Script)> =
funding_streams_outputs
.iter()
.map(|(amount, address)| (*amount, address.create_script_from_address()))
.collect();

// The HashMap returns funding streams in an arbitrary order,
// but Zebra's snapshot tests expect the same order every time.
if like_zcashd {
// zcashd sorts outputs in serialized data order, excluding the length field
coinbase_outputs.sort_by_key(|(_amount, script)| script.clone());

// The miner reward is always the first output independent of the sort order
coinbase_outputs.insert(
0,
(miner_reward, miner_address.create_script_from_address()),
);
} else {
// Unlike zcashd, in Zebra the miner reward is part of the sorting
coinbase_outputs.push((miner_reward, miner_address.create_script_from_address()));

// Zebra sorts by amount then script.
//
// Since the sort is stable, equal amounts will remain sorted by script.
Original file line number Diff line number Diff line change
@@ -13,6 +13,10 @@ V4(
),
],
outputs: [
Output(
value: 250000000,
lock_script: Script("a914adadadadadadadadadadadadadadadadadadadad87"),
),
Output(
value: 21875000,
lock_script: Script("a91469a9f95a98fe581b6eb52841ef4806dc4402eb9087"),
@@ -21,10 +25,6 @@ V4(
value: 25000000,
lock_script: Script("a914931fec54c1fea86e574462cc32013f5400b8912987"),
),
Output(
value: 250000000,
lock_script: Script("a914adadadadadadadadadadadadadadadadadadadad87"),
),
Output(
value: 15625000,
lock_script: Script("a914d45cb1adffb5215a42720532a076f02c7c778c9087"),
Original file line number Diff line number Diff line change
@@ -13,6 +13,10 @@ V4(
),
],
outputs: [
Output(
value: 250000000,
lock_script: Script("a914adadadadadadadadadadadadadadadadadadadad87"),
),
Output(
value: 15625000,
lock_script: Script("a9140c0bcca02f3cba01a5d7423ac3903d40586399eb87"),
@@ -25,10 +29,6 @@ V4(
value: 25000000,
lock_script: Script("a91471e1df05024288a00802de81e08c437859586c8787"),
),
Output(
value: 250000000,
lock_script: Script("a914adadadadadadadadadadadadadadadadadadadad87"),
),
],
lock_time: Height(Height(0)),
expiry_height: Height(1842421),
Original file line number Diff line number Diff line change
@@ -12,15 +12,15 @@ expression: block_template
"lightclientroothash": "02990723c6b62a724651322d141b4a72a4ffd66518167d809badbd5117d5518a",
"finalsaplingroothash": "02990723c6b62a724651322d141b4a72a4ffd66518167d809badbd5117d5518a",
"defaultroots": {
"merkleroot": "e049ed10466f566a045702ad712bbb596c6863cd08cdb4646da749b2287bc219",
"merkleroot": "7df8ce149b9beafc09b649c2ccfd866ce96d1b94331d9f7f3728cbefa36431f6",
"chainhistoryroot": "94470fa66ebd1a5fdb109a5aa3f3204f14de3a42135e71aa7f4c44055847e0b5",
"authdataroot": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"blockcommitmentshash": "02990723c6b62a724651322d141b4a72a4ffd66518167d809badbd5117d5518a"
},
"transactions": [],
"coinbasetxn": {
"data": "0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff050341be1900ffffffff0438c94d010000000017a91469a9f95a98fe581b6eb52841ef4806dc4402eb908740787d010000000017a914931fec54c1fea86e574462cc32013f5400b891298780b2e60e0000000017a914adadadadadadadadadadadadadadadadadadadad87286bee000000000017a914d45cb1adffb5215a42720532a076f02c7c778c90870000000041be19000000000000000000000000",
"hash": "e049ed10466f566a045702ad712bbb596c6863cd08cdb4646da749b2287bc219",
"data": "0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff050341be1900ffffffff0480b2e60e0000000017a914adadadadadadadadadadadadadadadadadadadad8738c94d010000000017a91469a9f95a98fe581b6eb52841ef4806dc4402eb908740787d010000000017a914931fec54c1fea86e574462cc32013f5400b8912987286bee000000000017a914d45cb1adffb5215a42720532a076f02c7c778c90870000000041be19000000000000000000000000",
"hash": "7df8ce149b9beafc09b649c2ccfd866ce96d1b94331d9f7f3728cbefa36431f6",
"authdigest": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"depends": [],
"fee": 0,
Original file line number Diff line number Diff line change
@@ -12,15 +12,15 @@ expression: block_template
"lightclientroothash": "3b25791957f9383b6ce851d728a78309664d5d7a82ca87b6a9125a2f2c529792",
"finalsaplingroothash": "3b25791957f9383b6ce851d728a78309664d5d7a82ca87b6a9125a2f2c529792",
"defaultroots": {
"merkleroot": "f1f2db76c33c4a81f799d0c5cfba83c99c20cc8c51958a615d410fe7fbf92b34",
"merkleroot": "e919e7a3325b82b571b3658408118c14f2688ea254f9cb54d354a8ff17bd5b81",
"chainhistoryroot": "03bc75f00c307a05aed2023819e18c2672cbe15fbd3200944997def141967387",
"authdataroot": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"blockcommitmentshash": "3b25791957f9383b6ce851d728a78309664d5d7a82ca87b6a9125a2f2c529792"
},
"transactions": [],
"coinbasetxn": {
"data": "0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff0503f51c1c00ffffffff04286bee000000000017a9140c0bcca02f3cba01a5d7423ac3903d40586399eb8738c94d010000000017a9144e3f0d9a33a2721604cbae2de8d9171e21f8fbe48740787d010000000017a91471e1df05024288a00802de81e08c437859586c878780b2e60e0000000017a914adadadadadadadadadadadadadadadadadadadad8700000000f51c1c000000000000000000000000",
"hash": "f1f2db76c33c4a81f799d0c5cfba83c99c20cc8c51958a615d410fe7fbf92b34",
"data": "0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff0503f51c1c00ffffffff0480b2e60e0000000017a914adadadadadadadadadadadadadadadadadadadad87286bee000000000017a9140c0bcca02f3cba01a5d7423ac3903d40586399eb8738c94d010000000017a9144e3f0d9a33a2721604cbae2de8d9171e21f8fbe48740787d010000000017a91471e1df05024288a00802de81e08c437859586c878700000000f51c1c000000000000000000000000",
"hash": "e919e7a3325b82b571b3658408118c14f2688ea254f9cb54d354a8ff17bd5b81",
"authdigest": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"depends": [],
"fee": 0,
Original file line number Diff line number Diff line change
@@ -13,6 +13,10 @@ V4(
),
],
outputs: [
Output(
value: 250000000,
lock_script: Script("a914adadadadadadadadadadadadadadadadadadadad87"),
),
Output(
value: 21875000,
lock_script: Script("a91469a9f95a98fe581b6eb52841ef4806dc4402eb9087"),
@@ -21,10 +25,6 @@ V4(
value: 25000000,
lock_script: Script("a914931fec54c1fea86e574462cc32013f5400b8912987"),
),
Output(
value: 250000000,
lock_script: Script("a914adadadadadadadadadadadadadadadadadadadad87"),
),
Output(
value: 15625000,
lock_script: Script("a914d45cb1adffb5215a42720532a076f02c7c778c9087"),
Original file line number Diff line number Diff line change
@@ -13,6 +13,10 @@ V4(
),
],
outputs: [
Output(
value: 250000000,
lock_script: Script("a914adadadadadadadadadadadadadadadadadadadad87"),
),
Output(
value: 15625000,
lock_script: Script("a9140c0bcca02f3cba01a5d7423ac3903d40586399eb87"),
@@ -25,10 +29,6 @@ V4(
value: 25000000,
lock_script: Script("a91471e1df05024288a00802de81e08c437859586c8787"),
),
Output(
value: 250000000,
lock_script: Script("a914adadadadadadadadadadadadadadadadadadadad87"),
),
],
lock_time: Height(Height(0)),
expiry_height: Height(1842421),
Original file line number Diff line number Diff line change
@@ -12,15 +12,15 @@ expression: block_template
"lightclientroothash": "02990723c6b62a724651322d141b4a72a4ffd66518167d809badbd5117d5518a",
"finalsaplingroothash": "02990723c6b62a724651322d141b4a72a4ffd66518167d809badbd5117d5518a",
"defaultroots": {
"merkleroot": "e049ed10466f566a045702ad712bbb596c6863cd08cdb4646da749b2287bc219",
"merkleroot": "7df8ce149b9beafc09b649c2ccfd866ce96d1b94331d9f7f3728cbefa36431f6",
"chainhistoryroot": "94470fa66ebd1a5fdb109a5aa3f3204f14de3a42135e71aa7f4c44055847e0b5",
"authdataroot": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"blockcommitmentshash": "02990723c6b62a724651322d141b4a72a4ffd66518167d809badbd5117d5518a"
},
"transactions": [],
"coinbasetxn": {
"data": "0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff050341be1900ffffffff0438c94d010000000017a91469a9f95a98fe581b6eb52841ef4806dc4402eb908740787d010000000017a914931fec54c1fea86e574462cc32013f5400b891298780b2e60e0000000017a914adadadadadadadadadadadadadadadadadadadad87286bee000000000017a914d45cb1adffb5215a42720532a076f02c7c778c90870000000041be19000000000000000000000000",
"hash": "e049ed10466f566a045702ad712bbb596c6863cd08cdb4646da749b2287bc219",
"data": "0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff050341be1900ffffffff0480b2e60e0000000017a914adadadadadadadadadadadadadadadadadadadad8738c94d010000000017a91469a9f95a98fe581b6eb52841ef4806dc4402eb908740787d010000000017a914931fec54c1fea86e574462cc32013f5400b8912987286bee000000000017a914d45cb1adffb5215a42720532a076f02c7c778c90870000000041be19000000000000000000000000",
"hash": "7df8ce149b9beafc09b649c2ccfd866ce96d1b94331d9f7f3728cbefa36431f6",
"authdigest": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"depends": [],
"fee": 0,
Original file line number Diff line number Diff line change
@@ -12,15 +12,15 @@ expression: block_template
"lightclientroothash": "3b25791957f9383b6ce851d728a78309664d5d7a82ca87b6a9125a2f2c529792",
"finalsaplingroothash": "3b25791957f9383b6ce851d728a78309664d5d7a82ca87b6a9125a2f2c529792",
"defaultroots": {
"merkleroot": "f1f2db76c33c4a81f799d0c5cfba83c99c20cc8c51958a615d410fe7fbf92b34",
"merkleroot": "e919e7a3325b82b571b3658408118c14f2688ea254f9cb54d354a8ff17bd5b81",
"chainhistoryroot": "03bc75f00c307a05aed2023819e18c2672cbe15fbd3200944997def141967387",
"authdataroot": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"blockcommitmentshash": "3b25791957f9383b6ce851d728a78309664d5d7a82ca87b6a9125a2f2c529792"
},
"transactions": [],
"coinbasetxn": {
"data": "0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff0503f51c1c00ffffffff04286bee000000000017a9140c0bcca02f3cba01a5d7423ac3903d40586399eb8738c94d010000000017a9144e3f0d9a33a2721604cbae2de8d9171e21f8fbe48740787d010000000017a91471e1df05024288a00802de81e08c437859586c878780b2e60e0000000017a914adadadadadadadadadadadadadadadadadadadad8700000000f51c1c000000000000000000000000",
"hash": "f1f2db76c33c4a81f799d0c5cfba83c99c20cc8c51958a615d410fe7fbf92b34",
"data": "0400008085202f89010000000000000000000000000000000000000000000000000000000000000000ffffffff0503f51c1c00ffffffff0480b2e60e0000000017a914adadadadadadadadadadadadadadadadadadadad87286bee000000000017a9140c0bcca02f3cba01a5d7423ac3903d40586399eb8738c94d010000000017a9144e3f0d9a33a2721604cbae2de8d9171e21f8fbe48740787d010000000017a91471e1df05024288a00802de81e08c437859586c878700000000f51c1c000000000000000000000000",
"hash": "e919e7a3325b82b571b3658408118c14f2688ea254f9cb54d354a8ff17bd5b81",
"authdigest": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"depends": [],
"fee": 0,
28 changes: 23 additions & 5 deletions zebra-rpc/src/methods/tests/vectors.rs
Original file line number Diff line number Diff line change
@@ -1601,7 +1601,6 @@ async fn rpc_getblocktemplate_mining_address(use_p2pkh: bool) {
amount::NonNegative,
block::{Hash, MAX_BLOCK_BYTES, ZCASH_BLOCK_VERSION},
chain_sync_status::MockSyncStatus,
parameters::NetworkKind,
serialization::DateTime32,
transaction::{zip317, VerifiedUnminedTx},
work::difficulty::{CompactDifficulty, ExpandedDifficulty, U256},
@@ -1633,15 +1632,21 @@ async fn rpc_getblocktemplate_mining_address(use_p2pkh: bool) {
let mut mock_sync_status = MockSyncStatus::default();
mock_sync_status.set_is_close_to_tip(true);

let network = NetworkKind::Mainnet;
let network = Network::Mainnet;
let miner_address = match use_p2pkh {
false => Some(transparent::Address::from_script_hash(network, [0x7e; 20])),
true => Some(transparent::Address::from_pub_key_hash(network, [0x7e; 20])),
false => Some(transparent::Address::from_script_hash(
network.kind(),
[0x7e; 20],
)),
true => Some(transparent::Address::from_pub_key_hash(
network.kind(),
[0x7e; 20],
)),
};

#[allow(clippy::unnecessary_struct_initialization)]
let mining_config = crate::config::mining::Config {
miner_address,
miner_address: miner_address.clone(),
extra_coinbase_data: None,
debug_like_zcashd: true,
// TODO: Use default field values when optional features are enabled in tests #8183
@@ -1727,6 +1732,19 @@ async fn rpc_getblocktemplate_mining_address(use_p2pkh: bool) {
panic!("this getblocktemplate call without parameters should return the `TemplateMode` variant of the response")
};

let coinbase_transaction =
Transaction::zcash_deserialize(get_block_template.coinbase_txn.data.as_ref())
.expect("coinbase transaction data should be deserializable");

assert_eq!(
coinbase_transaction
.outputs()
.first()
.unwrap()
.address(&network),
miner_address
);

assert_eq!(
get_block_template.capabilities,
GET_BLOCK_TEMPLATE_CAPABILITIES_FIELD.to_vec()