consensus/metadata: added coin serial and new coin public inputs

This commit is contained in:
aggstam
2022-11-15 20:29:57 +02:00
parent 83a380b080
commit 8a60502a2f
4 changed files with 60 additions and 11 deletions

View File

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

View File

@@ -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![],

View File

@@ -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![];

View File

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