-
Notifications
You must be signed in to change notification settings - Fork 4k
dtl: add query param based querying for txs #479
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
0491ff0
5f6cf32
79df951
f5b8763
2e92209
e86ee09
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@eth-optimism/data-transport-layer": patch | ||
| --- | ||
|
|
||
| Add backwards compatible query params to REST API | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -48,9 +48,12 @@ const optionSettings = { | |
| return validators.isUrl(val) || validators.isJsonRpcProvider(val) | ||
| }, | ||
| }, | ||
| showUnconfirmedTransactions: { | ||
| validate: validators.isBoolean, | ||
| }, | ||
| defaultSource: { | ||
| default: 'batched', | ||
| validate: (val: string) => { | ||
| return val === 'batched' || val === 'sequenced' | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will we have more sources than
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if we anticipate adding more sources ['batched', 'sequenced'].includes(val)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They don't necessarily correspond to L1 and L2 per say, really the abstraction is batched or batched + pre-batched. The batched transactions are currently batched to Ethereum L1 but will be batched to an Eth2 data shard in the future. Working on unifying the language between the different codebases.
We only have 2 sources right now so I think its fine. I prefer writing JS using a subset of the language that is as C like as possible with Python sprinkled in, see https://github.com/handshake-org/hsd/blob/master/lib/blockchain/chain.js as an example |
||
| } | ||
| } | ||
| } | ||
|
|
||
| export class L1TransportServer extends BaseService<L1TransportServerOptions> { | ||
|
|
@@ -66,7 +69,6 @@ export class L1TransportServer extends BaseService<L1TransportServerOptions> { | |
| } = {} as any | ||
|
|
||
| protected async _init(): Promise<void> { | ||
| // TODO: I don't know if this is strictly necessary, but it's probably a good thing to do. | ||
| if (!this.options.db.isOpen()) { | ||
| await this.options.db.open() | ||
| } | ||
|
|
@@ -171,14 +173,26 @@ export class L1TransportServer extends BaseService<L1TransportServerOptions> { | |
| * TODO: Link to our API spec. | ||
| */ | ||
| private _registerAllRoutes(): void { | ||
| // TODO: Maybe add doc-like comments to each of these routes? | ||
|
|
||
| this._registerRoute( | ||
| 'get', | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @smartcontracts Any thoughts on how to reduce complexity in this endpoint? We need to add the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I'm talking about the crazy if/else nesting |
||
| '/eth/syncing', | ||
| async (): Promise<SyncingResponse> => { | ||
| const highestL2BlockNumber = await this.state.db.getHighestL2BlockNumber() | ||
| const currentL2Block = await this.state.db.getLatestTransaction() | ||
| async (req): Promise<SyncingResponse> => { | ||
| const source = req.query.source || this.options.defaultSource | ||
|
|
||
| let currentL2Block | ||
| let highestL2BlockNumber | ||
| switch (source) { | ||
| case 'batched': | ||
| currentL2Block = await this.state.db.getLatestTransaction() | ||
| highestL2BlockNumber = await this.state.db.getHighestL2BlockNumber() | ||
| break | ||
| case 'sequenced': | ||
| currentL2Block = await this.state.db.getLatestUnconfirmedTransaction() | ||
| highestL2BlockNumber = await this.state.db.getHighestSyncedUnconfirmedBlock() | ||
| break | ||
| default: | ||
| throw new Error(`Unknown transaction source ${source}`) | ||
| } | ||
|
|
||
| if (currentL2Block === null) { | ||
| if (highestL2BlockNumber === null) { | ||
|
|
@@ -329,21 +343,19 @@ export class L1TransportServer extends BaseService<L1TransportServerOptions> { | |
| this._registerRoute( | ||
| 'get', | ||
| '/transaction/latest', | ||
| async (): Promise<TransactionResponse> => { | ||
| let transaction = await this.state.db.getLatestFullTransaction() | ||
| if (this.options.showUnconfirmedTransactions) { | ||
| const latestUnconfirmedTx = await this.state.db.getLatestUnconfirmedTransaction() | ||
| if ( | ||
| transaction === null || | ||
| transaction === undefined || | ||
| latestUnconfirmedTx.index >= transaction.index | ||
| ) { | ||
| transaction = latestUnconfirmedTx | ||
| } | ||
| } | ||
| async (req): Promise<TransactionResponse> => { | ||
| const source = req.query.source || this.options.defaultSource | ||
| let transaction = null | ||
|
|
||
| if (transaction === null) { | ||
| transaction = await this.state.db.getLatestFullTransaction() | ||
| switch (source) { | ||
| case 'batched': | ||
| transaction = await this.state.db.getLatestFullTransaction() | ||
| break | ||
| case 'sequenced': | ||
| transaction = await this.state.db.getLatestUnconfirmedTransaction() | ||
| break | ||
| default: | ||
| throw new Error(`Unknown transaction source ${source}`) | ||
| } | ||
|
|
||
| if (transaction === null) { | ||
|
|
@@ -368,17 +380,22 @@ export class L1TransportServer extends BaseService<L1TransportServerOptions> { | |
| 'get', | ||
| '/transaction/index/:index', | ||
| async (req): Promise<TransactionResponse> => { | ||
| const source = req.query.source || this.options.defaultSource | ||
| let transaction = null | ||
| if (this.options.showUnconfirmedTransactions) { | ||
| transaction = await this.state.db.getUnconfirmedTransactionByIndex( | ||
| BigNumber.from(req.params.index).toNumber() | ||
| ) | ||
| } | ||
|
|
||
| if (transaction === null) { | ||
| transaction = await this.state.db.getFullTransactionByIndex( | ||
| BigNumber.from(req.params.index).toNumber() | ||
| ) | ||
| switch (source) { | ||
| case 'batched': | ||
| transaction = await this.state.db.getFullTransactionByIndex( | ||
| BigNumber.from(req.params.index).toNumber() | ||
| ) | ||
| break | ||
| case 'sequenced': | ||
| transaction = await this.state.db.getUnconfirmedTransactionByIndex( | ||
| BigNumber.from(req.params.index).toNumber() | ||
| ) | ||
| break | ||
| default: | ||
| throw new Error(`Unknown transaction source ${source}`) | ||
| } | ||
|
|
||
| if (transaction === null) { | ||
|
|
@@ -456,21 +473,19 @@ export class L1TransportServer extends BaseService<L1TransportServerOptions> { | |
| this._registerRoute( | ||
| 'get', | ||
| '/stateroot/latest', | ||
| async (): Promise<StateRootResponse> => { | ||
| let stateRoot = await this.state.db.getLatestStateRoot() | ||
| if (this.options.showUnconfirmedTransactions) { | ||
| const latestUnconfirmedStateRoot = await this.state.db.getLatestUnconfirmedStateRoot() | ||
| if ( | ||
| stateRoot === null || | ||
| stateRoot === undefined || | ||
| latestUnconfirmedStateRoot.index >= stateRoot.index | ||
| ) { | ||
| stateRoot = latestUnconfirmedStateRoot | ||
| } | ||
| } | ||
| async (req): Promise<StateRootResponse> => { | ||
| const source = req.query.source || this.options.defaultSource | ||
| let stateRoot = null | ||
|
|
||
| if (stateRoot === null) { | ||
| stateRoot = await this.state.db.getLatestStateRoot() | ||
| switch (source) { | ||
| case 'batched': | ||
| stateRoot = await this.state.db.getLatestStateRoot() | ||
| break | ||
| case 'sequenced': | ||
| stateRoot = await this.state.db.getLatestUnconfirmedStateRoot() | ||
| break | ||
| default: | ||
| throw new Error(`Unknown transaction source ${source}`) | ||
| } | ||
|
|
||
| if (stateRoot === null) { | ||
|
|
@@ -495,17 +510,22 @@ export class L1TransportServer extends BaseService<L1TransportServerOptions> { | |
| 'get', | ||
| '/stateroot/index/:index', | ||
| async (req): Promise<StateRootResponse> => { | ||
| const source = req.query.source || this.options.defaultSource | ||
| let stateRoot = null | ||
| if (this.options.showUnconfirmedTransactions) { | ||
| stateRoot = await this.state.db.getUnconfirmedStateRootByIndex( | ||
| BigNumber.from(req.params.index).toNumber() | ||
| ) | ||
| } | ||
|
|
||
| if (stateRoot === null) { | ||
| stateRoot = await this.state.db.getStateRootByIndex( | ||
| BigNumber.from(req.params.index).toNumber() | ||
| ) | ||
| switch (source) { | ||
| case 'batched': | ||
| stateRoot = await this.state.db.getStateRootByIndex( | ||
| BigNumber.from(req.params.index).toNumber() | ||
| ) | ||
| break | ||
| case 'sequenced': | ||
| stateRoot = await this.state.db.getUnconfirmedStateRootByIndex( | ||
| BigNumber.from(req.params.index).toNumber() | ||
| ) | ||
| break | ||
| default: | ||
| throw new Error(`Unknown transaction source ${source}`) | ||
| } | ||
|
|
||
| if (stateRoot === null) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: May want to make your message a bit clearer, I do not understand what you changed just by reading this.
Something like: Allow the DTL to provide data from either L1 or L2, configurable via a query param sent by the client.