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 spending of immature coinbase utxos #1637

Merged
Show file tree
Hide file tree
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
2 changes: 2 additions & 0 deletions libtonode-tests/tests/concrete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1225,6 +1225,7 @@ mod fast {
.unwrap();
faucet.quick_shield().await.unwrap();
}
#[ignore = "requires 100 blocks to be generated to shield coinbase. wait for zebrad integration."]
#[tokio::test]
async fn mine_to_transparent_and_propose_shielding() {
let regtest_network = RegtestNetwork::all_upgrades_active();
Expand Down Expand Up @@ -1257,6 +1258,7 @@ mod fast {
NonNegativeAmount::const_from_u64((block_rewards::CANOPY * 4) - expected_fee)
)
}
#[ignore = "requires 100 blocks to be generated to shield coinbase. wait for zebrad integration."]
#[tokio::test]
async fn mine_to_transparent_and_propose_shielding_with_div_addr() {
let regtest_network = RegtestNetwork::all_upgrades_active();
Expand Down
6 changes: 3 additions & 3 deletions zingolib/src/wallet/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ use super::{
};

impl LightWallet {
/// Changes in version 30:
/// - New WalletCapability version (v4) which implements read/write for rejection addresses
/// Changes in version 31:
/// - Added `is_coinbase` bool to transparent outputs
pub const fn serialized_version() -> u64 {
30
31
}

/// TODO: Add Doc Comment Here!
Expand Down
17 changes: 15 additions & 2 deletions zingolib/src/wallet/notes/transparent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ pub struct TransparentOutput {
pub script: Vec<u8>,
/// TODO: Add Doc Comment Here!
pub value: u64,

/// whether, where, and when it was spent
spend: Option<(TxId, ConfirmationStatus)>,
/// Output is from a coinbase transaction
pub is_coinbase: bool,
}

impl OutputInterface for TransparentOutput {
Expand Down Expand Up @@ -85,6 +86,7 @@ impl TransparentOutput {
script: Vec<u8>,
value: u64,
spend: Option<(TxId, ConfirmationStatus)>,
is_coinbase: bool,
) -> Self {
Self {
address,
Expand All @@ -93,6 +95,7 @@ impl TransparentOutput {
script,
value,
spend,
is_coinbase,
}
}

Expand All @@ -103,7 +106,7 @@ impl TransparentOutput {

/// write + read
pub fn serialized_version() -> u64 {
4
5
}

/// TODO: Add Doc Comment Here!
Expand Down Expand Up @@ -137,6 +140,8 @@ impl TransparentOutput {
w.write_i32::<byteorder::LittleEndian>(s)
})?;

writer.write_u8(self.is_coinbase as u8)?;

Ok(())
}

Expand Down Expand Up @@ -202,13 +207,20 @@ impl TransparentOutput {
let spend =
spent_tuple.map(|(txid, height)| (txid, ConfirmationStatus::Confirmed(height.into())));

let is_coinbase = if version >= 5 {
reader.read_u8()? != 0
} else {
false
};

Ok(TransparentOutput {
address,
txid: transaction_id,
output_index,
script,
value,
spend,
is_coinbase,
})
}
}
Expand Down Expand Up @@ -261,6 +273,7 @@ pub mod mocks {
self.script.clone().unwrap(),
self.value.unwrap(),
self.spending_tx_status.unwrap(),
false,
)
}
}
Expand Down
6 changes: 6 additions & 0 deletions zingolib/src/wallet/transaction_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ mod decrypt_transaction {

/// This method records that receipt in the relevant receiving
/// TransactionRecord in the TransactionRecordsById database.
#[allow(clippy::too_many_arguments)]
async fn record_taddr_receipt(
&self,
transaction: &zcash_primitives::transaction::Transaction,
Expand All @@ -226,6 +227,7 @@ mod decrypt_transaction {
block_time: Option<u32>,
vout: &zcash_primitives::transaction::components::TxOut,
n: usize,
is_coinbase: bool,
) {
self.transaction_metadata_set
.write()
Expand All @@ -238,6 +240,7 @@ mod decrypt_transaction {
block_time,
vout,
n as u32,
is_coinbase,
);
}
/// New value has been detected for one of the wallet's transparent
Expand All @@ -250,6 +253,8 @@ mod decrypt_transaction {
block_time: Option<u32>,
) {
if let Some(t_bundle) = transaction.transparent_bundle() {
let is_coinbase = t_bundle.is_coinbase();

// Collect our t-addresses for easy checking
// the get_taddrs method includes ephemeral 320 taddrs
let taddrs_set = self.key.get_taddrs(&self.config.chain);
Expand All @@ -264,6 +269,7 @@ mod decrypt_transaction {
block_time,
vout,
n,
is_coinbase,
)
.await;
}
Expand Down
2 changes: 1 addition & 1 deletion zingolib/src/wallet/transaction_record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ impl TransactionRecord {

/// TODO: Add Doc Comment Here!
pub fn serialized_version() -> u64 {
24
25
}

/// TODO: Add Doc Comment Here!
Expand Down
2 changes: 2 additions & 0 deletions zingolib/src/wallet/transaction_records_by_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,7 @@ impl TransactionRecordsById {
timestamp: Option<u32>,
vout: &zcash_primitives::transaction::components::TxOut,
output_num: u32,
is_coinbase: bool,
) {
// Read or create the current TxId
let transaction_metadata =
Expand All @@ -693,6 +694,7 @@ impl TransactionRecordsById {
vout.script_pubkey.0.clone(),
u64::from(vout.value),
None,
is_coinbase,
),
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,17 @@ impl InputSource for TransactionRecordsById {
})
.flat_map(|tx| {
tx.transparent_outputs().iter().filter_map(|output| {
if output.spending_tx_status().is_none()
let mature = if output.is_coinbase {
tx.status
.get_confirmed_height()
.expect("transaction should be confirmed")
<= target_height - 100
} else {
true
};

if mature
&& output.spending_tx_status().is_none()
&& (output.address
== address.encode(&zcash_primitives::consensus::MAIN_NETWORK)
|| output.address
Expand Down
2 changes: 1 addition & 1 deletion zingolib/src/wallet/tx_map/read_write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use super::{spending_data::SpendingData, TransactionRecordsById, TxMap};
impl TxMap {
/// TODO: Doc-comment!
pub fn serialized_version() -> u64 {
22
23
}

/// TODO: Doc-comment!
Expand Down