mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 22:57:59 -05:00
blockchain/Block: moved producer tx at last position of blocks' txs vec
This commit is contained in:
@@ -22,6 +22,7 @@ use darkfi::{
|
||||
blockchain::{BlockInfo, Header},
|
||||
net::Settings,
|
||||
rpc::jsonrpc::JsonSubscriber,
|
||||
tx::Transaction,
|
||||
util::time::TimeKeeper,
|
||||
validator::{pid::slot_pid_output, Validator, ValidatorConfig},
|
||||
Result,
|
||||
@@ -64,9 +65,13 @@ impl Harness {
|
||||
// Generate default genesis block
|
||||
let mut genesis_block = BlockInfo::default();
|
||||
|
||||
// Retrieve genesis producer transaction
|
||||
let producer_tx = genesis_block.txs.pop().unwrap();
|
||||
|
||||
// Append genesis transactions and calculate their total
|
||||
genesis_block.txs.push(genesis_stake_tx);
|
||||
genesis_block.txs.push(genesis_mint_tx);
|
||||
genesis_block.txs.push(producer_tx);
|
||||
let genesis_txs_total = genesis_txs_total(&genesis_block.txs)?;
|
||||
genesis_block.slots[0].total_tokens = genesis_txs_total;
|
||||
|
||||
@@ -201,9 +206,8 @@ impl Harness {
|
||||
// Generate block
|
||||
let block = BlockInfo::new(
|
||||
header,
|
||||
vec![],
|
||||
vec![Transaction::default()],
|
||||
previous.signature,
|
||||
previous.proposal.clone(),
|
||||
previous.eta,
|
||||
slots,
|
||||
);
|
||||
|
||||
@@ -41,10 +41,16 @@ use crate::proto::{ProtocolBlock, ProtocolProposal, ProtocolSync, ProtocolTx};
|
||||
/// Auxiliary function to calculate the total amount of minted tokens in provided
|
||||
/// genesis transactions set. This includes both staked and normal tokens.
|
||||
/// If a non-genesis transaction is found, execution fails.
|
||||
/// Set must also include the genesis transaction(empty) at last position.
|
||||
pub fn genesis_txs_total(txs: &[Transaction]) -> Result<u64> {
|
||||
let mut total = 0;
|
||||
|
||||
for tx in txs {
|
||||
if txs.is_empty() {
|
||||
return Ok(total)
|
||||
}
|
||||
|
||||
// Iterate transactions, exluding producer(last) one
|
||||
for tx in &txs[..txs.len() - 1] {
|
||||
// Transaction must contain a single Consensus::GenesisStake or Money::GenesisMint call
|
||||
if tx.calls.len() != 1 {
|
||||
return Err(TxVerifyFailed::ErroneousTxs(vec![tx.clone()]).into())
|
||||
@@ -69,6 +75,11 @@ pub fn genesis_txs_total(txs: &[Transaction]) -> Result<u64> {
|
||||
total += value;
|
||||
}
|
||||
|
||||
let tx = txs.last().unwrap();
|
||||
if tx != &Transaction::default() {
|
||||
return Err(TxVerifyFailed::ErroneousTxs(vec![tx.clone()]).into())
|
||||
}
|
||||
|
||||
Ok(total)
|
||||
}
|
||||
|
||||
|
||||
@@ -49,8 +49,6 @@ pub struct Block {
|
||||
pub txs: Vec<blake3::Hash>,
|
||||
/// Block producer signature
|
||||
pub signature: Signature,
|
||||
/// Proposal transaction
|
||||
pub proposal: Transaction,
|
||||
/// Block producer ETA
|
||||
pub eta: pallas::Base,
|
||||
/// Slots up until this block
|
||||
@@ -62,12 +60,11 @@ impl Block {
|
||||
header: blake3::Hash,
|
||||
txs: Vec<blake3::Hash>,
|
||||
signature: Signature,
|
||||
proposal: Transaction,
|
||||
eta: pallas::Base,
|
||||
slots: Vec<u64>,
|
||||
) -> Self {
|
||||
let magic = BLOCK_MAGIC_BYTES;
|
||||
Self { magic, header, txs, signature, proposal, eta, slots }
|
||||
Self { magic, header, txs, signature, eta, slots }
|
||||
}
|
||||
|
||||
/// Calculate the block hash
|
||||
@@ -87,8 +84,6 @@ pub struct BlockInfo {
|
||||
pub txs: Vec<Transaction>,
|
||||
/// Block producer signature
|
||||
pub signature: Signature,
|
||||
/// Proposal transaction
|
||||
pub proposal: Transaction,
|
||||
/// Block producer ETA
|
||||
pub eta: pallas::Base,
|
||||
/// Slots payload
|
||||
@@ -102,9 +97,8 @@ impl Default for BlockInfo {
|
||||
Self {
|
||||
magic,
|
||||
header: Header::default(),
|
||||
txs: vec![],
|
||||
txs: vec![Transaction::default()],
|
||||
signature: Signature::dummy(),
|
||||
proposal: Transaction::default(),
|
||||
eta: pallas::Base::ZERO,
|
||||
slots: vec![Slot::default()],
|
||||
}
|
||||
@@ -116,12 +110,11 @@ impl BlockInfo {
|
||||
header: Header,
|
||||
txs: Vec<Transaction>,
|
||||
signature: Signature,
|
||||
proposal: Transaction,
|
||||
eta: pallas::Base,
|
||||
slots: Vec<Slot>,
|
||||
) -> Self {
|
||||
let magic = BLOCK_MAGIC_BYTES;
|
||||
Self { magic, header, txs, signature, proposal, eta, slots }
|
||||
Self { magic, header, txs, signature, eta, slots }
|
||||
}
|
||||
|
||||
/// Calculate the block hash
|
||||
@@ -140,7 +133,6 @@ impl From<BlockInfo> for Block {
|
||||
header: block_info.header.headerhash().unwrap(),
|
||||
txs,
|
||||
signature: block_info.signature,
|
||||
proposal: block_info.proposal,
|
||||
eta: block_info.eta,
|
||||
slots,
|
||||
}
|
||||
|
||||
@@ -192,14 +192,7 @@ impl Blockchain {
|
||||
let slots = self.slots.get(&block.slots, true)?;
|
||||
let slots = slots.iter().map(|x| x.clone().unwrap()).collect();
|
||||
|
||||
let info = BlockInfo::new(
|
||||
header,
|
||||
txs,
|
||||
block.signature,
|
||||
block.proposal.clone(),
|
||||
block.eta,
|
||||
slots,
|
||||
);
|
||||
let info = BlockInfo::new(header, txs, block.signature, block.eta, slots);
|
||||
ret.push(info);
|
||||
}
|
||||
|
||||
@@ -514,14 +507,7 @@ impl BlockchainOverlay {
|
||||
let slots = self.slots.get(&block.slots, true)?;
|
||||
let slots = slots.iter().map(|x| x.clone().unwrap()).collect();
|
||||
|
||||
let info = BlockInfo::new(
|
||||
header,
|
||||
txs,
|
||||
block.signature,
|
||||
block.proposal.clone(),
|
||||
block.eta,
|
||||
slots,
|
||||
);
|
||||
let info = BlockInfo::new(header, txs, block.signature, block.eta, slots);
|
||||
ret.push(info);
|
||||
}
|
||||
|
||||
|
||||
@@ -360,6 +360,9 @@ pub enum Error {
|
||||
#[error("Block with order number {0} not found in database")]
|
||||
BlockNumberNotFound(u64),
|
||||
|
||||
#[error("Block {0} contains 0 transactions")]
|
||||
BlockContainsNoTransactions(String),
|
||||
|
||||
#[error("Verifying slot missmatch")]
|
||||
VerifyingSlotMissmatch(),
|
||||
|
||||
|
||||
@@ -128,8 +128,11 @@ impl Consensus {
|
||||
}
|
||||
let fork = &self.forks[fork_index];
|
||||
|
||||
// Grab forks' unproposed transactions and their root
|
||||
let unproposed_txs = fork.unproposed_txs(&self.blockchain, &time_keeper).await?;
|
||||
// Grab forks' unproposed transactions
|
||||
let mut unproposed_txs = fork.unproposed_txs(&self.blockchain, &time_keeper).await?;
|
||||
unproposed_txs.push(proposal_tx);
|
||||
|
||||
// Calculate transactions tree root
|
||||
let mut tree = MerkleTree::new(100);
|
||||
// The following is pretty weird, so something better should be done.
|
||||
for tx in &unproposed_txs {
|
||||
@@ -158,14 +161,8 @@ impl Consensus {
|
||||
let signature = secret_key.sign(&mut OsRng, &header.headerhash()?.as_bytes()[..]);
|
||||
|
||||
// Generate the block and its proposal
|
||||
let block = BlockInfo::new(
|
||||
header,
|
||||
unproposed_txs,
|
||||
signature,
|
||||
proposal_tx,
|
||||
slot.last_eta,
|
||||
fork.slots.clone(),
|
||||
);
|
||||
let block =
|
||||
BlockInfo::new(header, unproposed_txs, signature, slot.last_eta, fork.slots.clone());
|
||||
let proposal = Proposal::new(block);
|
||||
|
||||
Ok(proposal)
|
||||
|
||||
@@ -70,19 +70,26 @@ pub async fn verify_genesis_block(
|
||||
return Err(Error::SlotIsInvalid(genesis_slot.id))
|
||||
}
|
||||
|
||||
// Verify there is not reward
|
||||
// Verify there is no reward
|
||||
if genesis_slot.reward != 0 {
|
||||
return Err(Error::SlotIsInvalid(genesis_slot.id))
|
||||
}
|
||||
|
||||
// Genesis transaction must be the Transaction::default() one (empty)
|
||||
if block.proposal != Transaction::default() {
|
||||
error!(target: "validator::verification::verify_genesis_block", "Genesis proposal transaction is not default one");
|
||||
return Err(TxVerifyFailed::ErroneousTxs(vec![block.proposal.clone()]).into())
|
||||
// Verify transactions vector contains at least one(producers) transaction
|
||||
if block.txs.is_empty() {
|
||||
return Err(Error::BlockContainsNoTransactions(block_hash))
|
||||
}
|
||||
|
||||
// Verify transactions
|
||||
let erroneous_txs = verify_transactions(overlay, time_keeper, &block.txs).await?;
|
||||
// Genesis transaction must be the Transaction::default() one(empty)
|
||||
let tx = block.txs.last().unwrap();
|
||||
if tx != &Transaction::default() {
|
||||
error!(target: "validator::verification::verify_genesis_block", "Genesis proposal transaction is not default one");
|
||||
return Err(TxVerifyFailed::ErroneousTxs(vec![tx.clone()]).into())
|
||||
}
|
||||
|
||||
// Verify transactions, exluding producer(last) one
|
||||
let txs = &block.txs[..block.txs.len() - 1];
|
||||
let erroneous_txs = verify_transactions(overlay, time_keeper, txs).await?;
|
||||
if !erroneous_txs.is_empty() {
|
||||
warn!(target: "validator::verification::verify_genesis_block", "Erroneous transactions found in set");
|
||||
overlay.lock().unwrap().overlay.lock().unwrap().purge_new_trees()?;
|
||||
@@ -121,14 +128,21 @@ pub async fn verify_block(
|
||||
// Validate block, using its previous
|
||||
validate_block(block, previous, expected_reward)?;
|
||||
|
||||
// Verify transactions vector contains at least one(producers) transaction
|
||||
if block.txs.is_empty() {
|
||||
return Err(Error::BlockContainsNoTransactions(block_hash))
|
||||
}
|
||||
|
||||
// Validate proposal transaction if not in testing mode
|
||||
if !testing_mode {
|
||||
verify_proposal_transaction(overlay, time_keeper, &block.proposal).await?;
|
||||
let tx = block.txs.last().unwrap();
|
||||
verify_proposal_transaction(overlay, time_keeper, tx).await?;
|
||||
verify_producer_signature(block)?;
|
||||
}
|
||||
|
||||
// Verify transactions
|
||||
let erroneous_txs = verify_transactions(overlay, time_keeper, &block.txs).await?;
|
||||
// Verify transactions, exluding producer(last) one
|
||||
let txs = &block.txs[..block.txs.len() - 1];
|
||||
let erroneous_txs = verify_transactions(overlay, time_keeper, txs).await?;
|
||||
if !erroneous_txs.is_empty() {
|
||||
warn!(target: "validator::verification::verify_block", "Erroneous transactions found in set");
|
||||
overlay.lock().unwrap().overlay.lock().unwrap().purge_new_trees()?;
|
||||
|
||||
@@ -82,14 +82,7 @@ impl Harness {
|
||||
let header =
|
||||
Header::new(previous_hash, previous.header.epoch, id, timestamp, previous.header.root);
|
||||
|
||||
BlockInfo::new(
|
||||
header,
|
||||
vec![],
|
||||
previous.signature,
|
||||
previous.proposal.clone(),
|
||||
previous.eta,
|
||||
vec![slot],
|
||||
)
|
||||
BlockInfo::new(header, previous.txs.clone(), previous.signature, previous.eta, vec![slot])
|
||||
}
|
||||
|
||||
fn add_blocks(&self, blocks: &[BlockInfo]) -> Result<()> {
|
||||
|
||||
Reference in New Issue
Block a user