1
1
use std:: collections:: hash_set:: * ;
2
2
use util:: hash:: * ;
3
+ use util:: bytes:: * ;
4
+ use util:: uint:: * ;
3
5
use util:: error:: * ;
6
+ use util:: overlaydb:: * ;
4
7
use transaction:: * ;
8
+ use receipt:: * ;
9
+ use blockchain:: * ;
5
10
use engine:: * ;
6
11
use header:: * ;
7
12
use env_info:: * ;
@@ -25,7 +30,7 @@ pub struct Block {
25
30
}
26
31
27
32
impl Block {
28
- fn new ( header : Header , state : State ) -> Block {
33
+ fn new ( state : State ) -> Block {
29
34
Block {
30
35
header : Header :: new ( ) ,
31
36
state : state,
@@ -55,97 +60,101 @@ pub trait IsBlock {
55
60
impl IsBlock for Block {
56
61
fn block ( & self ) -> & Block { self }
57
62
}
58
- /*
63
+
59
64
/// Block that is ready for transactions to be added.
60
65
///
61
66
/// It's a bit like a Vec<Transaction>, eccept that whenever a transaction is pushed, we execute it and
62
67
/// maintain the system `state()`. We also archive execution receipts in preparation for later block creation.
63
- pub struct OpenBlock {
68
+ pub struct OpenBlock < ' engine > {
64
69
block : Block ,
65
- engine: &Engine,
70
+ engine : & ' engine Engine ,
66
71
last_hashes : LastHashes ,
67
72
}
68
73
69
74
/// Just like OpenBlock, except that we've applied `Engine::on_close_block`, finished up the non-seal header fields,
70
75
/// and collected the uncles.
71
76
///
72
77
/// 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 > ,
76
81
}
77
82
78
83
/// A block that has a valid seal.
79
84
///
80
85
/// The block's header has valid seal arguments. The block cannot be reversed into a ClosedBlock or OpenBlock.
81
86
pub struct SealedBlock {
82
87
block : Block ,
83
- bytes : Bytes,
88
+ _bytes : Bytes ,
84
89
}
85
90
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 > {
88
94
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 ( ) ) ) ,
90
96
engine : engine,
91
97
last_hashes : last_hashes,
92
- }
98
+ } ;
93
99
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 ) ;
96
102
r
97
103
}
98
104
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 ( ) ,
106
113
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 ) {
110
123
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 )
114
127
}
115
128
Err ( x) => Err ( x)
116
129
}
117
130
}
118
131
119
132
/// 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 ! ( ) ; }
121
134
}
122
135
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 }
126
138
}
127
139
128
- impl ClosedBlock {
140
+ impl < ' engine > ClosedBlock < ' engine > {
129
141
/// Get the hash of the header without seal arguments.
130
142
pub fn preseal_hash ( & self ) -> H256 { unimplemented ! ( ) ; }
131
143
132
144
/// 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 ! ( ) ; }
134
146
135
147
/// Turn this back into an `OpenBlock`.
136
- pub fn reopen(self) -> OpenBlock { unimplemented!(); }
148
+ pub fn reopen ( self ) -> OpenBlock < ' engine > { unimplemented ! ( ) ; }
137
149
}
138
150
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 }
142
153
}
143
154
144
155
impl SealedBlock {
145
156
}
146
157
147
158
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 }
150
160
}
151
- */
0 commit comments