mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
validator/consensus: use blocks previous previous VRF for ranking
This commit is contained in:
@@ -16,19 +16,15 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::io::Cursor;
|
||||
|
||||
use darkfi_sdk::{
|
||||
blockchain::Slot,
|
||||
crypto::{ecvrf::VrfProof, pasta_prelude::PrimeField, schnorr::Signature},
|
||||
crypto::schnorr::Signature,
|
||||
pasta::{group::ff::FromUniformBytes, pallas},
|
||||
};
|
||||
#[cfg(feature = "async-serial")]
|
||||
use darkfi_serial::async_trait;
|
||||
|
||||
use darkfi_serial::{
|
||||
deserialize, serialize, Decodable, Encodable, SerialDecodable, SerialEncodable,
|
||||
};
|
||||
use darkfi_serial::{deserialize, serialize, Encodable, SerialDecodable, SerialEncodable};
|
||||
|
||||
use crate::{tx::Transaction, Error, Result};
|
||||
|
||||
@@ -147,46 +143,6 @@ impl BlockInfo {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Compute block's rank, assuming the block is valid.
|
||||
pub fn rank(&self) -> Result<u64> {
|
||||
// Genesis block has rank 0
|
||||
if self.header.height == 0 {
|
||||
return Ok(0)
|
||||
}
|
||||
|
||||
// Extract VRF proof from the producer transaction
|
||||
let tx = self.txs.last().unwrap();
|
||||
let data = &tx.calls[0].data;
|
||||
let position = match self.header.version {
|
||||
// PoW uses MoneyPoWRewardParamsV1
|
||||
1 => 563,
|
||||
// PoS uses ConsensusProposalParamsV1
|
||||
2 => 490,
|
||||
_ => return Err(Error::BlockVersionIsInvalid(self.header.version)),
|
||||
};
|
||||
let mut decoder = Cursor::new(&data);
|
||||
decoder.set_position(position);
|
||||
let vrf_proof: VrfProof = Decodable::decode(&mut decoder)?;
|
||||
|
||||
// Compute nonce u64
|
||||
let mut nonce = [0u8; 8];
|
||||
nonce.copy_from_slice(&self.header.nonce.to_repr()[..8]);
|
||||
let nonce = u64::from_be_bytes(nonce);
|
||||
|
||||
// Compute VRF u64
|
||||
let mut vrf = [0u8; 64];
|
||||
vrf[..blake3::OUT_LEN].copy_from_slice(vrf_proof.hash_output().as_bytes());
|
||||
let vrf_pallas = pallas::Base::from_uniform_bytes(&vrf);
|
||||
let mut vrf = [0u8; 8];
|
||||
vrf.copy_from_slice(&vrf_pallas.to_repr()[..8]);
|
||||
let vrf = u64::from_be_bytes(vrf);
|
||||
|
||||
// Finally, compute the rank
|
||||
let rank = nonce % vrf;
|
||||
|
||||
Ok(rank)
|
||||
}
|
||||
}
|
||||
|
||||
/// [`Block`] sled tree
|
||||
|
||||
@@ -29,7 +29,9 @@ use crate::{
|
||||
blockchain::{BlockInfo, Blockchain, BlockchainOverlay, BlockchainOverlayPtr, Header},
|
||||
tx::Transaction,
|
||||
util::time::{TimeKeeper, Timestamp},
|
||||
validator::{pid::slot_pid_output, pow::PoWModule, verify_block, verify_transactions},
|
||||
validator::{
|
||||
pid::slot_pid_output, pow::PoWModule, utils::block_rank, verify_block, verify_transactions,
|
||||
},
|
||||
Error, Result,
|
||||
};
|
||||
|
||||
@@ -632,7 +634,19 @@ impl Fork {
|
||||
let mut sum = 0;
|
||||
let proposals = self.overlay.lock().unwrap().get_blocks_by_hash(&self.proposals)?;
|
||||
for proposal in &proposals {
|
||||
sum += proposal.rank()?;
|
||||
// For block height > 3, retrieve their previous previous block
|
||||
let previous_previous = if proposal.header.height > 3 {
|
||||
let previous = &self
|
||||
.overlay
|
||||
.lock()
|
||||
.unwrap()
|
||||
.get_blocks_by_hash(&[proposal.header.previous])?[0];
|
||||
self.overlay.lock().unwrap().get_blocks_by_hash(&[previous.header.previous])?[0]
|
||||
.clone()
|
||||
} else {
|
||||
proposal.clone()
|
||||
};
|
||||
sum += block_rank(proposal, &previous_previous)?;
|
||||
}
|
||||
|
||||
// Use fork(proposals) length as a multiplier to compute the actual fork rank
|
||||
|
||||
@@ -16,12 +16,23 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use darkfi_sdk::crypto::{PublicKey, CONSENSUS_CONTRACT_ID, DAO_CONTRACT_ID, MONEY_CONTRACT_ID};
|
||||
use darkfi_serial::serialize;
|
||||
use std::io::Cursor;
|
||||
|
||||
use darkfi_sdk::{
|
||||
crypto::{
|
||||
ecvrf::VrfProof, pasta_prelude::PrimeField, PublicKey, CONSENSUS_CONTRACT_ID,
|
||||
DAO_CONTRACT_ID, MONEY_CONTRACT_ID,
|
||||
},
|
||||
pasta::{group::ff::FromUniformBytes, pallas},
|
||||
};
|
||||
use darkfi_serial::{serialize, Decodable};
|
||||
use log::info;
|
||||
|
||||
use crate::{
|
||||
blockchain::BlockchainOverlayPtr, runtime::vm_runtime::Runtime, util::time::TimeKeeper, Result,
|
||||
blockchain::{BlockInfo, BlockchainOverlayPtr},
|
||||
runtime::vm_runtime::Runtime,
|
||||
util::time::TimeKeeper,
|
||||
Error, Result,
|
||||
};
|
||||
|
||||
/// Deploy DarkFi native wasm contracts to provided blockchain overlay.
|
||||
@@ -86,3 +97,51 @@ pub fn deploy_native_contracts(
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Compute a block's rank, assuming the its valid.
|
||||
/// Genesis block has rank 0.
|
||||
/// First 2 blocks rank is equal to their nonce, since their previous
|
||||
/// previous block producer doesn't exist or have a VRF.
|
||||
pub fn block_rank(block: &BlockInfo, previous_previous: &BlockInfo) -> Result<u64> {
|
||||
// Genesis block has rank 0
|
||||
if block.header.height == 0 {
|
||||
return Ok(0)
|
||||
}
|
||||
|
||||
// Compute nonce u64
|
||||
let mut nonce = [0u8; 8];
|
||||
nonce.copy_from_slice(&block.header.nonce.to_repr()[..8]);
|
||||
let nonce = u64::from_be_bytes(nonce);
|
||||
|
||||
// First 2 block have rank equal to their nonce
|
||||
if block.header.height < 3 {
|
||||
return Ok(nonce)
|
||||
}
|
||||
|
||||
// Extract VRF proof from the previous previous producer transaction
|
||||
let tx = previous_previous.txs.last().unwrap();
|
||||
let data = &tx.calls[0].data;
|
||||
let position = match previous_previous.header.version {
|
||||
// PoW uses MoneyPoWRewardParamsV1
|
||||
1 => 563,
|
||||
// PoS uses ConsensusProposalParamsV1
|
||||
2 => 490,
|
||||
_ => return Err(Error::BlockVersionIsInvalid(previous_previous.header.version)),
|
||||
};
|
||||
let mut decoder = Cursor::new(&data);
|
||||
decoder.set_position(position);
|
||||
let vrf_proof: VrfProof = Decodable::decode(&mut decoder)?;
|
||||
|
||||
// Compute VRF u64
|
||||
let mut vrf = [0u8; 64];
|
||||
vrf[..blake3::OUT_LEN].copy_from_slice(vrf_proof.hash_output().as_bytes());
|
||||
let vrf_pallas = pallas::Base::from_uniform_bytes(&vrf);
|
||||
let mut vrf = [0u8; 8];
|
||||
vrf.copy_from_slice(&vrf_pallas.to_repr()[..8]);
|
||||
let vrf = u64::from_be_bytes(vrf);
|
||||
|
||||
// Finally, compute the rank
|
||||
let rank = nonce % vrf;
|
||||
|
||||
Ok(rank)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user