@leofcoin/chain 1.7.133 → 1.7.135
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/chain.js +34 -2
- package/exports/chain.js +34 -2
- package/package.json +1 -1
package/exports/browser/chain.js
CHANGED
|
@@ -4754,8 +4754,11 @@ class State extends Contract {
|
|
|
4754
4754
|
});
|
|
4755
4755
|
};
|
|
4756
4756
|
this.#lastBlockHandler = async () => {
|
|
4757
|
+
const lastBlock = await this.lastBlock;
|
|
4758
|
+
// Don't advertise 0x0 as a valid block to other peers
|
|
4759
|
+
const response = lastBlock.hash !== '0x0' ? lastBlock : undefined;
|
|
4757
4760
|
return new globalThis.peernet.protos['peernet-response']({
|
|
4758
|
-
response
|
|
4761
|
+
response
|
|
4759
4762
|
});
|
|
4760
4763
|
};
|
|
4761
4764
|
this.#knownBlocksHandler = async () => {
|
|
@@ -5080,6 +5083,11 @@ class State extends Contract {
|
|
|
5080
5083
|
}
|
|
5081
5084
|
debug$1(`Local block height: ${localIndex}, remote block height: ${remoteIndex}`);
|
|
5082
5085
|
debug$1(`Local state hash: ${localStateHash}, remote block hash: ${remoteBlockHash}`);
|
|
5086
|
+
// Skip syncing if remote block hash is 0x0 (invalid state)
|
|
5087
|
+
if (remoteBlockHash === '0x0') {
|
|
5088
|
+
debug$1(`Remote block hash is 0x0, skipping sync`);
|
|
5089
|
+
return;
|
|
5090
|
+
}
|
|
5083
5091
|
// Use state hash comparison: only resolve if remote hash differs from local state hash
|
|
5084
5092
|
if (localStateHash !== remoteBlockHash) {
|
|
5085
5093
|
// Remote block hash differs from our local state, need to resolve
|
|
@@ -5251,7 +5259,7 @@ class State extends Contract {
|
|
|
5251
5259
|
promiseRequests(promises) {
|
|
5252
5260
|
return new Promise(async (resolve, reject) => {
|
|
5253
5261
|
const timeout = setTimeout(() => {
|
|
5254
|
-
resolve([
|
|
5262
|
+
resolve([]);
|
|
5255
5263
|
debug$1('sync timed out');
|
|
5256
5264
|
}, this.requestTimeout);
|
|
5257
5265
|
promises = await Promise.allSettled(promises);
|
|
@@ -5945,8 +5953,30 @@ class Chain extends VersionControl {
|
|
|
5945
5953
|
}
|
|
5946
5954
|
}
|
|
5947
5955
|
async #addBlock(block) {
|
|
5956
|
+
// Store the original received encoded bytes for validation
|
|
5957
|
+
const receivedEncoded = block instanceof BlockMessage ? block.encoded : block;
|
|
5948
5958
|
const blockMessage = await new BlockMessage(block);
|
|
5949
5959
|
const hash = await blockMessage.hash();
|
|
5960
|
+
// Verify data integrity: re-encode should produce the same bytes
|
|
5961
|
+
const canonicalEncoded = blockMessage.encoded;
|
|
5962
|
+
if (receivedEncoded.length === canonicalEncoded.length) {
|
|
5963
|
+
let mismatch = false;
|
|
5964
|
+
for (let i = 0; i < receivedEncoded.length; i++) {
|
|
5965
|
+
if (receivedEncoded[i] !== canonicalEncoded[i]) {
|
|
5966
|
+
mismatch = true;
|
|
5967
|
+
break;
|
|
5968
|
+
}
|
|
5969
|
+
}
|
|
5970
|
+
if (mismatch) {
|
|
5971
|
+
console.warn(`[chain] ⚠️ Block data corrupted in transit: encoded bytes don't match canonical form for block #${blockMessage.decoded.index}`);
|
|
5972
|
+
}
|
|
5973
|
+
else {
|
|
5974
|
+
console.log(`[chain] ✅ Block data integrity verified via codec: ${hash}`);
|
|
5975
|
+
}
|
|
5976
|
+
}
|
|
5977
|
+
else {
|
|
5978
|
+
console.warn(`[chain] ⚠️ Block data size mismatch: received ${receivedEncoded.length} bytes but canonical is ${canonicalEncoded.length} bytes for block #${blockMessage.decoded.index}`);
|
|
5979
|
+
}
|
|
5950
5980
|
const transactions = await Promise.all(blockMessage.decoded.transactions
|
|
5951
5981
|
// @ts-ignore
|
|
5952
5982
|
.map(async (hash) => {
|
|
@@ -6163,6 +6193,8 @@ class Chain extends VersionControl {
|
|
|
6163
6193
|
await this.machine.addLoadedBlock({ ...blockMessage.decoded, loaded: true, hash: await blockMessage.hash() });
|
|
6164
6194
|
await this.updateState(blockMessage);
|
|
6165
6195
|
debug(`created block: ${hash} @${block.index}`);
|
|
6196
|
+
// Publish canonical encoded form via codec interface
|
|
6197
|
+
console.log(`[chain] 📤 Publishing block #${block.index} | hash: ${hash} | encoded bytes: ${blockMessage.encoded.length}`);
|
|
6166
6198
|
globalThis.peernet.publish('add-block', blockMessage.encoded);
|
|
6167
6199
|
globalThis.pubsub.publish('add-block', blockMessage.decoded);
|
|
6168
6200
|
}
|
package/exports/chain.js
CHANGED
|
@@ -881,8 +881,11 @@ class State extends Contract {
|
|
|
881
881
|
});
|
|
882
882
|
};
|
|
883
883
|
this.#lastBlockHandler = async () => {
|
|
884
|
+
const lastBlock = await this.lastBlock;
|
|
885
|
+
// Don't advertise 0x0 as a valid block to other peers
|
|
886
|
+
const response = lastBlock.hash !== '0x0' ? lastBlock : undefined;
|
|
884
887
|
return new globalThis.peernet.protos['peernet-response']({
|
|
885
|
-
response
|
|
888
|
+
response
|
|
886
889
|
});
|
|
887
890
|
};
|
|
888
891
|
this.#knownBlocksHandler = async () => {
|
|
@@ -1207,6 +1210,11 @@ class State extends Contract {
|
|
|
1207
1210
|
}
|
|
1208
1211
|
debug$1(`Local block height: ${localIndex}, remote block height: ${remoteIndex}`);
|
|
1209
1212
|
debug$1(`Local state hash: ${localStateHash}, remote block hash: ${remoteBlockHash}`);
|
|
1213
|
+
// Skip syncing if remote block hash is 0x0 (invalid state)
|
|
1214
|
+
if (remoteBlockHash === '0x0') {
|
|
1215
|
+
debug$1(`Remote block hash is 0x0, skipping sync`);
|
|
1216
|
+
return;
|
|
1217
|
+
}
|
|
1210
1218
|
// Use state hash comparison: only resolve if remote hash differs from local state hash
|
|
1211
1219
|
if (localStateHash !== remoteBlockHash) {
|
|
1212
1220
|
// Remote block hash differs from our local state, need to resolve
|
|
@@ -1378,7 +1386,7 @@ class State extends Contract {
|
|
|
1378
1386
|
promiseRequests(promises) {
|
|
1379
1387
|
return new Promise(async (resolve, reject) => {
|
|
1380
1388
|
const timeout = setTimeout(() => {
|
|
1381
|
-
resolve([
|
|
1389
|
+
resolve([]);
|
|
1382
1390
|
debug$1('sync timed out');
|
|
1383
1391
|
}, this.requestTimeout);
|
|
1384
1392
|
promises = await Promise.allSettled(promises);
|
|
@@ -2072,8 +2080,30 @@ class Chain extends VersionControl {
|
|
|
2072
2080
|
}
|
|
2073
2081
|
}
|
|
2074
2082
|
async #addBlock(block) {
|
|
2083
|
+
// Store the original received encoded bytes for validation
|
|
2084
|
+
const receivedEncoded = block instanceof BlockMessage ? block.encoded : block;
|
|
2075
2085
|
const blockMessage = await new BlockMessage(block);
|
|
2076
2086
|
const hash = await blockMessage.hash();
|
|
2087
|
+
// Verify data integrity: re-encode should produce the same bytes
|
|
2088
|
+
const canonicalEncoded = blockMessage.encoded;
|
|
2089
|
+
if (receivedEncoded.length === canonicalEncoded.length) {
|
|
2090
|
+
let mismatch = false;
|
|
2091
|
+
for (let i = 0; i < receivedEncoded.length; i++) {
|
|
2092
|
+
if (receivedEncoded[i] !== canonicalEncoded[i]) {
|
|
2093
|
+
mismatch = true;
|
|
2094
|
+
break;
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
2097
|
+
if (mismatch) {
|
|
2098
|
+
console.warn(`[chain] ⚠️ Block data corrupted in transit: encoded bytes don't match canonical form for block #${blockMessage.decoded.index}`);
|
|
2099
|
+
}
|
|
2100
|
+
else {
|
|
2101
|
+
console.log(`[chain] ✅ Block data integrity verified via codec: ${hash}`);
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
2104
|
+
else {
|
|
2105
|
+
console.warn(`[chain] ⚠️ Block data size mismatch: received ${receivedEncoded.length} bytes but canonical is ${canonicalEncoded.length} bytes for block #${blockMessage.decoded.index}`);
|
|
2106
|
+
}
|
|
2077
2107
|
const transactions = await Promise.all(blockMessage.decoded.transactions
|
|
2078
2108
|
// @ts-ignore
|
|
2079
2109
|
.map(async (hash) => {
|
|
@@ -2290,6 +2320,8 @@ class Chain extends VersionControl {
|
|
|
2290
2320
|
await this.machine.addLoadedBlock({ ...blockMessage.decoded, loaded: true, hash: await blockMessage.hash() });
|
|
2291
2321
|
await this.updateState(blockMessage);
|
|
2292
2322
|
debug(`created block: ${hash} @${block.index}`);
|
|
2323
|
+
// Publish canonical encoded form via codec interface
|
|
2324
|
+
console.log(`[chain] 📤 Publishing block #${block.index} | hash: ${hash} | encoded bytes: ${blockMessage.encoded.length}`);
|
|
2293
2325
|
globalThis.peernet.publish('add-block', blockMessage.encoded);
|
|
2294
2326
|
globalThis.pubsub.publish('add-block', blockMessage.decoded);
|
|
2295
2327
|
}
|