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

abci: implement finalize block #9468

Merged
merged 46 commits into from
Nov 28, 2022
Merged

abci: implement finalize block #9468

merged 46 commits into from
Nov 28, 2022

Conversation

cmwaters
Copy link
Contributor

Closes: #9427

This PR ports the work around finalize block present in v0.36. Given extensive changes in the abci++ package prior to the finalize block changes, this was manually done and several decisions were made in the process, of note:

  • The removal of the Async methods in the Client interface (as previously done)
  • The addition of contexts and errors and usage of pointers instead of concrete structs.
  • The ported commits depended on changes in the ABCI concurrency model. This was reverted to the previous behaviour (as it is in v0.34/v0.37). As such:
    • The proxyApp which multiplexes the abci.Client over four connections is still in place
    • The global mutex around the local client is still in place
  • AppHash in ResponseFinalizeBlock was renamed to AgreedAppData to signify that the returned values do not need to be a hash and any arbitrary size of bytes can be used to demonstrate state machine replication.
  • The PersistentKVStoreApplication and KVStoreApplication were merged to a single struct with a DB object passed in the constructor. This means an "in-memory" db can be used or the "go-cleveldb" in the case of the persistent application.
  • The prior commits relied on the EventSink abstraction introduced in v0.35 and v0.36 but not present in v0.34 and v0.37. This work (or some rendition of it) should still be done, but in order to get the BlockIndexer operational, I've added a new EventDataNewBlockEvents struct which specifically contains the Events from ResponseFinalizeBlock (which concatenates the previous BeginBlock and EndBlock events). The other option would have been to use EventDataNewBlock which would provide the entire block (not just the block events needed).
  • I have kept ABCIResponses as LegacyABCIResponses to maintain backwards compatibility. If LoadFinalizeBlockResponses is called, it will first try to unmarshal the bytes as ResponseFinalizeBlock and then as LegacyABCIResponses. If it is the legacy data it will then convert it to ReponseFinalizeBlock and return that. We will need to follow up on this later as it's possible that ResponseFinalizeBlock does not need to be persisted at all but I've left that decision for the future.
  • The ported commit includes fixes to the ABCI socket protocol which one can find here (abci: Flush socket requests and responses immediately. #6997). This flushes the buffer after every write. The Flush method still exists but it is now redundant.

For the Reviewer, the significant changes can be found:

  • in proto/tendermint/abci and proto/tendermint/state (for the proto changes)
  • in the abci package
  • in state/execution.go
  • in mempool/v0/clist_mempool.go (removal of async and thus the callbacks)
  • in state/store.go. The handling of persisting and loading ResponseFinalizeBlock

The PR can already be viewed but I still need to:

  • Add notes in UPGRADING.md
  • Add a changelog entry

@cmwaters cmwaters requested a review from a team September 21, 2022 12:09
@cmwaters cmwaters self-assigned this Oct 10, 2022
@github-actions
Copy link

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@github-actions github-actions bot added the stale for use by stalebot label Oct 21, 2022
@faustbrian
Copy link

@cmwaters is this branch safe to be used as a basis of implementing FinalizeBlock in ABCI++ applications until it gets merged or are there any bigger changes planned?

@thanethomson thanethomson removed the stale for use by stalebot label Oct 21, 2022
Copy link
Contributor

@sergio-mena sergio-mena left a comment

Choose a reason for hiding this comment

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

I have started reviewing this. A +6K, -8K PR is certainly going to be very hard to review especially, if the backport was done manually.
I am posting the first comments I have. I will continue with this later today and after my vacation.
One general question I have: if the removal of Async was needed to make the backport of #7798 easier (I can imagine), was the corresponding commit cherry-picked first as described in #9396 ?

EchoAsync(msg string) *ReqRes
InfoAsync(types.RequestInfo) *ReqRes
DeliverTxAsync(types.RequestDeliverTx) *ReqRes
CheckTxAsync(types.RequestCheckTx) *ReqRes
Copy link
Contributor

Choose a reason for hiding this comment

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

Removing CheckTxAsync was decision that was made as part of v0.36. We have been revisiting all decisions made in v0.35 and v0.36, I think this one should be no exception.
Futher, I'm not sure I agree with CheckTx being synchrnous, as CheckTx is explained in the spec as an asynchronous method, which makes sense for performance reasons when the App is not in the same process.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we want CheckTx to be asynchronous, I'd recommend simply running it in a go routine but given that calls are serialized to the application, I'm not sure what it really provides in terms of performance.

Copy link
Contributor

Choose a reason for hiding this comment

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

After doing a second pass on the beginning for this diff, I realize this goes further than #7607 in removing Async methods. The original #7607 leaves the possibility of leveraging some async methods in the future. This patch, which is supposed to be a backport (or a set of them), removes that possibility.

reqRes := NewReqRes(req)
reqRes.Response = res
return reqRes
return app.Application.FinalizeBlock(ctx, req)
Copy link
Contributor

Choose a reason for hiding this comment

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

In v0.37.x Application interface does not return an error here, why this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

v0.36 added contexts and errors to all ABCI calls. I included this as I felt this made sense to port across. I don't think it would be too difficult however to remove the errors if we feel that way

Copy link
Contributor

Choose a reason for hiding this comment

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

OK, since you decided to port them, let's keep them. But don't you think the initial diff was big enough to try to limit the amount of things we want to bring in here?

Tx: b.Data.Txs[i],
Result: *(r.DeliverTxs[i]),
Height: height,
Index: uint32(idx),

Check failure

Code scanning / gosec

Potential integer overflow by integer type conversion

Potential integer overflow by integer type conversion
@@ -28,7 +31,7 @@
// NewSnapshotStore creates a new snapshot store.
func NewSnapshotStore(dir string) (*SnapshotStore, error) {
store := &SnapshotStore{dir: dir}
if err := os.MkdirAll(dir, 0o755); err != nil {
if err := os.MkdirAll(dir, 0755); err != nil {

Check failure

Code scanning / gosec

Expect directory permissions to be 0750 or less

Expect directory permissions to be 0750 or less
@@ -692,7 +693,7 @@
return nil
})
}
_ = txmp.proxyAppConn.FlushAsync()
_ = txmp.proxyAppConn.Flush(context.TODO())

Check warning

Code scanning / gosec

Returned error is not propagated up the stack.

Returned error is not propagated up the stack.
// v0.37 with endblock to v0.38 with finalize block and thus
// does not have the app hash saved from the previous height
// here we take the appHash provided from the Info handshake
if len(finalizeBlockResponse.AgreedAppData) == 0 {
Copy link
Contributor

Choose a reason for hiding this comment

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

👏 👏 👏
I think we didn't get to this case in v0.36. Nice.

Copy link
Contributor

@sergio-mena sergio-mena left a comment

Choose a reason for hiding this comment

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

Thanks @cmwaters for your patience.
Please make sure you address @williambanfield's comments

Copy link
Contributor

@williambanfield williambanfield left a comment

Choose a reason for hiding this comment

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

The main change to replace BeginBlock and EndBlock with FinalizeBlock appears correct. There are a few extra changes that make reviewing this a bit difficult. I've added a few non-blocking suggestions.

abci/server/grpc_server.go Show resolved Hide resolved
state/execution.go Outdated Show resolved Hide resolved
proto/tendermint/abci/types.proto Show resolved Hide resolved
legacyResp := new(tmstate.LegacyABCIResponses)
rerr := legacyResp.Unmarshal(buf)
if rerr != nil {
// DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we write a test for the case of loading the new type when the old type is present in the db?

state/store.go Outdated Show resolved Hide resolved
@thanethomson thanethomson added the C:abci Component: Application Blockchain Interface label Nov 28, 2022
@cmwaters cmwaters merged commit c5c2aaf into feature/abci++vef Nov 28, 2022
@cmwaters cmwaters deleted the cal/finalize-block branch November 28, 2022 22:12
@sergio-mena
Copy link
Contributor

Thanks @cmwaters !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C:abci Component: Application Blockchain Interface
Projects
Status: Done/Merged
Development

Successfully merging this pull request may close these issues.

None yet

5 participants