mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 14:48:08 -05:00
consensus/metadata: added coin serial and new coin public inputs
This commit is contained in:
@@ -43,8 +43,12 @@ pub struct Metadata {
|
||||
pub address: Address,
|
||||
/// Block owner slot competing coins public inputs
|
||||
pub public_inputs: Vec<pallas::Base>,
|
||||
/// Block owner newlly minted coin public inputs
|
||||
pub new_public_inputs: Vec<pallas::Base>,
|
||||
/// Block owner winning coin index
|
||||
pub winning_index: usize,
|
||||
/// Block owner winning coin serial number
|
||||
pub serial_number: pallas::Base,
|
||||
/// Response of global random oracle, or it's emulation.
|
||||
pub eta: [u8; 32],
|
||||
/// Leader NIZK proof
|
||||
@@ -59,11 +63,23 @@ impl Default for Metadata {
|
||||
let address = Address::from(keypair.public);
|
||||
let signature = Signature::dummy();
|
||||
let public_inputs = vec![];
|
||||
let new_public_inputs = vec![];
|
||||
let winning_index = 0;
|
||||
let serial_number = pallas::Base::from(0);
|
||||
let eta: [u8; 32] = *blake3::hash(b"let there be dark!").as_bytes();
|
||||
let proof = LeadProof::default();
|
||||
let participants = vec![];
|
||||
Self { signature, address, public_inputs, winning_index, eta, proof, participants }
|
||||
Self {
|
||||
signature,
|
||||
address,
|
||||
public_inputs,
|
||||
new_public_inputs,
|
||||
winning_index,
|
||||
serial_number,
|
||||
eta,
|
||||
proof,
|
||||
participants,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,12 +88,24 @@ impl Metadata {
|
||||
signature: Signature,
|
||||
address: Address,
|
||||
public_inputs: Vec<pallas::Base>,
|
||||
new_public_inputs: Vec<pallas::Base>,
|
||||
winning_index: usize,
|
||||
serial_number: pallas::Base,
|
||||
eta: [u8; 32],
|
||||
proof: LeadProof,
|
||||
participants: Vec<Participant>,
|
||||
) -> Self {
|
||||
Self { signature, address, public_inputs, winning_index, eta, proof, participants }
|
||||
Self {
|
||||
signature,
|
||||
address,
|
||||
public_inputs,
|
||||
new_public_inputs,
|
||||
winning_index,
|
||||
serial_number,
|
||||
eta,
|
||||
proof,
|
||||
participants,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -368,6 +368,8 @@ impl Stakeholder {
|
||||
info!("Winning coin index: {}", idx);
|
||||
// Generating leader proof
|
||||
let coin = self.epoch.get_coin(sl as usize, idx);
|
||||
// TODO: Generate new LeadCoin from newlly minted coin, will reuse original coin for now
|
||||
//let coin2 = something();
|
||||
let proof = self.epoch.get_proof(sl as usize, idx, &self.get_leadprovkingkey());
|
||||
//Verifying generated proof against winning coin public inputs
|
||||
info!("Leader proof generated successfully, veryfing...");
|
||||
@@ -389,7 +391,9 @@ impl Stakeholder {
|
||||
sign,
|
||||
addr,
|
||||
coin.public_inputs(),
|
||||
coin.public_inputs(),
|
||||
idx,
|
||||
coin.sn.unwrap(),
|
||||
self.get_eta().to_repr(),
|
||||
LeadProof::from(proof),
|
||||
vec![],
|
||||
|
||||
@@ -356,7 +356,7 @@ impl ValidatorState {
|
||||
/// Generate a block proposal for the current slot, containing all
|
||||
/// unconfirmed transactions. Proposal extends the longest fork
|
||||
/// chain the node is holding.
|
||||
pub fn propose(&self, idx: usize) -> Result<Option<BlockProposal>> {
|
||||
pub fn propose(&mut self, idx: usize) -> Result<Option<BlockProposal>> {
|
||||
let slot = self.current_slot();
|
||||
let (prev_hash, index) = self.longest_chain_last_hash().unwrap();
|
||||
let unproposed_txs = self.unproposed_txs(index);
|
||||
@@ -375,18 +375,25 @@ impl ValidatorState {
|
||||
let signed_proposal = self.secret.sign(&mut OsRng, &header.headerhash().as_bytes()[..]);
|
||||
let eta = self.get_eta().to_repr();
|
||||
// Generating leader proof
|
||||
let coin = self.consensus.coins[self.relative_slot(slot) as usize][idx];
|
||||
let relative_slot = self.relative_slot(slot) as usize;
|
||||
let coin = self.consensus.coins[relative_slot][idx];
|
||||
// TODO: Generate new LeadCoin from newlly minted coin, will reuse original coin for now
|
||||
//let coin2 = something();
|
||||
let proof = lead_proof::create_lead_proof(&self.proving_key, coin)?;
|
||||
let participants = self.consensus.participants.values().cloned().collect();
|
||||
let metadata = Metadata::new(
|
||||
signed_proposal,
|
||||
self.address,
|
||||
coin.public_inputs(),
|
||||
coin.public_inputs(),
|
||||
idx,
|
||||
coin.sn.unwrap(),
|
||||
eta,
|
||||
LeadProof::from(proof),
|
||||
participants,
|
||||
);
|
||||
// TODO: replace old coin with new coin
|
||||
self.consensus.coins[relative_slot][idx] = coin;
|
||||
|
||||
// TODO: [PLACEHOLDER] Add rewards calculation (proof?)
|
||||
// TODO: [PLACEHOLDER] Create and add rewards transaction
|
||||
@@ -470,7 +477,7 @@ impl ValidatorState {
|
||||
);
|
||||
return Err(Error::UnknownNodeError)
|
||||
}
|
||||
let leader = leader.unwrap();
|
||||
let mut leader = leader.unwrap().clone();
|
||||
|
||||
// Check if proposal header matches actual one
|
||||
let proposal_header = proposal.block.header.headerhash();
|
||||
@@ -490,6 +497,8 @@ impl ValidatorState {
|
||||
return Err(Error::InvalidPublicInputsError)
|
||||
}
|
||||
|
||||
// TODO: Verify winning coin serial number
|
||||
|
||||
// Verify proposal leader proof
|
||||
match proposal.block.metadata.proof.verify(&self.verifying_key, public_inputs) {
|
||||
Ok(_) => info!("receive_proposal(): Proof veryfied succsessfully!"),
|
||||
@@ -532,6 +541,12 @@ impl ValidatorState {
|
||||
}
|
||||
|
||||
// TODO: [PLACEHOLDER] Add rewards validation
|
||||
// TODO: Append serial to merkle tree
|
||||
|
||||
// Replacing participants public inputs with the newlly minted ones
|
||||
leader.coins[self.relative_slot(current) as usize][proposal.block.metadata.winning_index] =
|
||||
proposal.block.metadata.new_public_inputs.clone();
|
||||
self.append_participant(leader);
|
||||
|
||||
// Check if proposal fork has can be finalized, to broadcast those blocks
|
||||
let mut to_broadcast = vec![];
|
||||
|
||||
@@ -108,7 +108,7 @@ pub async fn proposal_task(consensus_p2p: P2pPtr, sync_p2p: P2pPtr, state: Valid
|
||||
// Node checks if it's the slot leader to generate a new proposal
|
||||
// for that slot.
|
||||
let (won, idx) = state.read().await.is_slot_leader();
|
||||
let result = if won { state.read().await.propose(idx) } else { Ok(None) };
|
||||
let result = if won { state.write().await.propose(idx) } else { Ok(None) };
|
||||
let proposal = match result {
|
||||
Ok(prop) => {
|
||||
if prop.is_none() {
|
||||
@@ -135,11 +135,13 @@ pub async fn proposal_task(consensus_p2p: P2pPtr, sync_p2p: P2pPtr, state: Valid
|
||||
}
|
||||
// Broadcast finalized blocks info, if any:
|
||||
if let Some(blocks) = to_broadcast {
|
||||
info!("consensus: Broadcasting finalized blocks");
|
||||
for info in blocks {
|
||||
match sync_p2p.broadcast(info).await {
|
||||
Ok(()) => info!("consensus: Broadcasted block"),
|
||||
Err(e) => error!("consensus: Failed broadcasting block: {}", e),
|
||||
if blocks.len() > 0 {
|
||||
info!("consensus: Broadcasting finalized blocks");
|
||||
for info in blocks {
|
||||
match sync_p2p.broadcast(info).await {
|
||||
Ok(()) => info!("consensus: Broadcasted block"),
|
||||
Err(e) => error!("consensus: Failed broadcasting block: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user