MCPcopy Create free account
hub / github.com/consensus-shipyard/ipc / commit

Method commit

fendermint/app/src/app.rs:977–1063  ·  view source on GitHub ↗

Commit the current state at the current height.

(&self)

Source from the content-addressed store, hash-verified

975
976 /// Commit the current state at the current height.
977 async fn commit(&self) -> AbciResult<response::Commit> {
978 let exec_state = self
979 .take_exec_state()
980 .await
981 .context("failed to load execution state")?;
982
983 let block_height = exec_state.block_height();
984 let timestamp = exec_state.timestamp();
985 let (state_root, params, _) = exec_state.commit().context("failed to commit FVM")?;
986
987 let mut c = self.light_client_commitments.lock().await;
988 // because of the take, no need to *c = None
989 let state =
990 self.project_post_exec_state(block_height, timestamp, state_root, params, c.take())?;
991
992 let app_hash = state.app_hash();
993 let block_height = state.app_state.block_height;
994
995 // Tell CometBFT how much of the block history it can forget.
996 let retain_height = if self.state_hist_size == 0 {
997 Default::default()
998 } else {
999 block_height.saturating_sub(self.state_hist_size)
1000 };
1001
1002 tracing::debug!(
1003 block_height,
1004 state_root = state.app_state.state_params.state_root.to_string(),
1005 app_hash = app_hash.to_string(),
1006 timestamp = state.app_state.state_params.timestamp.0,
1007 "commit state"
1008 );
1009
1010 // TODO: We can defer committing changes the resolution pool to this point.
1011 // For example if a checkpoint is successfully executed, that's when we want to remove
1012 // that checkpoint from the pool, and not propose it to other validators again.
1013 // However, once Tendermint starts delivering the transactions, the commit will surely
1014 // follow at the end, so we can also remove these checkpoints from memory at the time
1015 // the transaction is delivered, rather than when the whole thing is committed.
1016 // It is only important to the persistent database changes as an atomic step in the
1017 // commit in case the block execution fails somewhere in the middle for uknown reasons.
1018 // But if that happened, we will have to restart the application again anyway, and
1019 // repopulate the in-memory checkpoints based on the last committed ledger.
1020 // So, while the pool is theoretically part of the evolving state and we can pass
1021 // it in and out, unless we want to defer commit to here (which the interpreters aren't
1022 // notified about), we could add it to the `ChainMessageInterpreter` as a constructor argument,
1023 // a sort of "ambient state", and not worry about in in the `App` at all.
1024
1025 // Notify the snapshotter. It wasn't clear whether this should be done in `commit` or `begin_block`,
1026 // that is, whether the _height_ of the snapshot should be `block_height` or `block_height+1`.
1027 // When CometBFT calls `offer_snapshot` it sends an `app_hash` in it that we compare to the CID
1028 // of the `state_params`. Based on end-to-end testing it looks like it gives the `app_hash` from
1029 // the *next* block, so we have to do it here.
1030 // For example:
1031 // a) Notify in `begin_block`: say we are at committing block 899, then we notify in `begin_block`
1032 // that block 900 has this state (so we use `block_height+1` in notification);
1033 // CometBFT is going to offer it with the `app_hash` of block 901, which won't match, because
1034 // by then the timestamp will be different in the state params after committing block 900.

Callers

nothing calls this directly

Calls 13

emitFunction · 0.85
contextMethod · 0.80
timestampMethod · 0.80
takeMethod · 0.80
app_hashMethod · 0.80
notifyMethod · 0.80
set_committed_stateMethod · 0.80
try_intoMethod · 0.80
take_exec_stateMethod · 0.45
block_heightMethod · 0.45

Tested by

no test coverage detected