Skip to content

Commit

Permalink
feat(reqresp): request l2 blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
Maddiaa0 committed Jan 20, 2025
1 parent df0bc25 commit b69b464
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 4 deletions.
2 changes: 2 additions & 0 deletions yarn-project/p2p/src/mocks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ export const MOCK_SUB_PROTOCOL_HANDLERS: ReqRespSubProtocolHandlers = {
[ReqRespSubProtocol.STATUS]: statusHandler,
[ReqRespSubProtocol.TX]: (_msg: any) => Promise.resolve(Buffer.from('tx')),
[ReqRespSubProtocol.GOODBYE]: (_msg: any) => Promise.resolve(Buffer.from('goodbye')),
[ReqRespSubProtocol.BLOCK]: (_msg: any) => Promise.resolve(Buffer.from('block')),
};

// By default, all requests are valid
Expand All @@ -162,6 +163,7 @@ export const MOCK_SUB_PROTOCOL_VALIDATORS: ReqRespSubProtocolValidators = {
[ReqRespSubProtocol.STATUS]: noopValidator,
[ReqRespSubProtocol.TX]: noopValidator,
[ReqRespSubProtocol.GOODBYE]: noopValidator,
[ReqRespSubProtocol.BLOCK]: noopValidator,
};

/**
Expand Down
6 changes: 4 additions & 2 deletions yarn-project/p2p/src/services/libp2p/libp2p_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ import { PeerManager } from '../peer-manager/peer_manager.js';
import { PeerScoring } from '../peer-manager/peer_scoring.js';
import { DEFAULT_SUB_PROTOCOL_VALIDATORS, ReqRespSubProtocol, type SubProtocolMap } from '../reqresp/interface.js';
import { reqGoodbyeHandler } from '../reqresp/protocols/goodbye.js';
import { pingHandler, statusHandler } from '../reqresp/protocols/index.js';
import { reqRespTxHandler } from '../reqresp/protocols/tx.js';
import { pingHandler, reqRespBlockHandler, reqRespTxHandler, statusHandler } from '../reqresp/protocols/index.js';
import { ReqResp } from '../reqresp/reqresp.js';
import type { P2PService, PeerDiscoveryService } from '../service.js';
import { GossipSubEvent } from '../types.js';
Expand Down Expand Up @@ -300,12 +299,14 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
// Create request response protocol handlers
const txHandler = reqRespTxHandler(this.mempools);
const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
const blockHandler = reqRespBlockHandler(this.l2BlockSource);

const requestResponseHandlers = {
[ReqRespSubProtocol.PING]: pingHandler,
[ReqRespSubProtocol.STATUS]: statusHandler,
[ReqRespSubProtocol.TX]: txHandler.bind(this),
[ReqRespSubProtocol.GOODBYE]: goodbyeHandler.bind(this),
[ReqRespSubProtocol.BLOCK]: blockHandler.bind(this),
};

// Add p2p topic validators
Expand Down Expand Up @@ -335,6 +336,7 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
// Define the sub protocol validators - This is done within this start() method to gain a callback to the existing validateTx function
const reqrespSubProtocolValidators = {
...DEFAULT_SUB_PROTOCOL_VALIDATORS,
// TODO(#11336): A request validator for blocks
[ReqRespSubProtocol.TX]: this.validateRequestedTx.bind(this),
};
await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators);
Expand Down
11 changes: 10 additions & 1 deletion yarn-project/p2p/src/services/reqresp/interface.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Tx, TxHash } from '@aztec/circuit-types';
import { L2Block, Tx, TxHash } from '@aztec/circuit-types';
import { Fr } from '@aztec/foundation/fields';

import { type PeerId } from '@libp2p/interface';

Expand All @@ -9,12 +10,14 @@ export const PING_PROTOCOL = '/aztec/req/ping/0.1.0';
export const STATUS_PROTOCOL = '/aztec/req/status/0.1.0';
export const GOODBYE_PROTOCOL = '/aztec/req/goodbye/0.1.0';
export const TX_REQ_PROTOCOL = '/aztec/req/tx/0.1.0';
export const BLOCK_REQ_PROTOCOL = '/aztec/req/block/0.1.0';

export enum ReqRespSubProtocol {
PING = PING_PROTOCOL,
STATUS = STATUS_PROTOCOL,
GOODBYE = GOODBYE_PROTOCOL,
TX = TX_REQ_PROTOCOL,
BLOCK = BLOCK_REQ_PROTOCOL,
}

/**
Expand Down Expand Up @@ -75,6 +78,7 @@ export const DEFAULT_SUB_PROTOCOL_VALIDATORS: ReqRespSubProtocolValidators = {
[ReqRespSubProtocol.STATUS]: noopValidator,
[ReqRespSubProtocol.TX]: noopValidator,
[ReqRespSubProtocol.GOODBYE]: noopValidator,
[ReqRespSubProtocol.BLOCK]: noopValidator,
};

/**
Expand All @@ -101,6 +105,7 @@ export const DEFAULT_SUB_PROTOCOL_HANDLERS: ReqRespSubProtocolHandlers = {
[ReqRespSubProtocol.STATUS]: defaultHandler,
[ReqRespSubProtocol.TX]: defaultHandler,
[ReqRespSubProtocol.GOODBYE]: defaultHandler,
[ReqRespSubProtocol.BLOCK]: defaultHandler,
};

/**
Expand Down Expand Up @@ -158,4 +163,8 @@ export const subProtocolMap: SubProtocolMap = {
request: RequestableBuffer,
response: RequestableBuffer,
},
[ReqRespSubProtocol.BLOCK]: {
request: Fr, // block number
response: L2Block,
},
};
15 changes: 15 additions & 0 deletions yarn-project/p2p/src/services/reqresp/protocols/block.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { type L2BlockSource } from '@aztec/circuit-types';
import { Fr } from '@aztec/foundation/fields';

import { type PeerId } from '@libp2p/interface';

import { type ReqRespSubProtocolHandler } from '../interface.js';

export function reqRespBlockHandler(l2BlockSource: L2BlockSource): ReqRespSubProtocolHandler {
return async (_peerId: PeerId, msg: Buffer) => {
const blockNumber = Fr.fromBuffer(msg);

const foundBlock = await l2BlockSource.getBlock(Number(blockNumber));
return foundBlock ? foundBlock.toBuffer() : Buffer.alloc(0);
};
}
1 change: 1 addition & 0 deletions yarn-project/p2p/src/services/reqresp/protocols/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from './ping.js';
export * from './status.js';
export * from './tx.js';
export * from './goodbye.js';
export * from './block.js';
10 changes: 10 additions & 0 deletions yarn-project/p2p/src/services/reqresp/rate-limiter/rate_limits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ export const DEFAULT_RATE_LIMITS: ReqRespSubProtocolRateLimits = {
quotaCount: 10,
},
},
[ReqRespSubProtocol.BLOCK]: {
peerLimit: {
quotaTimeMs: 1000,
quotaCount: 2,
},
globalLimit: {
quotaTimeMs: 1000,
quotaCount: 5,
},
},
[ReqRespSubProtocol.GOODBYE]: {
peerLimit: {
quotaTimeMs: 1000,
Expand Down
30 changes: 29 additions & 1 deletion yarn-project/p2p/src/services/reqresp/reqresp.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { PeerErrorSeverity, TxHash, mockTx } from '@aztec/circuit-types';
import { L2Block, type L2BlockSource, PeerErrorSeverity, TxHash, mockTx } from '@aztec/circuit-types';
import { Fr } from '@aztec/foundation/fields';
import { createLogger } from '@aztec/foundation/log';
import { sleep } from '@aztec/foundation/sleep';

Expand All @@ -19,6 +20,7 @@ import {
import { type PeerManager } from '../peer-manager/peer_manager.js';
import { type PeerScoring } from '../peer-manager/peer_scoring.js';
import { ReqRespSubProtocol, RequestableBuffer } from './interface.js';
import { reqRespBlockHandler } from './protocols/block.js';
import { GoodByeReason, reqGoodbyeHandler } from './protocols/goodbye.js';

const PING_REQUEST = RequestableBuffer.fromBuffer(Buffer.from('ping'));
Expand Down Expand Up @@ -341,6 +343,32 @@ describe('ReqResp', () => {
});
});

describe('Block protocol', () => {
it('should handle block requests', async () => {
const blockNumber = 1;
const blockNumberFr = Fr.ONE;
const block = L2Block.random(blockNumber);

const l2BlockSource: MockProxy<L2BlockSource> = mock<L2BlockSource>();
l2BlockSource.getBlock.mockImplementation((_blockNumber: number) => {
return Promise.resolve(block);
});

const protocolHandlers = MOCK_SUB_PROTOCOL_HANDLERS;
protocolHandlers[ReqRespSubProtocol.BLOCK] = reqRespBlockHandler(l2BlockSource);

nodes = await createNodes(peerScoring, 2);

await startNodes(nodes, protocolHandlers);
await sleep(500);
await connectToPeers(nodes);
await sleep(500);

const res = await nodes[0].req.sendRequest(ReqRespSubProtocol.BLOCK, blockNumberFr);
expect(res).toEqual(block);
});
});

describe('Batch requests', () => {
it('should send a batch request between many peers', async () => {
const batchSize = 9;
Expand Down

0 comments on commit b69b464

Please sign in to comment.