@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.
- package/README.md +269 -0
- package/dist/cjs/blockchain.d.ts +372 -0
- package/dist/cjs/blockchain.d.ts.map +1 -0
- package/dist/cjs/blockchain.js +1105 -0
- package/dist/cjs/blockchain.js.map +1 -0
- package/dist/cjs/consensus/casper.d.ts +16 -0
- package/dist/cjs/consensus/casper.d.ts.map +1 -0
- package/dist/cjs/consensus/casper.js +28 -0
- package/dist/cjs/consensus/casper.js.map +1 -0
- package/dist/cjs/consensus/clique.d.ts +164 -0
- package/dist/cjs/consensus/clique.d.ts.map +1 -0
- package/dist/cjs/consensus/clique.js +520 -0
- package/dist/cjs/consensus/clique.js.map +1 -0
- package/dist/cjs/consensus/ethash.d.ts +29 -0
- package/dist/cjs/consensus/ethash.d.ts.map +1 -0
- package/dist/cjs/consensus/ethash.js +48 -0
- package/dist/cjs/consensus/ethash.js.map +1 -0
- package/dist/cjs/consensus/index.d.ts +5 -0
- package/dist/cjs/consensus/index.d.ts.map +1 -0
- package/dist/cjs/consensus/index.js +10 -0
- package/dist/cjs/consensus/index.js.map +1 -0
- package/dist/cjs/constructors.d.ts +13 -0
- package/dist/cjs/constructors.d.ts.map +1 -0
- package/dist/cjs/constructors.js +80 -0
- package/dist/cjs/constructors.js.map +1 -0
- package/dist/cjs/db/cache.d.ts +17 -0
- package/dist/cjs/db/cache.d.ts.map +1 -0
- package/dist/cjs/db/cache.js +38 -0
- package/dist/cjs/db/cache.js.map +1 -0
- package/dist/cjs/db/constants.d.ts +23 -0
- package/dist/cjs/db/constants.d.ts.map +1 -0
- package/dist/cjs/db/constants.js +54 -0
- package/dist/cjs/db/constants.js.map +1 -0
- package/dist/cjs/db/helpers.d.ts +9 -0
- package/dist/cjs/db/helpers.d.ts.map +1 -0
- package/dist/cjs/db/helpers.js +68 -0
- package/dist/cjs/db/helpers.js.map +1 -0
- package/dist/cjs/db/manager.d.ts +78 -0
- package/dist/cjs/db/manager.d.ts.map +1 -0
- package/dist/cjs/db/manager.js +203 -0
- package/dist/cjs/db/manager.js.map +1 -0
- package/dist/cjs/db/operation.d.ts +45 -0
- package/dist/cjs/db/operation.d.ts.map +1 -0
- package/dist/cjs/db/operation.js +110 -0
- package/dist/cjs/db/operation.js.map +1 -0
- package/dist/cjs/helpers.d.ts +19 -0
- package/dist/cjs/helpers.d.ts.map +1 -0
- package/dist/cjs/helpers.js +34 -0
- package/dist/cjs/helpers.js.map +1 -0
- package/dist/cjs/index.d.ts +7 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +33 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/types.d.ts +219 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +3 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/esm/blockchain.d.ts +372 -0
- package/dist/esm/blockchain.d.ts.map +1 -0
- package/dist/esm/blockchain.js +1101 -0
- package/dist/esm/blockchain.js.map +1 -0
- package/dist/esm/consensus/casper.d.ts +16 -0
- package/dist/esm/consensus/casper.d.ts.map +1 -0
- package/dist/esm/consensus/casper.js +24 -0
- package/dist/esm/consensus/casper.js.map +1 -0
- package/dist/esm/consensus/clique.d.ts +164 -0
- package/dist/esm/consensus/clique.d.ts.map +1 -0
- package/dist/esm/consensus/clique.js +516 -0
- package/dist/esm/consensus/clique.js.map +1 -0
- package/dist/esm/consensus/ethash.d.ts +29 -0
- package/dist/esm/consensus/ethash.d.ts.map +1 -0
- package/dist/esm/consensus/ethash.js +44 -0
- package/dist/esm/consensus/ethash.js.map +1 -0
- package/dist/esm/consensus/index.d.ts +5 -0
- package/dist/esm/consensus/index.d.ts.map +1 -0
- package/dist/esm/consensus/index.js +5 -0
- package/dist/esm/consensus/index.js.map +1 -0
- package/dist/esm/constructors.d.ts +13 -0
- package/dist/esm/constructors.d.ts.map +1 -0
- package/dist/esm/constructors.js +76 -0
- package/dist/esm/constructors.js.map +1 -0
- package/dist/esm/db/cache.d.ts +17 -0
- package/dist/esm/db/cache.d.ts.map +1 -0
- package/dist/esm/db/cache.js +34 -0
- package/dist/esm/db/cache.js.map +1 -0
- package/dist/esm/db/constants.d.ts +23 -0
- package/dist/esm/db/constants.d.ts.map +1 -0
- package/dist/esm/db/constants.js +46 -0
- package/dist/esm/db/constants.js.map +1 -0
- package/dist/esm/db/helpers.d.ts +9 -0
- package/dist/esm/db/helpers.d.ts.map +1 -0
- package/dist/esm/db/helpers.js +61 -0
- package/dist/esm/db/helpers.js.map +1 -0
- package/dist/esm/db/manager.d.ts +78 -0
- package/dist/esm/db/manager.d.ts.map +1 -0
- package/dist/esm/db/manager.js +199 -0
- package/dist/esm/db/manager.js.map +1 -0
- package/dist/esm/db/operation.d.ts +45 -0
- package/dist/esm/db/operation.d.ts.map +1 -0
- package/dist/esm/db/operation.js +106 -0
- package/dist/esm/db/operation.js.map +1 -0
- package/dist/esm/helpers.d.ts +19 -0
- package/dist/esm/helpers.d.ts.map +1 -0
- package/dist/esm/helpers.js +30 -0
- package/dist/esm/helpers.js.map +1 -0
- package/dist/esm/index.d.ts +7 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/types.d.ts +219 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/tsconfig.prod.cjs.tsbuildinfo +1 -0
- package/dist/tsconfig.prod.esm.tsbuildinfo +1 -0
- package/package.json +75 -0
- package/src/blockchain.ts +1353 -0
- package/src/consensus/casper.ts +33 -0
- package/src/consensus/clique.ts +633 -0
- package/src/consensus/ethash.ts +69 -0
- package/src/consensus/index.ts +5 -0
- package/src/constructors.ts +119 -0
- package/src/db/cache.ts +39 -0
- package/src/db/constants.ts +73 -0
- package/src/db/helpers.ts +81 -0
- package/src/db/manager.ts +243 -0
- package/src/db/operation.ts +152 -0
- package/src/helpers.ts +37 -0
- package/src/index.ts +12 -0
- package/src/types.ts +256 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Blockchain } from './index.ts';
|
|
2
|
+
import type { BlockData } from '@feelyourprotocol/block';
|
|
3
|
+
import type { BlockchainOptions } from './index.ts';
|
|
4
|
+
export declare function createBlockchain(opts?: BlockchainOptions): Promise<Blockchain>;
|
|
5
|
+
/**
|
|
6
|
+
* Creates a blockchain from a list of block objects,
|
|
7
|
+
* objects must be readable by {@link createBlock}
|
|
8
|
+
*
|
|
9
|
+
* @param blockData List of block objects
|
|
10
|
+
* @param opts Constructor options, see {@link BlockchainOptions}
|
|
11
|
+
*/
|
|
12
|
+
export declare function createBlockchainFromBlocksData(blocksData: BlockData[], opts?: BlockchainOptions): Promise<Blockchain>;
|
|
13
|
+
//# sourceMappingURL=constructors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constructors.d.ts","sourceRoot":"","sources":["../../src/constructors.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,UAAU,EAMX,MAAM,YAAY,CAAA;AAEnB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAElD,OAAO,KAAK,EAAE,iBAAiB,EAAQ,MAAM,YAAY,CAAA;AAKzD,wBAAsB,gBAAgB,CAAC,IAAI,GAAE,iBAAsB,uBAsElE;AAED;;;;;;GAMG;AACH,wBAAsB,8BAA8B,CAClD,UAAU,EAAE,SAAS,EAAE,EACvB,IAAI,GAAE,iBAAsB,uBAW7B"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { createBlock } from '@feelyourprotocol/block';
|
|
2
|
+
import { BIGINT_0, EthereumJSErrorWithoutCode, bytesToHex, equalsBytes, isDebugEnabled, } from '@feelyourprotocol/util';
|
|
3
|
+
import debugDefault from 'debug';
|
|
4
|
+
import { Blockchain, DBSaveLookups, DBSetBlockOrHeader, DBSetTD, genGenesisStateRoot, getGenesisStateRoot, } from "./index.js";
|
|
5
|
+
const DEBUG = isDebugEnabled('ethjs');
|
|
6
|
+
const debug = debugDefault('blockchain:#');
|
|
7
|
+
export async function createBlockchain(opts = {}) {
|
|
8
|
+
const blockchain = new Blockchain(opts);
|
|
9
|
+
await blockchain.consensus?.setup({ blockchain });
|
|
10
|
+
let stateRoot = opts.genesisBlock?.header.stateRoot ?? opts.genesisStateRoot;
|
|
11
|
+
if (stateRoot === undefined) {
|
|
12
|
+
if (blockchain['_customGenesisState'] !== undefined) {
|
|
13
|
+
stateRoot = await genGenesisStateRoot(blockchain['_customGenesisState'], blockchain.common);
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
stateRoot = await getGenesisStateRoot(Number(blockchain.common.chainId()), blockchain.common);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const genesisBlock = opts.genesisBlock ?? blockchain.createGenesisBlock(stateRoot);
|
|
20
|
+
let genesisHash = await blockchain.dbManager.numberToHash(BIGINT_0);
|
|
21
|
+
const dbGenesisBlock = genesisHash !== undefined ? await blockchain.dbManager.getBlock(genesisHash) : undefined;
|
|
22
|
+
// If the DB has a genesis block, then verify that the genesis block in the
|
|
23
|
+
// DB is indeed the Genesis block generated or assigned.
|
|
24
|
+
if (dbGenesisBlock !== undefined && !equalsBytes(genesisBlock.hash(), dbGenesisBlock.hash())) {
|
|
25
|
+
throw EthereumJSErrorWithoutCode('The genesis block in the DB has a different hash than the provided genesis block.');
|
|
26
|
+
}
|
|
27
|
+
genesisHash = genesisBlock.hash();
|
|
28
|
+
if (!dbGenesisBlock) {
|
|
29
|
+
// If there is no genesis block put the genesis block in the DB.
|
|
30
|
+
// For that TD, the BlockOrHeader, and the Lookups have to be saved.
|
|
31
|
+
const dbOps = [];
|
|
32
|
+
dbOps.push(DBSetTD(genesisBlock.header.difficulty, BIGINT_0, genesisHash));
|
|
33
|
+
DBSetBlockOrHeader(genesisBlock).map((op) => dbOps.push(op));
|
|
34
|
+
DBSaveLookups(genesisHash, BIGINT_0).map((op) => dbOps.push(op));
|
|
35
|
+
await blockchain.dbManager.batch(dbOps);
|
|
36
|
+
await blockchain.consensus?.genesisInit(genesisBlock);
|
|
37
|
+
}
|
|
38
|
+
// At this point, we can safely set the genesis:
|
|
39
|
+
// it is either the one we put in the DB, or it is equal to the one
|
|
40
|
+
// which we read from the DB.
|
|
41
|
+
blockchain['_genesisBlock'] = genesisBlock;
|
|
42
|
+
// load verified iterator heads
|
|
43
|
+
const heads = await blockchain.dbManager.getHeads();
|
|
44
|
+
blockchain['_heads'] = heads ?? {};
|
|
45
|
+
// load headerchain head
|
|
46
|
+
let hash = await blockchain.dbManager.getHeadHeader();
|
|
47
|
+
blockchain['_headHeaderHash'] = hash ?? genesisHash;
|
|
48
|
+
// load blockchain head
|
|
49
|
+
hash = await blockchain.dbManager.getHeadBlock();
|
|
50
|
+
blockchain['_headBlockHash'] = hash ?? genesisHash;
|
|
51
|
+
if (blockchain['_hardforkByHeadBlockNumber']) {
|
|
52
|
+
const latestHeader = await blockchain['_getHeader'](blockchain['_headHeaderHash']);
|
|
53
|
+
await blockchain.checkAndTransitionHardForkByNumber(latestHeader.number, latestHeader.timestamp);
|
|
54
|
+
}
|
|
55
|
+
DEBUG && debug(`genesis block initialized with hash ${bytesToHex(genesisHash)}`);
|
|
56
|
+
return blockchain;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Creates a blockchain from a list of block objects,
|
|
60
|
+
* objects must be readable by {@link createBlock}
|
|
61
|
+
*
|
|
62
|
+
* @param blockData List of block objects
|
|
63
|
+
* @param opts Constructor options, see {@link BlockchainOptions}
|
|
64
|
+
*/
|
|
65
|
+
export async function createBlockchainFromBlocksData(blocksData, opts = {}) {
|
|
66
|
+
const blockchain = await createBlockchain(opts);
|
|
67
|
+
for (const blockData of blocksData) {
|
|
68
|
+
const block = createBlock(blockData, {
|
|
69
|
+
common: blockchain.common,
|
|
70
|
+
setHardfork: true,
|
|
71
|
+
});
|
|
72
|
+
await blockchain.putBlock(block);
|
|
73
|
+
}
|
|
74
|
+
return blockchain;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=constructors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constructors.js","sourceRoot":"","sources":["../../src/constructors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { LRUCache } from 'lru-cache';
|
|
2
|
+
/**
|
|
3
|
+
* Simple LRU Cache that allows for keys of type Uint8Array
|
|
4
|
+
* @hidden
|
|
5
|
+
*/
|
|
6
|
+
export declare class Cache<V> {
|
|
7
|
+
_cache: LRUCache<string, {
|
|
8
|
+
value: V;
|
|
9
|
+
}, void>;
|
|
10
|
+
constructor(opts: LRUCache.Options<string, {
|
|
11
|
+
value: V;
|
|
12
|
+
}, void>);
|
|
13
|
+
set(key: string | Uint8Array, value: V): void;
|
|
14
|
+
get(key: string | Uint8Array): V | undefined;
|
|
15
|
+
del(key: string | Uint8Array): void;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../src/db/cache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAEpC;;;GAGG;AACH,qBAAa,KAAK,CAAC,CAAC;IAClB,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,CAAC,CAAA;KAAE,EAAE,IAAI,CAAC,CAAA;gBAEhC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,CAAC,CAAA;KAAE,EAAE,IAAI,CAAC;IAI9D,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAQ7C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,CAAC,GAAG,SAAS;IAS5C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;CAOpC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { bytesToUnprefixedHex } from '@feelyourprotocol/util';
|
|
2
|
+
import { LRUCache } from 'lru-cache';
|
|
3
|
+
/**
|
|
4
|
+
* Simple LRU Cache that allows for keys of type Uint8Array
|
|
5
|
+
* @hidden
|
|
6
|
+
*/
|
|
7
|
+
export class Cache {
|
|
8
|
+
constructor(opts) {
|
|
9
|
+
this._cache = new LRUCache(opts);
|
|
10
|
+
}
|
|
11
|
+
set(key, value) {
|
|
12
|
+
if (key instanceof Uint8Array) {
|
|
13
|
+
// Using deprecated bytesToUnprefixedHex for performance: used as LRU cache keys (string encoding).
|
|
14
|
+
key = bytesToUnprefixedHex(key);
|
|
15
|
+
}
|
|
16
|
+
this._cache.set(key, { value });
|
|
17
|
+
}
|
|
18
|
+
get(key) {
|
|
19
|
+
if (key instanceof Uint8Array) {
|
|
20
|
+
// Using deprecated bytesToUnprefixedHex for performance: used as LRU cache keys (string encoding).
|
|
21
|
+
key = bytesToUnprefixedHex(key);
|
|
22
|
+
}
|
|
23
|
+
const elem = this._cache.get(key);
|
|
24
|
+
return elem !== undefined ? elem.value : undefined;
|
|
25
|
+
}
|
|
26
|
+
del(key) {
|
|
27
|
+
if (key instanceof Uint8Array) {
|
|
28
|
+
// Using deprecated bytesToUnprefixedHex for performance: used as LRU cache keys (string encoding).
|
|
29
|
+
key = bytesToUnprefixedHex(key);
|
|
30
|
+
}
|
|
31
|
+
this._cache.delete(key);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../../src/db/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAEpC;;;GAGG;AACH,MAAM,OAAO,KAAK;IAGhB,YAAY,IAAkD;QAC5D,IAAI,CAAC,MAAM,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAA;IAClC,CAAC;IAED,GAAG,CAAC,GAAwB,EAAE,KAAQ;QACpC,IAAI,GAAG,YAAY,UAAU,EAAE,CAAC;YAC9B,mGAAmG;YACnG,GAAG,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAA;QACjC,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;IACjC,CAAC;IAED,GAAG,CAAC,GAAwB;QAC1B,IAAI,GAAG,YAAY,UAAU,EAAE,CAAC;YAC9B,mGAAmG;YACnG,GAAG,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAA;QACjC,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACjC,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;IACpD,CAAC;IAED,GAAG,CAAC,GAAwB;QAC1B,IAAI,GAAG,YAAY,UAAU,EAAE,CAAC;YAC9B,mGAAmG;YACnG,GAAG,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAA;QACjC,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IACzB,CAAC;CACF"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
declare const HEADS_KEY = "heads";
|
|
2
|
+
/**
|
|
3
|
+
* Current canonical head for light sync
|
|
4
|
+
*/
|
|
5
|
+
declare const HEAD_HEADER_KEY = "LastHeader";
|
|
6
|
+
/**
|
|
7
|
+
* Current canonical head for full sync
|
|
8
|
+
*/
|
|
9
|
+
declare const HEAD_BLOCK_KEY = "LastBlock";
|
|
10
|
+
/**
|
|
11
|
+
* Convert bigint to big endian Uint8Array
|
|
12
|
+
*/
|
|
13
|
+
declare const bytesBE8: (n: bigint) => Uint8Array<ArrayBufferLike>;
|
|
14
|
+
declare const tdKey: (n: bigint, hash: Uint8Array) => Uint8Array<ArrayBuffer>;
|
|
15
|
+
declare const headerKey: (n: bigint, hash: Uint8Array) => Uint8Array<ArrayBuffer>;
|
|
16
|
+
declare const bodyKey: (n: bigint, hash: Uint8Array) => Uint8Array<ArrayBuffer>;
|
|
17
|
+
declare const numberToHashKey: (n: bigint) => Uint8Array<ArrayBuffer>;
|
|
18
|
+
declare const hashToNumberKey: (hash: Uint8Array) => Uint8Array<ArrayBuffer>;
|
|
19
|
+
/**
|
|
20
|
+
* @hidden
|
|
21
|
+
*/
|
|
22
|
+
export { bodyKey, bytesBE8, hashToNumberKey, HEAD_BLOCK_KEY, HEAD_HEADER_KEY, headerKey, HEADS_KEY, numberToHashKey, tdKey, };
|
|
23
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/db/constants.ts"],"names":[],"mappings":"AAIA,QAAA,MAAM,SAAS,UAAU,CAAA;AAEzB;;GAEG;AACH,QAAA,MAAM,eAAe,eAAe,CAAA;AAEpC;;GAEG;AACH,QAAA,MAAM,cAAc,cAAc,CAAA;AA6BlC;;GAEG;AACH,QAAA,MAAM,QAAQ,GAAI,GAAG,MAAM,gCAAyC,CAAA;AAEpE,QAAA,MAAM,KAAK,GAAI,GAAG,MAAM,EAAE,MAAM,UAAU,4BACgB,CAAA;AAE1D,QAAA,MAAM,SAAS,GAAI,GAAG,MAAM,EAAE,MAAM,UAAU,4BAAkD,CAAA;AAEhG,QAAA,MAAM,OAAO,GAAI,GAAG,MAAM,EAAE,MAAM,UAAU,4BAAgD,CAAA;AAE5F,QAAA,MAAM,eAAe,GAAI,GAAG,MAAM,4BAAwD,CAAA;AAE1F,QAAA,MAAM,eAAe,GAAI,MAAM,UAAU,4BAAyC,CAAA;AAElF;;GAEG;AACH,OAAO,EACL,OAAO,EACP,QAAQ,EACR,eAAe,EACf,cAAc,EACd,eAAe,EACf,SAAS,EACT,SAAS,EACT,eAAe,EACf,KAAK,GACN,CAAA"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { bigIntToBytes, concatBytes, utf8ToBytes } from '@feelyourprotocol/util';
|
|
2
|
+
// Geth compatible DB keys
|
|
3
|
+
const HEADS_KEY = 'heads';
|
|
4
|
+
/**
|
|
5
|
+
* Current canonical head for light sync
|
|
6
|
+
*/
|
|
7
|
+
const HEAD_HEADER_KEY = 'LastHeader';
|
|
8
|
+
/**
|
|
9
|
+
* Current canonical head for full sync
|
|
10
|
+
*/
|
|
11
|
+
const HEAD_BLOCK_KEY = 'LastBlock';
|
|
12
|
+
/**
|
|
13
|
+
* headerPrefix + number + hash -> header
|
|
14
|
+
*/
|
|
15
|
+
const HEADER_PREFIX = utf8ToBytes('h');
|
|
16
|
+
/**
|
|
17
|
+
* headerPrefix + number + hash + tdSuffix -> td
|
|
18
|
+
*/
|
|
19
|
+
const TD_SUFFIX = utf8ToBytes('t');
|
|
20
|
+
/**
|
|
21
|
+
* headerPrefix + number + numSuffix -> hash
|
|
22
|
+
*/
|
|
23
|
+
const NUM_SUFFIX = utf8ToBytes('n');
|
|
24
|
+
/**
|
|
25
|
+
* blockHashPrefix + hash -> number
|
|
26
|
+
*/
|
|
27
|
+
const BLOCK_HASH_PREFIX = utf8ToBytes('H');
|
|
28
|
+
/**
|
|
29
|
+
* bodyPrefix + number + hash -> block body
|
|
30
|
+
*/
|
|
31
|
+
const BODY_PREFIX = utf8ToBytes('b');
|
|
32
|
+
// Utility functions
|
|
33
|
+
/**
|
|
34
|
+
* Convert bigint to big endian Uint8Array
|
|
35
|
+
*/
|
|
36
|
+
const bytesBE8 = (n) => bigIntToBytes(BigInt.asUintN(64, n));
|
|
37
|
+
const tdKey = (n, hash) => concatBytes(HEADER_PREFIX, bytesBE8(n), hash, TD_SUFFIX);
|
|
38
|
+
const headerKey = (n, hash) => concatBytes(HEADER_PREFIX, bytesBE8(n), hash);
|
|
39
|
+
const bodyKey = (n, hash) => concatBytes(BODY_PREFIX, bytesBE8(n), hash);
|
|
40
|
+
const numberToHashKey = (n) => concatBytes(HEADER_PREFIX, bytesBE8(n), NUM_SUFFIX);
|
|
41
|
+
const hashToNumberKey = (hash) => concatBytes(BLOCK_HASH_PREFIX, hash);
|
|
42
|
+
/**
|
|
43
|
+
* @hidden
|
|
44
|
+
*/
|
|
45
|
+
export { bodyKey, bytesBE8, hashToNumberKey, HEAD_BLOCK_KEY, HEAD_HEADER_KEY, headerKey, HEADS_KEY, numberToHashKey, tdKey, };
|
|
46
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/db/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE1E,0BAA0B;AAE1B,MAAM,SAAS,GAAG,OAAO,CAAA;AAEzB;;GAEG;AACH,MAAM,eAAe,GAAG,YAAY,CAAA;AAEpC;;GAEG;AACH,MAAM,cAAc,GAAG,WAAW,CAAA;AAElC;;GAEG;AACH,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;AAEtC;;GAEG;AACH,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;AAElC;;GAEG;AACH,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;AAEnC;;GAEG;AACH,MAAM,iBAAiB,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;AAE1C;;GAEG;AACH,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;AAEpC,oBAAoB;AAEpB;;GAEG;AACH,MAAM,QAAQ,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;AAEpE,MAAM,KAAK,GAAG,CAAC,CAAS,EAAE,IAAgB,EAAE,EAAE,CAC5C,WAAW,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,CAAA;AAE1D,MAAM,SAAS,GAAG,CAAC,CAAS,EAAE,IAAgB,EAAE,EAAE,CAAC,WAAW,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;AAEhG,MAAM,OAAO,GAAG,CAAC,CAAS,EAAE,IAAgB,EAAE,EAAE,CAAC,WAAW,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;AAE5F,MAAM,eAAe,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,WAAW,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAA;AAE1F,MAAM,eAAe,GAAG,CAAC,IAAgB,EAAE,EAAE,CAAC,WAAW,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAA;AAElF;;GAEG;AACH,OAAO,EACL,OAAO,EACP,QAAQ,EACR,eAAe,EACf,cAAc,EACd,eAAe,EACf,SAAS,EACT,SAAS,EACT,eAAe,EACf,KAAK,GACN,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Block } from '@feelyourprotocol/block';
|
|
2
|
+
import { DBOp } from './operation.ts';
|
|
3
|
+
import type { BlockHeader } from '@feelyourprotocol/block';
|
|
4
|
+
declare function DBSetTD(TD: bigint, blockNumber: bigint, blockHash: Uint8Array): DBOp;
|
|
5
|
+
declare function DBSetBlockOrHeader(blockBody: Block | BlockHeader): DBOp[];
|
|
6
|
+
declare function DBSetHashToNumber(blockHash: Uint8Array, blockNumber: bigint): DBOp;
|
|
7
|
+
declare function DBSaveLookups(blockHash: Uint8Array, blockNumber: bigint, skipNumIndex?: boolean): DBOp[];
|
|
8
|
+
export { DBOp, DBSaveLookups, DBSetBlockOrHeader, DBSetHashToNumber, DBSetTD };
|
|
9
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/db/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAKzC,OAAO,EAAE,IAAI,EAAY,MAAM,gBAAgB,CAAA;AAE/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAOpD,iBAAS,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,GAAG,IAAI,CAK7E;AASD,iBAAS,kBAAkB,CAAC,SAAS,EAAE,KAAK,GAAG,WAAW,GAAG,IAAI,EAAE,CA4BlE;AAED,iBAAS,iBAAiB,CAAC,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAK3E;AAED,iBAAS,aAAa,CAAC,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO,GAAG,IAAI,EAAE,CAajG;AAED,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAA"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Block } from '@feelyourprotocol/block';
|
|
2
|
+
import { RLP } from '@feelyourprotocol/rlp';
|
|
3
|
+
import { BIGINT_0 } from '@feelyourprotocol/util';
|
|
4
|
+
import { bytesBE8 } from "./constants.js";
|
|
5
|
+
import { DBOp, DBTarget } from "./operation.js";
|
|
6
|
+
/*
|
|
7
|
+
* This extra helper file serves as an interface between the blockchain API functionality
|
|
8
|
+
* and the DB operations from `db/operation.ts` and also handles the right encoding of the keys
|
|
9
|
+
*/
|
|
10
|
+
function DBSetTD(TD, blockNumber, blockHash) {
|
|
11
|
+
return DBOp.set(DBTarget.TotalDifficulty, RLP.encode(TD), {
|
|
12
|
+
blockNumber,
|
|
13
|
+
blockHash,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
/*
|
|
17
|
+
* This method accepts either a BlockHeader or a Block and returns a list of DatabaseOperation instances
|
|
18
|
+
*
|
|
19
|
+
* - A "Set Header Operation" is always added
|
|
20
|
+
* - A "Set Body Operation" is only added if the body is not empty (it has transactions/uncles) or if the block is the genesis block
|
|
21
|
+
* (if there is a header but no block saved the DB will implicitly assume the block to be empty)
|
|
22
|
+
*/
|
|
23
|
+
function DBSetBlockOrHeader(blockBody) {
|
|
24
|
+
const header = blockBody instanceof Block ? blockBody.header : blockBody;
|
|
25
|
+
const dbOps = [];
|
|
26
|
+
const blockNumber = header.number;
|
|
27
|
+
const blockHash = header.hash();
|
|
28
|
+
const headerValue = header.serialize();
|
|
29
|
+
dbOps.push(DBOp.set(DBTarget.Header, headerValue, {
|
|
30
|
+
blockNumber,
|
|
31
|
+
blockHash,
|
|
32
|
+
}));
|
|
33
|
+
const isGenesis = header.number === BIGINT_0;
|
|
34
|
+
if (isGenesis || blockBody instanceof Block) {
|
|
35
|
+
const bodyValue = RLP.encode(blockBody.raw().slice(1));
|
|
36
|
+
dbOps.push(DBOp.set(DBTarget.Body, bodyValue, {
|
|
37
|
+
blockNumber,
|
|
38
|
+
blockHash,
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
return dbOps;
|
|
42
|
+
}
|
|
43
|
+
function DBSetHashToNumber(blockHash, blockNumber) {
|
|
44
|
+
const blockNumber8Byte = bytesBE8(blockNumber);
|
|
45
|
+
return DBOp.set(DBTarget.HashToNumber, blockNumber8Byte, {
|
|
46
|
+
blockHash,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function DBSaveLookups(blockHash, blockNumber, skipNumIndex) {
|
|
50
|
+
const ops = [];
|
|
51
|
+
if (skipNumIndex !== true) {
|
|
52
|
+
ops.push(DBOp.set(DBTarget.NumberToHash, blockHash, { blockNumber }));
|
|
53
|
+
}
|
|
54
|
+
const blockNumber8Bytes = bytesBE8(blockNumber);
|
|
55
|
+
ops.push(DBOp.set(DBTarget.HashToNumber, blockNumber8Bytes, {
|
|
56
|
+
blockHash,
|
|
57
|
+
}));
|
|
58
|
+
return ops;
|
|
59
|
+
}
|
|
60
|
+
export { DBOp, DBSaveLookups, DBSetBlockOrHeader, DBSetHashToNumber, DBSetTD };
|
|
61
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/db/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACzC,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAA;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAE3C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAI/C;;;GAGG;AAEH,SAAS,OAAO,CAAC,EAAU,EAAE,WAAmB,EAAE,SAAqB;IACrE,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE;QACxD,WAAW;QACX,SAAS;KACV,CAAC,CAAA;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,kBAAkB,CAAC,SAA8B;IACxD,MAAM,MAAM,GAAgB,SAAS,YAAY,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAA;IACrF,MAAM,KAAK,GAAG,EAAE,CAAA;IAEhB,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAA;IACjC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,EAAE,CAAA;IAE/B,MAAM,WAAW,GAAG,MAAM,CAAC,SAAS,EAAE,CAAA;IACtC,KAAK,CAAC,IAAI,CACR,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE;QACrC,WAAW;QACX,SAAS;KACV,CAAC,CACH,CAAA;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAA;IAE5C,IAAI,SAAS,IAAI,SAAS,YAAY,KAAK,EAAE,CAAC;QAC5C,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;QACtD,KAAK,CAAC,IAAI,CACR,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE;YACjC,WAAW;YACX,SAAS;SACV,CAAC,CACH,CAAA;IACH,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,iBAAiB,CAAC,SAAqB,EAAE,WAAmB;IACnE,MAAM,gBAAgB,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAA;IAC9C,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,EAAE,gBAAgB,EAAE;QACvD,SAAS;KACV,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,SAAqB,EAAE,WAAmB,EAAE,YAAsB;IACvF,MAAM,GAAG,GAAG,EAAE,CAAA;IACd,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QAC1B,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,EAAE,SAAS,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,CAAA;IACvE,CAAC;IAED,MAAM,iBAAiB,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAA;IAC/C,GAAG,CAAC,IAAI,CACN,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,EAAE,iBAAiB,EAAE;QACjD,SAAS;KACV,CAAC,CACH,CAAA;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAA"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { Cache } from './cache.ts';
|
|
2
|
+
import { DBOp, DBTarget } from './operation.ts';
|
|
3
|
+
import type { Block, BlockBodyBytes } from '@feelyourprotocol/block';
|
|
4
|
+
import type { Common } from '@feelyourprotocol/common';
|
|
5
|
+
import type { DB, DBObject } from '@feelyourprotocol/util';
|
|
6
|
+
import type { DatabaseKey } from './operation.ts';
|
|
7
|
+
/**
|
|
8
|
+
* @hidden
|
|
9
|
+
*/
|
|
10
|
+
export interface GetOpts {
|
|
11
|
+
keyEncoding?: string;
|
|
12
|
+
valueEncoding?: string;
|
|
13
|
+
cache?: string;
|
|
14
|
+
}
|
|
15
|
+
export type CacheMap = {
|
|
16
|
+
[key: string]: Cache<Uint8Array>;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Abstraction over a DB to facilitate storing/fetching blockchain-related
|
|
20
|
+
* data, such as blocks and headers, indices, and the head block.
|
|
21
|
+
* @hidden
|
|
22
|
+
*/
|
|
23
|
+
export declare class DBManager {
|
|
24
|
+
private _cache;
|
|
25
|
+
readonly common: Common;
|
|
26
|
+
private _db;
|
|
27
|
+
constructor(db: DB<Uint8Array | string, Uint8Array | string | DBObject>, common: Common);
|
|
28
|
+
/**
|
|
29
|
+
* Fetches iterator heads from the db.
|
|
30
|
+
*/
|
|
31
|
+
getHeads(): Promise<{
|
|
32
|
+
[key: string]: Uint8Array;
|
|
33
|
+
}>;
|
|
34
|
+
/**
|
|
35
|
+
* Fetches header of the head block.
|
|
36
|
+
*/
|
|
37
|
+
getHeadHeader(): Promise<Uint8Array | undefined>;
|
|
38
|
+
/**
|
|
39
|
+
* Fetches head block.
|
|
40
|
+
*/
|
|
41
|
+
getHeadBlock(): Promise<Uint8Array | undefined>;
|
|
42
|
+
/**
|
|
43
|
+
* Fetches a block (header and body) given a block id,
|
|
44
|
+
* which can be either its hash or its number.
|
|
45
|
+
*/
|
|
46
|
+
getBlock(blockId: Uint8Array | bigint | number): Promise<Block | undefined>;
|
|
47
|
+
/**
|
|
48
|
+
* Fetches body of a block given its hash and number.
|
|
49
|
+
*/
|
|
50
|
+
getBody(blockHash: Uint8Array, blockNumber: bigint): Promise<BlockBodyBytes | undefined>;
|
|
51
|
+
/**
|
|
52
|
+
* Fetches header of a block given its hash and number.
|
|
53
|
+
*/
|
|
54
|
+
getHeader(blockHash: Uint8Array, blockNumber: bigint): Promise<import("@feelyourprotocol/block").BlockHeader>;
|
|
55
|
+
/**
|
|
56
|
+
* Fetches total difficulty for a block given its hash and number.
|
|
57
|
+
*/
|
|
58
|
+
getTotalDifficulty(blockHash: Uint8Array, blockNumber: bigint): Promise<bigint>;
|
|
59
|
+
/**
|
|
60
|
+
* Performs a block hash to block number lookup.
|
|
61
|
+
*/
|
|
62
|
+
hashToNumber(blockHash: Uint8Array): Promise<bigint | undefined>;
|
|
63
|
+
/**
|
|
64
|
+
* Performs a block number to block hash lookup.
|
|
65
|
+
*/
|
|
66
|
+
numberToHash(blockNumber: bigint): Promise<Uint8Array | undefined>;
|
|
67
|
+
/**
|
|
68
|
+
* Fetches a key from the db. If `opts.cache` is specified
|
|
69
|
+
* it first tries to load from cache, and on cache miss will
|
|
70
|
+
* try to put the fetched item on cache afterwards.
|
|
71
|
+
*/
|
|
72
|
+
get(dbOperationTarget: DBTarget, key?: DatabaseKey): Promise<any>;
|
|
73
|
+
/**
|
|
74
|
+
* Performs a batch operation on db.
|
|
75
|
+
*/
|
|
76
|
+
batch(ops: DBOp[]): Promise<void>;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/db/manager.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAE/C,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAA4B,MAAM,mBAAmB,CAAA;AACxF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,KAAK,EAAa,EAAE,EAAE,QAAQ,EAAsB,MAAM,kBAAkB,CAAA;AACnF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAEjD;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,MAAM,QAAQ,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,CAAA;CAAE,CAAA;AAE3D;;;;GAIG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAU;IACxB,SAAgB,MAAM,EAAE,MAAM,CAAA;IAC9B,OAAO,CAAC,GAAG,CAAyD;gBAExD,EAAE,EAAE,EAAE,CAAC,UAAU,GAAG,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM;IAYvF;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAAA;KAAE,CAAC;IAaxD;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAItD;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAIrD;;;OAGG;IACG,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC;IAqDjF;;OAEG;IACG,OAAO,CAAC,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IAK9F;;OAEG;IACG,SAAS,CAAC,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM;IAQ1D;;OAEG;IACG,kBAAkB,CAAC,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKrF;;OAEG;IACG,YAAY,CAAC,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAQtE;;OAEG;IACG,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAKxE;;;;OAIG;IACG,GAAG,CAAC,iBAAiB,EAAE,QAAQ,EAAE,GAAG,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC;IA6BvE;;OAEG;IACG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE;CAmBxB"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { createBlockFromBytesArray, createBlockHeaderFromBytesArray } from '@feelyourprotocol/block';
|
|
2
|
+
import { RLP } from '@feelyourprotocol/rlp';
|
|
3
|
+
import { EthereumJSErrorWithoutCode, KECCAK256_RLP, KECCAK256_RLP_ARRAY, bytesToBigInt, bytesToHex, equalsBytes, unprefixedHexToBytes, } from '@feelyourprotocol/util';
|
|
4
|
+
import { Cache } from "./cache.js";
|
|
5
|
+
import { DBOp, DBTarget } from "./operation.js";
|
|
6
|
+
/**
|
|
7
|
+
* Abstraction over a DB to facilitate storing/fetching blockchain-related
|
|
8
|
+
* data, such as blocks and headers, indices, and the head block.
|
|
9
|
+
* @hidden
|
|
10
|
+
*/
|
|
11
|
+
export class DBManager {
|
|
12
|
+
constructor(db, common) {
|
|
13
|
+
this._db = db;
|
|
14
|
+
this.common = common;
|
|
15
|
+
this._cache = {
|
|
16
|
+
td: new Cache({ max: 1024 }),
|
|
17
|
+
header: new Cache({ max: 512 }),
|
|
18
|
+
body: new Cache({ max: 256 }),
|
|
19
|
+
numberToHash: new Cache({ max: 2048 }),
|
|
20
|
+
hashToNumber: new Cache({ max: 2048 }),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Fetches iterator heads from the db.
|
|
25
|
+
*/
|
|
26
|
+
async getHeads() {
|
|
27
|
+
const heads = (await this.get(DBTarget.Heads));
|
|
28
|
+
if (heads === undefined)
|
|
29
|
+
return heads;
|
|
30
|
+
const decodedHeads = {};
|
|
31
|
+
for (const key of Object.keys(heads)) {
|
|
32
|
+
// Heads are stored in DB as hex strings since Level converts Uint8Arrays
|
|
33
|
+
// to nested JSON objects when they are included in a value being stored
|
|
34
|
+
// in the DB
|
|
35
|
+
decodedHeads[key] = unprefixedHexToBytes(heads[key]);
|
|
36
|
+
}
|
|
37
|
+
return decodedHeads;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Fetches header of the head block.
|
|
41
|
+
*/
|
|
42
|
+
async getHeadHeader() {
|
|
43
|
+
return this.get(DBTarget.HeadHeader);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Fetches head block.
|
|
47
|
+
*/
|
|
48
|
+
async getHeadBlock() {
|
|
49
|
+
return this.get(DBTarget.HeadBlock);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Fetches a block (header and body) given a block id,
|
|
53
|
+
* which can be either its hash or its number.
|
|
54
|
+
*/
|
|
55
|
+
async getBlock(blockId) {
|
|
56
|
+
if (typeof blockId === 'number' && Number.isInteger(blockId)) {
|
|
57
|
+
blockId = BigInt(blockId);
|
|
58
|
+
}
|
|
59
|
+
let number;
|
|
60
|
+
let hash;
|
|
61
|
+
if (blockId === undefined)
|
|
62
|
+
return undefined;
|
|
63
|
+
if (blockId instanceof Uint8Array) {
|
|
64
|
+
hash = blockId;
|
|
65
|
+
number = await this.hashToNumber(blockId);
|
|
66
|
+
}
|
|
67
|
+
else if (typeof blockId === 'bigint') {
|
|
68
|
+
number = blockId;
|
|
69
|
+
hash = await this.numberToHash(blockId);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
throw EthereumJSErrorWithoutCode('Unknown blockId type');
|
|
73
|
+
}
|
|
74
|
+
if (hash === undefined || number === undefined)
|
|
75
|
+
return undefined;
|
|
76
|
+
const header = await this.getHeader(hash, number);
|
|
77
|
+
let body = await this.getBody(hash, number);
|
|
78
|
+
// be backward compatible where we didn't use to store a body with no txs, uncles, withdrawals
|
|
79
|
+
// otherwise the body is never partially stored and if we have some body, its in entirety
|
|
80
|
+
if (body === undefined) {
|
|
81
|
+
body = [[], []];
|
|
82
|
+
// Do extra validations on the header since we are assuming empty transactions and uncles
|
|
83
|
+
if (!equalsBytes(header.transactionsTrie, KECCAK256_RLP)) {
|
|
84
|
+
throw EthereumJSErrorWithoutCode('transactionsTrie root should be equal to hash of null');
|
|
85
|
+
}
|
|
86
|
+
if (!equalsBytes(header.uncleHash, KECCAK256_RLP_ARRAY)) {
|
|
87
|
+
throw EthereumJSErrorWithoutCode('uncle hash should be equal to hash of empty array');
|
|
88
|
+
}
|
|
89
|
+
// If this block had empty withdrawals push an empty array in body
|
|
90
|
+
if (header.withdrawalsRoot !== undefined) {
|
|
91
|
+
// Do extra validations for withdrawal before assuming empty withdrawals
|
|
92
|
+
if (!equalsBytes(header.withdrawalsRoot, KECCAK256_RLP)) {
|
|
93
|
+
throw EthereumJSErrorWithoutCode('withdrawals root shoot be equal to hash of null when no withdrawals');
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
body.push([]);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const blockData = [header.raw(), ...body];
|
|
101
|
+
const opts = { common: this.common, setHardfork: true };
|
|
102
|
+
return createBlockFromBytesArray(blockData, opts);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Fetches body of a block given its hash and number.
|
|
106
|
+
*/
|
|
107
|
+
async getBody(blockHash, blockNumber) {
|
|
108
|
+
const body = await this.get(DBTarget.Body, { blockHash, blockNumber });
|
|
109
|
+
return body !== undefined ? RLP.decode(body) : undefined;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Fetches header of a block given its hash and number.
|
|
113
|
+
*/
|
|
114
|
+
async getHeader(blockHash, blockNumber) {
|
|
115
|
+
const encodedHeader = await this.get(DBTarget.Header, { blockHash, blockNumber });
|
|
116
|
+
const headerValues = RLP.decode(encodedHeader);
|
|
117
|
+
const opts = { common: this.common, setHardfork: true };
|
|
118
|
+
return createBlockHeaderFromBytesArray(headerValues, opts);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Fetches total difficulty for a block given its hash and number.
|
|
122
|
+
*/
|
|
123
|
+
async getTotalDifficulty(blockHash, blockNumber) {
|
|
124
|
+
const td = await this.get(DBTarget.TotalDifficulty, { blockHash, blockNumber });
|
|
125
|
+
return bytesToBigInt(RLP.decode(td));
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Performs a block hash to block number lookup.
|
|
129
|
+
*/
|
|
130
|
+
async hashToNumber(blockHash) {
|
|
131
|
+
const value = await this.get(DBTarget.HashToNumber, { blockHash });
|
|
132
|
+
if (value === undefined) {
|
|
133
|
+
throw EthereumJSErrorWithoutCode(`value for ${bytesToHex(blockHash)} not found in DB`);
|
|
134
|
+
}
|
|
135
|
+
return value !== undefined ? bytesToBigInt(value) : undefined;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Performs a block number to block hash lookup.
|
|
139
|
+
*/
|
|
140
|
+
async numberToHash(blockNumber) {
|
|
141
|
+
const value = await this.get(DBTarget.NumberToHash, { blockNumber });
|
|
142
|
+
return value;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Fetches a key from the db. If `opts.cache` is specified
|
|
146
|
+
* it first tries to load from cache, and on cache miss will
|
|
147
|
+
* try to put the fetched item on cache afterwards.
|
|
148
|
+
*/
|
|
149
|
+
async get(dbOperationTarget, key) {
|
|
150
|
+
const dbGetOperation = DBOp.get(dbOperationTarget, key);
|
|
151
|
+
const cacheString = dbGetOperation.cacheString;
|
|
152
|
+
const dbKey = dbGetOperation.baseDBOp.key;
|
|
153
|
+
if (cacheString !== undefined) {
|
|
154
|
+
if (this._cache[cacheString] === undefined) {
|
|
155
|
+
throw EthereumJSErrorWithoutCode(`Invalid cache: ${cacheString}`);
|
|
156
|
+
}
|
|
157
|
+
let value = this._cache[cacheString].get(dbKey);
|
|
158
|
+
if (value === undefined) {
|
|
159
|
+
value = (await this._db.get(dbKey, {
|
|
160
|
+
keyEncoding: dbGetOperation.baseDBOp.keyEncoding,
|
|
161
|
+
valueEncoding: dbGetOperation.baseDBOp.valueEncoding,
|
|
162
|
+
}));
|
|
163
|
+
if (value !== undefined) {
|
|
164
|
+
this._cache[cacheString].set(dbKey, value);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return value;
|
|
168
|
+
}
|
|
169
|
+
return this._db.get(dbKey, {
|
|
170
|
+
keyEncoding: dbGetOperation.baseDBOp.keyEncoding,
|
|
171
|
+
valueEncoding: dbGetOperation.baseDBOp.valueEncoding,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Performs a batch operation on db.
|
|
176
|
+
*/
|
|
177
|
+
async batch(ops) {
|
|
178
|
+
const convertedOps = ops.map((op) => {
|
|
179
|
+
const type = op.baseDBOp.type ?? (op.baseDBOp.value !== undefined ? 'put' : 'del');
|
|
180
|
+
const convertedOp = {
|
|
181
|
+
key: op.baseDBOp.key,
|
|
182
|
+
value: op.baseDBOp.value,
|
|
183
|
+
type,
|
|
184
|
+
opts: {
|
|
185
|
+
keyEncoding: op.baseDBOp.keyEncoding,
|
|
186
|
+
valueEncoding: op.baseDBOp.valueEncoding,
|
|
187
|
+
},
|
|
188
|
+
};
|
|
189
|
+
if (type === 'put')
|
|
190
|
+
return convertedOp;
|
|
191
|
+
else
|
|
192
|
+
return convertedOp;
|
|
193
|
+
});
|
|
194
|
+
// update the current cache for each operation
|
|
195
|
+
ops.map((op) => op.updateCache(this._cache));
|
|
196
|
+
return this._db.batch(convertedOps);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../src/db/manager.ts"],"names":[],"mappings":"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"}
|