@feelyourprotocol/blockchain 8141.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/README.md +269 -0
  2. package/dist/cjs/blockchain.d.ts +372 -0
  3. package/dist/cjs/blockchain.d.ts.map +1 -0
  4. package/dist/cjs/blockchain.js +1105 -0
  5. package/dist/cjs/blockchain.js.map +1 -0
  6. package/dist/cjs/consensus/casper.d.ts +16 -0
  7. package/dist/cjs/consensus/casper.d.ts.map +1 -0
  8. package/dist/cjs/consensus/casper.js +28 -0
  9. package/dist/cjs/consensus/casper.js.map +1 -0
  10. package/dist/cjs/consensus/clique.d.ts +164 -0
  11. package/dist/cjs/consensus/clique.d.ts.map +1 -0
  12. package/dist/cjs/consensus/clique.js +520 -0
  13. package/dist/cjs/consensus/clique.js.map +1 -0
  14. package/dist/cjs/consensus/ethash.d.ts +29 -0
  15. package/dist/cjs/consensus/ethash.d.ts.map +1 -0
  16. package/dist/cjs/consensus/ethash.js +48 -0
  17. package/dist/cjs/consensus/ethash.js.map +1 -0
  18. package/dist/cjs/consensus/index.d.ts +5 -0
  19. package/dist/cjs/consensus/index.d.ts.map +1 -0
  20. package/dist/cjs/consensus/index.js +10 -0
  21. package/dist/cjs/consensus/index.js.map +1 -0
  22. package/dist/cjs/constructors.d.ts +13 -0
  23. package/dist/cjs/constructors.d.ts.map +1 -0
  24. package/dist/cjs/constructors.js +80 -0
  25. package/dist/cjs/constructors.js.map +1 -0
  26. package/dist/cjs/db/cache.d.ts +17 -0
  27. package/dist/cjs/db/cache.d.ts.map +1 -0
  28. package/dist/cjs/db/cache.js +38 -0
  29. package/dist/cjs/db/cache.js.map +1 -0
  30. package/dist/cjs/db/constants.d.ts +23 -0
  31. package/dist/cjs/db/constants.d.ts.map +1 -0
  32. package/dist/cjs/db/constants.js +54 -0
  33. package/dist/cjs/db/constants.js.map +1 -0
  34. package/dist/cjs/db/helpers.d.ts +9 -0
  35. package/dist/cjs/db/helpers.d.ts.map +1 -0
  36. package/dist/cjs/db/helpers.js +68 -0
  37. package/dist/cjs/db/helpers.js.map +1 -0
  38. package/dist/cjs/db/manager.d.ts +78 -0
  39. package/dist/cjs/db/manager.d.ts.map +1 -0
  40. package/dist/cjs/db/manager.js +203 -0
  41. package/dist/cjs/db/manager.js.map +1 -0
  42. package/dist/cjs/db/operation.d.ts +45 -0
  43. package/dist/cjs/db/operation.d.ts.map +1 -0
  44. package/dist/cjs/db/operation.js +110 -0
  45. package/dist/cjs/db/operation.js.map +1 -0
  46. package/dist/cjs/helpers.d.ts +19 -0
  47. package/dist/cjs/helpers.d.ts.map +1 -0
  48. package/dist/cjs/helpers.js +34 -0
  49. package/dist/cjs/helpers.js.map +1 -0
  50. package/dist/cjs/index.d.ts +7 -0
  51. package/dist/cjs/index.d.ts.map +1 -0
  52. package/dist/cjs/index.js +33 -0
  53. package/dist/cjs/index.js.map +1 -0
  54. package/dist/cjs/package.json +3 -0
  55. package/dist/cjs/types.d.ts +219 -0
  56. package/dist/cjs/types.d.ts.map +1 -0
  57. package/dist/cjs/types.js +3 -0
  58. package/dist/cjs/types.js.map +1 -0
  59. package/dist/esm/blockchain.d.ts +372 -0
  60. package/dist/esm/blockchain.d.ts.map +1 -0
  61. package/dist/esm/blockchain.js +1101 -0
  62. package/dist/esm/blockchain.js.map +1 -0
  63. package/dist/esm/consensus/casper.d.ts +16 -0
  64. package/dist/esm/consensus/casper.d.ts.map +1 -0
  65. package/dist/esm/consensus/casper.js +24 -0
  66. package/dist/esm/consensus/casper.js.map +1 -0
  67. package/dist/esm/consensus/clique.d.ts +164 -0
  68. package/dist/esm/consensus/clique.d.ts.map +1 -0
  69. package/dist/esm/consensus/clique.js +516 -0
  70. package/dist/esm/consensus/clique.js.map +1 -0
  71. package/dist/esm/consensus/ethash.d.ts +29 -0
  72. package/dist/esm/consensus/ethash.d.ts.map +1 -0
  73. package/dist/esm/consensus/ethash.js +44 -0
  74. package/dist/esm/consensus/ethash.js.map +1 -0
  75. package/dist/esm/consensus/index.d.ts +5 -0
  76. package/dist/esm/consensus/index.d.ts.map +1 -0
  77. package/dist/esm/consensus/index.js +5 -0
  78. package/dist/esm/consensus/index.js.map +1 -0
  79. package/dist/esm/constructors.d.ts +13 -0
  80. package/dist/esm/constructors.d.ts.map +1 -0
  81. package/dist/esm/constructors.js +76 -0
  82. package/dist/esm/constructors.js.map +1 -0
  83. package/dist/esm/db/cache.d.ts +17 -0
  84. package/dist/esm/db/cache.d.ts.map +1 -0
  85. package/dist/esm/db/cache.js +34 -0
  86. package/dist/esm/db/cache.js.map +1 -0
  87. package/dist/esm/db/constants.d.ts +23 -0
  88. package/dist/esm/db/constants.d.ts.map +1 -0
  89. package/dist/esm/db/constants.js +46 -0
  90. package/dist/esm/db/constants.js.map +1 -0
  91. package/dist/esm/db/helpers.d.ts +9 -0
  92. package/dist/esm/db/helpers.d.ts.map +1 -0
  93. package/dist/esm/db/helpers.js +61 -0
  94. package/dist/esm/db/helpers.js.map +1 -0
  95. package/dist/esm/db/manager.d.ts +78 -0
  96. package/dist/esm/db/manager.d.ts.map +1 -0
  97. package/dist/esm/db/manager.js +199 -0
  98. package/dist/esm/db/manager.js.map +1 -0
  99. package/dist/esm/db/operation.d.ts +45 -0
  100. package/dist/esm/db/operation.d.ts.map +1 -0
  101. package/dist/esm/db/operation.js +106 -0
  102. package/dist/esm/db/operation.js.map +1 -0
  103. package/dist/esm/helpers.d.ts +19 -0
  104. package/dist/esm/helpers.d.ts.map +1 -0
  105. package/dist/esm/helpers.js +30 -0
  106. package/dist/esm/helpers.js.map +1 -0
  107. package/dist/esm/index.d.ts +7 -0
  108. package/dist/esm/index.d.ts.map +1 -0
  109. package/dist/esm/index.js +7 -0
  110. package/dist/esm/index.js.map +1 -0
  111. package/dist/esm/package.json +3 -0
  112. package/dist/esm/types.d.ts +219 -0
  113. package/dist/esm/types.d.ts.map +1 -0
  114. package/dist/esm/types.js +2 -0
  115. package/dist/esm/types.js.map +1 -0
  116. package/dist/tsconfig.prod.cjs.tsbuildinfo +1 -0
  117. package/dist/tsconfig.prod.esm.tsbuildinfo +1 -0
  118. package/package.json +75 -0
  119. package/src/blockchain.ts +1353 -0
  120. package/src/consensus/casper.ts +33 -0
  121. package/src/consensus/clique.ts +633 -0
  122. package/src/consensus/ethash.ts +69 -0
  123. package/src/consensus/index.ts +5 -0
  124. package/src/constructors.ts +119 -0
  125. package/src/db/cache.ts +39 -0
  126. package/src/db/constants.ts +73 -0
  127. package/src/db/helpers.ts +81 -0
  128. package/src/db/manager.ts +243 -0
  129. package/src/db/operation.ts +152 -0
  130. package/src/helpers.ts +37 -0
  131. package/src/index.ts +12 -0
  132. package/src/types.ts +256 -0
@@ -0,0 +1,152 @@
1
+ import { EthereumJSErrorWithoutCode, KeyEncoding, ValueEncoding } from '@feelyourprotocol/util'
2
+
3
+ import {
4
+ HEADS_KEY,
5
+ HEAD_BLOCK_KEY,
6
+ HEAD_HEADER_KEY,
7
+ bodyKey,
8
+ hashToNumberKey,
9
+ headerKey,
10
+ numberToHashKey,
11
+ tdKey,
12
+ } from './constants.ts'
13
+
14
+ import type { CacheMap } from './manager.ts'
15
+
16
+ export type DBTarget = (typeof DBTarget)[keyof typeof DBTarget]
17
+
18
+ export const DBTarget = {
19
+ Heads: 0,
20
+ HeadHeader: 1,
21
+ HeadBlock: 2,
22
+ HashToNumber: 3,
23
+ NumberToHash: 4,
24
+ TotalDifficulty: 5,
25
+ Body: 6,
26
+ Header: 7,
27
+ CliqueSignerStates: 8,
28
+ CliqueVotes: 9,
29
+ CliqueBlockSigners: 10,
30
+ } as const
31
+
32
+ /**
33
+ * DBOpData is a type which has the purpose of holding the actual data of the Database Operation.
34
+ * @hidden
35
+ */
36
+ export interface DBOpData {
37
+ type?: 'put' | 'del'
38
+ key: Uint8Array | string
39
+ keyEncoding: KeyEncoding
40
+ valueEncoding?: ValueEncoding
41
+ value?: Uint8Array | object
42
+ }
43
+
44
+ // a Database Key is identified by a block hash, a block number, or both
45
+ export type DatabaseKey = {
46
+ blockNumber?: bigint
47
+ blockHash?: Uint8Array
48
+ }
49
+
50
+ /**
51
+ * The DBOp class aids creating database operations which is used by `level` using a more high-level interface
52
+ */
53
+ export class DBOp {
54
+ public operationTarget: DBTarget
55
+ public baseDBOp: DBOpData
56
+ public cacheString: string | undefined
57
+
58
+ private constructor(operationTarget: DBTarget, key?: DatabaseKey) {
59
+ this.operationTarget = operationTarget
60
+
61
+ this.baseDBOp = {
62
+ key: '',
63
+ keyEncoding: KeyEncoding.Bytes,
64
+ valueEncoding: ValueEncoding.Bytes,
65
+ }
66
+
67
+ switch (operationTarget) {
68
+ case DBTarget.Heads: {
69
+ this.baseDBOp.key = HEADS_KEY
70
+ this.baseDBOp.valueEncoding = ValueEncoding.JSON
71
+ break
72
+ }
73
+ case DBTarget.HeadHeader: {
74
+ this.baseDBOp.key = HEAD_HEADER_KEY
75
+ this.baseDBOp.keyEncoding = KeyEncoding.String
76
+ break
77
+ }
78
+ case DBTarget.HeadBlock: {
79
+ this.baseDBOp.key = HEAD_BLOCK_KEY
80
+ this.baseDBOp.keyEncoding = KeyEncoding.String
81
+ break
82
+ }
83
+ case DBTarget.HashToNumber: {
84
+ this.baseDBOp.key = hashToNumberKey(key!.blockHash!)
85
+ this.cacheString = 'hashToNumber'
86
+ break
87
+ }
88
+ case DBTarget.NumberToHash: {
89
+ this.baseDBOp.key = numberToHashKey(key!.blockNumber!)
90
+ this.cacheString = 'numberToHash'
91
+ break
92
+ }
93
+ case DBTarget.TotalDifficulty: {
94
+ this.baseDBOp.key = tdKey(key!.blockNumber!, key!.blockHash!)
95
+ this.cacheString = 'td'
96
+ break
97
+ }
98
+ case DBTarget.Body: {
99
+ this.baseDBOp.key = bodyKey(key!.blockNumber!, key!.blockHash!)
100
+ this.cacheString = 'body'
101
+ break
102
+ }
103
+ case DBTarget.Header: {
104
+ this.baseDBOp.key = headerKey(key!.blockNumber!, key!.blockHash!)
105
+ this.cacheString = 'header'
106
+ break
107
+ }
108
+ }
109
+ }
110
+
111
+ public static get(operationTarget: DBTarget, key?: DatabaseKey): DBOp {
112
+ return new DBOp(operationTarget, key)
113
+ }
114
+
115
+ // set operation: note: value/key is not in default order
116
+ public static set(
117
+ operationTarget: DBTarget,
118
+ value: Uint8Array | object,
119
+ key?: DatabaseKey,
120
+ ): DBOp {
121
+ const dbOperation = new DBOp(operationTarget, key)
122
+ dbOperation.baseDBOp.value = value
123
+ dbOperation.baseDBOp.type = 'put'
124
+
125
+ if (operationTarget === DBTarget.Heads) {
126
+ dbOperation.baseDBOp.valueEncoding = ValueEncoding.JSON
127
+ } else {
128
+ dbOperation.baseDBOp.valueEncoding = ValueEncoding.Bytes
129
+ }
130
+
131
+ return dbOperation
132
+ }
133
+
134
+ public static del(operationTarget: DBTarget, key?: DatabaseKey): DBOp {
135
+ const dbOperation = new DBOp(operationTarget, key)
136
+ dbOperation.baseDBOp.type = 'del'
137
+ return dbOperation
138
+ }
139
+
140
+ public updateCache(cacheMap: CacheMap) {
141
+ if (this.cacheString !== undefined && cacheMap[this.cacheString] !== undefined) {
142
+ if (this.baseDBOp.type === 'put') {
143
+ this.baseDBOp.value instanceof Uint8Array &&
144
+ cacheMap[this.cacheString].set(this.baseDBOp.key, this.baseDBOp.value)
145
+ } else if (this.baseDBOp.type === 'del') {
146
+ cacheMap[this.cacheString].del(this.baseDBOp.key)
147
+ } else {
148
+ throw EthereumJSErrorWithoutCode('unsupported db operation on cache')
149
+ }
150
+ }
151
+ }
152
+ }
package/src/helpers.ts ADDED
@@ -0,0 +1,37 @@
1
+ import { ChainGenesis } from '@feelyourprotocol/common'
2
+ import { genesisMPTStateRoot } from '@feelyourprotocol/mpt'
3
+
4
+ import type { Chain, Common, GenesisState } from '@feelyourprotocol/common'
5
+
6
+ /**
7
+ * Safe creation of a new Blockchain object awaiting the initialization function,
8
+ * encouraged method to use when creating a blockchain object.
9
+ *
10
+ * @param opts Constructor options, see {@link BlockchainOptions}
11
+ */
12
+
13
+ /**
14
+ * Merkle genesis root
15
+ * @param genesisState
16
+ * @param common
17
+ * @returns
18
+ */
19
+ export async function genGenesisStateRoot(
20
+ genesisState: GenesisState,
21
+ common: Common,
22
+ ): Promise<Uint8Array> {
23
+ const genCommon = common.copy()
24
+ genCommon.setHardforkBy({
25
+ blockNumber: 0,
26
+ timestamp: genCommon.genesis().timestamp,
27
+ })
28
+ return genesisMPTStateRoot(genesisState)
29
+ }
30
+
31
+ /**
32
+ * Returns the genesis state root if chain is well known or an empty state's root otherwise
33
+ */
34
+ export async function getGenesisStateRoot(chainId: Chain, common: Common): Promise<Uint8Array> {
35
+ const chainGenesis = ChainGenesis[chainId]
36
+ return chainGenesis !== undefined ? chainGenesis.stateRoot : genGenesisStateRoot({}, common)
37
+ }
package/src/index.ts ADDED
@@ -0,0 +1,12 @@
1
+ export { Blockchain } from './blockchain.ts'
2
+ export { CasperConsensus, CliqueConsensus, EthashConsensus } from './consensus/index.ts'
3
+ export * from './constructors.ts'
4
+ export {
5
+ DBOp,
6
+ DBSaveLookups,
7
+ DBSetBlockOrHeader,
8
+ DBSetHashToNumber,
9
+ DBSetTD,
10
+ } from './db/helpers.ts'
11
+ export * from './helpers.ts'
12
+ export * from './types.ts'
package/src/types.ts ADDED
@@ -0,0 +1,256 @@
1
+ import type { Block, BlockHeader } from '@feelyourprotocol/block'
2
+ import type { Common, ConsensusAlgorithm, GenesisState } from '@feelyourprotocol/common'
3
+ import type { DB, DBObject } from '@feelyourprotocol/util'
4
+ import type { EventEmitter } from 'eventemitter3'
5
+ import type { Blockchain } from './index.ts'
6
+
7
+ export type OnBlock = (block: Block, reorg: boolean) => Promise<void> | void
8
+
9
+ export type BlockchainEvent = {
10
+ deletedCanonicalBlocks: (data: Block[], resolve?: (result?: any) => void) => void
11
+ }
12
+
13
+ export interface BlockchainInterface {
14
+ consensus: Consensus | undefined
15
+ /**
16
+ * Adds a block to the blockchain.
17
+ *
18
+ * @param block - The block to be added to the blockchain.
19
+ */
20
+ putBlock(block: Block): Promise<void>
21
+
22
+ /**
23
+ * Deletes a block from the blockchain. All child blocks in the chain are
24
+ * deleted and any encountered heads are set to the parent block.
25
+ *
26
+ * @param blockHash - The hash of the block to be deleted
27
+ */
28
+ delBlock(blockHash: Uint8Array): Promise<void>
29
+
30
+ /**
31
+ * Returns a block by its hash or number.
32
+ */
33
+ getBlock(blockId: Uint8Array | number | bigint): Promise<Block>
34
+
35
+ /**
36
+ * Iterates through blocks starting at the specified iterator head and calls
37
+ * the onBlock function on each block.
38
+ *
39
+ * @param name - Name of the state root head
40
+ * @param onBlock - Function called on each block with params (block: Block,
41
+ * @param maxBlocks - optional maximum number of blocks to iterate through
42
+ * reorg: boolean)
43
+ */
44
+ iterator(
45
+ name: string,
46
+ onBlock: OnBlock,
47
+ maxBlocks?: number,
48
+ releaseLockOnCallback?: boolean,
49
+ ): Promise<number>
50
+
51
+ /**
52
+ * Returns a shallow copy of the blockchain that may share state with the original
53
+ */
54
+ shallowCopy(): BlockchainInterface
55
+
56
+ /**
57
+ * Validates a block header, throwing if invalid. It is being validated against the reported `parentHash`.
58
+ * @param header - header to be validated
59
+ * @param height - If this is an uncle header, this is the height of the block that is including it
60
+ */
61
+ validateHeader(header: BlockHeader, height?: bigint): Promise<void>
62
+
63
+ /**
64
+ * Returns the specified iterator head.
65
+ *
66
+ * @param name - Optional name of the iterator head (default: 'vm')
67
+ */
68
+ getIteratorHead(name?: string): Promise<Block>
69
+
70
+ /**
71
+ * Set header hash of a certain `tag`.
72
+ * When calling the iterator, the iterator will start running the first child block after the header hash currently stored.
73
+ * @param tag - The tag to save the headHash to
74
+ * @param headHash - The head hash to save
75
+ */
76
+ setIteratorHead(tag: string, headHash: Uint8Array): Promise<void>
77
+
78
+ /**
79
+ * Gets total difficulty for a block specified by hash and number
80
+ */
81
+ getTotalDifficulty?(hash: Uint8Array, number?: bigint): Promise<bigint>
82
+
83
+ /**
84
+ * Returns the latest full block in the canonical chain.
85
+ */
86
+ getCanonicalHeadBlock(): Promise<Block>
87
+
88
+ /**
89
+ * Optional events emitter
90
+ */
91
+ events?: EventEmitter<BlockchainEvent>
92
+ }
93
+
94
+ export interface GenesisOptions {
95
+ /**
96
+ * The blockchain only initializes successfully if it has a genesis block. If
97
+ * there is no block available in the DB and a `genesisBlock` is provided,
98
+ * then the provided `genesisBlock` will be used as genesis. If no block is
99
+ * present in the DB and no block is provided, then the genesis block as
100
+ * provided from the `common` will be used.
101
+ */
102
+ genesisBlock?: Block
103
+
104
+ /**
105
+ * If you are using a custom chain {@link Common}, pass the genesis state.
106
+ *
107
+ * Pattern 1 (with genesis state see {@link GenesisState} for format):
108
+ *
109
+ * ```javascript
110
+ * {
111
+ * '0x0...01': '0x100', // For EoA
112
+ * }
113
+ * ```
114
+ *
115
+ * Pattern 2 (with complex genesis state, containing contract accounts and storage).
116
+ * Note that in {@link AccountState} there are two
117
+ * accepted types. This allows to easily insert accounts in the genesis state:
118
+ *
119
+ * A complex genesis state with Contract and EoA states would have the following format:
120
+ *
121
+ * ```javascript
122
+ * {
123
+ * '0x0...01': '0x100', // For EoA
124
+ * '0x0...02': ['0x1', '0xRUNTIME_BYTECODE', [[storageKey1, storageValue1], [storageKey2, storageValue2]]] // For contracts
125
+ * }
126
+ * ```
127
+ */
128
+ genesisState?: GenesisState
129
+
130
+ /**
131
+ * State root of the genesis state
132
+ */
133
+ genesisStateRoot?: Uint8Array
134
+ }
135
+
136
+ export type ConsensusDict = {
137
+ [consensusAlgorithm: ConsensusAlgorithm | string]: Consensus
138
+ }
139
+
140
+ /**
141
+ * This are the options that the Blockchain constructor can receive.
142
+ */
143
+ export interface BlockchainOptions extends GenesisOptions {
144
+ /**
145
+ * Specify the chain and hardfork by passing a {@link Common} instance.
146
+ *
147
+ * If not provided this defaults to chain `mainnet` and hardfork `chainstart`
148
+ *
149
+ */
150
+ common?: Common
151
+
152
+ /**
153
+ * Set the HF to the fork determined by the head block and update on head updates.
154
+ *
155
+ * Note: for HFs where the transition is also determined by a total difficulty
156
+ * threshold (merge HF) the calculated TD is additionally taken into account
157
+ * for HF determination.
158
+ *
159
+ * Default: `false` (HF is set to whatever default HF is set by the {@link Common} instance)
160
+ */
161
+ hardforkByHeadBlockNumber?: boolean
162
+
163
+ /**
164
+ * Database to store blocks and metadata.
165
+ * Can be any database implementation that adheres to the `DB` interface
166
+ */
167
+ db?: DB<Uint8Array | string | number, Uint8Array | string | DBObject>
168
+
169
+ /**
170
+ * This flag indicates if protocol-given consistency checks on
171
+ * block headers and included uncles and transactions should be performed,
172
+ * see Block#validate for details.
173
+ *
174
+ */
175
+ validateBlocks?: boolean
176
+
177
+ /**
178
+ * Validate the consensus with the respective consensus implementation passed
179
+ * to `consensusDict` (see respective option) `CasperConsensus` (which effectively
180
+ * does nothing) is available by default.
181
+ *
182
+ * For the build-in validation classes the following validations take place.
183
+ * - 'pow' with 'ethash' algorithm (validates the proof-of-work)
184
+ * - 'poa' with 'clique' algorithm (verifies the block signatures)
185
+ * Default: `false`.
186
+ */
187
+ validateConsensus?: boolean
188
+
189
+ /**
190
+ * Optional dictionary with consensus objects (adhering to the {@link Consensus} interface)
191
+ * if consensus validation is wished for certain consensus algorithms.
192
+ *
193
+ * Since consensus validation moved to the Ethereum consensus layer with Proof-of-Stake
194
+ * consensus is not validated by default. For `ConsensusAlgorithm.Ethash` and
195
+ * `ConsensusAlgorithm.Clique` consensus validation can be activated by passing in the
196
+ * respective consensus validation objects `EthashConsensus` or `CliqueConsensus`.
197
+ *
198
+ * ```ts
199
+ * import { CliqueConsensus, createBlockchain } from '@feelyourprotocol/blockchain'
200
+ * import type { ConsensusDict } from '@feelyourprotocol/blockchain'
201
+ *
202
+ * const consensusDict: ConsensusDict = {}
203
+ * consensusDict[ConsensusAlgorithm.Clique] = new CliqueConsensus()
204
+ * const blockchain = await createBlockchain({ common, consensusDict })
205
+ * ```
206
+ *
207
+ * Additionally it is possible to provide a fully custom consensus implementation.
208
+ * Note that this needs a custom `Common` object passed to the blockchain where
209
+ * the `ConsensusAlgorithm` string matches the string used here.
210
+ */
211
+ consensusDict?: ConsensusDict
212
+ }
213
+
214
+ /**
215
+ * Interface that a consensus class needs to implement.
216
+ */
217
+ export interface Consensus {
218
+ algorithm: ConsensusAlgorithm | string
219
+ /**
220
+ * Initialize genesis for consensus mechanism
221
+ * @param genesisBlock genesis block
222
+ */
223
+ genesisInit(genesisBlock: Block): Promise<void>
224
+
225
+ /**
226
+ * Set up consensus mechanism
227
+ */
228
+ setup({ blockchain }: ConsensusOptions): Promise<void>
229
+
230
+ /**
231
+ * Validate block consensus parameters
232
+ * @param block block to be validated
233
+ */
234
+ validateConsensus(block: Block): Promise<void>
235
+
236
+ validateDifficulty(header: BlockHeader): Promise<void>
237
+
238
+ /**
239
+ * Update consensus on new block
240
+ * @param block new block
241
+ * @param commonAncestor common ancestor block header (optional)
242
+ * @param ancientHeaders array of ancestor block headers (optional)
243
+ */
244
+ newBlock(
245
+ block: Block,
246
+ commonAncestor?: BlockHeader,
247
+ ancientHeaders?: BlockHeader[],
248
+ ): Promise<void>
249
+ }
250
+
251
+ /**
252
+ * Options when initializing a class that implements the Consensus interface.
253
+ */
254
+ export interface ConsensusOptions {
255
+ blockchain: Blockchain
256
+ }