Просмотр исходного кода

blockchain/header: changed nonce from pallas::Base to u64

skoupidi 2 лет назад
Родитель
Сommit
8eef36b898

+ 1 - 1
bin/darkfid/genesis_block_localnet

@@ -1 +1 @@
-9mbVkHECpef5uSqiQKKzj7Z5HjypYEL63oSDQdb54RkSXbZ8MafuPQ4F8P4auRoQLKAQWEX2nETDDPvnNbKHT38szyiCqwXArSo5eVcXsXEbbji4HSpTDxPFUy6jU5t4PoCn9LASqBWtef99XdWjwnoEs8JzxmBFPexctCeSncnNe2QCYErDtfEU84fecSkZNhUfMAvSZ6KK9BPjKpNoBj16ywrLX69yRGRwMq
+YGugtxfzw7nNYDoY49avu1EgWwsVbpi3u59x3MQ2pJjDGEU5QTzCEuHKasjmKzJTyEV1V1AVoC7TkSsh1iVJZCF8pPXrDiDbpCHANpbqjKUxrLoGBhoM1FD5eoFB9vZTuKMWRZad2iSzi6G8odmBsfJ8s4f6188PjBaqBhMrNi67pNcEibXRVTin4KJZqZ5crmXnk3rcZzJAtrZUEDiAkRSXQuUEqyHb5pLgrPHz6aqaUf5mThjBdUAw3ibct7zm5

+ 1 - 1
bin/darkfid/genesis_block_mainnet

@@ -1 +1 @@
-9mbVkHECpef5uSqiQKKzj7Z5HjypYEL63oSDQdb54RkSXbZ8MafuPQ4F8P4auRoQLKAQWEX2nETDDPvnNbKHT38szyiCqwXArSo5eVcXsXEbbji4HSpTDxPFUy6jU5t4PoCn9LASqBWtef99XdWjwnoEs8JzxmBFPexctCeSncnNe2QCYErDtfEU84fecSkZNhUfMAvSZ6KK9BPjKpNoBj16ywrLX69yRGRwMq
+YGugtxfzw7nNYDoY49avu1EgWwsVbpi3u59x3MQ2pJjDGEU5QTzCEuHKasjmKzJTyEV1V1AVoC7TkSsh1iVJZCF8pPXrDiDbpCHANpbqjKUxrLoGBhoM1FD5eoFB9vZTuKMWRZad2iSzi6G8odmBsfJ8s4f6188PjBaqBhMrNi67pNcEibXRVTin4KJZqZ5crmXnk3rcZzJAtrZUEDiAkRSXQuUEqyHb5pLgrPHz6aqaUf5mThjBdUAw3ibct7zm5

+ 1 - 1
bin/darkfid/genesis_block_testnet

@@ -1 +1 @@
-9mbVkHECpef5uSqiQKKzj7Z5HjypYEL63oSDQdb54RkSXbZ8MafuPQ4F8P4auRoQLKAQWEX2nETDDPvnNbKHT38szyiCqwXArSo5eVcXsXEbbji4HSpTDxPFUy6jU5t4PoCn9LASqBWtef99XdWjwnoEs8JzxmBFPexctCeSncnNe2QCYErDtfEU84fecSkZNhUfMAvSZ6KK9BPjKpNoBj16ywrLX69yRGRwMq
+YGugtxfzw7nNYDoY49avu1EgWwsVbpi3u59x3MQ2pJjDGEU5QTzCEuHKasjmKzJTyEV1V1AVoC7TkSsh1iVJZCF8pPXrDiDbpCHANpbqjKUxrLoGBhoM1FD5eoFB9vZTuKMWRZad2iSzi6G8odmBsfJ8s4f6188PjBaqBhMrNi67pNcEibXRVTin4KJZqZ5crmXnk3rcZzJAtrZUEDiAkRSXQuUEqyHb5pLgrPHz6aqaUf5mThjBdUAw3ibct7zm5

+ 2 - 3
bin/darkfid/src/task/miner.rs

@@ -37,7 +37,7 @@ use darkfi_sdk::{
     pasta::pallas,
     ContractCall,
 };
-use darkfi_serial::{deserialize, serialize, Encodable};
+use darkfi_serial::{serialize, Encodable};
 use log::info;
 use num_bigint::BigUint;
 use rand::rngs::OsRng;
@@ -111,8 +111,7 @@ async fn miner_loop(node: &Darkfid, recipient: &PublicKey) -> Result<()> {
         let block = JsonValue::String(base64::encode(&serialize(&next_block)));
         let response =
             node.miner_daemon_request("mine", JsonValue::Array(vec![target, block])).await?;
-        let nonce_bytes = base64::decode(response.get::<String>().unwrap()).unwrap();
-        next_block.header.nonce = deserialize::<pallas::Base>(&nonce_bytes)?;
+        next_block.header.nonce = *response.get::<f64>().unwrap() as u64;
 
         // Sign the mined block
         next_block.sign(&secret)?;

+ 11 - 12
doc/src/arch/consensus.md

@@ -60,17 +60,16 @@ in order to stop mining its proposal and start mining the new best fork.
 
 ## Ranking
 
-Each proposed block has a ranked based on the modulus of its nonce and its
-previous proposal previous proposal `VRF` proof, which is attached to the
-block producer reward transaction. 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` attached to their reward transaction.
-For rest blocks, the rank computes as following:
-1. Generate a `u64` using the first 8 bytes from the blocks nonce `pallas::Base`
-2. Grab the `VRF` proof from the reward transaction of the previous previous proposal
-3. Generate a `pallas::Base` from the `blake3::Hash` bytes of the proof
-4. Generate a `u64` using the first 8 bytes from the `pallas::Base` of the proofs hash
-5. Compute the rank: nonce_u64 % vrf_u64
+Each proposed block has a ranked based on the modulus of its previous proposal
+previous proposal `VRF` proof, which is attached to the block producer reward
+transaction, and its `nonce`. 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` attached to their reward transaction. For rest blocks, the rank
+computes as following:
+1. Grab the `VRF` proof from the reward transaction of the previous previous proposal
+2. Generate a `pallas::Base` from the `blake3::Hash` bytes of the proof
+3. Generate a `u64` using the first 8 bytes from the `pallas::Base` of the proofs hash
+4. Compute the rank: `vrf_u64` % `nonce` (If `nonce` is 0, rank is equal to `vrf_u64`)
 
 To calculate each fork rank, we simply sum all its block proposals ranks and multiply
 that with the forks length. We use the length multiplier to give a chance of higher
@@ -211,7 +210,7 @@ be used by the protocol.
 | `epoch`     | `u64`          | Epoch number                                   |
 | `height`    | `u64`          | Block height                                   |
 | `timestamp` | `Timestamp`    | Block creation timestamp                       |
-| `nonce`     | `pallas::Base` | The block's nonce value                        |
+| `nonce`     | `u64`          | The block's nonce value                        |
 | `tree`      | `MerkleTree`   | Merkle tree of the block's transactions hashes |
 
 ## Block

+ 6 - 2
script/research/gg/src/main.rs

@@ -101,10 +101,14 @@ async fn main() -> Result<()> {
                 genesis_block.header.timestamp = Timestamp(timestamp);
             }
 
+            // Retrieve genesis producer transaction
+            let producer_tx = genesis_block.txs.pop().unwrap();
+
             // Append genesis transactions
             if !genesis_txs.is_empty() {
-                genesis_block.txs.append(&mut genesis_txs);
+                genesis_block.append_txs(genesis_txs)?;
             }
+            genesis_block.append_txs(vec![producer_tx])?;
 
             // Write generated genesis block to stdin
             let encoded = bs58::encode(&serialize(&genesis_block)).into_string();
@@ -121,7 +125,7 @@ async fn main() -> Result<()> {
 
             // Initialize a temporary sled database
             let sled_db = sled::Config::new().temporary(true).open()?;
-            let (_, vks) = vks::read_or_gen_vks_and_pks()?;
+            let (_, vks) = vks::get_cached_pks_and_vks()?;
             vks::inject(&sled_db, &vks)?;
 
             // Create an overlay over whole blockchain

+ 2 - 3
script/research/minerd/src/rpc.rs

@@ -34,7 +34,7 @@ use darkfi::{
     validator::pow::mine_block,
 };
 use darkfi_sdk::num_traits::Num;
-use darkfi_serial::{async_trait, deserialize, serialize};
+use darkfi_serial::{async_trait, deserialize};
 
 use crate::{
     error::{server_error, RpcError},
@@ -123,7 +123,6 @@ impl Minerd {
         }
 
         // Return block nonce
-        let nonce = base64::encode(&serialize(&block.header.nonce));
-        JsonResponse::new(JsonValue::String(nonce), id).into()
+        JsonResponse::new(JsonValue::Number(block.header.nonce as f64), id).into()
     }
 }

+ 4 - 16
src/blockchain/header_store.rs

@@ -19,7 +19,6 @@
 use darkfi_sdk::{
     blockchain::{block_epoch, block_version},
     crypto::MerkleTree,
-    pasta::{group::ff::Field, pallas},
 };
 
 #[cfg(feature = "async-serial")]
@@ -43,20 +42,14 @@ pub struct Header {
     pub height: u64,
     /// Block creation timestamp
     pub timestamp: Timestamp,
-    /// The block's nonce.
-    /// In PoW, this value changes arbitrarily with mining.
-    pub nonce: pallas::Base,
+    /// The block's nonce. This value changes arbitrarily with mining.
+    pub nonce: u64,
     /// Merkle tree of the transactions hashes contained in this block
     pub tree: MerkleTree,
 }
 
 impl Header {
-    pub fn new(
-        previous: blake3::Hash,
-        height: u64,
-        timestamp: Timestamp,
-        nonce: pallas::Base,
-    ) -> Self {
+    pub fn new(previous: blake3::Hash, height: u64, timestamp: Timestamp, nonce: u64) -> Self {
         let version = block_version(height);
         let epoch = block_epoch(height);
         let tree = MerkleTree::new(1);
@@ -82,12 +75,7 @@ impl Header {
 impl Default for Header {
     /// Represents the genesis header on current timestamp
     fn default() -> Self {
-        Header::new(
-            blake3::hash(b"Let there be dark!"),
-            0,
-            Timestamp::current_time(),
-            pallas::Base::ZERO,
-        )
+        Header::new(blake3::hash(b"Let there be dark!"), 0, Timestamp::current_time(), 0)
     }
 }
 

+ 2 - 2
src/contract/money/src/client/pow_reward_v1.rs

@@ -72,7 +72,7 @@ pub struct PoWRewardCallBuilder {
     /// Rewarded block height
     pub block_height: u64,
     /// Extending fork last proposal/block nonce
-    pub last_nonce: pallas::Base,
+    pub last_nonce: u64,
     /// Extending fork second to last proposal/block hash
     pub fork_previous_hash: blake3::Hash,
     /// Merkle tree of coins used to create inclusion proofs
@@ -155,7 +155,7 @@ impl PoWRewardCallBuilder {
 
         info!("Building Consensus::ProposalV1 VRF proof");
         let mut vrf_input = Vec::with_capacity(32 + blake3::OUT_LEN + 32);
-        vrf_input.extend_from_slice(&self.last_nonce.to_repr());
+        vrf_input.extend_from_slice(&pallas::Base::from(self.last_nonce).to_repr());
         vrf_input.extend_from_slice(self.fork_previous_hash.as_bytes());
         vrf_input.extend_from_slice(&pallas::Base::from(self.block_height).to_repr());
         let vrf_proof = VrfProof::prove(self.secret, &vrf_input, &mut OsRng);

+ 3 - 2
src/contract/money/src/entrypoint/pow_reward_v1.rs

@@ -107,8 +107,9 @@ pub(crate) fn money_pow_reward_process_instruction_v1(
 
     // Construct VRF input
     let mut vrf_input = Vec::with_capacity(32 + blake3::OUT_LEN + 32);
-    vrf_input.extend_from_slice(&last_block_info[8..40]);
-    vrf_input.extend_from_slice(&last_block_info[40..]);
+    let nonce: u64 = deserialize(&last_block_info[8..16])?;
+    vrf_input.extend_from_slice(&pallas::Base::from(nonce).to_repr());
+    vrf_input.extend_from_slice(&last_block_info[16..]);
     vrf_input.extend_from_slice(&pallas::Base::from(verifying_block_height).to_repr());
 
     // Verify VRF proof

+ 3 - 5
src/runtime/import/util.rs

@@ -19,8 +19,6 @@
 use log::error;
 use wasmer::{FunctionEnvMut, WasmPtr};
 
-use darkfi_sdk::crypto::pasta_prelude::PrimeField;
-
 use super::acl::acl_allow;
 use crate::runtime::vm_runtime::{ContractSection, Env};
 
@@ -307,12 +305,12 @@ pub(crate) fn get_last_block_info(mut ctx: FunctionEnvMut<Env>) -> i64 {
     };
 
     // Subtract used gas. Here we count the size of the object.
-    env.subtract_gas(&mut store, (8 + 32 + blake3::OUT_LEN) as u64);
+    env.subtract_gas(&mut store, (8 + 8 + blake3::OUT_LEN) as u64);
 
     // Create the return object
-    let mut ret = Vec::with_capacity(8 + 32 + blake3::OUT_LEN);
+    let mut ret = Vec::with_capacity(8 + 8 + blake3::OUT_LEN);
     ret.extend_from_slice(&darkfi_serial::serialize(&block.header.height));
-    ret.extend_from_slice(&block.header.nonce.to_repr());
+    ret.extend_from_slice(&darkfi_serial::serialize(&block.header.nonce));
     ret.extend_from_slice(block.header.previous.as_bytes());
 
     // Copy Vec<u8> to the VM

+ 3 - 10
src/validator/consensus.rs

@@ -16,10 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-use darkfi_sdk::{
-    crypto::{MerkleTree, SecretKey},
-    pasta::pallas,
-};
+use darkfi_sdk::crypto::{MerkleTree, SecretKey};
 use darkfi_serial::{async_trait, serialize, SerialDecodable, SerialEncodable};
 use log::{debug, error, info};
 use num_bigint::BigUint;
@@ -92,12 +89,8 @@ impl Consensus {
         let previous = fork.last_proposal()?;
 
         // Generate the new header
-        let header = Header::new(
-            previous.block.hash()?,
-            next_block_height,
-            Timestamp::current_time(),
-            pallas::Base::zero(),
-        );
+        let header =
+            Header::new(previous.block.hash()?, next_block_height, Timestamp::current_time(), 0);
 
         // Generate the block
         let mut block = BlockInfo::new_empty(header);

+ 6 - 9
src/validator/pow.rs

@@ -18,17 +18,14 @@
 
 use std::{
     sync::{
-        atomic::{AtomicBool, AtomicU32, Ordering},
+        atomic::{AtomicBool, AtomicU64, Ordering},
         Arc,
     },
     thread,
     time::Instant,
 };
 
-use darkfi_sdk::{
-    num_traits::{One, Zero},
-    pasta::pallas,
-};
+use darkfi_sdk::num_traits::{One, Zero};
 use log::debug;
 use num_bigint::BigUint;
 use randomx::{RandomXCache, RandomXDataset, RandomXFlags, RandomXVM};
@@ -322,8 +319,8 @@ pub fn mine_block(
     let mining_time = Instant::now();
     let mut handles = vec![];
     let found_block = Arc::new(AtomicBool::new(false));
-    let found_nonce = Arc::new(AtomicU32::new(0));
-    let threads = threads as u32;
+    let found_nonce = Arc::new(AtomicU64::new(0));
+    let threads = threads as u64;
     for t in 0..threads {
         let target = target.clone();
         let mut block = miner_block.clone();
@@ -343,7 +340,7 @@ pub fn mine_block(
                     break
                 }
 
-                block.header.nonce = pallas::Base::from(miner_nonce as u64);
+                block.header.nonce = miner_nonce;
                 if found_block.load(Ordering::SeqCst) {
                     debug!(target: "validator::pow::mine_block", "[MINER] Block found, thread #{} exiting", t);
                     break
@@ -380,7 +377,7 @@ pub fn mine_block(
     debug!(target: "validator::pow::mine_block", "[MINER] Mining time: {:?}", mining_time.elapsed());
 
     // Set the valid mined nonce in the block
-    miner_block.header.nonce = pallas::Base::from(found_nonce.load(Ordering::SeqCst) as u64);
+    miner_block.header.nonce = found_nonce.load(Ordering::SeqCst);
 
     Ok(())
 }

+ 3 - 5
src/validator/utils.rs

@@ -109,10 +109,8 @@ pub async fn block_rank(block: &BlockInfo, previous_previous: &BlockInfo) -> Res
         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);
+    // Grab block nonce
+    let nonce = block.header.nonce;
 
     // First 2 blocks have rank equal to their nonce
     if block.header.height < 3 {
@@ -136,7 +134,7 @@ pub async fn block_rank(block: &BlockInfo, previous_previous: &BlockInfo) -> Res
     let vrf = u64::from_be_bytes(vrf);
 
     // Finally, compute the rank
-    let rank = nonce % vrf;
+    let rank = if nonce != 0 { vrf % nonce } else { vrf };
 
     Ok(rank)
 }