-
-
Notifications
You must be signed in to change notification settings - Fork 474
feat: add getStateBuilders endpoint #9593
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 all commits
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 |
|---|---|---|
| @@ -1,9 +1,18 @@ | ||
| import {routes} from "@lodestar/api"; | ||
| import {CheckpointWithHex, IForkChoice} from "@lodestar/fork-choice"; | ||
| import {GENESIS_SLOT} from "@lodestar/params"; | ||
| import {IBeaconStateView, PubkeyCache} from "@lodestar/state-transition"; | ||
| import {BLSPubkey, Epoch, RootHex, Slot, ValidatorIndex, getValidatorStatus, phase0} from "@lodestar/types"; | ||
| import {fromHex} from "@lodestar/utils"; | ||
| import {IBeaconStateView, IBeaconStateViewGloas, PubkeyCache} from "@lodestar/state-transition"; | ||
| import { | ||
| BLSPubkey, | ||
| BuilderIndex, | ||
| Epoch, | ||
| RootHex, | ||
| Slot, | ||
| ValidatorIndex, | ||
| getValidatorStatus, | ||
| phase0, | ||
| } from "@lodestar/types"; | ||
| import {byteArrayEquals, fromHex} from "@lodestar/utils"; | ||
| import {IBeaconChain} from "../../../../chain/index.js"; | ||
| import {ApiError, ValidationError} from "../../errors.js"; | ||
|
|
||
|
|
@@ -78,6 +87,50 @@ export function toValidatorResponse( | |
| }; | ||
| } | ||
|
|
||
| type StateBuilderIndexResponse = | ||
| | {valid: true; builderIndex: BuilderIndex} | ||
| | {valid: false; code: number; reason: string}; | ||
|
|
||
| export function getStateBuilderIndex( | ||
|
Member
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. this could also be made reusable between validators/builders but I don't like to be overly DRY for the sake of it, and it would definitely become less readable, we also don't wanna couple the code too much as there might be a drift in the future between builders and validators
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. Agreed. I would keep the builder and validator paths separate here for readability and to avoid coupling them before we know whether the APIs drift. No code change from me on this thread. |
||
| id: routes.beacon.BuilderId | BLSPubkey, | ||
| state: IBeaconStateViewGloas | ||
| ): StateBuilderIndexResponse { | ||
| if (typeof id === "string") { | ||
| // mutate `id` and fallthrough to below | ||
| if (id.startsWith("0x")) { | ||
| try { | ||
| id = fromHex(id); | ||
| } catch (_e) { | ||
| return {valid: false, code: 400, reason: "Invalid pubkey hex encoding"}; | ||
| } | ||
| } else { | ||
| id = Number(id); | ||
| } | ||
| } | ||
|
|
||
| if (typeof id === "number") { | ||
| const builderIndex = id; | ||
| // builder is invalid or added later than given stateId | ||
| if (!Number.isSafeInteger(builderIndex) || builderIndex < 0) { | ||
| return {valid: false, code: 400, reason: "Invalid builder index"}; | ||
| } | ||
| if (builderIndex >= state.getBuildersLength()) { | ||
| return {valid: false, code: 404, reason: "Builder index from future state"}; | ||
| } | ||
| return {valid: true, builderIndex}; | ||
| } | ||
|
|
||
| // typeof id === Uint8Array | ||
| // There is no builder pubkey cache, linear scan over the registry | ||
| const buildersLength = state.getBuildersLength(); | ||
| for (let builderIndex = 0; builderIndex < buildersLength; builderIndex++) { | ||
| if (byteArrayEquals(state.getBuilder(builderIndex).pubkey, id)) { | ||
| return {valid: true, builderIndex}; | ||
| } | ||
| } | ||
| return {valid: false, code: 404, reason: "Builder pubkey not found in state"}; | ||
| } | ||
|
|
||
| export function filterStateValidatorsByStatus( | ||
| statuses: string[], | ||
| state: IBeaconStateView, | ||
|
|
@@ -122,7 +175,7 @@ export function getStateValidatorIndex( | |
| if (typeof id === "number") { | ||
| const validatorIndex = id; | ||
| // validator is invalid or added later than given stateId | ||
| if (!Number.isSafeInteger(validatorIndex)) { | ||
| if (!Number.isSafeInteger(validatorIndex) || validatorIndex < 0) { | ||
| return {valid: false, code: 400, reason: "Invalid validator index"}; | ||
| } | ||
| if (validatorIndex >= state.validatorCount) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -398,6 +398,14 @@ export class BeaconStateView implements IBeaconStateViewLatestFork { | |
| return (this.cachedState as CachedBeaconStateGloas).builders.getReadonly(index); | ||
| } | ||
|
|
||
| getBuildersLength(): number { | ||
|
Member
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. we might need a new binding for that cc @spiral-ladder
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. Good point. This PR already adds the TypeScript state-view surface and the native wrapper call for getBuildersLength, and the current native portability check is passing on this head. If the underlying native binding implementation needs an explicit addition, I would leave that to the native binding follow-up/owner rather than adding more JS-side churn here. |
||
| if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.gloas) { | ||
| throw new Error("Builders are not supported before Gloas"); | ||
| } | ||
|
|
||
| return (this.cachedState as CachedBeaconStateGloas).builders.length; | ||
| } | ||
|
|
||
| canBuilderCoverBid(builderIndex: BuilderIndex, bidAmount: number): boolean { | ||
| if (this.config.getForkSeq(this.cachedState.slot) < ForkSeq.gloas) { | ||
| throw new Error("Builders are not supported before Gloas"); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.