Skip to content

Commit 31ba89b

Browse files
authored
Merge pull request #273 from proto-kit/refactor/l1-messages
Refactor L1 message retrieval
2 parents 7da2dd2 + f9dd0d7 commit 31ba89b

File tree

15 files changed

+319
-80
lines changed

15 files changed

+319
-80
lines changed

packages/persistance/src/services/prisma/PrismaMessageStorage.ts

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,41 @@ export class PrismaMessageStorage implements MessageStorage {
1212
private readonly transactionMapper: TransactionMapper
1313
) {}
1414

15-
public async getMessages(
16-
fromMessageHash: string
17-
): Promise<PendingTransaction[]> {
15+
public async getMessageBatches(
16+
fromMessagesHash: string,
17+
toMessagesHash: string
18+
) {
19+
// TODO Make efficient
20+
21+
const batches: {
22+
fromMessagesHash: string;
23+
toMessagesHash: string;
24+
messages: PendingTransaction[];
25+
}[] = [];
26+
let currentHash = fromMessagesHash;
27+
28+
while (currentHash !== toMessagesHash) {
29+
// eslint-disable-next-line no-await-in-loop
30+
const batch = await this.getNextMessagesBatch(currentHash);
31+
32+
if (batch === undefined) {
33+
return batches;
34+
}
35+
36+
batches.push(batch);
37+
currentHash = batch.toMessagesHash;
38+
}
39+
return batches;
40+
}
41+
42+
public async getNextMessagesBatch(fromMessageHash: string): Promise<
43+
| {
44+
fromMessagesHash: string;
45+
toMessagesHash: string;
46+
messages: PendingTransaction[];
47+
}
48+
| undefined
49+
> {
1850
const { prismaClient } = this.connection;
1951

2052
const batch = await prismaClient.incomingMessageBatch.findFirst({
@@ -31,14 +63,22 @@ export class PrismaMessageStorage implements MessageStorage {
3163
});
3264

3365
if (batch === null) {
34-
return [];
66+
return undefined;
3567
}
3668

3769
const dbTransactions = batch.messages.map((message) => {
3870
return message.transaction;
3971
});
4072

41-
return dbTransactions.map((dbTx) => this.transactionMapper.mapIn(dbTx));
73+
const messages = dbTransactions.map((dbTx) =>
74+
this.transactionMapper.mapIn(dbTx)
75+
);
76+
77+
return {
78+
fromMessagesHash: fromMessageHash,
79+
toMessagesHash: batch.toMessageHash,
80+
messages,
81+
};
4282
}
4383

4484
public async pushMessages(

packages/persistance/src/services/prisma/PrismaSettlementStorage.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Settlement, SettlementStorage } from "@proto-kit/sequencer";
22
import { inject, injectable } from "tsyringe";
3+
import { Prisma } from "@prisma/client";
34

45
import type { PrismaConnection } from "../../PrismaDatabaseConnection";
56

@@ -12,6 +13,31 @@ export class PrismaSettlementStorage implements SettlementStorage {
1213
private readonly settlementMapper: SettlementMapper
1314
) {}
1415

16+
public async getLatestSettlement(): Promise<Settlement | undefined> {
17+
const { prismaClient } = this.connection;
18+
19+
const batch = await prismaClient.batch.findFirst({
20+
where: {
21+
settlementTransactionHash: {
22+
not: null,
23+
},
24+
},
25+
orderBy: [
26+
{
27+
height: Prisma.SortOrder.desc,
28+
},
29+
],
30+
include: {
31+
settlement: true,
32+
},
33+
});
34+
35+
if (batch !== null) {
36+
return this.settlementMapper.mapIn([batch.settlement!, []]);
37+
}
38+
return undefined;
39+
}
40+
1541
public async pushSettlement(settlement: Settlement): Promise<void> {
1642
const { prismaClient } = this.connection;
1743

packages/sequencer/src/protocol/baselayer/NoopBaseLayer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
import { BaseLayer, BaseLayerDependencyRecord } from "./BaseLayer";
1717

1818
class NoopIncomingMessageAdapter implements IncomingMessageAdapter {
19-
async getPendingMessages(
19+
async fetchPendingMessages(
2020
address: PublicKey,
2121
params: {
2222
fromActionHash: string;

packages/sequencer/src/protocol/production/sequencing/BlockProducerModule.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { inject } from "tsyringe";
22
import { log } from "@proto-kit/common";
3-
import { ACTIONS_EMPTY_HASH } from "@proto-kit/protocol";
43
import {
54
MethodIdResolver,
65
MethodParameterEncoder,
@@ -23,8 +22,8 @@ import {
2322
BlockResult,
2423
BlockWithResult,
2524
} from "../../../storage/model/Block";
26-
import { MessageStorage } from "../../../storage/repositories/MessageStorage";
2725
import { Database } from "../../../storage/Database";
26+
import { IncomingMessagesService } from "../../../settlement/messages/IncomingMessagesService";
2827

2928
import { BlockProductionService } from "./BlockProductionService";
3029
import { BlockResultService } from "./BlockResultService";
@@ -40,7 +39,7 @@ export class BlockProducerModule extends SequencerModule<BlockConfig> {
4039

4140
public constructor(
4241
@inject("Mempool") private readonly mempool: Mempool,
43-
@inject("MessageStorage") private readonly messageStorage: MessageStorage,
42+
private readonly messageService: IncomingMessagesService,
4443
@inject("UnprovenStateService")
4544
private readonly unprovenStateService: AsyncStateService,
4645
@inject("UnprovenMerkleStore")
@@ -186,10 +185,7 @@ export class BlockProducerModule extends SequencerModule<BlockConfig> {
186185
};
187186
}
188187

189-
const messages = await this.messageStorage.getMessages(
190-
parentBlock?.block.toMessagesHash.toString() ??
191-
ACTIONS_EMPTY_HASH.toString()
192-
);
188+
const messages = await this.messageService.getPendingMessages();
193189

194190
log.debug(
195191
`Block collected, ${txs.length} txs, ${messages.length} messages`

packages/sequencer/src/protocol/production/trigger/BlockTrigger.ts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import { BlockQueue } from "../../../storage/repositories/BlockStorage";
1313
import { SequencerModule } from "../../../sequencer/builder/SequencerModule";
1414
import { SettlementModule } from "../../../settlement/SettlementModule";
1515
import { Block, BlockWithResult } from "../../../storage/model/Block";
16-
import { SettlementStorage } from "../../../storage/repositories/SettlementStorage";
1716

1817
/**
1918
* A BlockTrigger is the primary method to start the production of a block and
@@ -44,8 +43,7 @@ export class BlockTriggerBase<
4443
protected readonly blockProducerModule: BlockProducerModule,
4544
protected readonly batchProducerModule: BatchProducerModule | undefined,
4645
protected readonly settlementModule: SettlementModule | undefined,
47-
protected readonly blockQueue: BlockQueue,
48-
protected readonly settlementStorage: SettlementStorage | undefined
46+
protected readonly blockQueue: BlockQueue
4947
) {
5048
super();
5149
}
@@ -96,14 +94,7 @@ export class BlockTriggerBase<
9694
);
9795
return undefined;
9896
}
99-
if (this.settlementStorage === undefined) {
100-
throw new Error(
101-
"SettlementStorage module not configured, check provided database moduel"
102-
);
103-
}
104-
const settlement = await this.settlementModule.settleBatch(batch);
105-
await this.settlementStorage.pushSettlement(settlement);
106-
return settlement;
97+
return await this.settlementModule.settleBatch(batch);
10798
}
10899

109100
public async start(): Promise<void> {

packages/sequencer/src/protocol/production/trigger/ManualBlockTrigger.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { BlockProducerModule } from "../sequencing/BlockProducerModule";
88
import { Block, BlockWithResult } from "../../../storage/model/Block";
99
import { BlockQueue } from "../../../storage/repositories/BlockStorage";
1010
import { SettlementModule } from "../../../settlement/SettlementModule";
11-
import { SettlementStorage } from "../../../storage/repositories/SettlementStorage";
1211

1312
import { BlockTrigger, BlockTriggerBase } from "./BlockTrigger";
1413

@@ -25,17 +24,14 @@ export class ManualBlockTrigger
2524
@injectOptional("SettlementModule")
2625
settlementModule: SettlementModule | undefined,
2726
@inject("BlockQueue")
28-
blockQueue: BlockQueue,
29-
@injectOptional("SettlementStorage")
30-
settlementStorage: SettlementStorage | undefined
27+
blockQueue: BlockQueue
3128
) {
3229
super(
3330
blockProducerModule,
3431
batchProducerModule,
3532
settlementModule,
3633

37-
blockQueue,
38-
settlementStorage
34+
blockQueue
3935
);
4036
}
4137

packages/sequencer/src/protocol/production/trigger/TimedBlockTrigger.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { Mempool } from "../../../mempool/Mempool";
88
import { BlockQueue } from "../../../storage/repositories/BlockStorage";
99
import { BlockProducerModule } from "../sequencing/BlockProducerModule";
1010
import { SettlementModule } from "../../../settlement/SettlementModule";
11-
import { SettlementStorage } from "../../../storage/repositories/SettlementStorage";
1211

1312
import { BlockEvents, BlockTrigger, BlockTriggerBase } from "./BlockTrigger";
1413

@@ -49,17 +48,14 @@ export class TimedBlockTrigger
4948
settlementModule: SettlementModule | undefined,
5049
@inject("BlockQueue")
5150
blockQueue: BlockQueue,
52-
@injectOptional("SettlementStorage")
53-
settlementStorage: SettlementStorage | undefined,
5451
@inject("Mempool")
5552
private readonly mempool: Mempool
5653
) {
5754
super(
5855
blockProducerModule,
5956
batchProducerModule,
6057
settlementModule,
61-
blockQueue,
62-
settlementStorage
58+
blockQueue
6359
);
6460
}
6561

packages/sequencer/src/settlement/SettlementModule.ts

Lines changed: 13 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,11 @@ import {
66
SettlementSmartContract,
77
MandatorySettlementModulesRecord,
88
MandatoryProtocolModulesRecord,
9-
BlockProverPublicOutput,
109
SettlementSmartContractBase,
1110
DynamicBlockProof,
1211
} from "@proto-kit/protocol";
1312
import {
1413
AccountUpdate,
15-
Field,
1614
Mina,
1715
PrivateKey,
1816
PublicKey,
@@ -35,15 +33,14 @@ import {
3533
SequencerModule,
3634
sequencerModule,
3735
} from "../sequencer/builder/SequencerModule";
38-
import { MessageStorage } from "../storage/repositories/MessageStorage";
3936
import type { MinaBaseLayer } from "../protocol/baselayer/MinaBaseLayer";
4037
import { Batch, SettleableBatch } from "../storage/model/Batch";
4138
import { BlockProofSerializer } from "../protocol/production/tasks/serializers/BlockProofSerializer";
4239
import { Settlement } from "../storage/model/Settlement";
4340
import { FeeStrategy } from "../protocol/baselayer/fees/FeeStrategy";
4441
import { SettlementStartupModule } from "../sequencer/SettlementStartupModule";
42+
import { SettlementStorage } from "../storage/repositories/SettlementStorage";
4543

46-
import { IncomingMessageAdapter } from "./messages/IncomingMessageAdapter";
4744
import { MinaTransactionSender } from "./transactions/MinaTransactionSender";
4845
import { ProvenSettlementPermissions } from "./permissions/ProvenSettlementPermissions";
4946
import { SignedSettlementPermissions } from "./permissions/SignedSettlementPermissions";
@@ -88,10 +85,8 @@ export class SettlementModule
8885
@inject("BaseLayer") baseLayer: MinaBaseLayer,
8986
@inject("Protocol")
9087
private readonly protocol: Protocol<MandatoryProtocolModulesRecord>,
91-
@inject("IncomingMessageAdapter")
92-
private readonly incomingMessagesAdapter: IncomingMessageAdapter,
93-
@inject("MessageStorage")
94-
private readonly messageStorage: MessageStorage,
88+
@inject("SettlementStorage")
89+
private readonly settlementStorage: SettlementStorage,
9590
private readonly blockProofSerializer: BlockProofSerializer,
9691
@inject("TransactionSender")
9792
private readonly transactionSender: MinaTransactionSender,
@@ -169,38 +164,20 @@ export class SettlementModule
169164
} = {}
170165
): Promise<Settlement> {
171166
await this.fetchContractAccounts();
172-
const { settlement, dispatch } = this.getContracts();
167+
const { settlement: settlementContract, dispatch } = this.getContracts();
173168
const { feepayer } = this.config;
174169

175170
log.debug("Preparing settlement");
176171

177172
const lastSettlementL1BlockHeight =
178-
settlement.lastSettlementL1BlockHeight.get().value;
173+
settlementContract.lastSettlementL1BlockHeight.get().value;
179174
const signature = Signature.create(feepayer, [
180175
BATCH_SIGNATURE_PREFIX,
181176
lastSettlementL1BlockHeight,
182177
]);
183178

184-
const fromSequenceStateHash = BlockProverPublicOutput.fromFields(
185-
batch.proof.publicOutput.map((x) => Field(x))
186-
).incomingMessagesHash;
187179
const latestSequenceStateHash = dispatch.account.actionState.get();
188180

189-
// Fetch actions and store them into the messageStorage
190-
const actions = await this.incomingMessagesAdapter.getPendingMessages(
191-
dispatch.address,
192-
{
193-
fromActionHash: fromSequenceStateHash.toString(),
194-
toActionHash: latestSequenceStateHash.toString(),
195-
fromL1BlockHeight: Number(lastSettlementL1BlockHeight.toString()),
196-
}
197-
);
198-
await this.messageStorage.pushMessages(
199-
actions.from,
200-
actions.to,
201-
actions.messages
202-
);
203-
204181
const blockProof = await this.blockProofSerializer
205182
.getBlockProofSerializer()
206183
.fromJSONProof(batch.proof);
@@ -215,7 +192,7 @@ export class SettlementModule
215192
memo: "Protokit settle",
216193
},
217194
async () => {
218-
await settlement.settle(
195+
await settlementContract.settle(
219196
dynamicBlockProof,
220197
signature,
221198
dispatch.address,
@@ -233,12 +210,16 @@ export class SettlementModule
233210

234211
log.info("Settlement transaction send queued");
235212

236-
this.events.emit("settlement-submitted", batch);
237-
238-
return {
213+
const settlement = {
239214
batches: [batch.height],
240215
promisedMessagesHash: latestSequenceStateHash.toString(),
241216
};
217+
218+
await this.settlementStorage.pushSettlement(settlement);
219+
220+
this.events.emit("settlement-submitted", batch);
221+
222+
return settlement;
242223
}
243224

244225
public async deploy(

packages/sequencer/src/settlement/messages/IncomingMessageAdapter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { PendingTransaction } from "../../mempool/PendingTransaction";
99
* (Dispatched Deposit Actions for example)
1010
*/
1111
export interface IncomingMessageAdapter {
12-
getPendingMessages: (
12+
fetchPendingMessages: (
1313
address: PublicKey,
1414
params: {
1515
fromActionHash: string;

0 commit comments

Comments
 (0)