@corpus-core/colibri-stateless 0.1.20 → 0.2.1
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 +213 -14
- package/c4w.js +1 -1
- package/index.d.ts +1 -0
- package/index.js +32 -9
- package/package.json +1 -1
- package/wasm.d.ts +1 -0
package/index.d.ts
CHANGED
|
@@ -39,6 +39,7 @@ export declare function handle_request(req: DataRequest, conf: Config): Promise<
|
|
|
39
39
|
export default class C4Client {
|
|
40
40
|
config: Config;
|
|
41
41
|
constructor(config?: Partial<Config>);
|
|
42
|
+
private getProoferConfig;
|
|
42
43
|
private get flags();
|
|
43
44
|
/**
|
|
44
45
|
* checks, whether the rpc-method is supported or proofable.
|
package/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Import the Emscripten-generated module
|
|
2
|
-
import {
|
|
2
|
+
import { as_bytes, as_char_ptr, as_json, copy_to_c, getC4w } from "./wasm.js";
|
|
3
3
|
export var MethodType;
|
|
4
4
|
(function (MethodType) {
|
|
5
5
|
MethodType[MethodType["PROOFABLE"] = 1] = "PROOFABLE";
|
|
@@ -11,12 +11,12 @@ async function initialize_storage(conf) {
|
|
|
11
11
|
// TODO handle trusted_block_hashes
|
|
12
12
|
const c4w = await getC4w();
|
|
13
13
|
}
|
|
14
|
-
async function fetch_rpc(urls,
|
|
14
|
+
async function fetch_rpc(urls, payload, as_proof = false) {
|
|
15
15
|
let last_error = "All nodes failed";
|
|
16
16
|
for (const url of urls) {
|
|
17
17
|
const response = await fetch(url, {
|
|
18
18
|
method: 'POST',
|
|
19
|
-
body: JSON.stringify({ id: 1, jsonrpc: "2.0",
|
|
19
|
+
body: JSON.stringify({ id: 1, jsonrpc: "2.0", ...payload }),
|
|
20
20
|
headers: {
|
|
21
21
|
"Content-Type": "application/json",
|
|
22
22
|
"Accept": as_proof ? "application/octet-stream" : "application/json"
|
|
@@ -44,7 +44,7 @@ function log(msg) {
|
|
|
44
44
|
}
|
|
45
45
|
export async function handle_request(req, conf) {
|
|
46
46
|
const free_buffers = [];
|
|
47
|
-
const servers = req.type == "beacon_api" ? conf.beacon_apis : conf.rpcs;
|
|
47
|
+
const servers = req.type == "beacon_api" ? ((conf.proofer && conf.proofer.length) ? conf.proofer : conf.beacon_apis) : conf.rpcs;
|
|
48
48
|
const c4w = await getC4w();
|
|
49
49
|
let path = (req.type == 'eth_rpc' && req.payload)
|
|
50
50
|
? `rpc: ${req.payload?.method}(${req.payload?.params.join(',')})`
|
|
@@ -96,6 +96,19 @@ export async function handle_request(req, conf) {
|
|
|
96
96
|
if (conf.debug)
|
|
97
97
|
log(`::: ${path} (Error: ${last_error})`);
|
|
98
98
|
}
|
|
99
|
+
function check_trusted_blockhashes(trusted_block_hashes, c4w, chainId) {
|
|
100
|
+
const blockhashes = new Uint8Array(32 * trusted_block_hashes.length);
|
|
101
|
+
for (let i = 0; i < trusted_block_hashes.length; i++) {
|
|
102
|
+
if (trusted_block_hashes[i].length != 66 || !trusted_block_hashes[i].startsWith("0x"))
|
|
103
|
+
throw new Error("Invalid trustedblockhash : " + trusted_block_hashes[i]);
|
|
104
|
+
for (let j = 0; j < 32; j++)
|
|
105
|
+
blockhashes[i * 32 + j] = parseInt(trusted_block_hashes[i].slice(2 + j * 2, 4 + j * 2), 16);
|
|
106
|
+
}
|
|
107
|
+
const ptr = copy_to_c(blockhashes, c4w);
|
|
108
|
+
c4w._c4w_set_trusted_blockhashes(BigInt(chainId), ptr, blockhashes.length);
|
|
109
|
+
c4w._free(ptr);
|
|
110
|
+
trusted_block_hashes.length = 0;
|
|
111
|
+
}
|
|
99
112
|
export default class C4Client {
|
|
100
113
|
config;
|
|
101
114
|
constructor(config) {
|
|
@@ -105,10 +118,18 @@ export default class C4Client {
|
|
|
105
118
|
beacon_apis: ["https://lodestar-mainnet.chainsafe.io"], // Default beacon API
|
|
106
119
|
rpcs: ["https://rpc.ankr.com/eth"], // Default RPC
|
|
107
120
|
trusted_block_hashes: [],
|
|
108
|
-
proofer: ["https://
|
|
109
|
-
},
|
|
121
|
+
proofer: ["https://mainnet.colibri-proof.tech"],
|
|
122
|
+
},
|
|
123
|
+
...config
|
|
110
124
|
};
|
|
111
125
|
}
|
|
126
|
+
async getProoferConfig() {
|
|
127
|
+
const c4w = await getC4w();
|
|
128
|
+
if (!c4w.storage)
|
|
129
|
+
return '0x';
|
|
130
|
+
const state = c4w.storage.get('state_' + this.config.chainId);
|
|
131
|
+
return '0x' + (state ? Array.from(state).map(_ => _.toString(16).padStart(2, '0')).join('') : '');
|
|
132
|
+
}
|
|
112
133
|
get flags() {
|
|
113
134
|
return this.config.include_code ? 1 : 0;
|
|
114
135
|
}
|
|
@@ -169,6 +190,8 @@ export default class C4Client {
|
|
|
169
190
|
const free_buffers = [];
|
|
170
191
|
let ctx = 0;
|
|
171
192
|
try {
|
|
193
|
+
if (this.config.trusted_block_hashes && this.config.trusted_block_hashes.length > 0)
|
|
194
|
+
check_trusted_blockhashes(this.config.trusted_block_hashes, c4w, this.config.chainId);
|
|
172
195
|
// Call the C function
|
|
173
196
|
ctx = c4w._c4w_create_verify_ctx(copy_to_c(proof, c4w, free_buffers), proof.length, as_char_ptr(method, c4w, free_buffers), as_char_ptr(JSON.stringify(args), c4w, free_buffers), BigInt(this.config.chainId));
|
|
174
197
|
while (true) {
|
|
@@ -206,14 +229,14 @@ export default class C4Client {
|
|
|
206
229
|
switch (method_type) {
|
|
207
230
|
case MethodType.PROOFABLE: {
|
|
208
231
|
if (this.config.verify && !this.config.verify(method, args))
|
|
209
|
-
return await fetch_rpc(this.config.rpcs, method, args, false);
|
|
232
|
+
return await fetch_rpc(this.config.rpcs, { method, params: args }, false);
|
|
210
233
|
proof = this.config.proofer && this.config.proofer.length
|
|
211
|
-
? await fetch_rpc(this.config.proofer, method, args, true)
|
|
234
|
+
? await fetch_rpc(this.config.proofer, { method, params: args, c4: await this.getProoferConfig() }, true)
|
|
212
235
|
: await this.createProof(method, args);
|
|
213
236
|
break;
|
|
214
237
|
}
|
|
215
238
|
case MethodType.UNPROOFABLE:
|
|
216
|
-
return await fetch_rpc(this.config.rpcs, method, args, false);
|
|
239
|
+
return await fetch_rpc(this.config.rpcs, { method, params: args }, false);
|
|
217
240
|
case MethodType.NOT_SUPPORTED:
|
|
218
241
|
throw new Error(`Method ${method} is not supported`);
|
|
219
242
|
case MethodType.LOCAL:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@corpus-core/colibri-stateless",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Colibri is a stateless and trustless ethereum client, which is optimized for the mobile apps or embedded devices, because it does not hols the state, but verifies on demand.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
package/wasm.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export interface C4W {
|
|
|
6
6
|
_c4w_req_set_response: (reqPtr: number, data: number, len: number, node_index: number) => void;
|
|
7
7
|
_c4w_req_set_error: (reqPtr: number, error: number, node_index: number) => void;
|
|
8
8
|
_c4w_get_method_type: (chain_id: bigint, method: number) => number;
|
|
9
|
+
_c4w_set_trusted_blockhashes: (chain_id: bigint, blockhashes: number, len: number) => void;
|
|
9
10
|
_c4w_create_verify_ctx: (proof: number, proof_len: number, method: number, args: number, chain_id: bigint) => number;
|
|
10
11
|
_c4w_free_verify_ctx: (verifyCtx: number) => void;
|
|
11
12
|
_c4w_verify_proof: (verifyCtx: number) => number;
|