@typeberry/lib 0.5.2-7570566 → 0.5.2-ab56433
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/package.json +2 -2
- package/packages/core/collections/blob-dictionary.d.ts.map +1 -1
- package/packages/core/collections/blob-dictionary.js +3 -3
- package/packages/core/pvm-host-calls/bin.js +6 -6
- package/packages/core/pvm-host-calls/ecalli-io-tracker.d.ts +32 -0
- package/packages/core/pvm-host-calls/ecalli-io-tracker.d.ts.map +1 -0
- package/packages/core/pvm-host-calls/ecalli-io-tracker.js +14 -0
- package/packages/core/pvm-host-calls/ecalli-trace-logger.d.ts +139 -0
- package/packages/core/pvm-host-calls/ecalli-trace-logger.d.ts.map +1 -0
- package/packages/core/pvm-host-calls/ecalli-trace-logger.js +209 -0
- package/packages/core/pvm-host-calls/ecalli-trace-logger.test.d.ts +2 -0
- package/packages/core/pvm-host-calls/ecalli-trace-logger.test.d.ts.map +1 -0
- package/packages/core/pvm-host-calls/ecalli-trace-logger.test.js +231 -0
- package/packages/core/pvm-host-calls/host-call-memory.d.ts +2 -0
- package/packages/core/pvm-host-calls/host-call-memory.d.ts.map +1 -1
- package/packages/core/pvm-host-calls/host-call-memory.js +12 -2
- package/packages/core/pvm-host-calls/host-call-registers.d.ts +6 -0
- package/packages/core/pvm-host-calls/host-call-registers.d.ts.map +1 -1
- package/packages/core/pvm-host-calls/host-call-registers.js +24 -0
- package/packages/core/pvm-host-calls/host-calls-executor.d.ts +31 -0
- package/packages/core/pvm-host-calls/host-calls-executor.d.ts.map +1 -0
- package/packages/core/pvm-host-calls/host-calls-executor.js +137 -0
- package/packages/core/pvm-host-calls/host-calls.d.ts +20 -26
- package/packages/core/pvm-host-calls/host-calls.d.ts.map +1 -1
- package/packages/core/pvm-host-calls/host-calls.js +40 -112
- package/packages/core/pvm-host-calls/index.d.ts +7 -6
- package/packages/core/pvm-host-calls/index.d.ts.map +1 -1
- package/packages/core/pvm-host-calls/index.js +7 -6
- package/packages/core/pvm-host-calls/{interpreter-instance-manager.d.ts → pvm-instance-manager.d.ts} +3 -3
- package/packages/core/pvm-host-calls/pvm-instance-manager.d.ts.map +1 -0
- package/packages/core/pvm-host-calls/{interpreter-instance-manager.js → pvm-instance-manager.js} +2 -2
- package/packages/jam/safrole/bandersnatch-vrf.d.ts +2 -0
- package/packages/jam/safrole/bandersnatch-vrf.d.ts.map +1 -1
- package/packages/jam/safrole/bandersnatch-vrf.js +11 -0
- package/packages/jam/safrole/bandersnatch-wasm.d.ts +1 -0
- package/packages/jam/safrole/bandersnatch-wasm.d.ts.map +1 -1
- package/packages/jam/safrole/bandersnatch-wasm.js +3 -0
- package/packages/jam/safrole/safrole-seal.d.ts +1 -3
- package/packages/jam/safrole/safrole-seal.d.ts.map +1 -1
- package/packages/jam/safrole/safrole-seal.js +14 -25
- package/packages/jam/transition/accumulate/pvm-executor.d.ts.map +1 -1
- package/packages/jam/transition/accumulate/pvm-executor.js +2 -2
- package/packages/jam/transition/disputes/disputes.d.ts.map +1 -1
- package/packages/jam/transition/disputes/disputes.js +5 -4
- package/packages/core/pvm-host-calls/host-calls-manager.d.ts +0 -23
- package/packages/core/pvm-host-calls/host-calls-manager.d.ts.map +0 -1
- package/packages/core/pvm-host-calls/host-calls-manager.js +0 -44
- package/packages/core/pvm-host-calls/interpreter-instance-manager.d.ts.map +0 -1
|
@@ -1,119 +1,47 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
status;
|
|
9
|
-
memorySlice;
|
|
10
|
-
constructor(consumedGas, status, memorySlice) {
|
|
11
|
-
this.consumedGas = consumedGas;
|
|
12
|
-
this.status = status;
|
|
13
|
-
this.memorySlice = memorySlice;
|
|
14
|
-
check `
|
|
15
|
-
${(status === null && memorySlice !== null) || (status !== null && memorySlice === null)}
|
|
16
|
-
'status' and 'memorySlice' must not both be null or both be non-null — exactly one must be provided
|
|
17
|
-
`;
|
|
18
|
-
}
|
|
19
|
-
static fromStatus(consumedGas, status) {
|
|
20
|
-
return new ReturnValue(consumedGas, status, null);
|
|
21
|
-
}
|
|
22
|
-
static fromMemorySlice(consumedGas, memorySlice) {
|
|
23
|
-
return new ReturnValue(consumedGas, null, memorySlice);
|
|
24
|
-
}
|
|
25
|
-
hasMemorySlice() {
|
|
26
|
-
return this.memorySlice instanceof Uint8Array && this.status === null;
|
|
27
|
-
}
|
|
28
|
-
hasStatus() {
|
|
29
|
-
return !this.hasMemorySlice();
|
|
30
|
-
}
|
|
31
|
-
}
|
|
1
|
+
import { Level, Logger } from "#@typeberry/logger";
|
|
2
|
+
import { tryAsU32 } from "#@typeberry/numbers";
|
|
3
|
+
import { tryAsSmallGas } from "#@typeberry/pvm-interface";
|
|
4
|
+
import { check } from "#@typeberry/utils";
|
|
5
|
+
import { tryAsHostCallIndex, } from "./host-call-handler.js";
|
|
6
|
+
const logger = Logger.new(import.meta.filename, "host-calls-pvm");
|
|
7
|
+
/** Container for all available host calls. */
|
|
32
8
|
export class HostCalls {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
constructor(
|
|
36
|
-
this.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const gasConsumed = pvmInstance.gas.used();
|
|
41
|
-
if (status === Status.OOG) {
|
|
42
|
-
return ReturnValue.fromStatus(gasConsumed, status);
|
|
43
|
-
}
|
|
44
|
-
if (status === Status.HALT) {
|
|
45
|
-
const regs = new HostCallRegisters(pvmInstance.registers.getAllEncoded());
|
|
46
|
-
const memory = new HostCallMemory(pvmInstance.memory);
|
|
47
|
-
const address = regs.get(7);
|
|
48
|
-
// NOTE we are taking the the lower U32 part of the register, hence it's safe.
|
|
49
|
-
const length = Number(regs.get(8) & 0xffffffffn);
|
|
50
|
-
const result = safeAllocUint8Array(length);
|
|
51
|
-
const loadResult = memory.loadInto(result, address);
|
|
52
|
-
if (loadResult.isError) {
|
|
53
|
-
return ReturnValue.fromMemorySlice(gasConsumed, new Uint8Array());
|
|
54
|
-
}
|
|
55
|
-
return ReturnValue.fromMemorySlice(gasConsumed, result);
|
|
9
|
+
hostCalls = new Map();
|
|
10
|
+
missing;
|
|
11
|
+
constructor({ missing, handlers = [], }) {
|
|
12
|
+
this.missing = missing;
|
|
13
|
+
for (const handler of handlers) {
|
|
14
|
+
check `${this.hostCalls.get(handler.index) === undefined} Overwriting host call handler at index ${handler.index}`;
|
|
15
|
+
this.hostCalls.set(handler.index, handler);
|
|
56
16
|
}
|
|
57
|
-
return ReturnValue.fromStatus(gasConsumed, Status.PANIC);
|
|
58
17
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
let status = pvmInstance.getStatus();
|
|
63
|
-
if (status !== Status.HOST) {
|
|
64
|
-
return this.getReturnValue(status, pvmInstance);
|
|
65
|
-
}
|
|
66
|
-
check `
|
|
67
|
-
${pvmInstance.getExitParam() !== null}
|
|
68
|
-
"We know that the exit param is not null, because the status is 'Status.HOST'
|
|
69
|
-
`;
|
|
70
|
-
const hostCallIndex = pvmInstance.getExitParam() ?? -1;
|
|
71
|
-
const gas = pvmInstance.gas;
|
|
72
|
-
const regs = new HostCallRegisters(pvmInstance.registers.getAllEncoded());
|
|
73
|
-
const memory = new HostCallMemory(pvmInstance.memory);
|
|
74
|
-
const index = tryAsHostCallIndex(hostCallIndex);
|
|
75
|
-
const hostCall = this.hostCalls.get(index);
|
|
76
|
-
const gasBefore = gas.get();
|
|
77
|
-
// NOTE: `basicGasCost(regs)` function is for compatibility reasons: pre GP 0.7.2
|
|
78
|
-
const basicGasCost = typeof hostCall.basicGasCost === "number" ? hostCall.basicGasCost : hostCall.basicGasCost(regs);
|
|
79
|
-
const underflow = gas.sub(basicGasCost);
|
|
80
|
-
const pcLog = `[PC: ${pvmInstance.getPC()}]`;
|
|
81
|
-
if (underflow) {
|
|
82
|
-
this.hostCalls.traceHostCall(`${pcLog} OOG`, index, hostCall, regs, gas.get());
|
|
83
|
-
return ReturnValue.fromStatus(gas.used(), Status.OOG);
|
|
84
|
-
}
|
|
85
|
-
this.hostCalls.traceHostCall(`${pcLog} Invoking`, index, hostCall, regs, gasBefore);
|
|
86
|
-
const result = await hostCall.execute(gas, regs, memory);
|
|
87
|
-
this.hostCalls.traceHostCall(result === undefined ? `${pcLog} Result` : `${pcLog} Status(${PvmExecution[result]})`, index, hostCall, regs, gas.get());
|
|
88
|
-
pvmInstance.registers.setAllEncoded(regs.getEncoded());
|
|
89
|
-
if (result === PvmExecution.Halt) {
|
|
90
|
-
status = Status.HALT;
|
|
91
|
-
return this.getReturnValue(status, pvmInstance);
|
|
92
|
-
}
|
|
93
|
-
if (result === PvmExecution.Panic) {
|
|
94
|
-
status = Status.PANIC;
|
|
95
|
-
return this.getReturnValue(status, pvmInstance);
|
|
96
|
-
}
|
|
97
|
-
if (result === PvmExecution.OOG) {
|
|
98
|
-
status = Status.OOG;
|
|
99
|
-
return this.getReturnValue(status, pvmInstance);
|
|
100
|
-
}
|
|
101
|
-
if (result === undefined) {
|
|
102
|
-
pvmInstance.runProgram();
|
|
103
|
-
status = pvmInstance.getStatus();
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
assertNever(result);
|
|
107
|
-
}
|
|
18
|
+
/** Get a host call by index. */
|
|
19
|
+
get(hostCallIndex) {
|
|
20
|
+
return this.hostCalls.get(hostCallIndex) ?? this.missing;
|
|
108
21
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
try {
|
|
113
|
-
return await this.execute(pvmInstance);
|
|
114
|
-
}
|
|
115
|
-
finally {
|
|
116
|
-
this.pvmInstanceManager.releaseInstance(pvmInstance);
|
|
22
|
+
traceHostCall(context, hostCallIndex, hostCallHandler, registers, gas) {
|
|
23
|
+
if (logger.getLevel() > Level.INSANE) {
|
|
24
|
+
return;
|
|
117
25
|
}
|
|
26
|
+
const { currentServiceId } = hostCallHandler;
|
|
27
|
+
const requested = hostCallIndex !== hostCallHandler.index ? ` (${hostCallIndex})` : "";
|
|
28
|
+
const name = `${hostCallHandler.constructor.name}:${hostCallHandler.index}`;
|
|
29
|
+
const registerValues = hostCallHandler.tracedRegisters
|
|
30
|
+
.map((idx) => [idx.toString().padStart(2, "0"), registers.get(idx)])
|
|
31
|
+
.filter((v) => v[1] !== 0n)
|
|
32
|
+
.map(([idx, value]) => {
|
|
33
|
+
return `r${idx}=${value} (0x${value.toString(16)})`;
|
|
34
|
+
})
|
|
35
|
+
.join(", ");
|
|
36
|
+
logger.insane `[${currentServiceId}] ${context} ${name}${requested}. Gas: ${gas}. Regs: ${registerValues}.`;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export class NoopMissing {
|
|
40
|
+
index = tryAsHostCallIndex(2 ** 32 - 1);
|
|
41
|
+
basicGasCost = tryAsSmallGas(0);
|
|
42
|
+
currentServiceId = tryAsU32(0);
|
|
43
|
+
tracedRegisters = [];
|
|
44
|
+
async execute() {
|
|
45
|
+
return;
|
|
118
46
|
}
|
|
119
47
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
export
|
|
1
|
+
export * from "./ecalli-trace-logger.js";
|
|
2
|
+
export * from "./host-call-handler.js";
|
|
3
|
+
export * from "./host-call-memory.js";
|
|
4
|
+
export * from "./host-call-registers.js";
|
|
5
|
+
export * from "./host-calls.js";
|
|
6
|
+
export * from "./host-calls-executor.js";
|
|
7
|
+
export * from "./pvm-instance-manager.js";
|
|
7
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../packages/core/pvm-host-calls/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../packages/core/pvm-host-calls/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,iBAAiB,CAAC;AAChC,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
export
|
|
1
|
+
export * from "./ecalli-trace-logger.js";
|
|
2
|
+
export * from "./host-call-handler.js";
|
|
3
|
+
export * from "./host-call-memory.js";
|
|
4
|
+
export * from "./host-call-registers.js";
|
|
5
|
+
export * from "./host-calls.js";
|
|
6
|
+
export * from "./host-calls-executor.js";
|
|
7
|
+
export * from "./pvm-instance-manager.js";
|
package/packages/core/pvm-host-calls/{interpreter-instance-manager.d.ts → pvm-instance-manager.d.ts}
RENAMED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { PvmBackend } from "#@typeberry/config";
|
|
2
2
|
import type { IPvmInterpreter } from "#@typeberry/pvm-interface";
|
|
3
|
-
export declare class
|
|
3
|
+
export declare class PvmInstanceManager {
|
|
4
4
|
private readonly instances;
|
|
5
5
|
private waitingQueue;
|
|
6
6
|
private constructor();
|
|
7
|
-
static new(interpreter: PvmBackend): Promise<
|
|
7
|
+
static new(interpreter: PvmBackend): Promise<PvmInstanceManager>;
|
|
8
8
|
getInstance(): Promise<IPvmInterpreter>;
|
|
9
9
|
releaseInstance(pvm: IPvmInterpreter): void;
|
|
10
10
|
}
|
|
11
|
-
//# sourceMappingURL=
|
|
11
|
+
//# sourceMappingURL=pvm-instance-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pvm-instance-manager.d.ts","sourceRoot":"","sources":["../../../../../packages/core/pvm-host-calls/pvm-instance-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAQhE,qBAAa,kBAAkB;IAGT,OAAO,CAAC,QAAQ,CAAC,SAAS;IAF9C,OAAO,CAAC,YAAY,CAAmB;IAEvC,OAAO;WAEM,GAAG,CAAC,WAAW,EAAE,UAAU,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAmBhE,WAAW,IAAI,OAAO,CAAC,eAAe,CAAC;IAU7C,eAAe,CAAC,GAAG,EAAE,eAAe;CAOrC"}
|
package/packages/core/pvm-host-calls/{interpreter-instance-manager.js → pvm-instance-manager.js}
RENAMED
|
@@ -3,7 +3,7 @@ import { Interpreter } from "#@typeberry/pvm-interpreter";
|
|
|
3
3
|
import { AnanasInterpreter } from "#@typeberry/pvm-interpreter-ananas";
|
|
4
4
|
import { assertNever } from "#@typeberry/utils";
|
|
5
5
|
// TODO [MaSo] Delete this & also make host calls independent from intepreters.
|
|
6
|
-
export class
|
|
6
|
+
export class PvmInstanceManager {
|
|
7
7
|
instances;
|
|
8
8
|
waitingQueue = [];
|
|
9
9
|
constructor(instances) {
|
|
@@ -23,7 +23,7 @@ export class InterpreterInstanceManager {
|
|
|
23
23
|
default:
|
|
24
24
|
assertNever(interpreter);
|
|
25
25
|
}
|
|
26
|
-
return new
|
|
26
|
+
return new PvmInstanceManager(instances);
|
|
27
27
|
}
|
|
28
28
|
async getInstance() {
|
|
29
29
|
const instance = this.instances.pop();
|
|
@@ -8,12 +8,14 @@ import { type Opaque, Result } from "#@typeberry/utils";
|
|
|
8
8
|
import type { BandernsatchWasm } from "./bandersnatch-wasm.js";
|
|
9
9
|
declare const FUNCTIONS: {
|
|
10
10
|
verifySeal: typeof verifySeal;
|
|
11
|
+
verifyHeaderSeals: typeof verifyHeaderSeals;
|
|
11
12
|
verifyTickets: typeof verifyTickets;
|
|
12
13
|
getRingCommitment: typeof getRingCommitment;
|
|
13
14
|
generateSeal: typeof generateSeal;
|
|
14
15
|
getVrfOutputHash: typeof getVrfOutputHash;
|
|
15
16
|
};
|
|
16
17
|
export default FUNCTIONS;
|
|
18
|
+
declare function verifyHeaderSeals(bandersnatch: BandernsatchWasm, authorKey: BandersnatchKey, signature: BandersnatchVrfSignature, payload: BytesBlob, encodedUnsealedHeader: BytesBlob, entropySignature: BandersnatchVrfSignature, entropyPayloadPrefix: BytesBlob): Promise<Result<[EntropyHash, EntropyHash], null>>;
|
|
17
19
|
declare function verifySeal(bandersnatch: BandernsatchWasm, authorKey: BandersnatchKey, signature: BandersnatchVrfSignature, payload: BytesBlob, encodedUnsealedHeader: BytesBlob): Promise<Result<EntropyHash, null>>;
|
|
18
20
|
declare function getRingCommitment(bandersnatch: BandernsatchWasm, validators: BandersnatchKey[]): Promise<Result<BandersnatchRingRoot, null>>;
|
|
19
21
|
declare function verifyTickets(bandersnatch: BandernsatchWasm, numberOfValidators: number, epochRoot: BandersnatchRingRoot, tickets: readonly SignedTicket[], entropy: EntropyHash): Promise<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bandersnatch-vrf.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/safrole/bandersnatch-vrf.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAS,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC9B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAa,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAwB/D,QAAA,MAAM,SAAS
|
|
1
|
+
{"version":3,"file":"bandersnatch-vrf.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/safrole/bandersnatch-vrf.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAS,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC9B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAa,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAwB/D,QAAA,MAAM,SAAS;;;;;;;CAOd,CAAC;AAKF,eAAe,SAAS,CAAC;AAEzB,iBAAe,iBAAiB,CAC9B,YAAY,EAAE,gBAAgB,EAC9B,SAAS,EAAE,eAAe,EAC1B,SAAS,EAAE,wBAAwB,EACnC,OAAO,EAAE,SAAS,EAClB,qBAAqB,EAAE,SAAS,EAChC,gBAAgB,EAAE,wBAAwB,EAC1C,oBAAoB,EAAE,SAAS,GAC9B,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,IAAI,CAAC,CAAC,CAkBnD;AAED,iBAAe,UAAU,CACvB,YAAY,EAAE,gBAAgB,EAC9B,SAAS,EAAE,eAAe,EAC1B,SAAS,EAAE,wBAAwB,EACnC,OAAO,EAAE,SAAS,EAClB,qBAAqB,EAAE,SAAS,GAC/B,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAapC;AAED,iBAAS,iBAAiB,CACxB,YAAY,EAAE,gBAAgB,EAC9B,UAAU,EAAE,eAAe,EAAE,GAC5B,OAAO,CAAC,MAAM,CAAC,oBAAoB,EAAE,IAAI,CAAC,CAAC,CAmB7C;AAkBD,iBAAe,aAAa,CAC1B,YAAY,EAAE,gBAAgB,EAC9B,kBAAkB,EAAE,MAAM,EAC1B,SAAS,EAAE,oBAAoB,EAC/B,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE,EAAE,CAAC,CAqB3D;AAED,iBAAe,YAAY,CACzB,YAAY,EAAE,gBAAgB,EAC9B,SAAS,EAAE,sBAAsB,EACjC,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,SAAS,GACjB,OAAO,CAAC,MAAM,CAAC,wBAAwB,EAAE,IAAI,CAAC,CAAC,CAQjD;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;AAElE,iBAAe,gBAAgB,CAC7B,YAAY,EAAE,gBAAgB,EAC9B,SAAS,EAAE,sBAAsB,EACjC,KAAK,EAAE,SAAS,GACf,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAQtC"}
|
|
@@ -20,6 +20,7 @@ var ResultValues;
|
|
|
20
20
|
const ringCommitmentCache = [];
|
|
21
21
|
const FUNCTIONS = {
|
|
22
22
|
verifySeal,
|
|
23
|
+
verifyHeaderSeals,
|
|
23
24
|
verifyTickets,
|
|
24
25
|
getRingCommitment,
|
|
25
26
|
generateSeal,
|
|
@@ -29,6 +30,16 @@ const FUNCTIONS = {
|
|
|
29
30
|
// Ideally we would just export functions and figure out how to mock
|
|
30
31
|
// properly in ESM.
|
|
31
32
|
export default FUNCTIONS;
|
|
33
|
+
async function verifyHeaderSeals(bandersnatch, authorKey, signature, payload, encodedUnsealedHeader, entropySignature, entropyPayloadPrefix) {
|
|
34
|
+
const sealResult = await bandersnatch.verifyHeaderSeals(authorKey.raw, signature.raw, payload.raw, encodedUnsealedHeader.raw, entropySignature.raw, entropyPayloadPrefix.raw);
|
|
35
|
+
if (sealResult[RESULT_INDEX] === ResultValues.Error) {
|
|
36
|
+
return Result.error(null, () => "Bandersnatch VRF seal verification failed");
|
|
37
|
+
}
|
|
38
|
+
return Result.ok([
|
|
39
|
+
Bytes.fromBlob(sealResult.subarray(1, 33), HASH_SIZE).asOpaque(),
|
|
40
|
+
Bytes.fromBlob(sealResult.subarray(33), HASH_SIZE).asOpaque(),
|
|
41
|
+
]);
|
|
42
|
+
}
|
|
32
43
|
async function verifySeal(bandersnatch, authorKey, signature, payload, encodedUnsealedHeader) {
|
|
33
44
|
const sealResult = await bandersnatch.verifySeal(authorKey.raw, signature.raw, payload.raw, encodedUnsealedHeader.raw);
|
|
34
45
|
if (sealResult[RESULT_INDEX] === ResultValues.Error) {
|
|
@@ -2,6 +2,7 @@ export declare class BandernsatchWasm {
|
|
|
2
2
|
private constructor();
|
|
3
3
|
static new(): Promise<BandernsatchWasm>;
|
|
4
4
|
verifySeal(authorKey: Uint8Array, signature: Uint8Array, payload: Uint8Array, auxData: Uint8Array): Promise<Uint8Array<ArrayBufferLike>>;
|
|
5
|
+
verifyHeaderSeals(authorKey: Uint8Array, headerSeal: Uint8Array, headerSealPayload: Uint8Array, unsealedHeader: Uint8Array, entropySeal: Uint8Array, entropyPayloadPrefix: Uint8Array): Promise<Uint8Array<ArrayBufferLike>>;
|
|
5
6
|
getRingCommitment(keys: Uint8Array): Promise<Uint8Array<ArrayBufferLike>>;
|
|
6
7
|
batchVerifyTicket(ringSize: number, commitment: Uint8Array, ticketsData: Uint8Array, contextLength: number): Promise<Uint8Array<ArrayBufferLike>>;
|
|
7
8
|
generateSeal(authorKey: Uint8Array, input: Uint8Array, auxData: Uint8Array): Promise<Uint8Array<ArrayBufferLike>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bandersnatch-wasm.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/safrole/bandersnatch-wasm.ts"],"names":[],"mappings":"AAEA,qBAAa,gBAAgB;IAC3B,OAAO;WAEM,GAAG;IAKV,UAAU,CAAC,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU;IAIjG,iBAAiB,CAAC,IAAI,EAAE,UAAU;IAIlC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM;IAI1G,YAAY,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU;IAI1E,gBAAgB,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU;CAGhE"}
|
|
1
|
+
{"version":3,"file":"bandersnatch-wasm.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/safrole/bandersnatch-wasm.ts"],"names":[],"mappings":"AAEA,qBAAa,gBAAgB;IAC3B,OAAO;WAEM,GAAG;IAKV,UAAU,CAAC,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU;IAIjG,iBAAiB,CACrB,SAAS,EAAE,UAAU,EACrB,UAAU,EAAE,UAAU,EACtB,iBAAiB,EAAE,UAAU,EAC7B,cAAc,EAAE,UAAU,EAC1B,WAAW,EAAE,UAAU,EACvB,oBAAoB,EAAE,UAAU;IAY5B,iBAAiB,CAAC,IAAI,EAAE,UAAU;IAIlC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM;IAI1G,YAAY,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU;IAI1E,gBAAgB,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU;CAGhE"}
|
|
@@ -8,6 +8,9 @@ export class BandernsatchWasm {
|
|
|
8
8
|
async verifySeal(authorKey, signature, payload, auxData) {
|
|
9
9
|
return bandersnatchWasm.verify_seal(authorKey, signature, payload, auxData);
|
|
10
10
|
}
|
|
11
|
+
async verifyHeaderSeals(authorKey, headerSeal, headerSealPayload, unsealedHeader, entropySeal, entropyPayloadPrefix) {
|
|
12
|
+
return bandersnatchWasm.verify_header_seals(authorKey, headerSeal, headerSealPayload, unsealedHeader, entropySeal, entropyPayloadPrefix);
|
|
13
|
+
}
|
|
11
14
|
async getRingCommitment(keys) {
|
|
12
15
|
return bandersnatchWasm.ring_commitment(keys);
|
|
13
16
|
}
|
|
@@ -8,8 +8,7 @@ export declare enum SafroleSealError {
|
|
|
8
8
|
InvalidValidatorIndex = 0,
|
|
9
9
|
InvalidValidator = 1,
|
|
10
10
|
InvalidTicket = 2,
|
|
11
|
-
IncorrectSeal = 3
|
|
12
|
-
IncorrectEntropySource = 4
|
|
11
|
+
IncorrectSeal = 3
|
|
13
12
|
}
|
|
14
13
|
export type SafroleSealState = Pick<State, "currentValidatorData" | "sealingKeySeries"> & {
|
|
15
14
|
currentEntropy: EntropyHash;
|
|
@@ -22,7 +21,6 @@ export declare class SafroleSeal {
|
|
|
22
21
|
* hence the state is passed as an argument for more control.
|
|
23
22
|
*/
|
|
24
23
|
verifyHeaderSeal(headerView: HeaderView, state: SafroleSealState): Promise<Result<EntropyHash, SafroleSealError>>;
|
|
25
|
-
private verifySeal;
|
|
26
24
|
/** Regular (non-fallback) mode of Safrole. */
|
|
27
25
|
verifySealWithTicket(tickets: PerEpochBlock<Ticket>, timeSlot: TimeSlot, entropy: EntropyHash, validatorData: ValidatorData, headerView: HeaderView): Promise<Result<EntropyHash, SafroleSealError>>;
|
|
28
26
|
/** Fallback mode of Safrole. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"safrole-seal.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/safrole/safrole-seal.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAEhB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,QAAQ,EACd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAE1D,OAAO,EAA0B,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE7D,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG1D,oBAAY,gBAAgB;IAC1B,qBAAqB,IAAI;IACzB,gBAAgB,IAAI;IACpB,aAAa,IAAI;IACjB,aAAa,IAAI;
|
|
1
|
+
{"version":3,"file":"safrole-seal.d.ts","sourceRoot":"","sources":["../../../../../packages/jam/safrole/safrole-seal.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAEhB,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,QAAQ,EACd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAE1D,OAAO,EAA0B,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE7D,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG1D,oBAAY,gBAAgB;IAC1B,qBAAqB,IAAI;IACzB,gBAAgB,IAAI;IACpB,aAAa,IAAI;IACjB,aAAa,IAAI;CAClB;AAED,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,EAAE,sBAAsB,GAAG,kBAAkB,CAAC,GAAG;IACxF,cAAc,EAAE,WAAW,CAAC;CAC7B,CAAC;AAIF,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAAZ,YAAY,GAAE,OAAO,CAAC,gBAAgB,CAA0B;IAC7F;;;OAGG;IACG,gBAAgB,CACpB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,gBAAgB,GACtB,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IAuBjD,8CAA8C;IACxC,oBAAoB,CACxB,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,EAC9B,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,WAAW,EACpB,aAAa,EAAE,aAAa,EAC5B,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IAmCjD,gCAAgC;IAC1B,kBAAkB,CACtB,IAAI,EAAE,aAAa,CAAC,eAAe,CAAC,EACpC,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,aAAa,EACxB,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;CA8BlD"}
|
|
@@ -12,7 +12,6 @@ export var SafroleSealError;
|
|
|
12
12
|
SafroleSealError[SafroleSealError["InvalidValidator"] = 1] = "InvalidValidator";
|
|
13
13
|
SafroleSealError[SafroleSealError["InvalidTicket"] = 2] = "InvalidTicket";
|
|
14
14
|
SafroleSealError[SafroleSealError["IncorrectSeal"] = 3] = "IncorrectSeal";
|
|
15
|
-
SafroleSealError[SafroleSealError["IncorrectEntropySource"] = 4] = "IncorrectEntropySource";
|
|
16
15
|
})(SafroleSealError || (SafroleSealError = {}));
|
|
17
16
|
const BANDERSNATCH_ZERO_KEY = Bytes.zero(BANDERSNATCH_KEY_BYTES).asOpaque();
|
|
18
17
|
export class SafroleSeal {
|
|
@@ -25,21 +24,6 @@ export class SafroleSeal {
|
|
|
25
24
|
* hence the state is passed as an argument for more control.
|
|
26
25
|
*/
|
|
27
26
|
async verifyHeaderSeal(headerView, state) {
|
|
28
|
-
const sealResult = await this.verifySeal(headerView, state);
|
|
29
|
-
if (sealResult.isError) {
|
|
30
|
-
return sealResult;
|
|
31
|
-
}
|
|
32
|
-
// verify entropySource
|
|
33
|
-
const payload = BytesBlob.blobFromParts(JAM_ENTROPY, sealResult.ok.raw);
|
|
34
|
-
const blockAuthorIndex = headerView.bandersnatchBlockAuthorIndex.materialize();
|
|
35
|
-
const blockAuthorKey = state.currentValidatorData.at(blockAuthorIndex)?.bandersnatch;
|
|
36
|
-
const entropySourceResult = await bandersnatchVrf.verifySeal(await this.bandersnatch, blockAuthorKey ?? BANDERSNATCH_ZERO_KEY, headerView.entropySource.materialize(), payload, BytesBlob.blobFromNumbers([]));
|
|
37
|
-
if (entropySourceResult.isError) {
|
|
38
|
-
return Result.error(SafroleSealError.IncorrectEntropySource, () => "Safrole: incorrect entropy source in header seal");
|
|
39
|
-
}
|
|
40
|
-
return Result.ok(entropySourceResult.ok);
|
|
41
|
-
}
|
|
42
|
-
async verifySeal(headerView, state) {
|
|
43
27
|
// we use transitioned keys already
|
|
44
28
|
const validatorIndex = headerView.bandersnatchBlockAuthorIndex.materialize();
|
|
45
29
|
const authorKeys = state.currentValidatorData.at(validatorIndex);
|
|
@@ -58,17 +42,21 @@ export class SafroleSeal {
|
|
|
58
42
|
async verifySealWithTicket(tickets, timeSlot, entropy, validatorData, headerView) {
|
|
59
43
|
const index = timeSlot % tickets.length;
|
|
60
44
|
const ticket = tickets.at(index);
|
|
61
|
-
|
|
62
|
-
|
|
45
|
+
if (ticket === undefined) {
|
|
46
|
+
return Result.error(SafroleSealError.IncorrectSeal, () => "Safrole: missing ticket");
|
|
47
|
+
}
|
|
48
|
+
const payload = BytesBlob.blobFromParts(JAM_TICKET_SEAL, entropy.raw, new Uint8Array([ticket.attempt]));
|
|
49
|
+
// verify seal and entropy source correctness
|
|
63
50
|
const authorKey = validatorData.bandersnatch;
|
|
64
|
-
const result = await bandersnatchVrf.
|
|
51
|
+
const result = await bandersnatchVrf.verifyHeaderSeals(await this.bandersnatch, authorKey ?? BANDERSNATCH_ZERO_KEY, headerView.seal.materialize(), payload, encodeUnsealedHeader(headerView), headerView.entropySource.materialize(), BytesBlob.blobFrom(JAM_ENTROPY));
|
|
65
52
|
if (result.isError) {
|
|
66
53
|
return Result.error(SafroleSealError.IncorrectSeal, () => "Safrole: incorrect seal with ticket");
|
|
67
54
|
}
|
|
68
|
-
|
|
69
|
-
|
|
55
|
+
const [sealOutput, entropyOutput] = result.ok;
|
|
56
|
+
if (!ticket.id.isEqualTo(sealOutput)) {
|
|
57
|
+
return Result.error(SafroleSealError.InvalidTicket, () => `Safrole: invalid ticket, expected ${ticket.id} got ${sealOutput}`);
|
|
70
58
|
}
|
|
71
|
-
return Result.ok(
|
|
59
|
+
return Result.ok(entropyOutput);
|
|
72
60
|
}
|
|
73
61
|
/** Fallback mode of Safrole. */
|
|
74
62
|
async verifySealWithKeys(keys, timeSlot, entropy, authorKey, headerView) {
|
|
@@ -78,12 +66,13 @@ export class SafroleSeal {
|
|
|
78
66
|
if (sealingKey === undefined || !sealingKey.isEqualTo(authorBandersnatchKey)) {
|
|
79
67
|
return Result.error(SafroleSealError.InvalidValidator, () => `Invalid Validator. Expected: ${sealingKey}, got: ${authorKey.bandersnatch}`);
|
|
80
68
|
}
|
|
81
|
-
// verify seal correctness
|
|
69
|
+
// verify seal and entropy source correctness
|
|
82
70
|
const payload = BytesBlob.blobFromParts(JAM_FALLBACK_SEAL, entropy.raw);
|
|
83
|
-
const result = await bandersnatchVrf.
|
|
71
|
+
const result = await bandersnatchVrf.verifyHeaderSeals(await this.bandersnatch, authorBandersnatchKey, headerView.seal.materialize(), payload, encodeUnsealedHeader(headerView), headerView.entropySource.materialize(), BytesBlob.blobFrom(JAM_ENTROPY));
|
|
84
72
|
if (result.isError) {
|
|
85
73
|
return Result.error(SafroleSealError.IncorrectSeal, () => "Safrole: incorrect seal with keys");
|
|
86
74
|
}
|
|
87
|
-
|
|
75
|
+
const [_, entropyOutput] = result.ok;
|
|
76
|
+
return Result.ok(entropyOutput);
|
|
88
77
|
}
|
|
89
78
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pvm-executor.d.ts","sourceRoot":"","sources":["../../../../../../packages/jam/transition/accumulate/pvm-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAc,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0DAA0D,CAAC;AAM7F,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,0BAA0B,CAAC;AAkBpD,KAAK,+BAA+B,GAAG;IACrC,YAAY,EAAE,YAAY,CAAC;IAC3B,kBAAkB,EAAE,OAAO,CAAC,mBAAmB,CAAC;IAChD,oBAAoB,EAAE,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC,cAAc,GAAG,OAAO,CAAC,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;CACpH,CAAC;AAEF,KAAK,+BAA+B,GAAG;IACrC,YAAY,EAAE,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC,cAAc,GAAG,OAAO,CAAC,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAC3G,kBAAkB,EAAE,OAAO,CAAC,mBAAmB,CAAC;CACjD,CAAC;AASF;;GAEG;AACH,qBAAa,WAAW;IAKpB,OAAO,CAAC,WAAW;IAEnB,OAAO,CAAC,UAAU;IANpB,OAAO,CAAC,QAAQ,CAAC,GAAG,
|
|
1
|
+
{"version":3,"file":"pvm-executor.d.ts","sourceRoot":"","sources":["../../../../../../packages/jam/transition/accumulate/pvm-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAc,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0DAA0D,CAAC;AAM7F,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,0BAA0B,CAAC;AAkBpD,KAAK,+BAA+B,GAAG;IACrC,YAAY,EAAE,YAAY,CAAC;IAC3B,kBAAkB,EAAE,OAAO,CAAC,mBAAmB,CAAC;IAChD,oBAAoB,EAAE,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC,cAAc,GAAG,OAAO,CAAC,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;CACpH,CAAC;AAEF,KAAK,+BAA+B,GAAG;IACrC,YAAY,EAAE,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC,cAAc,GAAG,OAAO,CAAC,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAC3G,kBAAkB,EAAE,OAAO,CAAC,mBAAmB,CAAC;CACjD,CAAC;AASF;;GAEG;AACH,qBAAa,WAAW;IAKpB,OAAO,CAAC,WAAW;IAEnB,OAAO,CAAC,UAAU;IANpB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAoB;IACxC,OAAO,CAAC,SAAS,CAAY;IAE7B,OAAO;mBAac,cAAc;IAInC,8CAA8C;IAC9C,OAAO,CAAC,MAAM,CAAC,0BAA0B;IAsBzC,6CAA6C;IAC7C,OAAO,CAAC,MAAM,CAAC,0BAA0B;IAazC;;;;;;OAMG;IACG,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG;;;;;;;;;;;;;IAInC,yEAAyE;WAC5D,wBAAwB,CACnC,SAAS,EAAE,SAAS,EACpB,WAAW,EAAE,SAAS,EACtB,aAAa,EAAE,+BAA+B,EAC9C,SAAS,EAAE,SAAS,EACpB,GAAG,EAAE,UAAU;IAOjB,0EAA0E;WAC7D,wBAAwB,CACnC,SAAS,EAAE,SAAS,EACpB,WAAW,EAAE,SAAS,EACtB,aAAa,EAAE,+BAA+B,EAC9C,GAAG,EAAE,UAAU;CAMlB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { accumulate, general } from "#@typeberry/jam-host-calls";
|
|
2
2
|
import { tryAsProgramCounter, } from "#@typeberry/jam-host-calls/externalities/refine-externalities.js";
|
|
3
|
-
import { HostCalls,
|
|
3
|
+
import { HostCalls, HostCallsExecutor, PvmInstanceManager } from "#@typeberry/pvm-host-calls";
|
|
4
4
|
const ACCUMULATE_HOST_CALL_CLASSES = [
|
|
5
5
|
accumulate.Bless,
|
|
6
6
|
accumulate.Assign,
|
|
@@ -38,7 +38,7 @@ export class PvmExecutor {
|
|
|
38
38
|
missing: new general.Missing(),
|
|
39
39
|
handlers: hostCallHandlers,
|
|
40
40
|
});
|
|
41
|
-
this.pvm = new
|
|
41
|
+
this.pvm = new HostCallsExecutor(pvmInstanceManager, this.hostCalls);
|
|
42
42
|
}
|
|
43
43
|
static async prepareBackend(pvm) {
|
|
44
44
|
return PvmInstanceManager.new(pvm);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"disputes.d.ts","sourceRoot":"","sources":["../../../../../../packages/jam/transition/disputes/disputes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGtE,OAAO,EAAkB,OAAO,EAA0B,MAAM,wBAAwB,CAAC;AACzF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAQ/C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAc9E,qBAAa,QAAQ;IAEjB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;aACR,KAAK,EAAE,aAAa;gBAFnB,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EACjB,KAAK,EAAE,aAAa;IAGtC,OAAO,CAAC,cAAc;IAoDtB,OAAO,CAAC,YAAY;IA8DpB,OAAO,CAAC,cAAc;IA6DtB,OAAO,CAAC,qBAAqB;IAoB7B,OAAO,CAAC,4BAA4B;IAsBpC,OAAO,CAAC,yBAAyB;IAoCjC,OAAO,CAAC,0BAA0B;IA0BlC;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;IAuBhC,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,yBAAyB;IAWjC,OAAO,CAAC,+BAA+B;IAoCvC,OAAO,CAAC,gBAAgB;
|
|
1
|
+
{"version":3,"file":"disputes.d.ts","sourceRoot":"","sources":["../../../../../../packages/jam/transition/disputes/disputes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGtE,OAAO,EAAkB,OAAO,EAA0B,MAAM,wBAAwB,CAAC;AACzF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAQ/C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAc9E,qBAAa,QAAQ;IAEjB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;aACR,KAAK,EAAE,aAAa;gBAFnB,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EACjB,KAAK,EAAE,aAAa;IAGtC,OAAO,CAAC,cAAc;IAoDtB,OAAO,CAAC,YAAY;IA8DpB,OAAO,CAAC,cAAc;IA6DtB,OAAO,CAAC,qBAAqB;IAoB7B,OAAO,CAAC,4BAA4B;IAsBpC,OAAO,CAAC,yBAAyB;IAoCjC,OAAO,CAAC,0BAA0B;IA0BlC;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;IAuBhC,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,yBAAyB;IAWjC,OAAO,CAAC,+BAA+B;IAoCvC,OAAO,CAAC,gBAAgB;IAaxB;;OAEG;IACG,UAAU,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CACpD,MAAM,CACJ;QACE,aAAa,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;QACnC,WAAW,EAAE,mBAAmB,CAAC;KAClC,EACD,iBAAiB,CAClB,CACF;CAwCF"}
|
|
@@ -291,10 +291,11 @@ export class Disputes {
|
|
|
291
291
|
const punishSetKeys = this.state.disputesRecords.punishSet;
|
|
292
292
|
const currentValidatorKeys = this.state.currentValidatorData.map((v) => v.ed25519);
|
|
293
293
|
const previousValidatorKeys = this.state.previousValidatorData.map((v) => v.ed25519);
|
|
294
|
-
const
|
|
295
|
-
|
|
296
|
-
.
|
|
297
|
-
|
|
294
|
+
const allValidatorKeysSet = HashSet.from(currentValidatorKeys.concat(previousValidatorKeys));
|
|
295
|
+
for (const key of punishSetKeys) {
|
|
296
|
+
allValidatorKeysSet.delete(key);
|
|
297
|
+
}
|
|
298
|
+
return allValidatorKeysSet;
|
|
298
299
|
}
|
|
299
300
|
/**
|
|
300
301
|
* Transition the disputes and return a list of offenders.
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { type Gas } from "#@typeberry/pvm-interface";
|
|
2
|
-
import { type HostCallHandler, type HostCallIndex, type PvmExecution } from "./host-call-handler.js";
|
|
3
|
-
import type { HostCallRegisters } from "./host-call-registers.js";
|
|
4
|
-
/** Container for all available host calls. */
|
|
5
|
-
export declare class HostCallsManager {
|
|
6
|
-
private readonly hostCalls;
|
|
7
|
-
private readonly missing;
|
|
8
|
-
constructor({ missing, handlers, }: {
|
|
9
|
-
missing: HostCallHandler;
|
|
10
|
-
handlers?: HostCallHandler[];
|
|
11
|
-
});
|
|
12
|
-
/** Get a host call by index. */
|
|
13
|
-
get(hostCallIndex: HostCallIndex): HostCallHandler;
|
|
14
|
-
traceHostCall(context: string, hostCallIndex: HostCallIndex, hostCallHandler: HostCallHandler, registers: HostCallRegisters, gas: Gas): void;
|
|
15
|
-
}
|
|
16
|
-
export declare class NoopMissing implements HostCallHandler {
|
|
17
|
-
index: number & import("@typeberry/numbers").WithBytesRepresentation<4> & import("@typeberry/utils").WithOpaque<"HostCallIndex[U32]">;
|
|
18
|
-
basicGasCost: number & import("@typeberry/numbers").WithBytesRepresentation<4> & import("@typeberry/utils").WithOpaque<"SmallGas[U32]">;
|
|
19
|
-
currentServiceId: import("@typeberry/numbers").U32;
|
|
20
|
-
tracedRegisters: never[];
|
|
21
|
-
execute(): Promise<undefined | PvmExecution>;
|
|
22
|
-
}
|
|
23
|
-
//# sourceMappingURL=host-calls-manager.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"host-calls-manager.d.ts","sourceRoot":"","sources":["../../../../../packages/core/pvm-host-calls/host-calls-manager.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,GAAG,EAAiB,MAAM,0BAA0B,CAAC;AAEnE,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,YAAY,EAElB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAIlE,8CAA8C;AAC9C,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6C;IACvE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAEb,EACV,OAAO,EACP,QAAa,GACd,EAAE;QACD,OAAO,EAAE,eAAe,CAAC;QACzB,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;KAC9B;IASD,gCAAgC;IAChC,GAAG,CAAC,aAAa,EAAE,aAAa,GAAG,eAAe;IAIlD,aAAa,CACX,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,aAAa,EAC5B,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,iBAAiB,EAC5B,GAAG,EAAE,GAAG;CAcX;AAED,qBAAa,WAAY,YAAW,eAAe;IACjD,KAAK,iIAAmC;IACxC,YAAY,4HAAoB;IAChC,gBAAgB,mCAAe;IAC/B,eAAe,UAAM;IAEf,OAAO,IAAI,OAAO,CAAC,SAAS,GAAG,YAAY,CAAC;CAGnD"}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { Logger } from "#@typeberry/logger";
|
|
2
|
-
import { tryAsU32 } from "#@typeberry/numbers";
|
|
3
|
-
import { tryAsSmallGas } from "#@typeberry/pvm-interface";
|
|
4
|
-
import { check } from "#@typeberry/utils";
|
|
5
|
-
import { tryAsHostCallIndex, } from "./host-call-handler.js";
|
|
6
|
-
const logger = Logger.new(import.meta.filename, "host-calls-pvm");
|
|
7
|
-
/** Container for all available host calls. */
|
|
8
|
-
export class HostCallsManager {
|
|
9
|
-
hostCalls = new Map();
|
|
10
|
-
missing;
|
|
11
|
-
constructor({ missing, handlers = [], }) {
|
|
12
|
-
this.missing = missing;
|
|
13
|
-
for (const handler of handlers) {
|
|
14
|
-
check `${this.hostCalls.get(handler.index) === undefined} Overwriting host call handler at index ${handler.index}`;
|
|
15
|
-
this.hostCalls.set(handler.index, handler);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
/** Get a host call by index. */
|
|
19
|
-
get(hostCallIndex) {
|
|
20
|
-
return this.hostCalls.get(hostCallIndex) ?? this.missing;
|
|
21
|
-
}
|
|
22
|
-
traceHostCall(context, hostCallIndex, hostCallHandler, registers, gas) {
|
|
23
|
-
const { currentServiceId } = hostCallHandler;
|
|
24
|
-
const requested = hostCallIndex !== hostCallHandler.index ? ` (${hostCallIndex})` : "";
|
|
25
|
-
const name = `${hostCallHandler.constructor.name}:${hostCallHandler.index}`;
|
|
26
|
-
const registerValues = hostCallHandler.tracedRegisters
|
|
27
|
-
.map((idx) => [idx.toString().padStart(2, "0"), registers.get(idx)])
|
|
28
|
-
.filter((v) => v[1] !== 0n)
|
|
29
|
-
.map(([idx, value]) => {
|
|
30
|
-
return `r${idx}=${value} (0x${value.toString(16)})`;
|
|
31
|
-
})
|
|
32
|
-
.join(", ");
|
|
33
|
-
logger.insane `[${currentServiceId}] ${context} ${name}${requested}. Gas: ${gas}. Regs: ${registerValues}.`;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
export class NoopMissing {
|
|
37
|
-
index = tryAsHostCallIndex(2 ** 32 - 1);
|
|
38
|
-
basicGasCost = tryAsSmallGas(0);
|
|
39
|
-
currentServiceId = tryAsU32(0);
|
|
40
|
-
tracedRegisters = [];
|
|
41
|
-
async execute() {
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"interpreter-instance-manager.d.ts","sourceRoot":"","sources":["../../../../../packages/core/pvm-host-calls/interpreter-instance-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAQhE,qBAAa,0BAA0B;IAGjB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAF9C,OAAO,CAAC,YAAY,CAAmB;IAEvC,OAAO;WAEM,GAAG,CAAC,WAAW,EAAE,UAAU,GAAG,OAAO,CAAC,0BAA0B,CAAC;IAmBxE,WAAW,IAAI,OAAO,CAAC,eAAe,CAAC;IAU7C,eAAe,CAAC,GAAG,EAAE,eAAe;CAOrC"}
|