blockchain/Block: moved producer tx at last position of blocks' txs vec

This commit is contained in:
aggstam
2023-09-14 19:54:16 +03:00
parent dba13ebef6
commit eca2c7e175
8 changed files with 58 additions and 58 deletions

View File

@@ -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,
);

View File

@@ -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)
}

View File

@@ -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,
}

View File

@@ -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);
}

View File

@@ -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(),

View File

@@ -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)

View File

@@ -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()?;

View File

@@ -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<()> {