Skip to content
This repository was archived by the owner on Nov 6, 2020. It is now read-only.

Commit 76ba2df

Browse files
committed
Compiling, fleshed-out Block.
1 parent 7bad30a commit 76ba2df

File tree

6 files changed

+72
-58
lines changed

6 files changed

+72
-58
lines changed

src/block.rs

+49-40
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
use std::collections::hash_set::*;
22
use util::hash::*;
3+
use util::bytes::*;
4+
use util::uint::*;
35
use util::error::*;
6+
use util::overlaydb::*;
47
use transaction::*;
8+
use receipt::*;
9+
use blockchain::*;
510
use engine::*;
611
use header::*;
712
use env_info::*;
@@ -25,7 +30,7 @@ pub struct Block {
2530
}
2631

2732
impl Block {
28-
fn new(header: Header, state: State) -> Block {
33+
fn new(state: State) -> Block {
2934
Block {
3035
header: Header::new(),
3136
state: state,
@@ -55,97 +60,101 @@ pub trait IsBlock {
5560
impl IsBlock for Block {
5661
fn block(&self) -> &Block { self }
5762
}
58-
/*
63+
5964
/// Block that is ready for transactions to be added.
6065
///
6166
/// It's a bit like a Vec<Transaction>, eccept that whenever a transaction is pushed, we execute it and
6267
/// maintain the system `state()`. We also archive execution receipts in preparation for later block creation.
63-
pub struct OpenBlock {
68+
pub struct OpenBlock<'engine> {
6469
block: Block,
65-
engine: &Engine,
70+
engine: &'engine Engine,
6671
last_hashes: LastHashes,
6772
}
6873

6974
/// Just like OpenBlock, except that we've applied `Engine::on_close_block`, finished up the non-seal header fields,
7075
/// and collected the uncles.
7176
///
7277
/// There is no function available to push a transaction. If you want that you'll need to `reopen()` it.
73-
pub struct ClosedBlock {
74-
open_block: OpenBlock,
75-
uncles: Vec<Header>,
78+
pub struct ClosedBlock<'engine> {
79+
open_block: OpenBlock<'engine>,
80+
_uncles: Vec<Header>,
7681
}
7782

7883
/// A block that has a valid seal.
7984
///
8085
/// The block's header has valid seal arguments. The block cannot be reversed into a ClosedBlock or OpenBlock.
8186
pub struct SealedBlock {
8287
block: Block,
83-
bytes: Bytes,
88+
_bytes: Bytes,
8489
}
8590

86-
impl OpenBlock {
87-
pub fn new(engine: &Engine, mut db: OverlayDB, parent: &Header, last_hashes: LastHashes) -> OpenBlock {
91+
impl<'engine> OpenBlock<'engine> {
92+
/// Create a new OpenBlock ready for transaction pushing.
93+
pub fn new<'a>(engine: &'a Engine, db: OverlayDB, parent: &Header, last_hashes: LastHashes) -> OpenBlock<'a> {
8894
let mut r = OpenBlock {
89-
block: Block::new(State::new_existing(db, parent.state_root.clone(), engine.account_start_nonce())),
95+
block: Block::new(State::from_existing(db, parent.state_root.clone(), engine.account_start_nonce())),
9096
engine: engine,
9197
last_hashes: last_hashes,
92-
}
98+
};
9399

94-
engine.populate_from_parent(r.block.header, parent);
95-
engine.on_init_block(&mut r);
100+
engine.populate_from_parent(&mut r.block.header, parent);
101+
engine.on_new_block(&mut r.block);
96102
r
97103
}
98104

99-
/// Turn this into a `ClosedBlock`. A BlockChain must be provided in order to figure ou the uncles.
100-
pub fn push_transaction(&mut self, t: Transaction, mut h: Option<H256>) -> Result<&Receipt, EthcoreError> {
101-
let env_info = EnvInfo{
102-
number: self.header.number,
103-
author: self.header.author,
104-
timestamp: self.header.timestamp,
105-
difficulty: self.header.difficulty,
105+
/// Get the environment info concerning this block.
106+
pub fn env_info(&self) -> EnvInfo {
107+
// TODO: memoise.
108+
EnvInfo {
109+
number: self.block.header.number.clone(),
110+
author: self.block.header.author.clone(),
111+
timestamp: self.block.header.timestamp.clone(),
112+
difficulty: self.block.header.difficulty.clone(),
106113
last_hashes: self.last_hashes.clone(),
107-
gas_used: if let Some(ref t) = self.archive.last() {t.receipt.gas_used} else {U256::from(0)},
108-
};
109-
match self.state.apply(env_info, self.engine, t, true) {
114+
gas_used: if let Some(ref t) = self.block.archive.last() {t.receipt.gas_used} else {U256::from(0)},
115+
gas_limit: self.block.header.gas_limit.clone(),
116+
}
117+
}
118+
119+
/// Push a transaction into the block. It will be executed, and archived together with the receipt.
120+
pub fn push_transaction(&mut self, t: Transaction, h: Option<H256>) -> Result<&Receipt, EthcoreError> {
121+
let env_info = self.env_info();
122+
match self.block.state.apply(&env_info, self.engine, &t, true) {
110123
Ok(x) => {
111-
self.transactionHashes.insert(h.unwrap_or_else(||t.sha3()));
112-
self.transactions.push(BlockTransaction{t, x.receipt});
113-
Ok(&self.transactions.last().unwrap().receipt)
124+
self.block.archive_set.insert(h.unwrap_or_else(||t.sha3()));
125+
self.block.archive.push(Entry { transaction: t, receipt: x.receipt });
126+
Ok(&self.block.archive.last().unwrap().receipt)
114127
}
115128
Err(x) => Err(x)
116129
}
117130
}
118131

119132
/// Turn this into a `ClosedBlock`. A BlockChain must be provided in order to figure ou the uncles.
120-
pub fn close(self, bc: &BlockChain) -> ClosedBlock { unimplemented!(); }
133+
pub fn close(self, _bc: &BlockChain) -> ClosedBlock { unimplemented!(); }
121134
}
122135

123-
impl IsBlock for OpenBlock {
124-
fn block(&self) -> &Block { self.block }
125-
fn block_mut(&self) -> &mut Block { self.block }
136+
impl<'engine> IsBlock for OpenBlock<'engine> {
137+
fn block(&self) -> &Block { &self.block }
126138
}
127139

128-
impl ClosedBlock {
140+
impl<'engine> ClosedBlock<'engine> {
129141
/// Get the hash of the header without seal arguments.
130142
pub fn preseal_hash(&self) -> H256 { unimplemented!(); }
131143

132144
/// Turn this into a `ClosedBlock`. A BlockChain must be provided in order to figure ou the uncles.
133-
pub fn seal(self, seal_fields: Vec<Bytes>) -> SealedBlock { unimplemented!(); }
145+
pub fn seal(self, _seal_fields: Vec<Bytes>) -> SealedBlock { unimplemented!(); }
134146

135147
/// Turn this back into an `OpenBlock`.
136-
pub fn reopen(self) -> OpenBlock { unimplemented!(); }
148+
pub fn reopen(self) -> OpenBlock<'engine> { unimplemented!(); }
137149
}
138150

139-
impl IsBlock for ClosedBlock {
140-
fn block(&self) -> &Block { self.open_block.block }
141-
fn block_mut(&self) -> &mut Block { self.open_block.block }
151+
impl<'engine> IsBlock for ClosedBlock<'engine> {
152+
fn block(&self) -> &Block { &self.open_block.block }
142153
}
143154

144155
impl SealedBlock {
145156
}
146157

147158
impl IsBlock for SealedBlock {
148-
fn block(&self) -> &Block { self.block }
149-
fn block_mut(&self) -> &mut Block { self.block.block }
159+
fn block(&self) -> &Block { &self.block }
150160
}
151-
*/

src/engine.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ pub trait Engine {
3636

3737
/// Some intrinsic operation parameters; by default they take their value from the `spec()`'s `engine_params`.
3838
fn maximum_extra_data_size(&self, _env_info: &EnvInfo) -> usize { decode(&self.spec().engine_params.get("maximum_extra_data_size").unwrap()) }
39-
fn account_start_nonce(&self, _env_info: &EnvInfo) -> U256 { decode(&self.spec().engine_params.get("account_start_nonce").unwrap()) }
39+
fn account_start_nonce(&self) -> U256 { decode(&self.spec().engine_params.get("account_start_nonce").unwrap()) }
4040

4141
/// Block transformation functions, before and after the transactions.
42-
fn on_new_block(&self, _block: &mut Block) -> Result<(), EthcoreError> { Ok(()) }
43-
fn on_close_block(&self, _block: &mut Block) -> Result<(), EthcoreError> { Ok(()) }
42+
fn on_new_block(&self, _block: &mut Block) {}
43+
fn on_close_block(&self, _block: &mut Block) {}
4444

4545
/// Verify that `header` is valid.
4646
/// `parent` (the parent header) and `block` (the header's full block) may be provided for additional
@@ -55,7 +55,7 @@ pub trait Engine {
5555

5656
/// Don't forget to call Super::populateFromParent when subclassing & overriding.
5757
// TODO: consider including State in the params.
58-
fn populate_from_parent(&self, _header: &mut Header, _parent: &Header) -> Result<(), EthcoreError> { Ok(()) }
58+
fn populate_from_parent(&self, _header: &mut Header, _parent: &Header) {}
5959

6060
// TODO: builtin contract routing - to do this properly, it will require removing the built-in configuration-reading logic
6161
// from Spec into here and removing the Spec::builtins field.

src/ethash.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use util::error::*;
1+
//use util::error::*;
22
use util::rlp::decode;
33
use engine::Engine;
44
use spec::Spec;
@@ -24,9 +24,10 @@ impl Engine for Ethash {
2424
fn evm_schedule(&self, _env_info: &EnvInfo) -> EvmSchedule { EvmSchedule::new_frontier() }
2525

2626
/// Apply the block reward on finalisation of the block.
27-
fn on_close_block(&self, block: &mut Block) -> Result<(), EthcoreError> {
27+
fn on_close_block(&self, block: &mut Block) {
2828
let a = block.header().author.clone();
2929
block.state_mut().add_balance(&a, &decode(&self.spec().engine_params.get("block_reward").unwrap()));
30-
Ok(())
3130
}
3231
}
32+
33+
// TODO: test for on_close_block.

src/receipt.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use util::hash::*;
2+
use util::uint::*;
23

34
/// Information describing execution of a transaction.
45
pub struct Receipt {
56
// TODO
67
pub state_root: H256,
8+
pub gas_used: U256,
79
}

src/state.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use engine::Engine;
1717

1818
/// Information concerning the result of the `State::apply` operation.
1919
pub struct ApplyInfo {
20-
r: Receipt,
20+
pub receipt: Receipt,
2121
}
2222

2323
pub type ApplyResult = Result<ApplyInfo, EthcoreError>;
@@ -49,7 +49,7 @@ impl State {
4949
}
5050

5151
/// Creates new state with existing state root
52-
pub fn new_existing(mut db: OverlayDB, mut root: H256, account_start_nonce: U256) -> State {
52+
pub fn from_existing(mut db: OverlayDB, mut root: H256, account_start_nonce: U256) -> State {
5353
{
5454
// trie should panic! if root does not exist
5555
let _ = TrieDB::new(&mut db, &mut root);
@@ -136,7 +136,7 @@ impl State {
136136

137137
/// Execute a given transaction.
138138
/// This will change the state accordingly.
139-
pub fn apply(_env_info: &EnvInfo, _engine: &Engine, _t: &Transaction, _is_permanent: bool) -> ApplyResult {
139+
pub fn apply(&mut self, _env_info: &EnvInfo, _engine: &Engine, _t: &Transaction, _is_permanent: bool) -> ApplyResult {
140140
unimplemented!();
141141
}
142142

@@ -161,7 +161,7 @@ impl State {
161161
}
162162

163163
{
164-
let mut trie = TrieDBMut::new_existing(db, &mut root);
164+
let mut trie = TrieDBMut::from_existing(db, &mut root);
165165
for (address, ref a) in accounts.iter() {
166166
match a {
167167
&&Some(ref account) => trie.insert(address, &account.rlp()),
@@ -245,7 +245,7 @@ fn code_from_database() {
245245
s.drop()
246246
};
247247

248-
let s = State::new_existing(db, r, U256::from(0u8));
248+
let s = State::from_existing(db, r, U256::from(0u8));
249249
assert_eq!(s.code(&a), Some([1u8, 2, 3].to_vec()));
250250
}
251251

@@ -259,7 +259,7 @@ fn storage_at_from_database() {
259259
s.drop()
260260
};
261261

262-
let s = State::new_existing(db, r, U256::from(0u8));
262+
let s = State::from_existing(db, r, U256::from(0u8));
263263
assert_eq!(s.storage_at(&a, &H256::from(&U256::from(01u64))), H256::from(&U256::from(69u64)));
264264
}
265265

@@ -275,7 +275,7 @@ fn get_from_database() {
275275
s.drop()
276276
};
277277

278-
let s = State::new_existing(db, r, U256::from(0u8));
278+
let s = State::from_existing(db, r, U256::from(0u8));
279279
assert_eq!(s.balance(&a), U256::from(69u64));
280280
assert_eq!(s.nonce(&a), U256::from(1u64));
281281
}

src/transaction.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,6 @@ use util::bytes::*;
33
use util::uint::*;
44
use util::rlp::*;
55

6-
pub struct Receipt {
7-
gas_used: U256,
8-
}
9-
106
/// A set of information describing an externally-originating message call
117
/// or contract creation operation.
128
pub struct Transaction {
@@ -23,10 +19,16 @@ impl Transaction {
2319
pub fn is_contract_creation(&self) -> bool {
2420
self.to.is_none()
2521
}
22+
2623
/// Is this transaction meant to send a message?
2724
pub fn is_message_call(&self) -> bool {
2825
!self.is_contract_creation()
2926
}
27+
28+
/// Get the hash of this transaction.
29+
pub fn sha3(&self) -> H256 {
30+
unimplemented!();
31+
}
3032
}
3133

3234
impl Encodable for Transaction {

0 commit comments

Comments
 (0)