Skip to content

feat(cosmos): mitigate install-bundle RPC limits by chunking #11202

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

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

michaelfig
Copy link
Member

closes: #XXXX
refs: #XXXX

Description

Security Considerations

Scaling Considerations

Documentation Considerations

Testing Considerations

Upgrade Considerations

@michaelfig michaelfig changed the title feat: mitigate agd tx swingset install-bundle RPC size limits by chunking feat(cosmos): mitigate install-bundle RPC limits by chunking Apr 2, 2025
@michaelfig michaelfig force-pushed the mfig-bundle-chunks branch from 418cd9d to cd634f7 Compare April 2, 2025 05:01
Copy link

cloudflare-workers-and-pages bot commented Apr 2, 2025

Deploying agoric-sdk with  Cloudflare Pages  Cloudflare Pages

Latest commit: 6dcbe8c
Status: ✅  Deploy successful!
Preview URL: https://c4b13578.agoric-sdk.pages.dev
Branch Preview URL: https://mfig-bundle-chunks.agoric-sdk.pages.dev

View logs

@michaelfig michaelfig force-pushed the mfig-bundle-chunks branch from cd634f7 to 7fdba5d Compare April 2, 2025 05:55
@michaelfig michaelfig force-pushed the mfig-bundle-chunks branch from 7fdba5d to 6dcbe8c Compare April 2, 2025 16:48
@michaelfig michaelfig self-assigned this Apr 3, 2025
Copy link
Member

@gibson042 gibson042 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First-pass comments, limited to the RPC/protobuf API.


option go_package = "github.com/Agoric/agoric-sdk/golang/cosmos/x/swingset/types";

// Transactions.
service Msg {
// Install a JavaScript sources bundle on the chain's SwingSet controller.
rpc InstallBundle(MsgInstallBundle) returns (MsgInstallBundleResponse);
// Send a chunk of a bundle to tolerate bandwidth constraints.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Send a chunk of a bundle to tolerate bandwidth constraints.
// Send a chunk of an artifact to tolerate RPC message size constraints.

@@ -122,18 +125,70 @@ message MsgInstallBundle {
(gogoproto.jsontag) = "submitter",
(gogoproto.moretags) = "yaml:\"submitter\""
];
// Either bundle or compressed_bundle will be set.
// Either bundle, compressed_bundle, or bundle_chunks will be set.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Either bundle, compressed_bundle, or bundle_chunks will be set.
// Of the fields for (complete, uncompressed) bundle, (complete) compressed
// bundle, and chunked bundle, exactly one must be non-empty.

Comment on lines 145 to 146
// MsgInstallBundleResponse is an empty acknowledgement that an install bundle
// message has been queued for the SwingSet kernel's consideration.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// MsgInstallBundleResponse is an empty acknowledgement that an install bundle
// message has been queued for the SwingSet kernel's consideration.
// MsgInstallBundleResponse is either an empty acknowledgement that an install
// bundle message has been queued for the SwingSet kernel's consideration, or
// (for install bundle messages that specify chunking) a container for the
// assigned id with which chunks must be associated.

}

// MsgInstallBundleResponse is an empty acknowledgement that an install bundle
// message has been queued for the SwingSet kernel's consideration.
message MsgInstallBundleResponse {}
message MsgInstallBundleResponse {
// The assigned pending installation, if chunks were specified.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// The assigned pending installation, if chunks were specified.

Comment on lines +223 to +227
// The hash of the complete bundle.
string bundle_hash = 1 [
(gogoproto.jsontag) = "bundle_hash",
(gogoproto.moretags) = "yaml:\"bundle_hash\""
];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no analog for this in MsgInstallBundle for the full uploads... what purpose is it serving here? If we're worried about corruption from someone uploading a chunk of a bundle without authority to do so, then I think we should instead be using cryptographic security (e.g., the initiator indicates authorized public keys). But in any case, we can't have such a field without documenting how to determine the associated algorithm (e.g., SHA-512).

Comment on lines +98 to +101
int64 start_block = 4 [
(gogoproto.jsontag) = "start_block",
(gogoproto.moretags) = "yaml:\"start_block\""
];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
int64 start_block = 4 [
(gogoproto.jsontag) = "start_block",
(gogoproto.moretags) = "yaml:\"start_block\""
];
int64 start_height = 4 [
(gogoproto.jsontag) = "start_height",
(gogoproto.moretags) = "yaml:\"start_height\""
];

Comment on lines +98 to +110
// The maximum number of blocks that an async installation can use. -1 is
// unlimited.
int64 installation_deadline_blocks = 7 [
(gogoproto.jsontag) = "installation_deadline_blocks",
(gogoproto.moretags) = "yaml:\"installation_deadline_blocks\""
];

// The maximum number of seconds that an async installation can use. -1 is
// unlimited.
int64 installation_deadline_seconds = 8 [
(gogoproto.jsontag) = "installation_deadline_seconds",
(gogoproto.moretags) = "yaml:\"installation_deadline_seconds\""
];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// The maximum number of blocks that an async installation can use. -1 is
// unlimited.
int64 installation_deadline_blocks = 7 [
(gogoproto.jsontag) = "installation_deadline_blocks",
(gogoproto.moretags) = "yaml:\"installation_deadline_blocks\""
];
// The maximum number of seconds that an async installation can use. -1 is
// unlimited.
int64 installation_deadline_seconds = 8 [
(gogoproto.jsontag) = "installation_deadline_seconds",
(gogoproto.moretags) = "yaml:\"installation_deadline_seconds\""
];
// The maximum number of blocks between creation of a chunked artifact and
// receipt of its final chunk. -1 is unlimited.
int64 chunked_artifact_deadline_blocks = 7 [
(gogoproto.jsontag) = "chunked_artifact_deadline_blocks",
(gogoproto.moretags) = "yaml:\"chunked_artifact_deadline_blocks\""
];
// The maximum number of seconds between creation of a chunked artifact and
// receipt of its final chunk. -1 is unlimited.
int64 chunked_artifact_deadline_seconds = 8 [
(gogoproto.jsontag) = "chunked_artifact_deadline_seconds",
(gogoproto.moretags) = "yaml:\"chunked_artifact_deadline_seconds\""
];

Comment on lines +121 to +131
// Doubly-linked list in order of start block and time.
uint64 first_pending_id = 2 [
(gogoproto.jsontag) = "first_pending_id",
(gogoproto.moretags) = "yaml:\"first_pending_id\""
];

// The last pending id that has not expired or completed.
uint64 last_pending_id = 3 [
(gogoproto.jsontag) = "last_pending_id",
(gogoproto.moretags) = "yaml:\"last_pending_id\""
];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Doubly-linked list in order of start block and time.
uint64 first_pending_id = 2 [
(gogoproto.jsontag) = "first_pending_id",
(gogoproto.moretags) = "yaml:\"first_pending_id\""
];
// The last pending id that has not expired or completed.
uint64 last_pending_id = 3 [
(gogoproto.jsontag) = "last_pending_id",
(gogoproto.moretags) = "yaml:\"last_pending_id\""
];
// The head of a doubly-linked list of pending chunked artifacts ordered by
// ascending start block and time (i.e., the ID of the oldest).
uint64 first_chunked_artifact_id = 2 [
(gogoproto.jsontag) = "first_chunked_artifact_id",
(gogoproto.moretags) = "yaml:\"first_chunked_artifact_id\""
];
// The tail of a doubly-linked list of pending chunked artifacts ordered by
// ascending start block and time (i.e., the ID of the youngest).
uint64 last_chunked_artifact_id = 3 [
(gogoproto.jsontag) = "last_chunked_artifact_id",
(gogoproto.moretags) = "yaml:\"last_chunked_artifact_id\""
];

Comment on lines +248 to +255
// The chunk is still in-flight.
CHUNK_STATE_IN_FLIGHT = 1;

// The chunk has been received.
CHUNK_STATE_RECEIVED = 2;

// The chunk has been processed.
CHUNK_STATE_PROCESSED = 3;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are the definitions of these states?

Comment on lines +279 to +284
// The pending installation node in the doubly-linked list of pending
// installations in descending order of age. This is used to track the state of
// a pending installation and to expire them efficiently.
message PendingInstallNode{
// The id of the pending bundle installation.
uint64 pending_id = 1 [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// The pending installation node in the doubly-linked list of pending
// installations in descending order of age. This is used to track the state of
// a pending installation and to expire them efficiently.
message PendingInstallNode{
// The id of the pending bundle installation.
uint64 pending_id = 1 [
// A node in the doubly-linked list of pending chunked artifacts ordered by
// ascending start block and time. This is used to efficiently expire stale
// chunked artifacts.
message PendingInstallNode{
// The id of the incomplete chunked artifact.
uint64 chunked_artifact_id = 1 [

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants