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(
|
||||
pending_effects,
|
||||
&[sender, receiver, &miner],
|
||||
&[sender, receiver],
|
||||
block_number,
|
||||
tx_index,
|
||||
&decode(hash)?,
|
||||
|
|
@ -466,7 +466,7 @@ pub async fn apply_selected_transaction_math(
|
|||
);
|
||||
index_selected_wallet_transaction(
|
||||
pending_effects,
|
||||
&[creator, &miner],
|
||||
&[creator],
|
||||
block_number,
|
||||
tx_index,
|
||||
&decode(hash)?,
|
||||
|
|
@ -504,7 +504,7 @@ pub async fn apply_selected_transaction_math(
|
|||
);
|
||||
index_selected_wallet_transaction(
|
||||
pending_effects,
|
||||
&[creator, &miner],
|
||||
&[creator],
|
||||
block_number,
|
||||
tx_index,
|
||||
&decode(hash)?,
|
||||
|
|
@ -539,7 +539,7 @@ pub async fn apply_selected_transaction_math(
|
|||
);
|
||||
index_selected_wallet_transaction(
|
||||
pending_effects,
|
||||
&[address, &miner],
|
||||
&[address],
|
||||
block_number,
|
||||
tx_index,
|
||||
&decode(hash)?,
|
||||
|
|
@ -612,7 +612,7 @@ pub async fn apply_selected_transaction_math(
|
|||
);
|
||||
index_selected_wallet_transaction(
|
||||
pending_effects,
|
||||
&[creator, &miner],
|
||||
&[creator],
|
||||
block_number,
|
||||
tx_index,
|
||||
&decode(hash)?,
|
||||
|
|
@ -638,7 +638,7 @@ pub async fn apply_selected_transaction_math(
|
|||
);
|
||||
index_selected_wallet_transaction(
|
||||
pending_effects,
|
||||
&[advertiser, &miner],
|
||||
&[advertiser],
|
||||
block_number,
|
||||
tx_index,
|
||||
&decode(hash)?,
|
||||
|
|
@ -668,7 +668,7 @@ pub async fn apply_selected_transaction_math(
|
|||
);
|
||||
index_selected_wallet_transaction(
|
||||
pending_effects,
|
||||
&[address, &miner],
|
||||
&[address],
|
||||
block_number,
|
||||
tx_index,
|
||||
&decode(hash)?,
|
||||
|
|
@ -748,7 +748,7 @@ pub async fn apply_selected_transaction_math(
|
|||
);
|
||||
index_selected_wallet_transaction(
|
||||
pending_effects,
|
||||
&[sender1, sender2, &miner],
|
||||
&[sender1, sender2],
|
||||
block_number,
|
||||
tx_index,
|
||||
&decode(hash)?,
|
||||
|
|
@ -817,7 +817,7 @@ pub async fn apply_selected_transaction_math(
|
|||
);
|
||||
index_selected_wallet_transaction(
|
||||
pending_effects,
|
||||
&[lender, borrower, &miner],
|
||||
&[lender, borrower],
|
||||
block_number,
|
||||
tx_index,
|
||||
&decode(hash)?,
|
||||
|
|
@ -886,7 +886,7 @@ pub async fn apply_selected_transaction_math(
|
|||
let lender_address = binary_to_string(lender.clone());
|
||||
index_selected_wallet_transaction(
|
||||
pending_effects,
|
||||
&[address, &lender_address, &miner],
|
||||
&[address, &lender_address],
|
||||
block_number,
|
||||
tx_index,
|
||||
&decode(hash)?,
|
||||
|
|
@ -941,7 +941,7 @@ pub async fn apply_selected_transaction_math(
|
|||
);
|
||||
index_selected_wallet_transaction(
|
||||
pending_effects,
|
||||
&[address, &miner],
|
||||
&[address],
|
||||
block_number,
|
||||
tx_index,
|
||||
&decode(hash)?,
|
||||
|
|
|
|||
|
|
@ -109,11 +109,7 @@ pub async fn process_borrower(
|
|||
pending_effects.set_tree("txid", txkey, txvalue.into_bytes());
|
||||
index_wallet_transaction(
|
||||
pending_effects,
|
||||
&[
|
||||
&transaction.unsigned_contract_payment.address,
|
||||
&lender,
|
||||
&miner,
|
||||
],
|
||||
&[&transaction.unsigned_contract_payment.address, &lender],
|
||||
block_header_number,
|
||||
**index as u32,
|
||||
&txhash_bytes,
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ pub async fn process_burn(
|
|||
pending_effects.set_tree("txid", txkey, txvalue.into_bytes());
|
||||
index_wallet_transaction(
|
||||
pending_effects,
|
||||
&[&transaction.unsigned_burn.address, &miner],
|
||||
&[&transaction.unsigned_burn.address],
|
||||
block_header_number,
|
||||
**index as u32,
|
||||
&txhash_bytes,
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ pub async fn process_collateral(
|
|||
pending_effects.set_tree("txid", txkey, txvalue.into_bytes());
|
||||
index_wallet_transaction(
|
||||
pending_effects,
|
||||
&[&transaction.unsigned_collateral_claim.address, &miner],
|
||||
&[&transaction.unsigned_collateral_claim.address],
|
||||
block_header_number,
|
||||
**index as u32,
|
||||
&txhash_bytes,
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ pub async fn process_issue_token(
|
|||
pending_effects.set_tree("txid", txkey.clone(), txvalue.into_bytes());
|
||||
index_wallet_transaction(
|
||||
pending_effects,
|
||||
&[&transaction.unsigned_issue_token.creator, &miner],
|
||||
&[&transaction.unsigned_issue_token.creator],
|
||||
block_header_number,
|
||||
**index as u32,
|
||||
&txkey,
|
||||
|
|
|
|||
|
|
@ -81,7 +81,6 @@ pub async fn process_lender(
|
|||
&[
|
||||
&transaction.unsigned_loan_contract.lender,
|
||||
&transaction.unsigned_loan_contract.borrower,
|
||||
&miner,
|
||||
],
|
||||
block_header_number,
|
||||
**index as u32,
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ pub async fn process_marketing(
|
|||
pending_effects.set_tree("txid", txkey, txvalue.into_bytes());
|
||||
index_wallet_transaction(
|
||||
pending_effects,
|
||||
&[&transaction.unsigned_marketing.advertiser, &miner],
|
||||
&[&transaction.unsigned_marketing.advertiser],
|
||||
block_header_number,
|
||||
**index as u32,
|
||||
&txhash_bytes,
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ pub async fn process_nft(
|
|||
pending_effects.set_tree("txid", txkey, txvalue.into_bytes());
|
||||
index_wallet_transaction(
|
||||
pending_effects,
|
||||
&[&transaction.unsigned_create_nft.creator, &miner],
|
||||
&[&transaction.unsigned_create_nft.creator],
|
||||
block_header_number,
|
||||
**index as u32,
|
||||
&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::memory::mempool::BASECOIN;
|
||||
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::sled::Db;
|
||||
use crate::Arc;
|
||||
|
|
@ -21,6 +21,8 @@ struct ImmatureReward {
|
|||
block_height: u32,
|
||||
miner: String,
|
||||
amount: u64,
|
||||
txid: Vec<u8>,
|
||||
entry_index: u32,
|
||||
}
|
||||
|
||||
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}"))?;
|
||||
}
|
||||
|
||||
index_wallet_transaction_direct(
|
||||
db,
|
||||
&reward.miner,
|
||||
reward.block_height,
|
||||
reward.entry_index,
|
||||
&reward.txid,
|
||||
)?;
|
||||
mark_reward_credit_applied(db, reward.block_height)
|
||||
}
|
||||
|
||||
|
|
@ -71,6 +80,8 @@ pub async fn record_saved_reward(
|
|||
block_height: u32,
|
||||
miner: String,
|
||||
amount: u64,
|
||||
txid: Vec<u8>,
|
||||
entry_index: u32,
|
||||
) -> Result<(), String> {
|
||||
let matured = {
|
||||
let mut rewards = IMMATURE_REWARDS.lock().await;
|
||||
|
|
@ -79,6 +90,8 @@ pub async fn record_saved_reward(
|
|||
block_height,
|
||||
miner,
|
||||
amount,
|
||||
txid,
|
||||
entry_index,
|
||||
});
|
||||
|
||||
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;
|
||||
|
||||
for transaction in block.transactions {
|
||||
for (position, transaction) in block.transactions.into_iter().enumerate() {
|
||||
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 {
|
||||
block_height,
|
||||
miner,
|
||||
amount: rewards.unsigned.value,
|
||||
txid,
|
||||
entry_index,
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
|
@ -138,7 +157,7 @@ pub async fn process_rewards(
|
|||
mut binary_data: Vec<u8>,
|
||||
_db: &Db,
|
||||
index_counter: Arc<Mutex<&mut usize>>,
|
||||
miner: String,
|
||||
_miner: String,
|
||||
block_header_number: u32,
|
||||
pending_effects: &mut PendingEffects,
|
||||
) -> Result<Vec<u8>, String> {
|
||||
|
|
@ -157,16 +176,9 @@ pub async fn process_rewards(
|
|||
binary_data.extend(transaction_bytes);
|
||||
|
||||
// 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 txvalue = format!("{block_header_number}:{}", **index);
|
||||
pending_effects.set_tree("txid", txkey.clone(), txvalue.into_bytes());
|
||||
index_wallet_transaction(
|
||||
pending_effects,
|
||||
&[&miner],
|
||||
block_header_number,
|
||||
**index as u32,
|
||||
&txkey,
|
||||
)?;
|
||||
pending_effects.set_tree("txid", txkey, txvalue.into_bytes());
|
||||
Ok(binary_data)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use crate::records::memory::chain_state::{
|
|||
cached_tip_hash, cached_tip_header, update_chain_state_after_save,
|
||||
};
|
||||
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,
|
||||
restore_selected_transactions_processed, select_transactions_for_block,
|
||||
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
|
||||
.vrf_block
|
||||
.to_bytes()
|
||||
|
|
@ -150,13 +146,17 @@ pub async fn save_block(params: SaveBlockParams) -> Result<(), String> {
|
|||
)
|
||||
.await?;
|
||||
|
||||
let saved_reward_amount = block
|
||||
.transactions
|
||||
.iter()
|
||||
.find_map(|transaction| match transaction {
|
||||
Transaction::Rewards(rewards) => Some(rewards.unsigned.value),
|
||||
_ => None,
|
||||
});
|
||||
let mut saved_reward = None;
|
||||
for (position, transaction) in block.transactions.iter().enumerate() {
|
||||
if let Transaction::Rewards(rewards) = transaction {
|
||||
let txid = decode(rewards.unsigned.hash().await)
|
||||
.map_err(|e| format!("Error decoding saved reward txid key: {e}"))?;
|
||||
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 index = index_mutex.lock().await;
|
||||
|
|
@ -219,8 +219,16 @@ pub async fn save_block(params: SaveBlockParams) -> Result<(), String> {
|
|||
.await?;
|
||||
}
|
||||
|
||||
if let Some(amount) = saved_reward_amount {
|
||||
if let Err(err) = record_saved_reward(&db, block_header_number, miner.clone(), amount).await
|
||||
if let Some((amount, txid, entry_index)) = saved_reward {
|
||||
if let Err(err) = record_saved_reward(
|
||||
&db,
|
||||
block_header_number,
|
||||
miner.clone(),
|
||||
amount,
|
||||
txid,
|
||||
entry_index,
|
||||
)
|
||||
.await
|
||||
{
|
||||
error!(
|
||||
"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.sender2,
|
||||
&miner,
|
||||
],
|
||||
block_header_number,
|
||||
**index as u32,
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ pub async fn process_token(
|
|||
pending_effects.set_tree("txid", txkey.clone(), txvalue.into_bytes());
|
||||
index_wallet_transaction(
|
||||
pending_effects,
|
||||
&[&transaction.unsigned_create_token.creator, &miner],
|
||||
&[&transaction.unsigned_create_token.creator],
|
||||
block_header_number,
|
||||
**index as u32,
|
||||
&txkey,
|
||||
|
|
|
|||
|
|
@ -75,7 +75,6 @@ pub async fn process_transfer(
|
|||
&[
|
||||
&transaction.unsigned_transfer.sender,
|
||||
&transaction.unsigned_transfer.receiver,
|
||||
&miner,
|
||||
],
|
||||
block_header_number,
|
||||
**index as u32,
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ pub async fn process_vanity(
|
|||
pending_effects.set_tree("txid", txkey.clone(), txvalue.into_bytes());
|
||||
index_wallet_transaction(
|
||||
pending_effects,
|
||||
&[owner_address, &miner],
|
||||
&[owner_address],
|
||||
block_header_number,
|
||||
**index as u32,
|
||||
&txkey,
|
||||
|
|
|
|||
|
|
@ -45,6 +45,22 @@ pub fn index_wallet_transaction(
|
|||
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> {
|
||||
let tree = db
|
||||
.open_tree("txid")
|
||||
|
|
|
|||
|
|
@ -34,6 +34,11 @@ use crate::Arc;
|
|||
use crate::Mutex;
|
||||
|
||||
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 {
|
||||
// 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("Candidate parent is not current chain parent.")
|
||||
|| 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")
|
||||
}
|
||||
|
||||
|
|
@ -299,6 +303,12 @@ pub async fn torrent_submission(
|
|||
.await;
|
||||
}
|
||||
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}");
|
||||
if should_trigger_orphan_check(&e) {
|
||||
trigger_orphan_check(
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
use crate::common::check_genesis::genesis_checkup;
|
||||
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::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::structs::{SaveBlockParams, SaveType};
|
||||
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());
|
||||
}
|
||||
|
||||
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.
|
||||
let signatures = match loaded_block
|
||||
.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 {
|
||||
warn!(
|
||||
info!(
|
||||
"[download] block is no longer next expected height: block_number={} current_height={} expected_height={}",
|
||||
params.block_number,
|
||||
current_height,
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use crate::wallets::structures::Wallet;
|
|||
use crate::Arc;
|
||||
use crate::Utc;
|
||||
|
||||
const ALLOWED_FUTURE_BLOCK_SECONDS: u32 = 1;
|
||||
const ALLOWED_FUTURE_BLOCK_SECONDS: u32 = 3;
|
||||
|
||||
impl Block {
|
||||
pub async fn verify(
|
||||
|
|
@ -82,7 +82,7 @@ impl Block {
|
|||
// validate hash
|
||||
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.
|
||||
if timestamp > current_timestamp.saturating_add(ALLOWED_FUTURE_BLOCK_SECONDS) {
|
||||
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
|
||||
// block timestamp plus 2 seconds
|
||||
// block timestamp plus 1 second
|
||||
let current_timestamp = Utc::now().timestamp() as u32;
|
||||
if current_timestamp < previous_block.unmined_block.timestamp + 1 {
|
||||
return Err("Mining to quickly".to_string());
|
||||
|
|
|
|||
Loading…
Reference in New Issue