Skip to content
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

ENG-326: Full Node Commitments #58

Merged
merged 113 commits into from
May 28, 2024
Merged

Conversation

l-monninger
Copy link
Collaborator

@l-monninger l-monninger commented May 13, 2024

Summary

Add MCR commitment processing to Suzuka full node.

Changelog

  • Suzuka full node settless block commitments with the MCR contract.

Testing

  • Unit tests of mcr-settlement-manager using the mock of mcr-settlement-client.

Design

full-node-commitments

  1. The top portion of the graphic above shows a high-level overview of dataflow in the system. Full-nodes execute blocks, generate commitments for the block, and then wait for events from the settlement contract.
  2. The bottom part shows an asynchronous pattern for this scheme wherein a commitment loop is responsible for handling the actual submission via the client to the settlement contract. This may be desirable for a few reasons:
    1. Execution can still optimistically proceed, i.e., does not have to wait on a commitment to be accepted.
    2. Honest nodes can still avoid making faulty commitments. The job of withholding these commitments is just delegated to the commitment loop.
    3. Separation of concern makes it easier to deal with batching and adjustments faulty commitment avoidance scheme (multisig).
    4. This can be generalized to a very generic MCR commitment service if the demand presents itself in the SDK.

Entrypoints for understanding

MCR Settlement Client (Stub): https://github.com/movementlabsxyz/movement/tree/eng-326/full-node-commitments/protocol-units/settlement/mcr/client

@l-monninger l-monninger marked this pull request as draft May 13, 2024 05:00
@l-monninger
Copy link
Collaborator Author

We'll use the working CI.

Copy link
Contributor

@0xmovses 0xmovses left a comment

Choose a reason for hiding this comment

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

One comment about e2e tests, up to yo whether we want to add them in this PR or a separate one.

util/movement-types/src/lib.rs Show resolved Hide resolved
@l-monninger
Copy link
Collaborator Author

@0xmovses for now, Mikhail will be working against a stub. e2e tests can come elsewhere.

@l-monninger
Copy link
Collaborator Author

l-monninger commented May 14, 2024

@mzabaluev Updated the stub with batching.

@l-monninger
Copy link
Collaborator Author

Oh, one more thing you can now expect that will be helpful...

@l-monninger
Copy link
Collaborator Author

l-monninger commented May 14, 2024

In the contract and now stub, I added a method get_max_tolerable_height which returns the height to which the contract allows any validator to commit. The corresponding restriction is needed to prevent validators from committing too far ahead and effectively staging an attack that locks down the validator set by assigning every block-height to the current epoch.

Here's the type signature.

async fn get_max_tolerable_block_height(&self) -> Result<u64, anyhow::Error>;

mzabaluev added 3 commits May 14, 2024 15:29
In SuzukaPartialNode, instantiate the stub McrSettlementClient.
Moar data that the executor should be able to
immediately provide upon executing the block.
Send the block commitments to the MCR contract via the settlement
client. This is done in a separate task from the executor loop to
avoid blocking it.
Comment on lines +180 to +189
let block_metadata = self.executor.build_block_metadata(
HashValue::sha3_256_of(block_id.as_bytes()),
block_timestamp
).await?;
let block_metadata_transaction = SignatureVerifiedTransaction::Valid(
Transaction::BlockMetadata(
block_metadata
)
);
block_transactions.push(block_metadata_transaction);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Aha, I thought this will be somehow pulled through DA, but it needs to be synthesized here.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe even lower it into maptos-opt-executor, then?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, we may have to reevaluate at some point. But, for now, we are going to assume that the executor can correctly decide the block height based on, well, the number of blocks it has seen.

This is, at least on the surface, a viable assumption because the if it is an honest node, it should fetch all the blocks up from the DA (and when we have state syncing from other nodes that have done so).

However, if we do need have it come up from the DA, the complexity we will have to deal with is that Celestia blob heights are continually pushed regardless of whether additional blobs have been added to a given namespace.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In theory, the sequencer could address by keeping its own counter. But, this could be problematic.

@l-monninger l-monninger removed the request for review from andyjsbell May 23, 2024 17:45
mzabaluev added 2 commits May 23, 2024 21:51
No need to compute the commitment for the metadata
workaround block.
@@ -329,7 +329,7 @@ impl Executor {
// Context has a reach-around to the db so the block height should
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

LGTM hopefully we'll have a productive conversation about where implementations are separate on Friday and Monday.

Copy link
Collaborator Author

@l-monninger l-monninger May 23, 2024

Choose a reason for hiding this comment

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

Scratch that. Build error.

Copy link
Contributor

@0xmovses 0xmovses left a comment

Choose a reason for hiding this comment

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

Thanks for this! Just a few thoughts

"--cfg tokio_unstable -C force-frame-pointers=yes -C force-unwind-tables=yes -C link-arg=/STACK:8000000"
else
"--cfg tokio_unstable -C force-frame-pointers=yes -C force-unwind-tables=yes";

Copy link
Contributor

Choose a reason for hiding this comment

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

👀 Be great if nix did handle config.toml. Seems subpar that it doesn't

{
tracing::debug!("Got transaction: {:?}", transaction)
}

Copy link
Contributor

Choose a reason for hiding this comment

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

👌

transaction_sender : Sender<SignedTransaction>,
pub transaction_receiver : Receiver<SignedTransaction>,
light_node_client: Arc<RwLock<LightNodeServiceClient<tonic::transport::Channel>>>,
pub struct SuzukaPartialNode<T> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's add in a doc comment for the struct and all its fields.

Copy link
Collaborator

Choose a reason for hiding this comment

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

There should be a wider ticket for documenting our public APIs (when they are stabilized enough to avoid unnecessary churn). I have filed #81 to track this.


fn bind_transaction_channel(&mut self) {
self.executor.set_tx_channel(self.transaction_sender.clone());
}

pub fn bound(
pub fn bound<C>(
Copy link
Contributor

Choose a reason for hiding this comment

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

any pub methods should have a doc comment.

@@ -110,9 +140,9 @@ impl <T : SuzukaExecutor + Send + Sync + Clone>SuzukaPartialNode<T> {
// receive transactions from the transaction channel and send them to be executed
// ! This assumes the m1 da light node is running sequencer mode
pub async fn read_blocks_from_da(&self) -> Result<(), anyhow::Error> {

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's turn those comments into doc comments

executor.execute_block(FinalityMode::Opt, block).await?;
let commitment = executor.execute_block(FinalityMode::Opt, block).await?;

// TODO: test the commitment
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this TODO outside the scope of this PR? Maybe lets make a tracking ticket . issue.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I've added some checks in fae30be
Not testing the commitment hash itself, it would require replicating much of the internal code.

mzabaluev added 6 commits May 24, 2024 18:32
Don't use the "logging" feature to gate individual tracing
macro expansions, tracing is designed to not need this.
Remove dependencies on env_logger and tracing-log,
these crates are no longer in use.
Test some properties of the BlockCommitment returned by a test
from the execute_block method. There's no easy way to verify the
commitment hash itself.
Rename to override_block_commitment for clarity.
To test dynamic behavior of the McrSettlementManager, add methods to
pause and resume streaming of commitments.
Test dynamic behavior: when the client is not ready
to process more incoming blocks, the manager should
pause with blocks as well. Then when the client is ready
to accept more, resume.
Included Liam's remarks on treating verifier errors as successful
verification.
Copy link
Contributor

@andyjsbell andyjsbell left a comment

Choose a reason for hiding this comment

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

lgtm

@andyjsbell andyjsbell merged commit 3dadd48 into main May 28, 2024
3 checks passed
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.

5 participants