changes for gui wallets
This commit is contained in:
parent
504207c424
commit
e479b8e5df
|
|
@ -399,7 +399,7 @@ pub async fn apply_selected_transaction_math(
|
||||||
);
|
);
|
||||||
index_selected_wallet_transaction(
|
index_selected_wallet_transaction(
|
||||||
pending_effects,
|
pending_effects,
|
||||||
&[sender, receiver, &miner],
|
&[sender, receiver],
|
||||||
block_number,
|
block_number,
|
||||||
tx_index,
|
tx_index,
|
||||||
&decode(hash)?,
|
&decode(hash)?,
|
||||||
|
|
@ -466,7 +466,7 @@ pub async fn apply_selected_transaction_math(
|
||||||
);
|
);
|
||||||
index_selected_wallet_transaction(
|
index_selected_wallet_transaction(
|
||||||
pending_effects,
|
pending_effects,
|
||||||
&[creator, &miner],
|
&[creator],
|
||||||
block_number,
|
block_number,
|
||||||
tx_index,
|
tx_index,
|
||||||
&decode(hash)?,
|
&decode(hash)?,
|
||||||
|
|
@ -504,7 +504,7 @@ pub async fn apply_selected_transaction_math(
|
||||||
);
|
);
|
||||||
index_selected_wallet_transaction(
|
index_selected_wallet_transaction(
|
||||||
pending_effects,
|
pending_effects,
|
||||||
&[creator, &miner],
|
&[creator],
|
||||||
block_number,
|
block_number,
|
||||||
tx_index,
|
tx_index,
|
||||||
&decode(hash)?,
|
&decode(hash)?,
|
||||||
|
|
@ -539,7 +539,7 @@ pub async fn apply_selected_transaction_math(
|
||||||
);
|
);
|
||||||
index_selected_wallet_transaction(
|
index_selected_wallet_transaction(
|
||||||
pending_effects,
|
pending_effects,
|
||||||
&[address, &miner],
|
&[address],
|
||||||
block_number,
|
block_number,
|
||||||
tx_index,
|
tx_index,
|
||||||
&decode(hash)?,
|
&decode(hash)?,
|
||||||
|
|
@ -612,7 +612,7 @@ pub async fn apply_selected_transaction_math(
|
||||||
);
|
);
|
||||||
index_selected_wallet_transaction(
|
index_selected_wallet_transaction(
|
||||||
pending_effects,
|
pending_effects,
|
||||||
&[creator, &miner],
|
&[creator],
|
||||||
block_number,
|
block_number,
|
||||||
tx_index,
|
tx_index,
|
||||||
&decode(hash)?,
|
&decode(hash)?,
|
||||||
|
|
@ -638,7 +638,7 @@ pub async fn apply_selected_transaction_math(
|
||||||
);
|
);
|
||||||
index_selected_wallet_transaction(
|
index_selected_wallet_transaction(
|
||||||
pending_effects,
|
pending_effects,
|
||||||
&[advertiser, &miner],
|
&[advertiser],
|
||||||
block_number,
|
block_number,
|
||||||
tx_index,
|
tx_index,
|
||||||
&decode(hash)?,
|
&decode(hash)?,
|
||||||
|
|
@ -668,7 +668,7 @@ pub async fn apply_selected_transaction_math(
|
||||||
);
|
);
|
||||||
index_selected_wallet_transaction(
|
index_selected_wallet_transaction(
|
||||||
pending_effects,
|
pending_effects,
|
||||||
&[address, &miner],
|
&[address],
|
||||||
block_number,
|
block_number,
|
||||||
tx_index,
|
tx_index,
|
||||||
&decode(hash)?,
|
&decode(hash)?,
|
||||||
|
|
@ -748,7 +748,7 @@ pub async fn apply_selected_transaction_math(
|
||||||
);
|
);
|
||||||
index_selected_wallet_transaction(
|
index_selected_wallet_transaction(
|
||||||
pending_effects,
|
pending_effects,
|
||||||
&[sender1, sender2, &miner],
|
&[sender1, sender2],
|
||||||
block_number,
|
block_number,
|
||||||
tx_index,
|
tx_index,
|
||||||
&decode(hash)?,
|
&decode(hash)?,
|
||||||
|
|
@ -817,7 +817,7 @@ pub async fn apply_selected_transaction_math(
|
||||||
);
|
);
|
||||||
index_selected_wallet_transaction(
|
index_selected_wallet_transaction(
|
||||||
pending_effects,
|
pending_effects,
|
||||||
&[lender, borrower, &miner],
|
&[lender, borrower],
|
||||||
block_number,
|
block_number,
|
||||||
tx_index,
|
tx_index,
|
||||||
&decode(hash)?,
|
&decode(hash)?,
|
||||||
|
|
@ -886,7 +886,7 @@ pub async fn apply_selected_transaction_math(
|
||||||
let lender_address = binary_to_string(lender.clone());
|
let lender_address = binary_to_string(lender.clone());
|
||||||
index_selected_wallet_transaction(
|
index_selected_wallet_transaction(
|
||||||
pending_effects,
|
pending_effects,
|
||||||
&[address, &lender_address, &miner],
|
&[address, &lender_address],
|
||||||
block_number,
|
block_number,
|
||||||
tx_index,
|
tx_index,
|
||||||
&decode(hash)?,
|
&decode(hash)?,
|
||||||
|
|
@ -941,7 +941,7 @@ pub async fn apply_selected_transaction_math(
|
||||||
);
|
);
|
||||||
index_selected_wallet_transaction(
|
index_selected_wallet_transaction(
|
||||||
pending_effects,
|
pending_effects,
|
||||||
&[address, &miner],
|
&[address],
|
||||||
block_number,
|
block_number,
|
||||||
tx_index,
|
tx_index,
|
||||||
&decode(hash)?,
|
&decode(hash)?,
|
||||||
|
|
|
||||||
|
|
@ -109,11 +109,7 @@ pub async fn process_borrower(
|
||||||
pending_effects.set_tree("txid", txkey, txvalue.into_bytes());
|
pending_effects.set_tree("txid", txkey, txvalue.into_bytes());
|
||||||
index_wallet_transaction(
|
index_wallet_transaction(
|
||||||
pending_effects,
|
pending_effects,
|
||||||
&[
|
&[&transaction.unsigned_contract_payment.address, &lender],
|
||||||
&transaction.unsigned_contract_payment.address,
|
|
||||||
&lender,
|
|
||||||
&miner,
|
|
||||||
],
|
|
||||||
block_header_number,
|
block_header_number,
|
||||||
**index as u32,
|
**index as u32,
|
||||||
&txhash_bytes,
|
&txhash_bytes,
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ pub async fn process_burn(
|
||||||
pending_effects.set_tree("txid", txkey, txvalue.into_bytes());
|
pending_effects.set_tree("txid", txkey, txvalue.into_bytes());
|
||||||
index_wallet_transaction(
|
index_wallet_transaction(
|
||||||
pending_effects,
|
pending_effects,
|
||||||
&[&transaction.unsigned_burn.address, &miner],
|
&[&transaction.unsigned_burn.address],
|
||||||
block_header_number,
|
block_header_number,
|
||||||
**index as u32,
|
**index as u32,
|
||||||
&txhash_bytes,
|
&txhash_bytes,
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ pub async fn process_collateral(
|
||||||
pending_effects.set_tree("txid", txkey, txvalue.into_bytes());
|
pending_effects.set_tree("txid", txkey, txvalue.into_bytes());
|
||||||
index_wallet_transaction(
|
index_wallet_transaction(
|
||||||
pending_effects,
|
pending_effects,
|
||||||
&[&transaction.unsigned_collateral_claim.address, &miner],
|
&[&transaction.unsigned_collateral_claim.address],
|
||||||
block_header_number,
|
block_header_number,
|
||||||
**index as u32,
|
**index as u32,
|
||||||
&txhash_bytes,
|
&txhash_bytes,
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ pub async fn process_issue_token(
|
||||||
pending_effects.set_tree("txid", txkey.clone(), txvalue.into_bytes());
|
pending_effects.set_tree("txid", txkey.clone(), txvalue.into_bytes());
|
||||||
index_wallet_transaction(
|
index_wallet_transaction(
|
||||||
pending_effects,
|
pending_effects,
|
||||||
&[&transaction.unsigned_issue_token.creator, &miner],
|
&[&transaction.unsigned_issue_token.creator],
|
||||||
block_header_number,
|
block_header_number,
|
||||||
**index as u32,
|
**index as u32,
|
||||||
&txkey,
|
&txkey,
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,6 @@ pub async fn process_lender(
|
||||||
&[
|
&[
|
||||||
&transaction.unsigned_loan_contract.lender,
|
&transaction.unsigned_loan_contract.lender,
|
||||||
&transaction.unsigned_loan_contract.borrower,
|
&transaction.unsigned_loan_contract.borrower,
|
||||||
&miner,
|
|
||||||
],
|
],
|
||||||
block_header_number,
|
block_header_number,
|
||||||
**index as u32,
|
**index as u32,
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ pub async fn process_marketing(
|
||||||
pending_effects.set_tree("txid", txkey, txvalue.into_bytes());
|
pending_effects.set_tree("txid", txkey, txvalue.into_bytes());
|
||||||
index_wallet_transaction(
|
index_wallet_transaction(
|
||||||
pending_effects,
|
pending_effects,
|
||||||
&[&transaction.unsigned_marketing.advertiser, &miner],
|
&[&transaction.unsigned_marketing.advertiser],
|
||||||
block_header_number,
|
block_header_number,
|
||||||
**index as u32,
|
**index as u32,
|
||||||
&txhash_bytes,
|
&txhash_bytes,
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ pub async fn process_nft(
|
||||||
pending_effects.set_tree("txid", txkey, txvalue.into_bytes());
|
pending_effects.set_tree("txid", txkey, txvalue.into_bytes());
|
||||||
index_wallet_transaction(
|
index_wallet_transaction(
|
||||||
pending_effects,
|
pending_effects,
|
||||||
&[&transaction.unsigned_create_nft.creator, &miner],
|
&[&transaction.unsigned_create_nft.creator],
|
||||||
block_header_number,
|
block_header_number,
|
||||||
**index as u32,
|
**index as u32,
|
||||||
&txhash_bytes,
|
&txhash_bytes,
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use crate::records::balance_sheet::operations::balance_sheet_operation_with_db;
|
||||||
use crate::records::block_height::get_block_height::get_height;
|
use crate::records::block_height::get_block_height::get_height;
|
||||||
use crate::records::memory::mempool::BASECOIN;
|
use crate::records::memory::mempool::BASECOIN;
|
||||||
use crate::records::record_chain::pending_effects::PendingEffects;
|
use crate::records::record_chain::pending_effects::PendingEffects;
|
||||||
use crate::records::record_chain::wallet_tx_index::index_wallet_transaction;
|
use crate::records::record_chain::wallet_tx_index::index_wallet_transaction_direct;
|
||||||
use crate::records::unpack_block::load_by_block_number::load_block;
|
use crate::records::unpack_block::load_by_block_number::load_block;
|
||||||
use crate::sled::Db;
|
use crate::sled::Db;
|
||||||
use crate::Arc;
|
use crate::Arc;
|
||||||
|
|
@ -21,6 +21,8 @@ struct ImmatureReward {
|
||||||
block_height: u32,
|
block_height: u32,
|
||||||
miner: String,
|
miner: String,
|
||||||
amount: u64,
|
amount: u64,
|
||||||
|
txid: Vec<u8>,
|
||||||
|
entry_index: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
|
|
@ -63,6 +65,13 @@ fn credit_matured_reward(db: &Db, reward: ImmatureReward) -> Result<(), String>
|
||||||
.map_err(|e| format!("Failed to finalize reward balance: {e}"))?;
|
.map_err(|e| format!("Failed to finalize reward balance: {e}"))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
index_wallet_transaction_direct(
|
||||||
|
db,
|
||||||
|
&reward.miner,
|
||||||
|
reward.block_height,
|
||||||
|
reward.entry_index,
|
||||||
|
&reward.txid,
|
||||||
|
)?;
|
||||||
mark_reward_credit_applied(db, reward.block_height)
|
mark_reward_credit_applied(db, reward.block_height)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,6 +80,8 @@ pub async fn record_saved_reward(
|
||||||
block_height: u32,
|
block_height: u32,
|
||||||
miner: String,
|
miner: String,
|
||||||
amount: u64,
|
amount: u64,
|
||||||
|
txid: Vec<u8>,
|
||||||
|
entry_index: u32,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let matured = {
|
let matured = {
|
||||||
let mut rewards = IMMATURE_REWARDS.lock().await;
|
let mut rewards = IMMATURE_REWARDS.lock().await;
|
||||||
|
|
@ -79,6 +90,8 @@ pub async fn record_saved_reward(
|
||||||
block_height,
|
block_height,
|
||||||
miner,
|
miner,
|
||||||
amount,
|
amount,
|
||||||
|
txid,
|
||||||
|
entry_index,
|
||||||
});
|
});
|
||||||
|
|
||||||
if rewards.len() > IMMATURE_REWARD_WINDOW {
|
if rewards.len() > IMMATURE_REWARD_WINDOW {
|
||||||
|
|
@ -112,12 +125,18 @@ pub async fn rebuild_immature_reward_window(db: &Db) -> Result<(), String> {
|
||||||
};
|
};
|
||||||
let miner = block.vrf_block.unmined_block.miner;
|
let miner = block.vrf_block.unmined_block.miner;
|
||||||
|
|
||||||
for transaction in block.transactions {
|
for (position, transaction) in block.transactions.into_iter().enumerate() {
|
||||||
if let Transaction::Rewards(rewards) = transaction {
|
if let Transaction::Rewards(rewards) = transaction {
|
||||||
|
let txid = decode(rewards.unsigned.hash().await)
|
||||||
|
.map_err(|e| format!("Error decoding rebuilt reward txid key: {e}"))?;
|
||||||
|
let entry_index = u32::try_from(position + 1)
|
||||||
|
.map_err(|_| "Reward transaction index overflowed".to_string())?;
|
||||||
rebuilt.push_back(ImmatureReward {
|
rebuilt.push_back(ImmatureReward {
|
||||||
block_height,
|
block_height,
|
||||||
miner,
|
miner,
|
||||||
amount: rewards.unsigned.value,
|
amount: rewards.unsigned.value,
|
||||||
|
txid,
|
||||||
|
entry_index,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -138,7 +157,7 @@ pub async fn process_rewards(
|
||||||
mut binary_data: Vec<u8>,
|
mut binary_data: Vec<u8>,
|
||||||
_db: &Db,
|
_db: &Db,
|
||||||
index_counter: Arc<Mutex<&mut usize>>,
|
index_counter: Arc<Mutex<&mut usize>>,
|
||||||
miner: String,
|
_miner: String,
|
||||||
block_header_number: u32,
|
block_header_number: u32,
|
||||||
pending_effects: &mut PendingEffects,
|
pending_effects: &mut PendingEffects,
|
||||||
) -> Result<Vec<u8>, String> {
|
) -> Result<Vec<u8>, String> {
|
||||||
|
|
@ -157,16 +176,9 @@ pub async fn process_rewards(
|
||||||
binary_data.extend(transaction_bytes);
|
binary_data.extend(transaction_bytes);
|
||||||
|
|
||||||
// Reward processing records the txid location for later lookup by
|
// Reward processing records the txid location for later lookup by
|
||||||
// block/index, but does not make the reward spendable yet.
|
// block/index, but does not index it into wallet history until maturity.
|
||||||
let txkey = decode(txhash).map_err(|e| format!("Error decoding rewards txid key: {e}"))?;
|
let txkey = decode(txhash).map_err(|e| format!("Error decoding rewards txid key: {e}"))?;
|
||||||
let txvalue = format!("{block_header_number}:{}", **index);
|
let txvalue = format!("{block_header_number}:{}", **index);
|
||||||
pending_effects.set_tree("txid", txkey.clone(), txvalue.into_bytes());
|
pending_effects.set_tree("txid", txkey, txvalue.into_bytes());
|
||||||
index_wallet_transaction(
|
|
||||||
pending_effects,
|
|
||||||
&[&miner],
|
|
||||||
block_header_number,
|
|
||||||
**index as u32,
|
|
||||||
&txkey,
|
|
||||||
)?;
|
|
||||||
Ok(binary_data)
|
Ok(binary_data)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ use crate::records::memory::chain_state::{
|
||||||
cached_tip_hash, cached_tip_header, update_chain_state_after_save,
|
cached_tip_hash, cached_tip_header, update_chain_state_after_save,
|
||||||
};
|
};
|
||||||
use crate::records::memory::mempool::{
|
use crate::records::memory::mempool::{
|
||||||
apply_selected_transaction_math, ensure_db_connection, mark_processed_by_signatures,
|
apply_selected_transaction_math, mark_processed_by_signatures,
|
||||||
mark_selected_transactions_processed, restore_processed_by_signatures,
|
mark_selected_transactions_processed, restore_processed_by_signatures,
|
||||||
restore_selected_transactions_processed, select_transactions_for_block,
|
restore_selected_transactions_processed, select_transactions_for_block,
|
||||||
spawn_processed_cleanup, stream_selected_transaction_originals,
|
spawn_processed_cleanup, stream_selected_transaction_originals,
|
||||||
|
|
@ -75,10 +75,6 @@ pub async fn save_block(params: SaveBlockParams) -> Result<(), String> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ensure_db_connection()
|
|
||||||
.await
|
|
||||||
.map_err(|err| format!("Postgres reconnect failed before block save: {err}"))?;
|
|
||||||
|
|
||||||
let header_bytes = block
|
let header_bytes = block
|
||||||
.vrf_block
|
.vrf_block
|
||||||
.to_bytes()
|
.to_bytes()
|
||||||
|
|
@ -150,13 +146,17 @@ pub async fn save_block(params: SaveBlockParams) -> Result<(), String> {
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let saved_reward_amount = block
|
let mut saved_reward = None;
|
||||||
.transactions
|
for (position, transaction) in block.transactions.iter().enumerate() {
|
||||||
.iter()
|
if let Transaction::Rewards(rewards) = transaction {
|
||||||
.find_map(|transaction| match transaction {
|
let txid = decode(rewards.unsigned.hash().await)
|
||||||
Transaction::Rewards(rewards) => Some(rewards.unsigned.value),
|
.map_err(|e| format!("Error decoding saved reward txid key: {e}"))?;
|
||||||
_ => None,
|
let entry_index = u32::try_from(position + 1)
|
||||||
});
|
.map_err(|_| "Reward transaction index overflowed".to_string())?;
|
||||||
|
saved_reward = Some((rewards.unsigned.value, txid, entry_index));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let start_index = {
|
let start_index = {
|
||||||
let index = index_mutex.lock().await;
|
let index = index_mutex.lock().await;
|
||||||
|
|
@ -219,8 +219,16 @@ pub async fn save_block(params: SaveBlockParams) -> Result<(), String> {
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(amount) = saved_reward_amount {
|
if let Some((amount, txid, entry_index)) = saved_reward {
|
||||||
if let Err(err) = record_saved_reward(&db, block_header_number, miner.clone(), amount).await
|
if let Err(err) = record_saved_reward(
|
||||||
|
&db,
|
||||||
|
block_header_number,
|
||||||
|
miner.clone(),
|
||||||
|
amount,
|
||||||
|
txid,
|
||||||
|
entry_index,
|
||||||
|
)
|
||||||
|
.await
|
||||||
{
|
{
|
||||||
error!(
|
error!(
|
||||||
"Failed to update immature reward window for block {block_header_number}: {err}"
|
"Failed to update immature reward window for block {block_header_number}: {err}"
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,6 @@ pub async fn process_swap(
|
||||||
&[
|
&[
|
||||||
&transaction.unsigned_swap.sender1,
|
&transaction.unsigned_swap.sender1,
|
||||||
&transaction.unsigned_swap.sender2,
|
&transaction.unsigned_swap.sender2,
|
||||||
&miner,
|
|
||||||
],
|
],
|
||||||
block_header_number,
|
block_header_number,
|
||||||
**index as u32,
|
**index as u32,
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ pub async fn process_token(
|
||||||
pending_effects.set_tree("txid", txkey.clone(), txvalue.into_bytes());
|
pending_effects.set_tree("txid", txkey.clone(), txvalue.into_bytes());
|
||||||
index_wallet_transaction(
|
index_wallet_transaction(
|
||||||
pending_effects,
|
pending_effects,
|
||||||
&[&transaction.unsigned_create_token.creator, &miner],
|
&[&transaction.unsigned_create_token.creator],
|
||||||
block_header_number,
|
block_header_number,
|
||||||
**index as u32,
|
**index as u32,
|
||||||
&txkey,
|
&txkey,
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,6 @@ pub async fn process_transfer(
|
||||||
&[
|
&[
|
||||||
&transaction.unsigned_transfer.sender,
|
&transaction.unsigned_transfer.sender,
|
||||||
&transaction.unsigned_transfer.receiver,
|
&transaction.unsigned_transfer.receiver,
|
||||||
&miner,
|
|
||||||
],
|
],
|
||||||
block_header_number,
|
block_header_number,
|
||||||
**index as u32,
|
**index as u32,
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ pub async fn process_vanity(
|
||||||
pending_effects.set_tree("txid", txkey.clone(), txvalue.into_bytes());
|
pending_effects.set_tree("txid", txkey.clone(), txvalue.into_bytes());
|
||||||
index_wallet_transaction(
|
index_wallet_transaction(
|
||||||
pending_effects,
|
pending_effects,
|
||||||
&[owner_address, &miner],
|
&[owner_address],
|
||||||
block_header_number,
|
block_header_number,
|
||||||
**index as u32,
|
**index as u32,
|
||||||
&txkey,
|
&txkey,
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,22 @@ pub fn index_wallet_transaction(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn index_wallet_transaction_direct(
|
||||||
|
db: &Db,
|
||||||
|
address: &str,
|
||||||
|
block_height: u32,
|
||||||
|
entry_index: u32,
|
||||||
|
txid: &[u8],
|
||||||
|
) -> Result<(), String> {
|
||||||
|
let key = wallet_tx_index_key(address, block_height, entry_index)?;
|
||||||
|
let tree = db
|
||||||
|
.open_tree(WALLET_TX_INDEX_TREE)
|
||||||
|
.map_err(|err| format!("Failed to open wallet transaction index: {err}"))?;
|
||||||
|
tree.insert(key, txid.to_vec())
|
||||||
|
.map_err(|err| format!("Failed to insert wallet transaction index: {err}"))?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn txid_block_height(db: &Db, txid: &[u8]) -> Result<Option<u32>, String> {
|
fn txid_block_height(db: &Db, txid: &[u8]) -> Result<Option<u32>, String> {
|
||||||
let tree = db
|
let tree = db
|
||||||
.open_tree("txid")
|
.open_tree("txid")
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,11 @@ use crate::Arc;
|
||||||
use crate::Mutex;
|
use crate::Mutex;
|
||||||
|
|
||||||
const LIVE_SYNC_HEIGHT_GAP: u32 = 10;
|
const LIVE_SYNC_HEIGHT_GAP: u32 = 10;
|
||||||
|
const STALE_NEXT_HEIGHT_ERROR: &str = "Incoming block is no longer the next expected height.";
|
||||||
|
|
||||||
|
fn is_stale_next_height_error(error: &str) -> bool {
|
||||||
|
error.contains(STALE_NEXT_HEIGHT_ERROR)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn should_trigger_orphan_check(error: &str) -> bool {
|
pub fn should_trigger_orphan_check(error: &str) -> bool {
|
||||||
// These errors mean the incoming torrent may belong to a competing
|
// These errors mean the incoming torrent may belong to a competing
|
||||||
|
|
@ -41,7 +46,6 @@ pub fn should_trigger_orphan_check(error: &str) -> bool {
|
||||||
error.contains("Incorrect previous_block_hash.")
|
error.contains("Incorrect previous_block_hash.")
|
||||||
|| error.contains("Candidate parent is not current chain parent.")
|
|| error.contains("Candidate parent is not current chain parent.")
|
||||||
|| error.contains("Difficulty mismatch with the blockchain data.")
|
|| error.contains("Difficulty mismatch with the blockchain data.")
|
||||||
|| error.contains("Incoming block is no longer the next expected height.")
|
|
||||||
|| error.contains("Unable to read block")
|
|| error.contains("Unable to read block")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -299,6 +303,12 @@ pub async fn torrent_submission(
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
if is_stale_next_height_error(&e) {
|
||||||
|
info!(
|
||||||
|
"[broadcast] ignored stale downloaded block: height={height} err={e}"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
error!("[broadcast] setup_download error: height={height} err={e}");
|
error!("[broadcast] setup_download error: height={height} err={e}");
|
||||||
if should_trigger_orphan_check(&e) {
|
if should_trigger_orphan_check(&e) {
|
||||||
trigger_orphan_check(
|
trigger_orphan_check(
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
use crate::common::check_genesis::genesis_checkup;
|
use crate::common::check_genesis::genesis_checkup;
|
||||||
use crate::common::skein::skein_128_hash_bytes;
|
use crate::common::skein::skein_128_hash_bytes;
|
||||||
use crate::log::{error, warn};
|
use crate::log::{error, info, warn};
|
||||||
use crate::miner::flag::is_reorganizing_mode;
|
use crate::miner::flag::is_reorganizing_mode;
|
||||||
use crate::records::block_height::get_block_height::get_height;
|
use crate::records::block_height::get_block_height::get_height;
|
||||||
use crate::records::memory::mempool::ensure_db_connection;
|
|
||||||
use crate::records::record_chain::save::save_block;
|
use crate::records::record_chain::save::save_block;
|
||||||
use crate::records::record_chain::structs::{SaveBlockParams, SaveType};
|
use crate::records::record_chain::structs::{SaveBlockParams, SaveType};
|
||||||
use crate::records::unpack_block::load_by_binary_data::load_block_from_binary;
|
use crate::records::unpack_block::load_by_binary_data::load_block_from_binary;
|
||||||
|
|
@ -98,10 +97,6 @@ async fn verify_and_save_block_payload(
|
||||||
return Err("Candidate previous hash does not match torrent metadata.".to_string());
|
return Err("Candidate previous hash does not match torrent metadata.".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
ensure_db_connection()
|
|
||||||
.await
|
|
||||||
.map_err(|err| format!("Postgres reconnect failed before block verification: {err}"))?;
|
|
||||||
|
|
||||||
// Run full block verification before allowing the chain save path to persist the downloaded block.
|
// Run full block verification before allowing the chain save path to persist the downloaded block.
|
||||||
let signatures = match loaded_block
|
let signatures = match loaded_block
|
||||||
.verify(¶ms.db, params.verification_service.clone())
|
.verify(¶ms.db, params.verification_service.clone())
|
||||||
|
|
@ -178,7 +173,7 @@ async fn ensure_next_expected_height(params: &DownloadSave) -> Result<(), String
|
||||||
};
|
};
|
||||||
|
|
||||||
if params.block_number < expected_height {
|
if params.block_number < expected_height {
|
||||||
warn!(
|
info!(
|
||||||
"[download] block is no longer next expected height: block_number={} current_height={} expected_height={}",
|
"[download] block is no longer next expected height: block_number={} current_height={} expected_height={}",
|
||||||
params.block_number,
|
params.block_number,
|
||||||
current_height,
|
current_height,
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ use crate::wallets::structures::Wallet;
|
||||||
use crate::Arc;
|
use crate::Arc;
|
||||||
use crate::Utc;
|
use crate::Utc;
|
||||||
|
|
||||||
const ALLOWED_FUTURE_BLOCK_SECONDS: u32 = 1;
|
const ALLOWED_FUTURE_BLOCK_SECONDS: u32 = 3;
|
||||||
|
|
||||||
impl Block {
|
impl Block {
|
||||||
pub async fn verify(
|
pub async fn verify(
|
||||||
|
|
@ -82,7 +82,7 @@ impl Block {
|
||||||
// validate hash
|
// validate hash
|
||||||
Self::validate_hash_difficulty(db, hash).await?;
|
Self::validate_hash_difficulty(db, hash).await?;
|
||||||
|
|
||||||
// Allow the same one-second clock skew tolerated during handshake,
|
// Allow the same three-second clock skew tolerated during handshake,
|
||||||
// while the parent timestamp check below still enforces block spacing.
|
// while the parent timestamp check below still enforces block spacing.
|
||||||
if timestamp > current_timestamp.saturating_add(ALLOWED_FUTURE_BLOCK_SECONDS) {
|
if timestamp > current_timestamp.saturating_add(ALLOWED_FUTURE_BLOCK_SECONDS) {
|
||||||
return Err("Timestamp in the block is in the future.".to_string());
|
return Err("Timestamp in the block is in the future.".to_string());
|
||||||
|
|
@ -148,7 +148,7 @@ impl Block {
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate that the current timestamp is greater the previous
|
// validate that the current timestamp is greater the previous
|
||||||
// block timestamp plus 2 seconds
|
// block timestamp plus 1 second
|
||||||
let current_timestamp = Utc::now().timestamp() as u32;
|
let current_timestamp = Utc::now().timestamp() as u32;
|
||||||
if current_timestamp < previous_block.unmined_block.timestamp + 1 {
|
if current_timestamp < previous_block.unmined_block.timestamp + 1 {
|
||||||
return Err("Mining to quickly".to_string());
|
return Err("Mining to quickly".to_string());
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue