@@ -10,7 +10,7 @@ const DB = require('../db');
1010const {
1111 PredefinedDbPaths,
1212 GenesisAccounts,
13- GenesisWhitelist ,
13+ GENESIS_VALIDATORS ,
1414 GenesisValues,
1515 GenesisFunctions,
1616 GenesisRules,
@@ -25,21 +25,20 @@ class Block {
2525 constructor ( lastHash , lastVotes , transactions , number , epoch , timestamp ,
2626 stateProofHash , proposer , validators ) {
2727 this . last_votes = lastVotes ;
28- this . transactions = transactions ;
28+ this . transactions = Block . sanitizeTransactions ( transactions ) ;
2929 // Block's header
3030 this . last_hash = lastHash ;
3131 this . last_votes_hash = ChainUtil . hashString ( stringify ( lastVotes ) ) ;
32- this . transactions_hash = ChainUtil . hashString ( stringify ( transactions ) ) ;
32+ this . transactions_hash = ChainUtil . hashString ( stringify ( this . transactions ) ) ;
3333 this . number = number ;
3434 this . epoch = epoch ;
3535 this . timestamp = timestamp ;
36- // TODO(lia): change this to snake case
37- this . stateProofHash = stateProofHash ;
36+ this . state_proof_hash = stateProofHash ;
3837 this . proposer = proposer ;
3938 this . validators = validators ;
40- this . size = sizeof ( this . transactions ) ;
4139 // Hash of block's header
4240 this . hash = Block . hash ( this ) ;
41+ this . size = Block . getSize ( this ) ;
4342 }
4443
4544 get header ( ) {
@@ -50,10 +49,16 @@ class Block {
5049 number : this . number ,
5150 epoch : this . epoch ,
5251 timestamp : this . timestamp ,
53- stateProofHash : this . stateProofHash ,
52+ state_proof_hash : this . state_proof_hash ,
5453 proposer : this . proposer ,
5554 validators : this . validators ,
56- size : this . size
55+ } ;
56+ }
57+
58+ get body ( ) {
59+ return {
60+ last_votes : this . last_votes ,
61+ transactions : this . transactions ,
5762 } ;
5863 }
5964
@@ -66,7 +71,7 @@ class Block {
6671 number: ${ this . number }
6772 epoch: ${ this . epoch }
6873 timestamp: ${ this . timestamp }
69- stateProofHash : ${ this . stateProofHash }
74+ state_proof_hash : ${ this . state_proof_hash }
7075 proposer: ${ this . proposer }
7176 validators: ${ this . validators }
7277 size: ${ this . size }
@@ -76,11 +81,29 @@ class Block {
7681 transactions: ${ stringify ( this . transactions ) } ` ;
7782 }
7883
84+ static sanitizeTransactions ( transactions ) {
85+ const sanitized = [ ] ;
86+ transactions . forEach ( ( tx ) => {
87+ sanitized . push ( {
88+ tx_body : Transaction . sanitizeTxBody ( tx . tx_body ) ,
89+ signature : tx . signature ,
90+ hash : tx . hash ,
91+ address : tx . address
92+ } ) ;
93+ } ) ;
94+ return sanitized ;
95+ }
96+
7997 static hash ( block ) {
8098 if ( ! ( block instanceof Block ) ) block = Block . parse ( block ) ;
8199 return ChainUtil . hashString ( stringify ( block . header ) ) ;
82100 }
83101
102+ static getSize ( block ) {
103+ if ( ! ( block instanceof Block ) ) block = Block . parse ( block ) ;
104+ return sizeof ( { ...block . header , ...block . body } ) ;
105+ }
106+
84107 static create ( lastHash , lastVotes , transactions , number , epoch ,
85108 stateProofHash , proposer , validators ) {
86109 return new Block ( lastHash , lastVotes , transactions , number , epoch , Date . now ( ) ,
@@ -102,35 +125,42 @@ class Block {
102125 if ( blockInfo instanceof Block ) return blockInfo ;
103126 return new Block ( blockInfo . last_hash , blockInfo . last_votes ,
104127 blockInfo . transactions , blockInfo . number , blockInfo . epoch , blockInfo . timestamp ,
105- blockInfo . stateProofHash , blockInfo . proposer , blockInfo . validators ) ;
128+ blockInfo . state_proof_hash , blockInfo . proposer , blockInfo . validators ) ;
106129 }
107130
108131 static hasRequiredFields ( block ) {
109132 return ( block && block . last_hash !== undefined && block . last_votes !== undefined &&
110133 block . transactions !== undefined && block . number !== undefined &&
111134 block . epoch !== undefined && block . timestamp !== undefined &&
112- block . stateProofHash !== undefined && block . proposer !== undefined &&
135+ block . state_proof_hash !== undefined && block . proposer !== undefined &&
113136 block . validators !== undefined ) ;
114137 }
115138
116139 static validateHashes ( block ) {
140+ const LOG_HEADER = 'validateHashes' ;
141+
117142 if ( block . hash !== Block . hash ( block ) ) {
118- logger . error ( `Block hash is incorrect for block ${ block . hash } ` ) ;
143+ logger . error ( `[ ${ LOG_HEADER } ] Block hash is incorrect for block ${ block . hash } ` ) ;
119144 return false ;
120145 }
121146 if ( block . transactions_hash !== ChainUtil . hashString ( stringify ( block . transactions ) ) ) {
122- logger . error ( `Transactions or transactions_hash is incorrect for block ${ block . hash } ` ) ;
147+ logger . error (
148+ `[${ LOG_HEADER } ] Transactions or transactions_hash is incorrect for block ${ block . hash } ` ) ;
123149 return false ;
124150 }
125151 if ( block . last_votes_hash !== ChainUtil . hashString ( stringify ( block . last_votes ) ) ) {
126- logger . error ( `Last votes or last_votes_hash is incorrect for block ${ block . hash } ` ) ;
152+ logger . error (
153+ `[${ LOG_HEADER } ] Last votes or last_votes_hash is incorrect for block ${ block . hash } ` ) ;
127154 return false ;
128155 }
129- logger . info ( `Hash check successfully done` ) ;
156+ logger . info (
157+ `[${ LOG_HEADER } ] Hash check successfully done for block: ${ block . number } / ${ block . epoch } ` ) ;
130158 return true ;
131159 }
132160
133161 static validateProposedBlock ( block ) {
162+ const LOG_HEADER = 'validateProposedBlock' ;
163+
134164 if ( ! Block . validateHashes ( block ) ) return false ;
135165 const nonceTracker = { } ;
136166 let tx ;
@@ -144,15 +174,15 @@ class Block {
144174 continue ;
145175 }
146176 if ( tx . tx_body . nonce != nonceTracker [ tx . address ] + 1 ) {
147- logger . error ( `Invalid noncing for ${ tx . address } ` +
177+ logger . error ( `[ ${ LOG_HEADER } ] Invalid noncing for ${ tx . address } ` +
148178 `Expected ${ nonceTracker [ tx . address ] + 1 } ` +
149179 `Received ${ tx . tx_body . nonce } ` ) ;
150180 return false ;
151181 }
152182 nonceTracker [ tx . address ] = tx . tx_body . nonce ;
153183 }
154184
155- logger . info ( `Valid block of number ${ block . number } ` ) ;
185+ logger . info ( `[ ${ LOG_HEADER } ] Validated block: ${ block . number } / ${ block . epoch } ` ) ;
156186 return true ;
157187 }
158188
@@ -229,6 +259,34 @@ class Block {
229259 return Transaction . signTxBody ( secondTxBody , privateKey ) ;
230260 }
231261
262+ static buildGenesisStakingTxs ( timestamp ) {
263+ const _ = require ( 'lodash' ) ;
264+ const txs = [ ] ;
265+ Object . entries ( GENESIS_VALIDATORS ) . forEach ( ( [ address , amount ] , index ) => {
266+ const privateKey = _ . get ( GenesisAccounts ,
267+ `${ AccountProperties . OTHERS } .${ index } .${ AccountProperties . PRIVATE_KEY } ` ) ;
268+ if ( ! privateKey ) {
269+ throw Error ( `GenesisAccounts missing values: ${ JSON . stringify ( GenesisAccounts ) } , ${ address } ` ) ;
270+ }
271+ const txBody = {
272+ nonce : - 1 ,
273+ timestamp,
274+ operation : {
275+ type : 'SET_VALUE' ,
276+ ref : ChainUtil . formatPath ( [
277+ PredefinedDbPaths . DEPOSIT_CONSENSUS ,
278+ address ,
279+ 1 ,
280+ PredefinedDbPaths . DEPOSIT_VALUE
281+ ] ) ,
282+ value : amount
283+ }
284+ } ;
285+ txs . push ( Transaction . signTxBody ( txBody , privateKey ) ) ;
286+ } ) ;
287+ return txs ;
288+ }
289+
232290 static getGenesisBlockData ( genesisTime ) {
233291 const ownerAddress = ChainUtil . getJsObject (
234292 GenesisAccounts , [ AccountProperties . OWNER , AccountProperties . ADDRESS ] ) ;
@@ -237,8 +295,10 @@ class Block {
237295
238296 const firstTx = this . buildDbSetupTx ( genesisTime , ownerPrivateKey ) ;
239297 const secondTx = this . buildAccountsSetupTx ( ownerAddress , genesisTime , ownerPrivateKey ) ;
298+ // TODO(lia): Change the logic to staking & signing by the current node
299+ const stakingTxs = this . buildGenesisStakingTxs ( genesisTime ) ;
240300
241- return [ firstTx , secondTx ] ;
301+ return [ firstTx , secondTx , ... stakingTxs ] ;
242302 }
243303
244304 static getGenesisStateProofHash ( ) {
@@ -270,7 +330,7 @@ class Block {
270330 const number = 0 ;
271331 const epoch = 0 ;
272332 const proposer = ownerAddress ;
273- const validators = GenesisWhitelist ;
333+ const validators = GENESIS_VALIDATORS ;
274334 const stateProofHash = Block . getGenesisStateProofHash ( ) ;
275335 return new Block ( lastHash , lastVotes , transactions , number , epoch , genesisTime ,
276336 stateProofHash , proposer , validators ) ;
0 commit comments