Skip to content

Commit 00ae9ee

Browse files
ilblackdragonfrol
authored andcommitted
Saving genesis chunks to make consistent output from chunks RPC
1 parent 9e66b10 commit 00ae9ee

File tree

6 files changed

+130
-76
lines changed

6 files changed

+130
-76
lines changed

chain/chain/src/chain.rs

+29-10
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use chrono::prelude::{DateTime, Utc};
77
use chrono::Duration;
88
use log::{debug, info};
99

10+
use near_primitives::block::genesis_chunks;
1011
use near_primitives::hash::{hash, CryptoHash};
1112
use near_primitives::merkle::{merklize, verify_path};
1213
use near_primitives::receipt::Receipt;
@@ -185,11 +186,15 @@ impl Chain {
185186

186187
// Get runtime initial state and create genesis block out of it.
187188
let (state_store_update, state_roots) = runtime_adapter.genesis_state();
188-
let genesis = Block::genesis(
189+
let genesis_chunks = genesis_chunks(
189190
state_roots.clone(),
190-
chain_genesis.time,
191191
runtime_adapter.num_shards(),
192192
chain_genesis.gas_limit,
193+
);
194+
let genesis = Block::genesis(
195+
genesis_chunks.iter().map(|chunk| chunk.header.clone()).collect(),
196+
chain_genesis.time,
197+
chain_genesis.gas_limit,
193198
chain_genesis.gas_price,
194199
chain_genesis.total_supply,
195200
);
@@ -227,6 +232,9 @@ impl Chain {
227232
}
228233
Err(err) => match err.kind() {
229234
ErrorKind::DBNotFoundErr(_) => {
235+
for chunk in genesis_chunks {
236+
store_update.save_chunk(&chunk.chunk_hash, chunk.clone());
237+
}
230238
runtime_adapter.add_validator_proposals(
231239
CryptoHash::default(),
232240
genesis.hash(),
@@ -247,7 +255,15 @@ impl Chain {
247255
store_update.save_chunk_extra(
248256
&genesis.hash(),
249257
chunk_header.inner.shard_id,
250-
ChunkExtra::new(state_root, vec![], 0, chain_genesis.gas_limit, 0, 0, 0),
258+
ChunkExtra::new(
259+
state_root,
260+
vec![],
261+
0,
262+
chain_genesis.gas_limit,
263+
0,
264+
0,
265+
0,
266+
),
251267
);
252268
}
253269

@@ -1652,11 +1668,14 @@ impl<'a> ChainUpdate<'a> {
16521668
self.chain_store_update.get_chunk_clone_from_header(&chunk_header)?;
16531669

16541670
let any_transaction_is_invalid = chunk.transactions.iter().any(|t| {
1655-
self.chain_store_update.get_chain_store().check_blocks_on_same_chain(
1656-
&block.header,
1657-
&t.transaction.block_hash,
1658-
self.transaction_validity_period,
1659-
).is_err()
1671+
self.chain_store_update
1672+
.get_chain_store()
1673+
.check_blocks_on_same_chain(
1674+
&block.header,
1675+
&t.transaction.block_hash,
1676+
self.transaction_validity_period,
1677+
)
1678+
.is_err()
16601679
});
16611680
if any_transaction_is_invalid {
16621681
debug!(target: "chain", "Invalid transactions in the chunk: {:?}", chunk.transactions);
@@ -1693,7 +1712,7 @@ impl<'a> ChainUpdate<'a> {
16931712
gas_limit,
16941713
apply_result.total_rent_paid,
16951714
apply_result.total_validator_reward,
1696-
apply_result.total_balance_burnt
1715+
apply_result.total_balance_burnt,
16971716
),
16981717
);
16991718
// Save resulting receipts.
@@ -2200,7 +2219,7 @@ impl<'a> ChainUpdate<'a> {
22002219
gas_limit,
22012220
apply_result.total_rent_paid,
22022221
apply_result.total_validator_reward,
2203-
apply_result.total_balance_burnt
2222+
apply_result.total_balance_burnt,
22042223
);
22052224
self.chain_store_update.save_chunk_extra(&block_header.hash, shard_id, chunk_extra);
22062225

chain/chain/src/types.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -483,17 +483,22 @@ mod tests {
483483
use chrono::Utc;
484484

485485
use near_crypto::{InMemorySigner, KeyType, Signature};
486+
use near_primitives::block::genesis_chunks;
486487

487488
use super::*;
488489

489490
#[test]
490491
fn test_block_produce() {
491492
let num_shards = 32;
492-
let genesis = Block::genesis(
493+
let genesis_chunks = genesis_chunks(
493494
vec![StateRoot { hash: CryptoHash::default(), num_parts: 9 /* TODO MOO */ }],
494-
Utc::now(),
495495
num_shards,
496496
1_000_000,
497+
);
498+
let genesis = Block::genesis(
499+
genesis_chunks.into_iter().map(|chunk| chunk.header).collect(),
500+
Utc::now(),
501+
1_000_000,
497502
100,
498503
1_000_000_000,
499504
);

chain/jsonrpc/tests/rpc_query.rs

+37-29
Original file line numberDiff line numberDiff line change
@@ -73,37 +73,45 @@ fn test_chunk_by_hash() {
7373
init_test_logger();
7474

7575
System::run(|| {
76-
let (_view_client_addr, addr) = start_all(false);
76+
let (_view_client_addr, addr) = start_all(true);
7777

7878
let mut client = new_client(&format!("http://{}", addr.clone()));
79-
actix::spawn(client.chunk(ChunkId::BlockShardId(BlockId::Height(0), ShardId::from(0u64))).then(move |chunk| {
80-
let chunk = chunk.unwrap();
81-
assert_eq!(chunk.header.balance_burnt, 0);
82-
assert_eq!(chunk.header.chunk_hash.as_ref().len(), 32);
83-
assert_eq!(chunk.header.encoded_length, 8);
84-
assert_eq!(chunk.header.encoded_merkle_root.as_ref().len(), 32);
85-
assert_eq!(chunk.header.gas_limit, 10000000);
86-
assert_eq!(chunk.header.gas_used, 0);
87-
assert_eq!(chunk.header.height_created, 0);
88-
assert_eq!(chunk.header.height_included, 0);
89-
assert_eq!(chunk.header.outgoing_receipts_root.as_ref().len(), 32);
90-
assert_eq!(chunk.header.prev_block_hash.as_ref().len(), 32);
91-
assert_eq!(chunk.header.prev_state_num_parts, 9);
92-
assert_eq!(chunk.header.prev_state_root_hash.as_ref().len(), 32);
93-
assert_eq!(chunk.header.rent_paid, 0);
94-
assert_eq!(chunk.header.shard_id, 0);
95-
assert!(if let Signature::ED25519(_) = chunk.header.signature { true } else { false });
96-
assert_eq!(chunk.header.tx_root.as_ref(), &[0; 32]);
97-
assert_eq!(chunk.header.validator_proposals, vec![]);
98-
assert_eq!(chunk.header.validator_reward, 0);
99-
let mut client = new_client(&format!("http://{}", addr));
100-
client.chunk(ChunkId::Hash(chunk.header.chunk_hash)).then(move |same_chunk| {
101-
let same_chunk = same_chunk.unwrap();
102-
assert_eq!(chunk.header.chunk_hash, same_chunk.header.chunk_hash);
103-
System::current().stop();
104-
future::ok(())
105-
})
106-
}));
79+
actix::spawn(
80+
client.chunk(ChunkId::BlockShardId(BlockId::Height(0), ShardId::from(0u64))).then(
81+
move |chunk| {
82+
let chunk = chunk.unwrap();
83+
assert_eq!(chunk.header.balance_burnt, 0);
84+
assert_eq!(chunk.header.chunk_hash.as_ref().len(), 32);
85+
assert_eq!(chunk.header.encoded_length, 8);
86+
assert_eq!(chunk.header.encoded_merkle_root.as_ref().len(), 32);
87+
assert_eq!(chunk.header.gas_limit, 1000000);
88+
assert_eq!(chunk.header.gas_used, 0);
89+
assert_eq!(chunk.header.height_created, 0);
90+
assert_eq!(chunk.header.height_included, 0);
91+
assert_eq!(chunk.header.outgoing_receipts_root.as_ref().len(), 32);
92+
assert_eq!(chunk.header.prev_block_hash.as_ref().len(), 32);
93+
assert_eq!(chunk.header.prev_state_num_parts, 17);
94+
assert_eq!(chunk.header.prev_state_root_hash.as_ref().len(), 32);
95+
assert_eq!(chunk.header.rent_paid, 0);
96+
assert_eq!(chunk.header.shard_id, 0);
97+
assert!(if let Signature::ED25519(_) = chunk.header.signature {
98+
true
99+
} else {
100+
false
101+
});
102+
assert_eq!(chunk.header.tx_root.as_ref(), &[0; 32]);
103+
assert_eq!(chunk.header.validator_proposals, vec![]);
104+
assert_eq!(chunk.header.validator_reward, 0);
105+
let mut client = new_client(&format!("http://{}", addr));
106+
client.chunk(ChunkId::Hash(chunk.header.chunk_hash)).then(move |same_chunk| {
107+
let same_chunk = same_chunk.unwrap();
108+
assert_eq!(chunk.header.chunk_hash, same_chunk.header.chunk_hash);
109+
System::current().stop();
110+
future::ok(())
111+
})
112+
},
113+
),
114+
);
107115
})
108116
.unwrap();
109117
}

core/primitives/benches/serialization.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use chrono::Utc;
99

1010
use near_crypto::{InMemorySigner, KeyType, PublicKey, Signature};
1111
use near_primitives::account::Account;
12-
use near_primitives::block::Block;
12+
use near_primitives::block::{genesis_chunks, Block};
1313
use near_primitives::hash::CryptoHash;
1414
use near_primitives::transaction::{Action, SignedTransaction, Transaction, TransferAction};
1515
use near_primitives::types::{EpochId, StateRoot};
@@ -33,11 +33,15 @@ fn create_transaction() -> SignedTransaction {
3333
}
3434

3535
fn create_block() -> Block {
36-
let genesis = Block::genesis(
36+
let genesis_chunks = genesis_chunks(
3737
vec![StateRoot { hash: CryptoHash::default(), num_parts: 1 /* TODO MOO */ }],
38-
Utc::now(),
3938
1,
4039
1_000,
40+
);
41+
let genesis = Block::genesis(
42+
genesis_chunks.into_iter().map(|chunk| chunk.header).collect(),
43+
Utc::now(),
44+
1_000,
4145
1_000,
4246
1_000,
4347
);

core/primitives/src/block.rs

+35-25
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use near_crypto::{EmptySigner, KeyType, PublicKey, Signature, Signer};
77

88
use crate::hash::{hash, CryptoHash};
99
use crate::merkle::merklize;
10-
use crate::sharding::{ChunkHashHeight, ShardChunkHeader};
10+
use crate::sharding::{ChunkHashHeight, EncodedShardChunk, ShardChunk, ShardChunkHeader};
1111
use crate::types::{
1212
Balance, BlockIndex, EpochId, Gas, MerkleHash, ShardId, StateRoot, ValidatorStake,
1313
};
@@ -242,38 +242,48 @@ pub struct Block {
242242
pub chunks: Vec<ShardChunkHeader>,
243243
}
244244

245+
pub fn genesis_chunks(
246+
state_roots: Vec<StateRoot>,
247+
num_shards: ShardId,
248+
initial_gas_limit: Gas,
249+
) -> Vec<ShardChunk> {
250+
assert!(state_roots.len() == 1 || state_roots.len() == (num_shards as usize));
251+
(0..num_shards)
252+
.map(|i| {
253+
let (encoded_chunk, _) = EncodedShardChunk::new(
254+
CryptoHash::default(),
255+
state_roots[i as usize % state_roots.len()].clone(),
256+
0,
257+
i,
258+
3,
259+
1,
260+
0,
261+
initial_gas_limit,
262+
0,
263+
0,
264+
0,
265+
CryptoHash::default(),
266+
vec![],
267+
&vec![],
268+
&vec![],
269+
CryptoHash::default(),
270+
&EmptySigner {},
271+
)
272+
.expect("Failed to decode genesis chunk");
273+
encoded_chunk.decode_chunk(1).expect("Failed to decode genesis chunk")
274+
})
275+
.collect()
276+
}
277+
245278
impl Block {
246279
/// Returns genesis block for given genesis date and state root.
247280
pub fn genesis(
248-
state_roots: Vec<StateRoot>,
281+
chunks: Vec<ShardChunkHeader>,
249282
timestamp: DateTime<Utc>,
250-
num_shards: ShardId,
251283
initial_gas_limit: Gas,
252284
initial_gas_price: Balance,
253285
initial_total_supply: Balance,
254286
) -> Self {
255-
assert!(state_roots.len() == 1 || state_roots.len() == (num_shards as usize));
256-
let chunks = (0..num_shards)
257-
.map(|i| {
258-
ShardChunkHeader::new(
259-
CryptoHash::default(),
260-
state_roots[i as usize % state_roots.len()].clone(),
261-
CryptoHash::default(),
262-
0,
263-
0,
264-
i,
265-
0,
266-
initial_gas_limit,
267-
0,
268-
0,
269-
0,
270-
CryptoHash::default(),
271-
CryptoHash::default(),
272-
vec![],
273-
&EmptySigner {},
274-
)
275-
})
276-
.collect();
277287
Block {
278288
header: BlockHeader::genesis(
279289
Block::compute_state_root(&chunks),

genesis-tools/genesis-populate/src/lib.rs

+15-7
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
//! Tools for creating a genesis block.
22
3+
use std::collections::BTreeMap;
4+
use std::fs::File;
5+
use std::io::Write;
6+
use std::path::{Path, PathBuf};
7+
use std::sync::Arc;
8+
39
use borsh::BorshSerialize;
410
use indicatif::{ProgressBar, ProgressStyle};
11+
use tempdir::TempDir;
12+
513
use near::{get_store_path, GenesisConfig, NightshadeRuntime};
614
use near_chain::{Block, ChainStore, RuntimeAdapter, Tip};
715
use near_crypto::{InMemorySigner, KeyType};
816
use near_primitives::account::AccessKey;
17+
use near_primitives::block::genesis_chunks;
918
use near_primitives::contract::ContractCode;
1019
use near_primitives::hash::{hash, CryptoHash};
1120
use near_primitives::serialize::to_base64;
@@ -15,12 +24,6 @@ use near_store::{
1524
create_store, get_account, set_access_key, set_account, set_code, Store, TrieUpdate, COL_STATE,
1625
};
1726
use node_runtime::StateRecord;
18-
use std::collections::BTreeMap;
19-
use std::fs::File;
20-
use std::io::Write;
21-
use std::path::{Path, PathBuf};
22-
use std::sync::Arc;
23-
use tempdir::TempDir;
2427

2528
fn get_account_id(account_index: u64) -> String {
2629
format!("near_{}_{}", account_index, account_index)
@@ -179,8 +182,13 @@ impl GenesisBuilder {
179182
}
180183

181184
fn write_genesis_block(&mut self) -> Result<()> {
182-
let genesis = Block::genesis(
185+
let genesis_chunks = genesis_chunks(
183186
self.roots.values().cloned().collect(),
187+
self.runtime.num_shards(),
188+
self.config.gas_limit,
189+
);
190+
let genesis = Block::genesis(
191+
genesis_chunks.into_iter().map(|chunk| chunk.header).collect(),
184192
self.config.genesis_time,
185193
self.runtime.num_shards(),
186194
self.config.gas_limit,

0 commit comments

Comments
 (0)