Skip to content

Commit 990d11b

Browse files
authored
fix(p2p): override msg Id (#10415)
1 parent bb5f364 commit 990d11b

File tree

6 files changed

+76
-3
lines changed

6 files changed

+76
-3
lines changed

yarn-project/circuit-types/src/p2p/block_proposal.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Buffer32 } from '@aztec/foundation/buffer';
2-
import { recoverAddress } from '@aztec/foundation/crypto';
2+
import { keccak256, recoverAddress } from '@aztec/foundation/crypto';
33
import { type EthAddress } from '@aztec/foundation/eth-address';
44
import { Signature } from '@aztec/foundation/eth-signature';
55
import { type Fr } from '@aztec/foundation/fields';
@@ -42,7 +42,7 @@ export class BlockProposal extends Gossipable {
4242
}
4343

4444
override p2pMessageIdentifier(): Buffer32 {
45-
return BlockProposalHash.fromField(this.payload.archive);
45+
return new BlockProposalHash(keccak256(this.signature.toBuffer()));
4646
}
4747

4848
get archive(): Fr {

yarn-project/circuit-types/src/p2p/interface.ts

+12
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,15 @@ export const TopicTypeMap: Record<string, typeof Gossipable> = {
1717
[TopicType.block_attestation]: BlockAttestation as unknown as typeof Gossipable,
1818
[TopicType.epoch_proof_quote]: EpochProofQuote as unknown as typeof Gossipable,
1919
};
20+
21+
/**
22+
* Map from topic to deserialiser
23+
*
24+
* Used in msgIdFn libp2p to get the p2pMessageIdentifier from a message
25+
*/
26+
export const TopicToDeserializer = {
27+
[Tx.p2pTopic]: Tx.fromBuffer,
28+
[BlockProposal.p2pTopic]: BlockProposal.fromBuffer,
29+
[BlockAttestation.p2pTopic]: BlockAttestation.fromBuffer,
30+
[EpochProofQuote.p2pTopic]: EpochProofQuote.fromBuffer,
31+
};

yarn-project/p2p/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@
9191
"libp2p": "1.5.0",
9292
"semver": "^7.6.0",
9393
"sha3": "^2.1.4",
94-
"tslib": "^2.4.0"
94+
"tslib": "^2.4.0",
95+
"xxhash-wasm": "^1.1.0"
9596
},
9697
"devDependencies": {
9798
"@aztec/archiver": "workspace:^",
+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Taken from lodestar: https://github.com/ChainSafe/lodestar
2+
import { sha256 } from '@aztec/foundation/crypto';
3+
4+
import { type RPC } from '@chainsafe/libp2p-gossipsub/message';
5+
import { type Message } from '@libp2p/interface';
6+
import xxhashFactory from 'xxhash-wasm';
7+
8+
// Load WASM
9+
const xxhash = await xxhashFactory();
10+
11+
// Use salt to prevent msgId from being mined for collisions
12+
const h64Seed = BigInt(Math.floor(Math.random() * 1e9));
13+
14+
// Shared buffer to convert msgId to string
15+
const sharedMsgIdBuf = Buffer.alloc(20);
16+
17+
/**
18+
* The function used to generate a gossipsub message id
19+
* We use the first 8 bytes of SHA256(data) for content addressing
20+
*/
21+
export function fastMsgIdFn(rpcMsg: RPC.Message): string {
22+
if (rpcMsg.data) {
23+
return xxhash.h64Raw(rpcMsg.data, h64Seed).toString(16);
24+
}
25+
return '0000000000000000';
26+
}
27+
28+
export function msgIdToStrFn(msgId: Uint8Array): string {
29+
// This happens serially, no need to reallocate the buffer
30+
sharedMsgIdBuf.set(msgId);
31+
return `0x${sharedMsgIdBuf.toString('hex')}`;
32+
}
33+
34+
/**
35+
* Get the message identifier from a libp2p message
36+
*
37+
* Follows similarly to:
38+
* https://github.com/ethereum/consensus-specs/blob/v1.1.0-alpha.7/specs/altair/p2p-interface.md#topics-and-messages
39+
*
40+
* @param message - The libp2p message
41+
* @returns The message identifier
42+
*/
43+
export function getMsgIdFn(message: Message) {
44+
const { topic } = message;
45+
46+
const vec = [Buffer.from(topic), message.data];
47+
return sha256(Buffer.concat(vec)).subarray(0, 20);
48+
}

yarn-project/p2p/src/service/libp2p_service.ts

+4
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import {
4343
} from '../tx_validator/index.js';
4444
import { type PubSubLibp2p, convertToMultiaddr } from '../util.js';
4545
import { AztecDatastore } from './data_store.js';
46+
import { fastMsgIdFn, getMsgIdFn, msgIdToStrFn } from './encoding.js';
4647
import { PeerManager } from './peer_manager.js';
4748
import { PeerErrorSeverity } from './peer_scoring.js';
4849
import { pingHandler, statusHandler } from './reqresp/handlers.js';
@@ -242,6 +243,9 @@ export class LibP2PService extends WithTracer implements P2PService {
242243
heartbeatInterval: config.gossipsubInterval,
243244
mcacheLength: config.gossipsubMcacheLength,
244245
mcacheGossip: config.gossipsubMcacheGossip,
246+
msgIdFn: getMsgIdFn,
247+
msgIdToStrFn: msgIdToStrFn,
248+
fastMsgIdFn: fastMsgIdFn,
245249
metricsRegister: otelMetricsAdapter,
246250
metricsTopicStrToLabel: metricsTopicStrToLabels(),
247251
scoreParams: createPeerScoreParams({

yarn-project/yarn.lock

+8
Original file line numberDiff line numberDiff line change
@@ -924,6 +924,7 @@ __metadata:
924924
typescript: ^5.0.4
925925
uint8arrays: ^5.0.3
926926
viem: ^2.7.15
927+
xxhash-wasm: ^1.1.0
927928
languageName: unknown
928929
linkType: soft
929930

@@ -18628,6 +18629,13 @@ __metadata:
1862818629
languageName: node
1862918630
linkType: hard
1863018631

18632+
"xxhash-wasm@npm:^1.1.0":
18633+
version: 1.1.0
18634+
resolution: "xxhash-wasm@npm:1.1.0"
18635+
checksum: 2ccecb3b1dac5fefe11002d5ff5d106bbb5b506f9ee817ecf1bda65e132ebff3c82701c6727df3cb90b94a6dc1d8b294337678606f2304bcb0fd6b8dc68afe0d
18636+
languageName: node
18637+
linkType: hard
18638+
1863118639
"y18n@npm:^5.0.5":
1863218640
version: 5.0.8
1863318641
resolution: "y18n@npm:5.0.8"

0 commit comments

Comments
 (0)