Browse Source

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

skoupidi 2 years ago
parent
commit
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,
     pasta::pallas,
     ContractCall,
     ContractCall,
 };
 };
-use darkfi_serial::{deserialize, serialize, Encodable};
+use darkfi_serial::{serialize, Encodable};
 use log::info;
 use log::info;
 use num_bigint::BigUint;
 use num_bigint::BigUint;
 use rand::rngs::OsRng;
 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 block = JsonValue::String(base64::encode(&serialize(&next_block)));
         let response =
         let response =
             node.miner_daemon_request("mine", JsonValue::Array(vec![target, block])).await?;
             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
         // Sign the mined block
         next_block.sign(&secret)?;
         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
 ## 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
 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
 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                                   |
 | `epoch`     | `u64`          | Epoch number                                   |
 | `height`    | `u64`          | Block height                                   |
 | `height`    | `u64`          | Block height                                   |
 | `timestamp` | `Timestamp`    | Block creation timestamp                       |
 | `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 |
 | `tree`      | `MerkleTree`   | Merkle tree of the block's transactions hashes |
 
 
 ## Block
 ## Block

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

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

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

@@ -34,7 +34,7 @@ use darkfi::{
     validator::pow::mine_block,
     validator::pow::mine_block,
 };
 };
 use darkfi_sdk::num_traits::Num;
 use darkfi_sdk::num_traits::Num;
-use darkfi_serial::{async_trait, deserialize, serialize};
+use darkfi_serial::{async_trait, deserialize};
 
 
 use crate::{
 use crate::{
     error::{server_error, RpcError},
     error::{server_error, RpcError},
@@ -123,7 +123,6 @@ impl Minerd {
         }
         }
 
 
         // Return block nonce
         // 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::{
 use darkfi_sdk::{
     blockchain::{block_epoch, block_version},
     blockchain::{block_epoch, block_version},
     crypto::MerkleTree,
     crypto::MerkleTree,
-    pasta::{group::ff::Field, pallas},
 };
 };
 
 
 #[cfg(feature = "async-serial")]
 #[cfg(feature = "async-serial")]
@@ -43,20 +42,14 @@ pub struct Header {
     pub height: u64,
     pub height: u64,
     /// Block creation timestamp
     /// Block creation timestamp
     pub timestamp: 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
     /// Merkle tree of the transactions hashes contained in this block
     pub tree: MerkleTree,
     pub tree: MerkleTree,
 }
 }
 
 
 impl Header {
 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 version = block_version(height);
         let epoch = block_epoch(height);
         let epoch = block_epoch(height);
         let tree = MerkleTree::new(1);
         let tree = MerkleTree::new(1);
@@ -82,12 +75,7 @@ impl Header {
 impl Default for Header {
 impl Default for Header {
     /// Represents the genesis header on current timestamp
     /// Represents the genesis header on current timestamp
     fn default() -> Self {
     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
     /// Rewarded block height
     pub block_height: u64,
     pub block_height: u64,
     /// Extending fork last proposal/block nonce
     /// Extending fork last proposal/block nonce
-    pub last_nonce: pallas::Base,
+    pub last_nonce: u64,
     /// Extending fork second to last proposal/block hash
     /// Extending fork second to last proposal/block hash
     pub fork_previous_hash: blake3::Hash,
     pub fork_previous_hash: blake3::Hash,
     /// Merkle tree of coins used to create inclusion proofs
     /// Merkle tree of coins used to create inclusion proofs
@@ -155,7 +155,7 @@ impl PoWRewardCallBuilder {
 
 
         info!("Building Consensus::ProposalV1 VRF proof");
         info!("Building Consensus::ProposalV1 VRF proof");
         let mut vrf_input = Vec::with_capacity(32 + blake3::OUT_LEN + 32);
         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(self.fork_previous_hash.as_bytes());
         vrf_input.extend_from_slice(&pallas::Base::from(self.block_height).to_repr());
         vrf_input.extend_from_slice(&pallas::Base::from(self.block_height).to_repr());
         let vrf_proof = VrfProof::prove(self.secret, &vrf_input, &mut OsRng);
         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
     // Construct VRF input
     let mut vrf_input = Vec::with_capacity(32 + blake3::OUT_LEN + 32);
     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());
     vrf_input.extend_from_slice(&pallas::Base::from(verifying_block_height).to_repr());
 
 
     // Verify VRF proof
     // Verify VRF proof

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

@@ -19,8 +19,6 @@
 use log::error;
 use log::error;
 use wasmer::{FunctionEnvMut, WasmPtr};
 use wasmer::{FunctionEnvMut, WasmPtr};
 
 
-use darkfi_sdk::crypto::pasta_prelude::PrimeField;
-
 use super::acl::acl_allow;
 use super::acl::acl_allow;
 use crate::runtime::vm_runtime::{ContractSection, Env};
 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.
     // 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
     // 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(&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());
     ret.extend_from_slice(block.header.previous.as_bytes());
 
 
     // Copy Vec<u8> to the VM
     // 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/>.
  * 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 darkfi_serial::{async_trait, serialize, SerialDecodable, SerialEncodable};
 use log::{debug, error, info};
 use log::{debug, error, info};
 use num_bigint::BigUint;
 use num_bigint::BigUint;
@@ -92,12 +89,8 @@ impl Consensus {
         let previous = fork.last_proposal()?;
         let previous = fork.last_proposal()?;
 
 
         // Generate the new header
         // 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
         // Generate the block
         let mut block = BlockInfo::new_empty(header);
         let mut block = BlockInfo::new_empty(header);

+ 6 - 9
src/validator/pow.rs

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