1
1
import { BlockHeader } from '@ethereumjs/block'
2
- const Trie = require ( 'merkle-patricia-tree/secure' )
3
- import * as util from 'ethereumjs-util'
4
- import * as url from 'url'
5
-
6
- function toBuffer ( string : string ) {
7
- return Buffer . from ( util . stripHexPrefix ( string ) , 'hex' )
8
- }
2
+ import { SecureTrie as Trie } from 'merkle-patricia-tree'
3
+ import { Account , BN , keccak , rlp , toBuffer , unpadBuffer , isHexPrefixed } from 'ethereumjs-util'
4
+ import { parse } from 'url'
9
5
10
6
export function parseBootnodes ( string : string ) {
11
7
if ( ! string ) {
@@ -17,7 +13,7 @@ export function parseBootnodes(string: string) {
17
13
if ( match ) {
18
14
return { ip : match [ 1 ] , port : match [ 2 ] }
19
15
}
20
- const { auth : id , hostname : ip , port } = url . parse ( s )
16
+ const { auth : id , hostname : ip , port } = parse ( s )
21
17
return { id, ip, port }
22
18
} )
23
19
} catch ( e ) {
@@ -44,87 +40,83 @@ export function parseTransports(transports: any[]) {
44
40
45
41
async function parseStorage ( storage : any ) {
46
42
const trie = new Trie ( )
47
- const promises = [ ]
48
- // eslint-disable-next-line prefer-const
49
- for ( let [ address , value ] of Object . entries ( storage ) ) {
50
- value = util . rlp . encode ( util . unpadBuffer ( toBuffer ( value as string ) ) )
51
- promises . push (
52
- new Promise ( ( resolve , reject ) => {
53
- trie . put ( toBuffer ( address ) , value , ( err : Error ) => {
54
- if ( err ) return reject ( err )
55
- resolve ( )
56
- } )
57
- } )
58
- )
43
+ for ( const [ address , value ] of Object . entries ( storage ) ) {
44
+ const key = Buffer . from ( address , 'hex' )
45
+ const val = rlp . encode ( unpadBuffer ( Buffer . from ( value as string , 'hex' ) ) )
46
+ await trie . put ( key , val )
59
47
}
60
- await Promise . all ( promises )
61
48
return trie
62
49
}
63
50
64
51
async function parseGethState ( alloc : any ) {
65
52
const trie = new Trie ( )
66
- const promises = [ ]
67
53
for ( const [ key , value ] of Object . entries ( alloc ) ) {
68
- const address = toBuffer ( key )
69
- const account = new util . Account ( )
70
- if ( ( value as any ) . balance ) {
71
- // TODO: convert to buffer w/ util.toBuffer()?
72
- // @ts -ignore: account. balance is type Buffer, not BN
73
- account . balance = new util . BN ( ( value as any ) . balance . slice ( 2 ) , 16 )
54
+ const address = isHexPrefixed ( key ) ? toBuffer ( key ) : Buffer . from ( key , 'hex' )
55
+ const { balance , code , storage } = value as any
56
+ const account = new Account ( )
57
+ if ( balance ) {
58
+ // note: balance is a Buffer
59
+ account . balance = new BN ( toBuffer ( balance ) )
74
60
}
75
- if ( ( value as any ) . code ) {
76
- account . codeHash = util . keccak ( util . toBuffer ( ( value as any ) . code ) )
61
+ if ( code ) {
62
+ account . codeHash = keccak ( toBuffer ( code ) )
77
63
}
78
- if ( ( value as any ) . storage ) {
79
- account . stateRoot = ( await parseStorage ( ( value as any ) . storage ) ) . root
64
+ if ( storage ) {
65
+ const storageTrie = await parseStorage ( storage )
66
+ account . stateRoot = storageTrie . root
80
67
}
81
- promises . push (
82
- new Promise ( ( resolve , reject ) => {
83
- trie . put ( address , account . serialize ( ) , ( err : Error ) => {
84
- if ( err ) return reject ( err )
85
- resolve ( )
86
- } )
87
- } )
88
- )
68
+ await trie . put ( address , account . serialize ( ) )
89
69
}
90
- await Promise . all ( promises )
91
70
return trie
92
71
}
93
72
94
73
async function parseGethHeader ( json : any ) {
95
- return BlockHeader . fromHeaderData (
96
- {
97
- gasLimit : new util . BN ( util . stripHexPrefix ( json . gasLimit ) , 16 ) ,
98
- difficulty : new util . BN ( util . stripHexPrefix ( json . difficulty ) , 16 ) ,
99
- extraData : toBuffer ( json . extraData ) ,
100
- number : new util . BN ( util . stripHexPrefix ( json . number ) , 16 ) ,
101
- nonce : toBuffer ( json . nonce ) ,
102
- timestamp : new util . BN ( util . stripHexPrefix ( json . timestamp ) , 16 ) ,
103
- mixHash : toBuffer ( json . mixHash ) ,
104
- stateRoot : ( await parseGethState ( json . alloc ) ) . root ,
105
- } ,
106
- {
107
- // TODO: Add optional Common param here?
108
- }
109
- )
74
+ const { gasLimit, difficulty, extraData, number, nonce, timestamp, mixHash, alloc } = json
75
+ const storageTrie = await parseGethState ( alloc )
76
+ const stateRoot = storageTrie . root
77
+ const headerData = {
78
+ gasLimit,
79
+ difficulty,
80
+ extraData,
81
+ number,
82
+ nonce,
83
+ timestamp,
84
+ mixHash,
85
+ stateRoot,
86
+ }
87
+ return BlockHeader . fromHeaderData ( headerData ) // TODO: Pass in common?
110
88
}
111
89
112
90
async function parseGethParams ( json : any ) {
91
+ const {
92
+ name,
93
+ config,
94
+ timestamp,
95
+ gasLimit,
96
+ difficulty,
97
+ nonce,
98
+ extraData,
99
+ mixHash,
100
+ coinbase,
101
+ } = json
102
+ const { chainId } = config
113
103
const header = await parseGethHeader ( json )
104
+ const { stateRoot } = header
105
+ const hash = header . hash ( )
114
106
const params : any = {
115
- name : json . name ,
116
- chainId : json . config . chainId ,
117
- networkId : json . config . chainId ,
107
+ name,
108
+ chainId,
109
+ networkId : chainId ,
118
110
genesis : {
119
- hash : header . hash ( ) ,
120
- timestamp : json . timestamp ,
121
- gasLimit : json . gasLimit ,
122
- difficulty : json . difficulty ,
123
- nonce : json . nonce ,
124
- extraData : json . extraData ,
125
- mixHash : json . mixHash ,
126
- coinbase : json . coinbase ,
127
- stateRoot : header . stateRoot ,
111
+ hash,
112
+ timestamp,
113
+ gasLimit,
114
+ difficulty,
115
+ nonce,
116
+ extraData,
117
+ mixHash,
118
+ coinbase,
119
+ stateRoot,
128
120
} ,
129
121
bootstrapNodes : [ ] ,
130
122
}
@@ -138,7 +130,7 @@ async function parseGethParams(json: any) {
138
130
'constantinople' ,
139
131
'hybridCasper' ,
140
132
]
141
- const forkMap : any = {
133
+ const forkMap : { [ key : string ] : string } = {
142
134
homestead : 'homesteadBlock' ,
143
135
dao : 'daoForkBlock' ,
144
136
tangerineWhistle : 'eip150Block' ,
@@ -147,7 +139,7 @@ async function parseGethParams(json: any) {
147
139
}
148
140
params . hardforks = hardforks . map ( ( name ) => ( {
149
141
name : name ,
150
- block : name === 'chainstart' ? 0 : json . config [ forkMap [ name ] ] || null ,
142
+ block : name === 'chainstart' ? 0 : config [ forkMap [ name ] ] || null ,
151
143
} ) )
152
144
return params
153
145
}
0 commit comments