@leofcoin/chain 1.10.6 → 1.10.7
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/exports/browser/{browser-D-r0O9Qn-8WfVE0Ux.js → browser-D-r0O9Qn-BZDYY6cg.js} +2 -2
- package/exports/browser/{browser-_hiyXwPp-DAxbV-UB.js → browser-_hiyXwPp-DYI1tyUr.js} +2 -2
- package/exports/browser/chain.js +112 -122
- package/exports/browser/{client-BVhUamQG-z0FD6cVJ.js → client-BVhUamQG-D-D1e_x8.js} +4 -4
- package/exports/browser/{constants-CVkCJ-VS.js → constants-gMYZLHKp.js} +1 -1
- package/exports/browser/{index-BD0Anx7_-Dgedz8qH.js → index-BD0Anx7_-Dg4_tCeN.js} +2 -2
- package/exports/browser/{messages-UKnuelZ7-CjCqR-Qe.js → messages-UKnuelZ7-DJT-98q-.js} +2 -2
- package/exports/browser/{node-browser-sxrQkd7t.js → node-browser-DlzZ5CP_.js} +4 -4
- package/exports/browser/node-browser.js +2 -2
- package/exports/browser/workers/machine-worker.js +8 -8
- package/exports/chain.js +102 -112
- package/exports/workers/machine-worker.js +8 -8
- package/package.json +1 -1
package/exports/chain.js
CHANGED
|
@@ -1115,6 +1115,87 @@ class Jobber {
|
|
|
1115
1115
|
}
|
|
1116
1116
|
}
|
|
1117
1117
|
|
|
1118
|
+
const MAX_RESPONSE_DEPTH$1 = 3;
|
|
1119
|
+
const asLastBlockMessage = async (blockInput, claimedHash) => {
|
|
1120
|
+
const block = new BlockMessage(blockInput);
|
|
1121
|
+
const hash = await block.hash();
|
|
1122
|
+
if (claimedHash && hash !== claimedHash) {
|
|
1123
|
+
throw new Error(`lastBlock hash mismatch: expected ${claimedHash}, got ${hash}`);
|
|
1124
|
+
}
|
|
1125
|
+
return new LastBlockMessage({ hash, index: block.decoded.index });
|
|
1126
|
+
};
|
|
1127
|
+
const resolveLegacyHash = async (hash) => {
|
|
1128
|
+
const blockData = await globalThis.peernet?.get?.(hash, "block");
|
|
1129
|
+
if (!blockData) throw new Error(`unable to resolve lastBlock hash: ${hash}`);
|
|
1130
|
+
return asLastBlockMessage(blockData, hash);
|
|
1131
|
+
};
|
|
1132
|
+
const resolveLastBlockMessage = async (result, depth = 0) => {
|
|
1133
|
+
if (depth > MAX_RESPONSE_DEPTH$1) throw new Error("lastBlock response nesting exceeds limit");
|
|
1134
|
+
if (result instanceof Uint8Array) {
|
|
1135
|
+
let codec;
|
|
1136
|
+
try {
|
|
1137
|
+
codec = new Codec(result);
|
|
1138
|
+
} catch {
|
|
1139
|
+
}
|
|
1140
|
+
if (codec) {
|
|
1141
|
+
if (codec.name === "peernet-response") {
|
|
1142
|
+
const ResponseMessage = globalThis.peernet?.protos?.["peernet-response"];
|
|
1143
|
+
if (!ResponseMessage) throw new Error("peernet-response codec is not registered");
|
|
1144
|
+
const wrapped = new ResponseMessage(result);
|
|
1145
|
+
if (wrapped?.decoded?.response === void 0) throw new Error("peernet-response has no response payload");
|
|
1146
|
+
return resolveLastBlockMessage(wrapped.decoded.response, depth + 1);
|
|
1147
|
+
}
|
|
1148
|
+
if (codec.name === "last-block-message") return new LastBlockMessage(result);
|
|
1149
|
+
if (codec.name === "block-message") return asLastBlockMessage(result);
|
|
1150
|
+
}
|
|
1151
|
+
const candidate = new TextDecoder().decode(result);
|
|
1152
|
+
if (candidate) return resolveLegacyHash(candidate);
|
|
1153
|
+
}
|
|
1154
|
+
if (typeof result === "string") return resolveLegacyHash(result);
|
|
1155
|
+
if (result && typeof result === "object") {
|
|
1156
|
+
const response = result.decoded?.response ?? result.response;
|
|
1157
|
+
if (response !== void 0) return resolveLastBlockMessage(response, depth + 1);
|
|
1158
|
+
if ("hash" in result && "index" in result) return new LastBlockMessage(result);
|
|
1159
|
+
if ("previousHash" in result && "index" in result) return asLastBlockMessage(result);
|
|
1160
|
+
}
|
|
1161
|
+
throw new Error(`invalid lastBlock payload: ${typeof result}`);
|
|
1162
|
+
};
|
|
1163
|
+
|
|
1164
|
+
const MAX_RESPONSE_DEPTH = 3;
|
|
1165
|
+
const decodeResponsePayload = async (result, depth = 0) => {
|
|
1166
|
+
if (depth > MAX_RESPONSE_DEPTH) throw new Error("peernet response nesting exceeds limit");
|
|
1167
|
+
if (result instanceof Uint8Array) {
|
|
1168
|
+
let codec;
|
|
1169
|
+
try {
|
|
1170
|
+
codec = new Codec(result);
|
|
1171
|
+
} catch {
|
|
1172
|
+
}
|
|
1173
|
+
if (codec?.name === "peernet-response") {
|
|
1174
|
+
const ResponseMessage = globalThis.peernet?.protos?.["peernet-response"];
|
|
1175
|
+
if (!ResponseMessage) throw new Error("peernet-response codec is not registered");
|
|
1176
|
+
const wrapped = new ResponseMessage(result);
|
|
1177
|
+
return decodeResponsePayload(wrapped.decoded.response, depth + 1);
|
|
1178
|
+
}
|
|
1179
|
+
try {
|
|
1180
|
+
return JSON.parse(new TextDecoder().decode(result));
|
|
1181
|
+
} catch {
|
|
1182
|
+
return result;
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
if (result && typeof result === "object") {
|
|
1186
|
+
const response = result.decoded?.response ?? result.response;
|
|
1187
|
+
if (response !== void 0) return decodeResponsePayload(response, depth + 1);
|
|
1188
|
+
}
|
|
1189
|
+
if (typeof result === "string") {
|
|
1190
|
+
try {
|
|
1191
|
+
return JSON.parse(result);
|
|
1192
|
+
} catch {
|
|
1193
|
+
return result;
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
return result;
|
|
1197
|
+
};
|
|
1198
|
+
|
|
1118
1199
|
const debug$1 = createDebugger("leofcoin/state");
|
|
1119
1200
|
class State extends Contract {
|
|
1120
1201
|
constructor(config) {
|
|
@@ -1194,42 +1275,6 @@ class State extends Contract {
|
|
|
1194
1275
|
get resolving() {
|
|
1195
1276
|
return this.#resolving;
|
|
1196
1277
|
}
|
|
1197
|
-
async #resolveLastBlockMessage(result) {
|
|
1198
|
-
if (result instanceof Uint8Array) {
|
|
1199
|
-
try {
|
|
1200
|
-
let payload = result;
|
|
1201
|
-
for (let i = 0; i < 3; i += 1) {
|
|
1202
|
-
try {
|
|
1203
|
-
const wrapped = await new globalThis.peernet.protos["peernet-response"](payload);
|
|
1204
|
-
if (wrapped?.decoded?.response === void 0) break;
|
|
1205
|
-
payload = wrapped.decoded.response;
|
|
1206
|
-
} catch {
|
|
1207
|
-
break;
|
|
1208
|
-
}
|
|
1209
|
-
}
|
|
1210
|
-
if (payload !== result) return this.#resolveLastBlockMessage(payload);
|
|
1211
|
-
return new LastBlockMessage(result);
|
|
1212
|
-
} catch {
|
|
1213
|
-
const candidate = new TextDecoder().decode(result);
|
|
1214
|
-
if (candidate) {
|
|
1215
|
-
const blockData = await globalThis.peernet.get(candidate, "block");
|
|
1216
|
-
if (blockData) return new BlockMessage(blockData);
|
|
1217
|
-
}
|
|
1218
|
-
}
|
|
1219
|
-
}
|
|
1220
|
-
if (typeof result === "string") {
|
|
1221
|
-
const blockData = await globalThis.peernet.get(result, "block");
|
|
1222
|
-
if (blockData) return new BlockMessage(blockData);
|
|
1223
|
-
}
|
|
1224
|
-
if (result && typeof result === "object") {
|
|
1225
|
-
const response = result.decoded?.response ?? result.response;
|
|
1226
|
-
if (response !== void 0) return this.#resolveLastBlockMessage(response);
|
|
1227
|
-
if ("hash" in result && "index" in result) {
|
|
1228
|
-
return new LastBlockMessage(result);
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
|
-
throw new Error(`invalid lastBlock payload: ${typeof result}`);
|
|
1232
|
-
}
|
|
1233
1278
|
get contracts() {
|
|
1234
1279
|
return this.#machine.contracts;
|
|
1235
1280
|
}
|
|
@@ -1674,21 +1719,9 @@ class State extends Contract {
|
|
|
1674
1719
|
compatiblePeerCount += 1;
|
|
1675
1720
|
const task = async () => {
|
|
1676
1721
|
try {
|
|
1677
|
-
|
|
1722
|
+
const result = await peer.request(node.encoded);
|
|
1678
1723
|
const resultType = result instanceof Uint8Array ? `bytes:${result.length}` : typeof result;
|
|
1679
1724
|
debug$1(`lastBlock result type: ${resultType}`);
|
|
1680
|
-
console.log({ result });
|
|
1681
|
-
if (result instanceof Uint8Array) {
|
|
1682
|
-
for (let i = 0; i < 3; i += 1) {
|
|
1683
|
-
try {
|
|
1684
|
-
const wrapped = await new globalThis.peernet.protos["peernet-response"](result);
|
|
1685
|
-
if (wrapped?.decoded?.response === void 0) break;
|
|
1686
|
-
result = wrapped.decoded.response;
|
|
1687
|
-
} catch {
|
|
1688
|
-
break;
|
|
1689
|
-
}
|
|
1690
|
-
}
|
|
1691
|
-
}
|
|
1692
1725
|
return { result, peer };
|
|
1693
1726
|
} catch (error) {
|
|
1694
1727
|
const peerId = peer?.peerId || peer?.id || peer?.address || "unknown";
|
|
@@ -1712,7 +1745,7 @@ class State extends Contract {
|
|
|
1712
1745
|
console.log({ promises });
|
|
1713
1746
|
promises = await Promise.all(
|
|
1714
1747
|
promises.map(async (item) => ({
|
|
1715
|
-
value: (await
|
|
1748
|
+
value: (await resolveLastBlockMessage(item.value)).decoded,
|
|
1716
1749
|
peer: item.peer
|
|
1717
1750
|
}))
|
|
1718
1751
|
);
|
|
@@ -1733,10 +1766,11 @@ class State extends Contract {
|
|
|
1733
1766
|
});
|
|
1734
1767
|
let node2 = await globalThis.peernet.prepareMessage(data2);
|
|
1735
1768
|
try {
|
|
1736
|
-
|
|
1737
|
-
|
|
1769
|
+
const message2 = await decodeResponsePayload(await peer.request(node2.encoded));
|
|
1770
|
+
const blocks = message2?.blocks;
|
|
1771
|
+
if (!Array.isArray(blocks)) throw new Error("knownBlocks response does not contain a blocks array");
|
|
1738
1772
|
const MAX_WANTLIST_SIZE = 1e3;
|
|
1739
|
-
const incoming =
|
|
1773
|
+
const incoming = blocks.filter((block) => !this.knownBlocks.includes(block));
|
|
1740
1774
|
const remaining = MAX_WANTLIST_SIZE - this.wantList.length;
|
|
1741
1775
|
if (remaining > 0) this.wantList.push(...incoming.slice(0, remaining));
|
|
1742
1776
|
} catch (error) {
|
|
@@ -1816,28 +1850,20 @@ class State extends Contract {
|
|
|
1816
1850
|
this.#chainState = "loaded";
|
|
1817
1851
|
return true;
|
|
1818
1852
|
}
|
|
1819
|
-
promiseRequests(promises) {
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
return { value: node.decoded.response, peer: value.peer };
|
|
1834
|
-
});
|
|
1835
|
-
promises = await Promise.all(promises);
|
|
1836
|
-
resolve(promises);
|
|
1837
|
-
} else {
|
|
1838
|
-
resolve([]);
|
|
1839
|
-
}
|
|
1840
|
-
});
|
|
1853
|
+
async promiseRequests(promises) {
|
|
1854
|
+
let timeout;
|
|
1855
|
+
const settled = await Promise.race([
|
|
1856
|
+
Promise.allSettled(promises),
|
|
1857
|
+
new Promise((resolve) => {
|
|
1858
|
+
timeout = setTimeout(() => resolve(null), this.requestTimeout);
|
|
1859
|
+
})
|
|
1860
|
+
]);
|
|
1861
|
+
clearTimeout(timeout);
|
|
1862
|
+
if (settled === null) {
|
|
1863
|
+
debug$1("sync timed out");
|
|
1864
|
+
return [];
|
|
1865
|
+
}
|
|
1866
|
+
return settled.filter(({ status }) => status === "fulfilled").map(({ value }) => ({ value: value.result, peer: value.peer }));
|
|
1841
1867
|
}
|
|
1842
1868
|
get canSync() {
|
|
1843
1869
|
if (this.#chainSyncing) return false;
|
|
@@ -2905,42 +2931,6 @@ class Chain extends VersionControl {
|
|
|
2905
2931
|
throw error;
|
|
2906
2932
|
}
|
|
2907
2933
|
}
|
|
2908
|
-
async #resolveLastBlockMessage(result) {
|
|
2909
|
-
if (result instanceof Uint8Array) {
|
|
2910
|
-
try {
|
|
2911
|
-
let payload = result;
|
|
2912
|
-
for (let i = 0; i < 3; i += 1) {
|
|
2913
|
-
try {
|
|
2914
|
-
const wrapped = await new globalThis.peernet.protos["peernet-response"](payload);
|
|
2915
|
-
if (wrapped?.decoded?.response === void 0) break;
|
|
2916
|
-
payload = wrapped.decoded.response;
|
|
2917
|
-
} catch {
|
|
2918
|
-
break;
|
|
2919
|
-
}
|
|
2920
|
-
}
|
|
2921
|
-
if (payload !== result) return this.#resolveLastBlockMessage(payload);
|
|
2922
|
-
return new LastBlockMessage(result);
|
|
2923
|
-
} catch {
|
|
2924
|
-
const candidate = new TextDecoder().decode(result);
|
|
2925
|
-
if (candidate) {
|
|
2926
|
-
const blockData = await globalThis.peernet.get(candidate, "block");
|
|
2927
|
-
if (blockData) return new BlockMessage(blockData);
|
|
2928
|
-
}
|
|
2929
|
-
}
|
|
2930
|
-
}
|
|
2931
|
-
if (typeof result === "string") {
|
|
2932
|
-
const blockData = await globalThis.peernet.get(result, "block");
|
|
2933
|
-
if (blockData) return new BlockMessage(blockData);
|
|
2934
|
-
}
|
|
2935
|
-
if (result && typeof result === "object") {
|
|
2936
|
-
const response = result.decoded?.response ?? result.response;
|
|
2937
|
-
if (response !== void 0) return this.#resolveLastBlockMessage(response);
|
|
2938
|
-
if ("hash" in result && "index" in result) {
|
|
2939
|
-
return new LastBlockMessage(result);
|
|
2940
|
-
}
|
|
2941
|
-
}
|
|
2942
|
-
throw new Error(`invalid lastBlock payload: ${typeof result}`);
|
|
2943
|
-
}
|
|
2944
2934
|
async #decodeKnownBlocksResponse(response) {
|
|
2945
2935
|
if (!response) return null;
|
|
2946
2936
|
if (Array.isArray(response)) {
|
|
@@ -3073,7 +3063,7 @@ class Chain extends VersionControl {
|
|
|
3073
3063
|
if (lastBlockRaw === void 0 || lastBlockRaw === null) {
|
|
3074
3064
|
throw new Error(`invalid lastBlock payload: ${typeof lastBlockRaw}`);
|
|
3075
3065
|
}
|
|
3076
|
-
const lastBlockMessage = await
|
|
3066
|
+
const lastBlockMessage = await resolveLastBlockMessage(lastBlockRaw);
|
|
3077
3067
|
console.log(lastBlockMessage);
|
|
3078
3068
|
lastBlock = lastBlockMessage.decoded;
|
|
3079
3069
|
} catch (error) {
|