EspressoSystems / HotShot

http://hotshot.docs.espressosys.com/
101 stars 25 forks source link

[CX-Marketplace] - Update `BlockRecv` Type to Support New Packed Struct #3380

Closed jparr721 closed 3 days ago

jparr721 commented 1 week ago

What is this task and why do we need to work on it?

HotShot needs to be able to accept multiple fees for a block to allow for multiple builders to submit bundles with requisite fees as a result of the Solver’s allocation result. Because of this, we’ll need to extend the flow of the Transactions task to support in-loop web requests depending on which version of the code we’re running, and combine this with the BundleAndMetadata type.

Specifically, consider this broadcast call:

broadcast_event(
    Arc::new(HotShotEvent::BlockRecv(
        block_data.block_payload.encode(),
        block_data.metadata,
        block_view,
        BuilderFee {
            fee_amount: blocks_initial_info.offered_fee,
            fee_account: block_data.sender,
            fee_signature: block_header.fee_signature,
        },
        block_header.vid_precompute_data,
    )),
    &event_stream,
)

Notice the types that are deconstructed from the BuilderResponses type. In the world where the BuilderFee is returned directly for the Bundle, we no longer need to rely on the info nor header fields as we’ll be now building those ourselves. All we need instead is the block data, which is provided via the metadata field, as it was previously. In the legacy code, this change should only affect the internal HotShot model of arranging data, but not necessarily the interaction mechanism by which other services submit blocks.

To ensure backwards compatibility, we’ll need to make a change to BlockRecv to support multiple builder fees from each builder that we’ve interacted with, but we’ll also need a more flexible type to disambiguate the fields that are now being distributed alongside the type, we’ll have a type called PackedBundle which is an internal-only HotShot type whose utility is to facilitate the following:

  1. Constructing a bundle depending on the version that we’re operating within.
  2. Disambiguating the two BuilderFee entries from the BundleAndMetadata response from the builder.

The type will be defined as:

struct PackedBundle<TYPES: NodeType> {
    payload: Arc<[u8]>,
    metadata: <TYPES::BlockPayload as BlockPayload<TYPES>>::Metadata,
    view_number: TYPES::Time,
    bid_fees: Vec1<BuilderFee<TYPES>>,
    sequencing_fees: Vec1<BuilderFee<TYPES>>,
    vid_precompute: VidPrecomputeData,
}

The existing definition of BlockRecv is defined as the following:

BlockRecv(
    Arc<[u8]>,
    <TYPES::BlockPayload as BlockPayload<TYPES>>::Metadata,
    TYPES::Time,
    BuilderFee<TYPES>,
    VidPrecomputeData,
)

The change is simple, we’ll use the Vec1 type to require at-least 1 fee (for the old code path), and we’ll index the block by the view number and include the packed data.

BlockRecv(
    TYPES::Time,
    PackedBundle<TYPES>,
)

And this should let us support the new code path. The default behavior is to make a new Vec1 with the single builder fee, and then map over the response vector of urls, query each builder, and get their content, as in the existing logic, we’ll then map over these results, extracting the relevant fee details.

Builder Failure Scenarios

What work will need to be done to complete this task?

No response

Are there any other details to include?

No response

What are the acceptance criteria to close this issue?

The new type is built for the legacy code path, no new version path will be added.

Branch work will be merged to (if not the default branch)

No response