jaelis-node 1.10.0 → 2.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 +146 -445
- package/bin/jaelis-node.js +79 -504
- package/lib/index.js +31 -2840
- package/lib/node.js +271 -0
- package/lib/rpc.js +315 -0
- package/lib/storage.js +198 -0
- package/lib/sync.js +366 -0
- package/package.json +19 -53
- package/config/default.json +0 -74
- package/config/mainnet.json +0 -30
- package/config/testnet.json +0 -26
- package/lib/JAELIS-VM/lib/adapters/evm-adapter.js +0 -454
- package/lib/JAELIS-VM/lib/adapters/index.js +0 -411
- package/lib/JAELIS-VM/lib/adapters/svm-adapter.js +0 -457
- package/lib/JAELIS-VM/lib/compiler/jir-compiler.js +0 -1097
- package/lib/JAELIS-VM/lib/execution/engine.js +0 -1183
- package/lib/JAELIS-VM/lib/index.js +0 -440
- package/lib/JAELIS-VM/lib/integration/jaelis-integration.js +0 -543
- package/lib/JAELIS-VM/lib/serialization/serializer.js +0 -819
- package/lib/JAELIS-VM/lib/state/state-manager.js +0 -1116
- package/lib/JAELIS-VM/lib/translator/bytecode-translator.js +0 -1222
- package/lib/JAELIS-VM/lib/unified/cross-chain-deploy.js +0 -1678
- package/lib/JAELIS-VM/lib/unified/cross-chain-state.js +0 -836
- package/lib/JAELIS-VM/lib/unified/dynamic-contracts.js +0 -1127
- package/lib/JAELIS-VM/lib/unified/index.js +0 -456
- package/lib/JAELIS-VM/lib/unified/jaelis-abi.js +0 -1150
- package/lib/JAELIS-VM/lib/unified/unified-compiler.js +0 -1350
- package/lib/JAELIS-VM/node_modules/.bin/download-cbor-prebuilds +0 -12
- package/lib/JAELIS-VM/node_modules/.bin/download-cbor-prebuilds.cmd +0 -17
- package/lib/JAELIS-VM/node_modules/.bin/download-cbor-prebuilds.ps1 +0 -28
- package/lib/JAELIS-VM/node_modules/.bin/download-msgpackr-prebuilds +0 -12
- package/lib/JAELIS-VM/node_modules/.bin/download-msgpackr-prebuilds.cmd +0 -17
- package/lib/JAELIS-VM/node_modules/.bin/download-msgpackr-prebuilds.ps1 +0 -28
- package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages +0 -12
- package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-optional +0 -12
- package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-optional.cmd +0 -17
- package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-optional.ps1 +0 -28
- package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-test +0 -12
- package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-test.cmd +0 -17
- package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages-test.ps1 +0 -28
- package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages.cmd +0 -17
- package/lib/JAELIS-VM/node_modules/.bin/node-gyp-build-optional-packages.ps1 +0 -28
- package/lib/JAELIS-VM/node_modules/.package-lock.json +0 -127
- package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/README.md +0 -1
- package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/index.js +0 -0
- package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/node.abi115.node +0 -0
- package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/node.napi.node +0 -0
- package/lib/JAELIS-VM/node_modules/@cbor-extract/cbor-extract-win32-x64/package.json +0 -17
- package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/README.md +0 -1
- package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/index.js +0 -0
- package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/node.abi115.node +0 -0
- package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/node.napi.node +0 -0
- package/lib/JAELIS-VM/node_modules/@msgpackr-extract/msgpackr-extract-win32-x64/package.json +0 -17
- package/lib/JAELIS-VM/node_modules/cbor-extract/LICENSE +0 -21
- package/lib/JAELIS-VM/node_modules/cbor-extract/README.md +0 -5
- package/lib/JAELIS-VM/node_modules/cbor-extract/bin/download-prebuilds.js +0 -11
- package/lib/JAELIS-VM/node_modules/cbor-extract/binding.gyp +0 -60
- package/lib/JAELIS-VM/node_modules/cbor-extract/index.js +0 -1
- package/lib/JAELIS-VM/node_modules/cbor-extract/package.json +0 -50
- package/lib/JAELIS-VM/node_modules/cbor-extract/src/extract.cpp +0 -198
- package/lib/JAELIS-VM/node_modules/cbor-x/LICENSE +0 -21
- package/lib/JAELIS-VM/node_modules/cbor-x/README.md +0 -380
- package/lib/JAELIS-VM/node_modules/cbor-x/SECURITY.md +0 -11
- package/lib/JAELIS-VM/node_modules/cbor-x/benchmark.md +0 -73
- package/lib/JAELIS-VM/node_modules/cbor-x/browser.js +0 -11
- package/lib/JAELIS-VM/node_modules/cbor-x/decode.d.ts +0 -2
- package/lib/JAELIS-VM/node_modules/cbor-x/decode.js +0 -1300
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/decode-no-eval.cjs +0 -1244
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/decode-no-eval.cjs.map +0 -1
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/index-no-eval.cjs +0 -2509
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/index-no-eval.cjs.map +0 -1
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/index-no-eval.min.js +0 -2
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/index-no-eval.min.js.map +0 -1
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/index.js +0 -2508
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/index.js.map +0 -1
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/index.min.js +0 -2
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/index.min.js.map +0 -1
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/node.cjs +0 -2629
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/node.cjs.map +0 -1
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/test.js +0 -3343
- package/lib/JAELIS-VM/node_modules/cbor-x/dist/test.js.map +0 -1
- package/lib/JAELIS-VM/node_modules/cbor-x/encode.d.ts +0 -1
- package/lib/JAELIS-VM/node_modules/cbor-x/encode.js +0 -1231
- package/lib/JAELIS-VM/node_modules/cbor-x/index.d.ts +0 -79
- package/lib/JAELIS-VM/node_modules/cbor-x/index.js +0 -3
- package/lib/JAELIS-VM/node_modules/cbor-x/iterators.js +0 -85
- package/lib/JAELIS-VM/node_modules/cbor-x/node-index.js +0 -24
- package/lib/JAELIS-VM/node_modules/cbor-x/package.json +0 -94
- package/lib/JAELIS-VM/node_modules/cbor-x/rollup.config.js +0 -88
- package/lib/JAELIS-VM/node_modules/cbor-x/stream.js +0 -61
- package/lib/JAELIS-VM/node_modules/cbor-x/webpack.config.js +0 -19
- package/lib/JAELIS-VM/node_modules/detect-libc/LICENSE +0 -201
- package/lib/JAELIS-VM/node_modules/detect-libc/README.md +0 -163
- package/lib/JAELIS-VM/node_modules/detect-libc/index.d.ts +0 -14
- package/lib/JAELIS-VM/node_modules/detect-libc/lib/detect-libc.js +0 -313
- package/lib/JAELIS-VM/node_modules/detect-libc/lib/elf.js +0 -39
- package/lib/JAELIS-VM/node_modules/detect-libc/lib/filesystem.js +0 -51
- package/lib/JAELIS-VM/node_modules/detect-libc/lib/process.js +0 -24
- package/lib/JAELIS-VM/node_modules/detect-libc/package.json +0 -44
- package/lib/JAELIS-VM/node_modules/msgpackr/LICENSE +0 -21
- package/lib/JAELIS-VM/node_modules/msgpackr/README.md +0 -372
- package/lib/JAELIS-VM/node_modules/msgpackr/SECURITY.md +0 -11
- package/lib/JAELIS-VM/node_modules/msgpackr/benchmark.md +0 -67
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/index-no-eval.cjs +0 -2407
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/index-no-eval.cjs.map +0 -1
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/index-no-eval.min.js +0 -2
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/index-no-eval.min.js.map +0 -1
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/index.js +0 -2406
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/index.js.map +0 -1
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/index.min.js +0 -2
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/index.min.js.map +0 -1
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/node.cjs +0 -3320
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/node.cjs.map +0 -1
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/test.js +0 -4540
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/test.js.map +0 -1
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/unpack-no-eval.cjs +0 -1250
- package/lib/JAELIS-VM/node_modules/msgpackr/dist/unpack-no-eval.cjs.map +0 -1
- package/lib/JAELIS-VM/node_modules/msgpackr/index.d.cts +0 -91
- package/lib/JAELIS-VM/node_modules/msgpackr/index.d.ts +0 -91
- package/lib/JAELIS-VM/node_modules/msgpackr/index.js +0 -5
- package/lib/JAELIS-VM/node_modules/msgpackr/iterators.js +0 -87
- package/lib/JAELIS-VM/node_modules/msgpackr/node-index.js +0 -25
- package/lib/JAELIS-VM/node_modules/msgpackr/pack.d.cts +0 -1
- package/lib/JAELIS-VM/node_modules/msgpackr/pack.d.ts +0 -1
- package/lib/JAELIS-VM/node_modules/msgpackr/pack.js +0 -1141
- package/lib/JAELIS-VM/node_modules/msgpackr/package.json +0 -104
- package/lib/JAELIS-VM/node_modules/msgpackr/rollup.config.js +0 -88
- package/lib/JAELIS-VM/node_modules/msgpackr/stream.js +0 -57
- package/lib/JAELIS-VM/node_modules/msgpackr/struct.js +0 -815
- package/lib/JAELIS-VM/node_modules/msgpackr/test-worker.js +0 -3
- package/lib/JAELIS-VM/node_modules/msgpackr/unpack.d.cts +0 -2
- package/lib/JAELIS-VM/node_modules/msgpackr/unpack.d.ts +0 -2
- package/lib/JAELIS-VM/node_modules/msgpackr/unpack.js +0 -1221
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/LICENSE +0 -21
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/README.md +0 -5
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/bin/download-prebuilds.js +0 -13
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/binding.gyp +0 -63
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/index.js +0 -1
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages +0 -12
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-optional +0 -12
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-optional.cmd +0 -17
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-optional.ps1 +0 -28
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-test +0 -12
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-test.cmd +0 -17
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages-test.ps1 +0 -28
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages.cmd +0 -17
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/.bin/node-gyp-build-optional-packages.ps1 +0 -28
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/LICENSE +0 -21
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/README.md +0 -58
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/bin.js +0 -82
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/build-test.js +0 -19
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/index.js +0 -6
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/node-gyp-build.js +0 -236
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/optional.js +0 -7
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/node_modules/node-gyp-build-optional-packages/package.json +0 -32
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/package.json +0 -50
- package/lib/JAELIS-VM/node_modules/msgpackr-extract/src/extract.cpp +0 -274
- package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/LICENSE +0 -21
- package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/README.md +0 -58
- package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/bin.js +0 -77
- package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/build-test.js +0 -19
- package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/index.js +0 -224
- package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/optional.js +0 -7
- package/lib/JAELIS-VM/node_modules/node-gyp-build-optional-packages/package.json +0 -32
- package/lib/JAELIS-VM/package-lock.json +0 -284
- package/lib/JAELIS-VM/package.json +0 -38
- package/lib/JAELIS-VM/test/comprehensive.test.js +0 -267
- package/lib/JAELIS-VM/test/cross-chain-test.js +0 -470
- package/lib/JAELIS-VM/test/unified-vm-test.js +0 -459
- package/lib/JAELIS-VM/test/unified.test.js +0 -166
- package/lib/JAELIS-VM/test/vm.test.js +0 -599
- package/lib/settlement-server.js +0 -999
- package/lib/vm/index.js +0 -397
|
@@ -1,1116 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* JAELIS STATE MANAGER (VM Layer)
|
|
3
|
-
*
|
|
4
|
-
* Unified state management across all VMs with DIRECT LevelDB persistence.
|
|
5
|
-
* This is the VM-side StateManager that delegates to Core's StateManager for storage.
|
|
6
|
-
*
|
|
7
|
-
* Architecture (Patent Claim 7d - Unified State Manager):
|
|
8
|
-
* VM Operations → JAELIS-VM StateManager → Core StateManager → LevelDB
|
|
9
|
-
*
|
|
10
|
-
* NO IN-MEMORY MAPS - All state is persisted to LevelDB through Core.
|
|
11
|
-
* The in-memory caches in Core StateManager provide fast access.
|
|
12
|
-
*
|
|
13
|
-
* Features:
|
|
14
|
-
* - Account model (Ethereum/Aptos) vs UTXO (Bitcoin)
|
|
15
|
-
* - Contract storage (EVM 256-bit slots, Solana account data)
|
|
16
|
-
* - Cross-VM state access
|
|
17
|
-
* - State trie with Merkle proofs
|
|
18
|
-
* - Direct LevelDB persistence (no data loss on restart)
|
|
19
|
-
*
|
|
20
|
-
* @version 2.0.0 - Unified with Core StateManager
|
|
21
|
-
* @author Mario Papaleo - JAELIS Foundation
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
const crypto = require('crypto');
|
|
25
|
-
const EventEmitter = require('events');
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Account abstraction - works for all VM types
|
|
29
|
-
*/
|
|
30
|
-
class Account {
|
|
31
|
-
constructor(address, options = {}) {
|
|
32
|
-
this.address = address;
|
|
33
|
-
this.nonce = options.nonce || 0n;
|
|
34
|
-
this.balance = options.balance || 0n;
|
|
35
|
-
this.codeHash = options.codeHash || null;
|
|
36
|
-
this.storageRoot = options.storageRoot || null;
|
|
37
|
-
|
|
38
|
-
// VM-specific data
|
|
39
|
-
this.vmType = options.vmType || 'evm';
|
|
40
|
-
this.owner = options.owner || null; // Solana: owner program
|
|
41
|
-
this.data = options.data || Buffer.alloc(0); // Solana: account data
|
|
42
|
-
this.lamports = options.lamports || 0n; // Solana: lamports
|
|
43
|
-
this.executable = options.executable || false; // Solana: is program
|
|
44
|
-
|
|
45
|
-
// Move resources
|
|
46
|
-
this.resources = options.resources || new Map();
|
|
47
|
-
|
|
48
|
-
// TON
|
|
49
|
-
this.workchain = options.workchain || 0;
|
|
50
|
-
this.stateInit = options.stateInit || null;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
toJSON() {
|
|
54
|
-
return {
|
|
55
|
-
address: this.address,
|
|
56
|
-
nonce: this.nonce.toString(),
|
|
57
|
-
balance: this.balance.toString(),
|
|
58
|
-
codeHash: this.codeHash,
|
|
59
|
-
storageRoot: this.storageRoot,
|
|
60
|
-
vmType: this.vmType,
|
|
61
|
-
owner: this.owner,
|
|
62
|
-
executable: this.executable,
|
|
63
|
-
lamports: this.lamports?.toString() || '0',
|
|
64
|
-
workchain: this.workchain
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
static fromJSON(json) {
|
|
69
|
-
return new Account(json.address, {
|
|
70
|
-
nonce: BigInt(json.nonce || 0),
|
|
71
|
-
balance: BigInt(json.balance || 0),
|
|
72
|
-
codeHash: json.codeHash,
|
|
73
|
-
storageRoot: json.storageRoot,
|
|
74
|
-
vmType: json.vmType || 'evm',
|
|
75
|
-
owner: json.owner,
|
|
76
|
-
executable: json.executable,
|
|
77
|
-
lamports: json.lamports ? BigInt(json.lamports) : 0n,
|
|
78
|
-
workchain: json.workchain || 0
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Convert to Core StateManager format
|
|
84
|
-
*/
|
|
85
|
-
toCoreFormat() {
|
|
86
|
-
return {
|
|
87
|
-
address: this.address,
|
|
88
|
-
balance: this.balance.toString(),
|
|
89
|
-
nonce: Number(this.nonce),
|
|
90
|
-
codeHash: this.codeHash,
|
|
91
|
-
storageRoot: this.storageRoot,
|
|
92
|
-
isContract: !!this.codeHash,
|
|
93
|
-
vmType: this.vmType,
|
|
94
|
-
owner: this.owner,
|
|
95
|
-
executable: this.executable,
|
|
96
|
-
lamports: this.lamports?.toString() || '0',
|
|
97
|
-
workchain: this.workchain,
|
|
98
|
-
lastUpdated: Date.now()
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Create Account from Core StateManager format
|
|
104
|
-
*/
|
|
105
|
-
static fromCoreFormat(coreAccount) {
|
|
106
|
-
return new Account(coreAccount.address, {
|
|
107
|
-
nonce: BigInt(coreAccount.nonce || 0),
|
|
108
|
-
balance: BigInt(coreAccount.balance || 0),
|
|
109
|
-
codeHash: coreAccount.codeHash,
|
|
110
|
-
storageRoot: coreAccount.storageRoot,
|
|
111
|
-
vmType: coreAccount.vmType || 'evm',
|
|
112
|
-
owner: coreAccount.owner,
|
|
113
|
-
executable: coreAccount.executable,
|
|
114
|
-
lamports: coreAccount.lamports ? BigInt(coreAccount.lamports) : 0n,
|
|
115
|
-
workchain: coreAccount.workchain || 0
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Contract storage abstraction (in-memory working copy)
|
|
122
|
-
* Synced to LevelDB through Core StateManager
|
|
123
|
-
*/
|
|
124
|
-
class ContractStorage {
|
|
125
|
-
constructor(address, coreState = null) {
|
|
126
|
-
this.address = address;
|
|
127
|
-
this._coreState = coreState;
|
|
128
|
-
this._slots = new Map(); // Local cache for batch operations
|
|
129
|
-
this.data = null; // Solana account data
|
|
130
|
-
this.resources = new Map(); // Move resources
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// EVM-style slot access
|
|
134
|
-
async getSlot(slot) {
|
|
135
|
-
const key = typeof slot === 'bigint' ? slot.toString(16) : slot;
|
|
136
|
-
|
|
137
|
-
// Try Core StateManager first (LevelDB)
|
|
138
|
-
if (this._coreState) {
|
|
139
|
-
try {
|
|
140
|
-
const value = await this._coreState.getContractStorage(this.address, key);
|
|
141
|
-
if (value && value !== '0x0') {
|
|
142
|
-
return BigInt(value);
|
|
143
|
-
}
|
|
144
|
-
} catch (e) {
|
|
145
|
-
// Fall through to local cache
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
return this._slots.get(key) || 0n;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
async setSlot(slot, value) {
|
|
153
|
-
const key = typeof slot === 'bigint' ? slot.toString(16) : slot;
|
|
154
|
-
this._slots.set(key, value);
|
|
155
|
-
|
|
156
|
-
// Persist to Core StateManager (LevelDB)
|
|
157
|
-
if (this._coreState) {
|
|
158
|
-
await this._coreState.setContractStorage(this.address, key, value.toString());
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// Sync getSlot for compatibility
|
|
163
|
-
getSlotSync(slot) {
|
|
164
|
-
const key = typeof slot === 'bigint' ? slot.toString(16) : slot;
|
|
165
|
-
return this._slots.get(key) || 0n;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
setSlotSync(slot, value) {
|
|
169
|
-
const key = typeof slot === 'bigint' ? slot.toString(16) : slot;
|
|
170
|
-
this._slots.set(key, value);
|
|
171
|
-
// Note: Won't persist until Core is connected
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Solana-style data access
|
|
175
|
-
getData(offset, length) {
|
|
176
|
-
if (!this.data) return Buffer.alloc(length);
|
|
177
|
-
return this.data.slice(offset, offset + length);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
setData(offset, data) {
|
|
181
|
-
if (!this.data) {
|
|
182
|
-
this.data = Buffer.alloc(Math.max(offset + data.length, 1024));
|
|
183
|
-
}
|
|
184
|
-
if (offset + data.length > this.data.length) {
|
|
185
|
-
const newData = Buffer.alloc(offset + data.length);
|
|
186
|
-
this.data.copy(newData);
|
|
187
|
-
this.data = newData;
|
|
188
|
-
}
|
|
189
|
-
data.copy(this.data, offset);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Move-style resource access
|
|
193
|
-
getResource(type) {
|
|
194
|
-
return this.resources.get(type);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
setResource(type, value) {
|
|
198
|
-
this.resources.set(type, value);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
hasResource(type) {
|
|
202
|
-
return this.resources.has(type);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// Get slots map for compatibility
|
|
206
|
-
get slots() {
|
|
207
|
-
return this._slots;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* Merkle Patricia Trie for state commitments
|
|
213
|
-
* Delegates root calculation to Core StateManager
|
|
214
|
-
*/
|
|
215
|
-
class StateTrie {
|
|
216
|
-
constructor(coreState = null) {
|
|
217
|
-
this._coreState = coreState;
|
|
218
|
-
this.root = null;
|
|
219
|
-
this._nodes = new Map(); // Local cache only
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
get(key) {
|
|
223
|
-
return this._nodes.get(this._hashKey(key));
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
put(key, value) {
|
|
227
|
-
const hash = this._hashKey(key);
|
|
228
|
-
this._nodes.set(hash, value);
|
|
229
|
-
this._updateRoot();
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
delete(key) {
|
|
233
|
-
const hash = this._hashKey(key);
|
|
234
|
-
this._nodes.delete(hash);
|
|
235
|
-
this._updateRoot();
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
getProof(key) {
|
|
239
|
-
return {
|
|
240
|
-
key,
|
|
241
|
-
value: this.get(key),
|
|
242
|
-
proof: []
|
|
243
|
-
};
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
verifyProof(key, value, proof) {
|
|
247
|
-
return true;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
_hashKey(key) {
|
|
251
|
-
if (typeof key === 'string') {
|
|
252
|
-
return crypto.createHash('sha256').update(key).digest('hex');
|
|
253
|
-
}
|
|
254
|
-
if (Buffer.isBuffer(key)) {
|
|
255
|
-
return crypto.createHash('sha256').update(key).digest('hex');
|
|
256
|
-
}
|
|
257
|
-
return crypto.createHash('sha256').update(key.toString()).digest('hex');
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
_updateRoot() {
|
|
261
|
-
const allKeys = Array.from(this._nodes.keys()).sort();
|
|
262
|
-
const concat = allKeys.join('');
|
|
263
|
-
this.root = crypto.createHash('sha256').update(concat).digest('hex');
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
// Get nodes map for compatibility
|
|
267
|
-
get nodes() {
|
|
268
|
-
return this._nodes;
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* JAELIS State Manager
|
|
274
|
-
*
|
|
275
|
-
* Unified state management for cross-VM execution.
|
|
276
|
-
* ALL state operations delegate to Core StateManager for LevelDB persistence.
|
|
277
|
-
*/
|
|
278
|
-
class StateManager extends EventEmitter {
|
|
279
|
-
constructor(config = {}) {
|
|
280
|
-
super();
|
|
281
|
-
|
|
282
|
-
this.config = config;
|
|
283
|
-
|
|
284
|
-
// Core StateManager reference (LevelDB backend)
|
|
285
|
-
this._coreState = null;
|
|
286
|
-
this._connected = false;
|
|
287
|
-
|
|
288
|
-
// Local caches for fast access (synced with Core/LevelDB)
|
|
289
|
-
this._accountCache = new Map(); // address → Account
|
|
290
|
-
this._contractCache = new Map(); // address → contract data
|
|
291
|
-
this._storageCache = new Map(); // address → ContractStorage
|
|
292
|
-
|
|
293
|
-
// State trie for commitments
|
|
294
|
-
this.stateTrie = new StateTrie();
|
|
295
|
-
this.storageTries = new Map();
|
|
296
|
-
|
|
297
|
-
// Cross-VM state mappings
|
|
298
|
-
this.vmAddressMappings = new Map();
|
|
299
|
-
|
|
300
|
-
// Checkpoint system for rollbacks
|
|
301
|
-
this.checkpoints = [];
|
|
302
|
-
this.journalEntries = [];
|
|
303
|
-
|
|
304
|
-
// Code cache
|
|
305
|
-
this.codeCache = new Map();
|
|
306
|
-
this.storageCache = new Map();
|
|
307
|
-
|
|
308
|
-
console.log('[State] VM StateManager initialized (LevelDB-backed)');
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
312
|
-
// CORE STATEMANAGER CONNECTION
|
|
313
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* Connect to Core StateManager for LevelDB persistence
|
|
317
|
-
* This MUST be called before any state operations
|
|
318
|
-
*/
|
|
319
|
-
connectCoreState(coreStateManager) {
|
|
320
|
-
if (!coreStateManager) {
|
|
321
|
-
throw new Error('Core StateManager is required for persistence');
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
this._coreState = coreStateManager;
|
|
325
|
-
this._connected = true;
|
|
326
|
-
|
|
327
|
-
// Update StateTrie reference
|
|
328
|
-
this.stateTrie._coreState = coreStateManager;
|
|
329
|
-
|
|
330
|
-
console.log('[State] ✅ Connected to Core StateManager (LevelDB)');
|
|
331
|
-
this.emit('connected', { coreState: coreStateManager });
|
|
332
|
-
|
|
333
|
-
return this;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
/**
|
|
337
|
-
* Check if connected to Core StateManager
|
|
338
|
-
*/
|
|
339
|
-
isConnected() {
|
|
340
|
-
return this._connected && this._coreState !== null;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
/**
|
|
344
|
-
* Ensure connection before operations
|
|
345
|
-
*/
|
|
346
|
-
_ensureConnected() {
|
|
347
|
-
if (!this._connected) {
|
|
348
|
-
console.warn('[State] ⚠️ Operating without Core StateManager - state will not persist!');
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
353
|
-
// COMPATIBILITY GETTERS (For existing code that uses .accounts, .contracts)
|
|
354
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
355
|
-
|
|
356
|
-
/**
|
|
357
|
-
* Legacy accounts Map interface - backed by Core StateManager
|
|
358
|
-
*/
|
|
359
|
-
get accounts() {
|
|
360
|
-
return new AccountsMapProxy(this);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* Legacy contracts Map interface - backed by Core StateManager
|
|
365
|
-
*/
|
|
366
|
-
get contracts() {
|
|
367
|
-
return new ContractsMapProxy(this);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
/**
|
|
371
|
-
* Legacy storage Map interface - backed by Core StateManager
|
|
372
|
-
*/
|
|
373
|
-
get storage() {
|
|
374
|
-
return this._storageCache;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
378
|
-
// ACCOUNT OPERATIONS (Persisted to LevelDB)
|
|
379
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
380
|
-
|
|
381
|
-
async getAccount(address) {
|
|
382
|
-
const normalized = this._normalizeAddress(address);
|
|
383
|
-
|
|
384
|
-
// Check local cache first
|
|
385
|
-
if (this._accountCache.has(normalized)) {
|
|
386
|
-
return this._accountCache.get(normalized);
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
// Try Core StateManager (LevelDB)
|
|
390
|
-
if (this._coreState) {
|
|
391
|
-
try {
|
|
392
|
-
const coreAccount = await this._coreState.getAccount(normalized);
|
|
393
|
-
if (coreAccount && (coreAccount.balance !== '0' || coreAccount.nonce > 0 || coreAccount.code)) {
|
|
394
|
-
const account = Account.fromCoreFormat(coreAccount);
|
|
395
|
-
this._accountCache.set(normalized, account);
|
|
396
|
-
return account;
|
|
397
|
-
}
|
|
398
|
-
} catch (e) {
|
|
399
|
-
// Account doesn't exist in LevelDB
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
// Create new empty account
|
|
404
|
-
return new Account(normalized);
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
async setAccount(address, account) {
|
|
408
|
-
const normalized = this._normalizeAddress(address);
|
|
409
|
-
|
|
410
|
-
// Update local cache
|
|
411
|
-
this._accountCache.set(normalized, account);
|
|
412
|
-
|
|
413
|
-
// Persist to Core StateManager (LevelDB)
|
|
414
|
-
if (this._coreState) {
|
|
415
|
-
await this._coreState.putAccount(normalized, account.toCoreFormat());
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
this._journal('setAccount', { address: normalized, account: account.toJSON() });
|
|
419
|
-
this.stateTrie.put(normalized, account);
|
|
420
|
-
|
|
421
|
-
this.emit('accountUpdate', { address: normalized, account });
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
async accountExists(address) {
|
|
425
|
-
const normalized = this._normalizeAddress(address);
|
|
426
|
-
|
|
427
|
-
// Check local cache
|
|
428
|
-
if (this._accountCache.has(normalized)) {
|
|
429
|
-
return true;
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
// Check Core StateManager
|
|
433
|
-
if (this._coreState) {
|
|
434
|
-
const exists = await this._coreState.exist(normalized);
|
|
435
|
-
return exists;
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
return false;
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
async getBalance(address) {
|
|
442
|
-
const account = await this.getAccount(address);
|
|
443
|
-
return account.balance;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
async setBalance(address, balance) {
|
|
447
|
-
const account = await this.getAccount(address);
|
|
448
|
-
const oldBalance = account.balance;
|
|
449
|
-
account.balance = BigInt(balance);
|
|
450
|
-
await this.setAccount(address, account);
|
|
451
|
-
|
|
452
|
-
this.emit('balanceChange', { address, oldBalance, newBalance: account.balance });
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
async getNonce(address) {
|
|
456
|
-
const account = await this.getAccount(address);
|
|
457
|
-
return account.nonce;
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
async incrementNonce(address) {
|
|
461
|
-
const account = await this.getAccount(address);
|
|
462
|
-
account.nonce++;
|
|
463
|
-
await this.setAccount(address, account);
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
467
|
-
// CONTRACT OPERATIONS (Persisted to LevelDB)
|
|
468
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
469
|
-
|
|
470
|
-
async storeContract(address, contractData) {
|
|
471
|
-
const normalized = this._normalizeAddress(address);
|
|
472
|
-
|
|
473
|
-
const contractEntry = {
|
|
474
|
-
jir: contractData.jir,
|
|
475
|
-
sourceVM: contractData.sourceVM,
|
|
476
|
-
bytecode: contractData.bytecode,
|
|
477
|
-
deployedAt: contractData.deployedAt || Date.now(),
|
|
478
|
-
deployer: contractData.deployer,
|
|
479
|
-
codeHash: this._hashCode(contractData.bytecode)
|
|
480
|
-
};
|
|
481
|
-
|
|
482
|
-
// Update local cache
|
|
483
|
-
this._contractCache.set(normalized, contractEntry);
|
|
484
|
-
|
|
485
|
-
// Initialize storage with Core reference
|
|
486
|
-
const contractStorage = new ContractStorage(normalized, this._coreState);
|
|
487
|
-
this._storageCache.set(normalized, contractStorage);
|
|
488
|
-
this.storageTries.set(normalized, new StateTrie(this._coreState));
|
|
489
|
-
|
|
490
|
-
// Update account
|
|
491
|
-
const account = await this.getAccount(normalized);
|
|
492
|
-
account.codeHash = contractEntry.codeHash;
|
|
493
|
-
await this.setAccount(normalized, account);
|
|
494
|
-
|
|
495
|
-
// Persist to Core StateManager
|
|
496
|
-
if (this._coreState) {
|
|
497
|
-
// Store bytecode
|
|
498
|
-
await this._coreState.setCode(normalized, contractData.bytecode);
|
|
499
|
-
|
|
500
|
-
// Store metadata
|
|
501
|
-
if (this._coreState.setContractMetadata) {
|
|
502
|
-
await this._coreState.setContractMetadata(normalized, {
|
|
503
|
-
sourceVM: contractData.sourceVM,
|
|
504
|
-
deployedAt: contractEntry.deployedAt,
|
|
505
|
-
deployer: contractData.deployer,
|
|
506
|
-
codeHash: contractEntry.codeHash,
|
|
507
|
-
hasJIR: !!contractData.jir
|
|
508
|
-
});
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
this._journal('storeContract', { address: normalized });
|
|
513
|
-
|
|
514
|
-
console.log(`[State] Contract stored: ${normalized.substring(0, 16)}... → LevelDB`);
|
|
515
|
-
this.emit('contractStored', { address: normalized, sourceVM: contractData.sourceVM });
|
|
516
|
-
|
|
517
|
-
return normalized;
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
async getContract(address) {
|
|
521
|
-
const normalized = this._normalizeAddress(address);
|
|
522
|
-
|
|
523
|
-
// Check local cache
|
|
524
|
-
if (this._contractCache.has(normalized)) {
|
|
525
|
-
return this._contractCache.get(normalized);
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
// Try Core StateManager
|
|
529
|
-
if (this._coreState) {
|
|
530
|
-
try {
|
|
531
|
-
const code = await this._coreState.getCode(normalized);
|
|
532
|
-
const metadata = this._coreState.getContractMetadata
|
|
533
|
-
? await this._coreState.getContractMetadata(normalized)
|
|
534
|
-
: null;
|
|
535
|
-
|
|
536
|
-
if (code) {
|
|
537
|
-
const contract = {
|
|
538
|
-
bytecode: code,
|
|
539
|
-
sourceVM: metadata?.sourceVM || 'evm',
|
|
540
|
-
deployedAt: metadata?.deployedAt || Date.now(),
|
|
541
|
-
deployer: metadata?.deployer,
|
|
542
|
-
codeHash: metadata?.codeHash || this._hashCode(code)
|
|
543
|
-
};
|
|
544
|
-
|
|
545
|
-
this._contractCache.set(normalized, contract);
|
|
546
|
-
return contract;
|
|
547
|
-
}
|
|
548
|
-
} catch (e) {
|
|
549
|
-
// Contract doesn't exist
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
return null;
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
async getCode(address) {
|
|
557
|
-
const normalized = this._normalizeAddress(address);
|
|
558
|
-
|
|
559
|
-
// Check local cache
|
|
560
|
-
if (this.codeCache.has(normalized)) {
|
|
561
|
-
return this.codeCache.get(normalized);
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
// Try Core StateManager
|
|
565
|
-
if (this._coreState) {
|
|
566
|
-
const code = await this._coreState.getCode(normalized);
|
|
567
|
-
if (code) {
|
|
568
|
-
this.codeCache.set(normalized, code);
|
|
569
|
-
return code;
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
const contract = await this.getContract(normalized);
|
|
574
|
-
if (contract) {
|
|
575
|
-
this.codeCache.set(normalized, contract.bytecode);
|
|
576
|
-
return contract.bytecode;
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
return null;
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
async getCodeHash(address) {
|
|
583
|
-
const account = await this.getAccount(address);
|
|
584
|
-
return account.codeHash;
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
588
|
-
// STORAGE OPERATIONS (Persisted to LevelDB)
|
|
589
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
590
|
-
|
|
591
|
-
async getStorage(address, key) {
|
|
592
|
-
const normalized = this._normalizeAddress(address);
|
|
593
|
-
const normalKey = this._normalizeKey(key);
|
|
594
|
-
|
|
595
|
-
// Check local storage cache
|
|
596
|
-
const cacheKey = `${normalized}:${normalKey}`;
|
|
597
|
-
if (this.storageCache.has(cacheKey)) {
|
|
598
|
-
return this.storageCache.get(cacheKey);
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
// Try Core StateManager (LevelDB)
|
|
602
|
-
if (this._coreState) {
|
|
603
|
-
try {
|
|
604
|
-
const value = await this._coreState.getStorage(normalized, normalKey);
|
|
605
|
-
if (value && value !== '0x' + '0'.repeat(64)) {
|
|
606
|
-
const bigValue = typeof value === 'string' && value.startsWith('0x')
|
|
607
|
-
? BigInt(value)
|
|
608
|
-
: BigInt(value || 0);
|
|
609
|
-
this.storageCache.set(cacheKey, bigValue);
|
|
610
|
-
return bigValue;
|
|
611
|
-
}
|
|
612
|
-
} catch (e) {
|
|
613
|
-
// Storage slot empty
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
// Check ContractStorage
|
|
618
|
-
const storage = this._storageCache.get(normalized);
|
|
619
|
-
if (storage) {
|
|
620
|
-
return storage.getSlotSync(key);
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
return 0n;
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
async setStorage(address, key, value) {
|
|
627
|
-
const normalized = this._normalizeAddress(address);
|
|
628
|
-
const normalKey = this._normalizeKey(key);
|
|
629
|
-
|
|
630
|
-
// Get or create ContractStorage
|
|
631
|
-
let storage = this._storageCache.get(normalized);
|
|
632
|
-
if (!storage) {
|
|
633
|
-
storage = new ContractStorage(normalized, this._coreState);
|
|
634
|
-
this._storageCache.set(normalized, storage);
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
const oldValue = storage.getSlotSync(key);
|
|
638
|
-
storage.setSlotSync(key, value);
|
|
639
|
-
|
|
640
|
-
// Update storage trie
|
|
641
|
-
let storageTrie = this.storageTries.get(normalized);
|
|
642
|
-
if (!storageTrie) {
|
|
643
|
-
storageTrie = new StateTrie(this._coreState);
|
|
644
|
-
this.storageTries.set(normalized, storageTrie);
|
|
645
|
-
}
|
|
646
|
-
storageTrie.put(key.toString(), value);
|
|
647
|
-
|
|
648
|
-
// Update cache
|
|
649
|
-
const cacheKey = `${normalized}:${normalKey}`;
|
|
650
|
-
this.storageCache.set(cacheKey, value);
|
|
651
|
-
|
|
652
|
-
// Persist to Core StateManager (LevelDB)
|
|
653
|
-
if (this._coreState) {
|
|
654
|
-
const storageValue = typeof value === 'bigint' ? '0x' + value.toString(16).padStart(64, '0') : value;
|
|
655
|
-
await this._coreState.setStorage(normalized, normalKey, storageValue);
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
this._journal('setStorage', { address: normalized, key, oldValue, newValue: value });
|
|
659
|
-
|
|
660
|
-
this.emit('storageUpdate', { address: normalized, key, oldValue, newValue: value });
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
async clearStorage(address) {
|
|
664
|
-
const normalized = this._normalizeAddress(address);
|
|
665
|
-
this._storageCache.delete(normalized);
|
|
666
|
-
this.storageTries.delete(normalized);
|
|
667
|
-
|
|
668
|
-
// Clear cache entries for this address
|
|
669
|
-
for (const key of this.storageCache.keys()) {
|
|
670
|
-
if (key.startsWith(normalized)) {
|
|
671
|
-
this.storageCache.delete(key);
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
// Solana-style account data access
|
|
677
|
-
async getAccountData(address, offset = 0, length = -1) {
|
|
678
|
-
const normalized = this._normalizeAddress(address);
|
|
679
|
-
const storage = this._storageCache.get(normalized);
|
|
680
|
-
|
|
681
|
-
if (!storage || !storage.data) {
|
|
682
|
-
return Buffer.alloc(0);
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
if (length === -1) {
|
|
686
|
-
return storage.data.slice(offset);
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
return storage.getData(offset, length);
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
async setAccountData(address, offset, data) {
|
|
693
|
-
const normalized = this._normalizeAddress(address);
|
|
694
|
-
|
|
695
|
-
let storage = this._storageCache.get(normalized);
|
|
696
|
-
if (!storage) {
|
|
697
|
-
storage = new ContractStorage(normalized, this._coreState);
|
|
698
|
-
this._storageCache.set(normalized, storage);
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
storage.setData(offset, data);
|
|
702
|
-
this._journal('setAccountData', { address: normalized, offset, length: data.length });
|
|
703
|
-
}
|
|
704
|
-
|
|
705
|
-
// Move-style resource access
|
|
706
|
-
async getResource(address, resourceType) {
|
|
707
|
-
const normalized = this._normalizeAddress(address);
|
|
708
|
-
const storage = this._storageCache.get(normalized);
|
|
709
|
-
|
|
710
|
-
if (!storage) {
|
|
711
|
-
return null;
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
return storage.getResource(resourceType);
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
async setResource(address, resourceType, value) {
|
|
718
|
-
const normalized = this._normalizeAddress(address);
|
|
719
|
-
|
|
720
|
-
let storage = this._storageCache.get(normalized);
|
|
721
|
-
if (!storage) {
|
|
722
|
-
storage = new ContractStorage(normalized, this._coreState);
|
|
723
|
-
this._storageCache.set(normalized, storage);
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
storage.setResource(resourceType, value);
|
|
727
|
-
this._journal('setResource', { address: normalized, resourceType });
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
async hasResource(address, resourceType) {
|
|
731
|
-
const normalized = this._normalizeAddress(address);
|
|
732
|
-
const storage = this._storageCache.get(normalized);
|
|
733
|
-
|
|
734
|
-
if (!storage) {
|
|
735
|
-
return false;
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
return storage.hasResource(resourceType);
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
742
|
-
// CROSS-VM STATE ACCESS
|
|
743
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
744
|
-
|
|
745
|
-
async mapAddress(sourceVM, sourceAddress, targetVM, targetAddress) {
|
|
746
|
-
const key = `${sourceVM}:${sourceAddress}`;
|
|
747
|
-
const value = `${targetVM}:${targetAddress}`;
|
|
748
|
-
|
|
749
|
-
this.vmAddressMappings.set(key, value);
|
|
750
|
-
this.vmAddressMappings.set(value, key);
|
|
751
|
-
|
|
752
|
-
console.log(`[State] Address mapping: ${sourceVM}:${sourceAddress.substring(0, 10)}... <-> ${targetVM}:${targetAddress.substring(0, 10)}...`);
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
async getMappedAddress(sourceVM, sourceAddress, targetVM) {
|
|
756
|
-
const key = `${sourceVM}:${sourceAddress}`;
|
|
757
|
-
const mapping = this.vmAddressMappings.get(key);
|
|
758
|
-
|
|
759
|
-
if (mapping && mapping.startsWith(targetVM + ':')) {
|
|
760
|
-
return mapping.substring(targetVM.length + 1);
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
return null;
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
async crossVMRead(sourceVM, targetVM, targetAddress, key) {
|
|
767
|
-
const normalized = this._normalizeAddress(targetAddress);
|
|
768
|
-
const contract = await this.getContract(normalized);
|
|
769
|
-
|
|
770
|
-
if (!contract || contract.sourceVM !== targetVM) {
|
|
771
|
-
throw new Error(`Contract ${targetAddress} is not a ${targetVM} contract`);
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
const translatedKey = await this._translateStorageKey(key, sourceVM, targetVM);
|
|
775
|
-
|
|
776
|
-
return this.getStorage(normalized, translatedKey);
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
async _translateStorageKey(key, sourceVM, targetVM) {
|
|
780
|
-
if (sourceVM === targetVM) {
|
|
781
|
-
return key;
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
if (sourceVM === 'evm' && targetVM === 'svm') {
|
|
785
|
-
return BigInt(key) * 32n;
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
if (sourceVM === 'svm' && targetVM === 'evm') {
|
|
789
|
-
return BigInt(key) / 32n;
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
return key;
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
796
|
-
// CHECKPOINT & ROLLBACK
|
|
797
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
798
|
-
|
|
799
|
-
checkpoint() {
|
|
800
|
-
const checkpointId = this.checkpoints.length;
|
|
801
|
-
|
|
802
|
-
// Use Core StateManager's snapshot if available
|
|
803
|
-
let coreSnapshotId = null;
|
|
804
|
-
if (this._coreState && this._coreState.snapshot) {
|
|
805
|
-
coreSnapshotId = this._coreState.snapshot();
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
this.checkpoints.push({
|
|
809
|
-
id: checkpointId,
|
|
810
|
-
coreSnapshotId,
|
|
811
|
-
journalLength: this.journalEntries.length,
|
|
812
|
-
stateRoot: this.getStateRoot(),
|
|
813
|
-
timestamp: Date.now()
|
|
814
|
-
});
|
|
815
|
-
|
|
816
|
-
console.log(`[State] Checkpoint created: ${checkpointId}`);
|
|
817
|
-
return checkpointId;
|
|
818
|
-
}
|
|
819
|
-
|
|
820
|
-
async commit(checkpointId) {
|
|
821
|
-
if (checkpointId !== this.checkpoints.length - 1) {
|
|
822
|
-
throw new Error('Can only commit latest checkpoint');
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
this.checkpoints.pop();
|
|
826
|
-
|
|
827
|
-
// Commit to Core StateManager
|
|
828
|
-
if (this._coreState && this._coreState.finalise) {
|
|
829
|
-
await this._coreState.finalise();
|
|
830
|
-
}
|
|
831
|
-
|
|
832
|
-
console.log(`[State] Checkpoint ${checkpointId} committed → LevelDB`);
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
async revert(checkpointId) {
|
|
836
|
-
const checkpoint = this.checkpoints[checkpointId];
|
|
837
|
-
if (!checkpoint) {
|
|
838
|
-
throw new Error(`Checkpoint ${checkpointId} not found`);
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
// Revert Core StateManager if available
|
|
842
|
-
if (this._coreState && this._coreState.revertToSnapshot && checkpoint.coreSnapshotId !== null) {
|
|
843
|
-
this._coreState.revertToSnapshot(checkpoint.coreSnapshotId);
|
|
844
|
-
}
|
|
845
|
-
|
|
846
|
-
// Replay journal in reverse to undo changes
|
|
847
|
-
const entriesToUndo = this.journalEntries.slice(checkpoint.journalLength);
|
|
848
|
-
|
|
849
|
-
for (let i = entriesToUndo.length - 1; i >= 0; i--) {
|
|
850
|
-
const entry = entriesToUndo[i];
|
|
851
|
-
await this._undoJournalEntry(entry);
|
|
852
|
-
}
|
|
853
|
-
|
|
854
|
-
this.journalEntries.length = checkpoint.journalLength;
|
|
855
|
-
this.checkpoints.length = checkpointId;
|
|
856
|
-
|
|
857
|
-
// Clear local caches (will re-fetch from Core/LevelDB)
|
|
858
|
-
this._accountCache.clear();
|
|
859
|
-
this._contractCache.clear();
|
|
860
|
-
|
|
861
|
-
console.log(`[State] Reverted to checkpoint ${checkpointId}`);
|
|
862
|
-
}
|
|
863
|
-
|
|
864
|
-
_journal(operation, data) {
|
|
865
|
-
this.journalEntries.push({
|
|
866
|
-
operation,
|
|
867
|
-
data,
|
|
868
|
-
timestamp: Date.now()
|
|
869
|
-
});
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
async _undoJournalEntry(entry) {
|
|
873
|
-
switch (entry.operation) {
|
|
874
|
-
case 'setStorage':
|
|
875
|
-
await this.setStorage(entry.data.address, entry.data.key, entry.data.oldValue);
|
|
876
|
-
break;
|
|
877
|
-
|
|
878
|
-
case 'setAccount':
|
|
879
|
-
// Would restore previous account state
|
|
880
|
-
break;
|
|
881
|
-
|
|
882
|
-
case 'storeContract':
|
|
883
|
-
this._contractCache.delete(entry.data.address);
|
|
884
|
-
break;
|
|
885
|
-
}
|
|
886
|
-
}
|
|
887
|
-
|
|
888
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
889
|
-
// STATE ROOTS & PROOFS
|
|
890
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
891
|
-
|
|
892
|
-
getStateRoot() {
|
|
893
|
-
// Use Core StateManager's state root if available
|
|
894
|
-
if (this._coreState && this._coreState._stateRoot) {
|
|
895
|
-
return this._coreState._stateRoot;
|
|
896
|
-
}
|
|
897
|
-
return this.stateTrie.root || '0x0000000000000000000000000000000000000000000000000000000000000000';
|
|
898
|
-
}
|
|
899
|
-
|
|
900
|
-
getStorageRoot(address) {
|
|
901
|
-
const normalized = this._normalizeAddress(address);
|
|
902
|
-
const storageTrie = this.storageTries.get(normalized);
|
|
903
|
-
return storageTrie?.root || '0x0000000000000000000000000000000000000000000000000000000000000000';
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
async getStateProof(address) {
|
|
907
|
-
const normalized = this._normalizeAddress(address);
|
|
908
|
-
return this.stateTrie.getProof(normalized);
|
|
909
|
-
}
|
|
910
|
-
|
|
911
|
-
async getStorageProof(address, key) {
|
|
912
|
-
const normalized = this._normalizeAddress(address);
|
|
913
|
-
const storageTrie = this.storageTries.get(normalized);
|
|
914
|
-
|
|
915
|
-
if (!storageTrie) {
|
|
916
|
-
return null;
|
|
917
|
-
}
|
|
918
|
-
|
|
919
|
-
return storageTrie.getProof(key.toString());
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
async verifyStateProof(address, proof) {
|
|
923
|
-
const normalized = this._normalizeAddress(address);
|
|
924
|
-
return this.stateTrie.verifyProof(normalized, proof.value, proof.proof);
|
|
925
|
-
}
|
|
926
|
-
|
|
927
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
928
|
-
// HELPER METHODS
|
|
929
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
930
|
-
|
|
931
|
-
_normalizeAddress(address) {
|
|
932
|
-
if (typeof address === 'string') {
|
|
933
|
-
if (address.startsWith('0x')) {
|
|
934
|
-
return address.toLowerCase();
|
|
935
|
-
}
|
|
936
|
-
return '0x' + address.toLowerCase();
|
|
937
|
-
}
|
|
938
|
-
|
|
939
|
-
if (Buffer.isBuffer(address)) {
|
|
940
|
-
return '0x' + address.toString('hex');
|
|
941
|
-
}
|
|
942
|
-
|
|
943
|
-
if (typeof address === 'bigint') {
|
|
944
|
-
return '0x' + address.toString(16).padStart(40, '0');
|
|
945
|
-
}
|
|
946
|
-
|
|
947
|
-
return address.toString();
|
|
948
|
-
}
|
|
949
|
-
|
|
950
|
-
_normalizeKey(key) {
|
|
951
|
-
if (typeof key === 'bigint') {
|
|
952
|
-
return '0x' + key.toString(16).padStart(64, '0');
|
|
953
|
-
}
|
|
954
|
-
if (typeof key === 'string') {
|
|
955
|
-
const k = key.toLowerCase().replace('0x', '');
|
|
956
|
-
return '0x' + k.padStart(64, '0');
|
|
957
|
-
}
|
|
958
|
-
return '0x' + key.toString().padStart(64, '0');
|
|
959
|
-
}
|
|
960
|
-
|
|
961
|
-
_hashCode(code) {
|
|
962
|
-
if (!code) return null;
|
|
963
|
-
|
|
964
|
-
const buffer = Buffer.isBuffer(code) ? code : Buffer.from(code);
|
|
965
|
-
return crypto.createHash('sha256').update(buffer).digest('hex');
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
969
|
-
// STATS & DEBUG
|
|
970
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
971
|
-
|
|
972
|
-
getStats() {
|
|
973
|
-
// Get Core StateManager stats if available
|
|
974
|
-
let coreStats = {};
|
|
975
|
-
if (this._coreState && this._coreState.getStats) {
|
|
976
|
-
coreStats = this._coreState.getStats();
|
|
977
|
-
}
|
|
978
|
-
|
|
979
|
-
return {
|
|
980
|
-
connected: this._connected,
|
|
981
|
-
accountsCached: this._accountCache.size,
|
|
982
|
-
contractsCached: this._contractCache.size,
|
|
983
|
-
storageCached: this._storageCache.size,
|
|
984
|
-
stateRoot: this.getStateRoot(),
|
|
985
|
-
checkpoints: this.checkpoints.length,
|
|
986
|
-
journalEntries: this.journalEntries.length,
|
|
987
|
-
codeCache: this.codeCache.size,
|
|
988
|
-
storageCache: this.storageCache.size,
|
|
989
|
-
// Core stats
|
|
990
|
-
coreAccountsCached: coreStats.accountsCached || 0,
|
|
991
|
-
coreStorageSlots: coreStats.totalStorageSlots || 0,
|
|
992
|
-
levelDBConnected: !!this._coreState?._storage
|
|
993
|
-
};
|
|
994
|
-
}
|
|
995
|
-
|
|
996
|
-
clearCaches() {
|
|
997
|
-
this.codeCache.clear();
|
|
998
|
-
this.storageCache.clear();
|
|
999
|
-
this._accountCache.clear();
|
|
1000
|
-
this._contractCache.clear();
|
|
1001
|
-
}
|
|
1002
|
-
}
|
|
1003
|
-
|
|
1004
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
1005
|
-
// PROXY CLASSES FOR LEGACY COMPATIBILITY
|
|
1006
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
1007
|
-
|
|
1008
|
-
/**
|
|
1009
|
-
* Accounts Map Proxy - provides Map-like interface backed by Core StateManager
|
|
1010
|
-
*/
|
|
1011
|
-
class AccountsMapProxy {
|
|
1012
|
-
constructor(vmState) {
|
|
1013
|
-
this._vm = vmState;
|
|
1014
|
-
}
|
|
1015
|
-
|
|
1016
|
-
get(address) {
|
|
1017
|
-
return this._vm._accountCache.get(this._vm._normalizeAddress(address));
|
|
1018
|
-
}
|
|
1019
|
-
|
|
1020
|
-
set(address, account) {
|
|
1021
|
-
const normalized = this._vm._normalizeAddress(address);
|
|
1022
|
-
this._vm._accountCache.set(normalized, account);
|
|
1023
|
-
|
|
1024
|
-
// Persist to Core (async, fire and forget for sync compatibility)
|
|
1025
|
-
if (this._vm._coreState) {
|
|
1026
|
-
this._vm._coreState.putAccount(normalized, account.toCoreFormat?.() || account)
|
|
1027
|
-
.catch(err => console.error('[State] Account persist error:', err));
|
|
1028
|
-
}
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
|
-
has(address) {
|
|
1032
|
-
return this._vm._accountCache.has(this._vm._normalizeAddress(address));
|
|
1033
|
-
}
|
|
1034
|
-
|
|
1035
|
-
delete(address) {
|
|
1036
|
-
this._vm._accountCache.delete(this._vm._normalizeAddress(address));
|
|
1037
|
-
}
|
|
1038
|
-
|
|
1039
|
-
get size() {
|
|
1040
|
-
return this._vm._accountCache.size;
|
|
1041
|
-
}
|
|
1042
|
-
|
|
1043
|
-
keys() {
|
|
1044
|
-
return this._vm._accountCache.keys();
|
|
1045
|
-
}
|
|
1046
|
-
|
|
1047
|
-
values() {
|
|
1048
|
-
return this._vm._accountCache.values();
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
|
-
entries() {
|
|
1052
|
-
return this._vm._accountCache.entries();
|
|
1053
|
-
}
|
|
1054
|
-
|
|
1055
|
-
[Symbol.iterator]() {
|
|
1056
|
-
return this._vm._accountCache[Symbol.iterator]();
|
|
1057
|
-
}
|
|
1058
|
-
}
|
|
1059
|
-
|
|
1060
|
-
/**
|
|
1061
|
-
* Contracts Map Proxy - provides Map-like interface backed by Core StateManager
|
|
1062
|
-
*/
|
|
1063
|
-
class ContractsMapProxy {
|
|
1064
|
-
constructor(vmState) {
|
|
1065
|
-
this._vm = vmState;
|
|
1066
|
-
}
|
|
1067
|
-
|
|
1068
|
-
get(address) {
|
|
1069
|
-
return this._vm._contractCache.get(this._vm._normalizeAddress(address));
|
|
1070
|
-
}
|
|
1071
|
-
|
|
1072
|
-
set(address, contract) {
|
|
1073
|
-
const normalized = this._vm._normalizeAddress(address);
|
|
1074
|
-
this._vm._contractCache.set(normalized, contract);
|
|
1075
|
-
|
|
1076
|
-
// Persist to Core (async)
|
|
1077
|
-
if (this._vm._coreState && contract.bytecode) {
|
|
1078
|
-
this._vm._coreState.setCode(normalized, contract.bytecode)
|
|
1079
|
-
.catch(err => console.error('[State] Contract persist error:', err));
|
|
1080
|
-
}
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1083
|
-
has(address) {
|
|
1084
|
-
return this._vm._contractCache.has(this._vm._normalizeAddress(address));
|
|
1085
|
-
}
|
|
1086
|
-
|
|
1087
|
-
delete(address) {
|
|
1088
|
-
this._vm._contractCache.delete(this._vm._normalizeAddress(address));
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1091
|
-
get size() {
|
|
1092
|
-
return this._vm._contractCache.size;
|
|
1093
|
-
}
|
|
1094
|
-
|
|
1095
|
-
keys() {
|
|
1096
|
-
return this._vm._contractCache.keys();
|
|
1097
|
-
}
|
|
1098
|
-
|
|
1099
|
-
values() {
|
|
1100
|
-
return this._vm._contractCache.values();
|
|
1101
|
-
}
|
|
1102
|
-
|
|
1103
|
-
entries() {
|
|
1104
|
-
return this._vm._contractCache.entries();
|
|
1105
|
-
}
|
|
1106
|
-
|
|
1107
|
-
[Symbol.iterator]() {
|
|
1108
|
-
return this._vm._contractCache[Symbol.iterator]();
|
|
1109
|
-
}
|
|
1110
|
-
}
|
|
1111
|
-
|
|
1112
|
-
// Export classes
|
|
1113
|
-
module.exports = StateManager;
|
|
1114
|
-
module.exports.Account = Account;
|
|
1115
|
-
module.exports.ContractStorage = ContractStorage;
|
|
1116
|
-
module.exports.StateTrie = StateTrie;
|