-
Notifications
You must be signed in to change notification settings - Fork 264
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
feat!: sync with mainline ABCI #1003
Conversation
rpc/core/blocks.go
Outdated
func EncodeDataRootTuple(height uint64, dataRoot [32]byte, squareSize uint64) ([]byte, error) { | ||
func EncodeDataRootTuple(height uint64, dataRoot []byte) ([]byte, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like this previously relied on the square size but when I follow the link https://github.com/celestiaorg/quantum-gravity-bridge/blob/5edb5906766b63eb6b9c24314df554feb1e83506/src/DataRootTuple.sol#L8 it seems that only the height and data root are used. Is it possible to remove the square size here? cc @sweexordious
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is a PR for that: celestiaorg/blobstream-contracts#145
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opened this to maybe remove the square size:
celestiaorg/blobstream-contracts#154
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cmwaters square size can be removed. Do you want to do it in this PR? or I open a subsequent PR to remove it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's great. Let's do it in a subsequent PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Converting this as a draft for now. It seems my original assumption that the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No blocking feedback, overall I'm a fan of this!
Opening this PR back for review again. This is for after mainnet just to be clear. I think we might even want to create a new branch |
abci/types/application.go
Outdated
@@ -98,11 +101,18 @@ func (BaseApplication) ApplySnapshotChunk(req RequestApplySnapshotChunk) Respons | |||
} | |||
|
|||
func (BaseApplication) PrepareProposal(req RequestPrepareProposal) ResponsePrepareProposal { | |||
return ResponsePrepareProposal{BlockData: req.BlockData} | |||
squareSize := len(req.Txs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[question] why is the squareSize set to the number of transactions? I think of these as two distinct values. For example, a block with 100 send transactions could have a square size of 4.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah this is a good point. So I've made the decision here that I want celestia-core to be specific to celestia-app. Concretely, we extend the rules around PrepareProposal
and ProcessProposal
that there must always be two transactions returned and the last and second to last are the squareSize and dataHash respectively. It's obviously somewhat hacky but means we keep within the boundaries of ABCI and are able to use the SDK without requiring a fork.
If the rule isn't followed, consensus panics. I could have chosen to simply ignore the rules when an application sends back 0 txs (thus supporting all the test applications in Tendermint) but I felt better to actually enforce the rule thus I had to modify all the test applications including the BaseApplication
.
The square size and hash here are placeholders. I could use the value 0 (which is invalid in the case of Celestia) instead. This should not be used outside of testing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[optional] Thanks for clarifying that they are placeholders. If they are expected to be overwritten by celestia-app, then proposal to do something like:
func (BaseApplication) PrepareProposal(req RequestPrepareProposal) ResponsePrepareProposal {
placeholderDataHash := tmhash.Sum(nil)
placeholderSquareSizeBytes := make([]byte, 8)
binary.BigEndian.PutUint64(placeholderSquareSizeBytes, uint64(1))
// placeholderDataHash and placeholderSquareSizeBytes are expected to be
// overwritten by celestia-app.
req.Txs = append(req.Txs, placeholderDataHash, placeholderSquareSizeBytes)
return ResponsePrepareProposal{Txs: req.Txs}
}
consensus/mempool_test.go
Outdated
@@ -254,5 +254,13 @@ func (app *CounterApplication) Commit() abci.ResponseCommit { | |||
|
|||
func (app *CounterApplication) PrepareProposal( | |||
req abci.RequestPrepareProposal) abci.ResponsePrepareProposal { | |||
return abci.ResponsePrepareProposal{BlockData: req.BlockData} | |||
dataHash := types.ToTxs(req.Txs).Hash() | |||
squareSize := len(req.Txs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same question regarding the relationship between squareSize and req.Txs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] can these placeholders look identical to PrepareProposal
in abci/types/application.go
tendermint.types.Data block_data = 1; | ||
// If an application decides to populate block_data with extra information, they can not exceed this value. | ||
int64 block_data_size = 2; | ||
repeated bytes txs = 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[question] can the protobuf field 2
be reused? Is it a breaking change if it is reused? Asking b/c prior to this PR field 2
was a in64 for block_data_size
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes this is an important detail. AFAIK we can't simply reserve those numbers and slide all the field numbers down if we want to have compatibility with the mainline version (in this case the SDK would not be able to decode the ABCI request that celestia-core would send). Thus we need to break ABCI. I've thought about this a bit and I don't think breaking ABCI will affect the backwards compatibility promises we make of our state machine. PrepareProposal
and ProcessProposal
(and all the other methods should work the same for v1 and v2)
/* | ||
TODO: Include vote extensions information when implementing vote extensions. | ||
VoteExtension: []byte{}, | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[uber nit] I think it's convention to use //
for this type of comment
Go provides C-style /* */ block comments and C++-style // line comments. Line comments are the norm; block comments appear mostly as package comments, but are useful within an expression or to disable large swaths of code.
Source: https://go.dev/doc/effective_go
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just copied from cometbft/cometbft
but I don't mind changing it to //
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh no worries, we can preserve /*
style comments if that's what is upstream.
abci/types/application.go
Outdated
@@ -98,11 +101,18 @@ func (BaseApplication) ApplySnapshotChunk(req RequestApplySnapshotChunk) Respons | |||
} | |||
|
|||
func (BaseApplication) PrepareProposal(req RequestPrepareProposal) ResponsePrepareProposal { | |||
return ResponsePrepareProposal{BlockData: req.BlockData} | |||
squareSize := len(req.Txs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[optional] Thanks for clarifying that they are placeholders. If they are expected to be overwritten by celestia-app, then proposal to do something like:
func (BaseApplication) PrepareProposal(req RequestPrepareProposal) ResponsePrepareProposal {
placeholderDataHash := tmhash.Sum(nil)
placeholderSquareSizeBytes := make([]byte, 8)
binary.BigEndian.PutUint64(placeholderSquareSizeBytes, uint64(1))
// placeholderDataHash and placeholderSquareSizeBytes are expected to be
// overwritten by celestia-app.
req.Txs = append(req.Txs, placeholderDataHash, placeholderSquareSizeBytes)
return ResponsePrepareProposal{Txs: req.Txs}
}
consensus/mempool_test.go
Outdated
@@ -254,5 +254,13 @@ func (app *CounterApplication) Commit() abci.ResponseCommit { | |||
|
|||
func (app *CounterApplication) PrepareProposal( | |||
req abci.RequestPrepareProposal) abci.ResponsePrepareProposal { | |||
return abci.ResponsePrepareProposal{BlockData: req.BlockData} | |||
dataHash := types.ToTxs(req.Txs).Hash() | |||
squareSize := len(req.Txs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] can these placeholders look identical to PrepareProposal
in abci/types/application.go
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall LGTM w/ one blocking comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concerning the PR description:
`SquareSize` is also no longer needed...
It is still needed for QGB. I guess the description needs to be updated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we also need to change the data root to use the second to last hash?
Lines 1025 to 1037 in c3ab251
// Hash returns the hash of the data | |
func (data *Data) Hash() cmtbytes.HexBytes { | |
if data == nil { | |
return (Txs{}).Hash() | |
} | |
if data.hash == nil { | |
data.hash = data.Txs.Hash() // NOTE: leaves of merkle tree are TxIDs | |
} | |
// this is the expected behavior where `data.hash` was set by celestia-app | |
// in PrepareProposal | |
return data.hash | |
} |
otherwise LGTM, should be nice
enum EvidenceType { | ||
message ExtendedVoteInfo { | ||
Validator validator = 1 [(gogoproto.nullable) = false]; | ||
bool signed_last_block = 2; | ||
bytes vote_extension = 3; // Reserved for future use | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes square size is still present. I will update the description |
No because the txs in the data struct don't actually contain the hash. The hash (as well as the square size) remains part of the The "hack" with the two extra transactions is purely across the ABCI layer |
Description
This PR modifies the ABCI interface to match that of CometBFT v0.37 and v0.47 of the SDK. There is no utility to extracting out blobs into a separate field within
Data
.To get past the problem of the data availabiilty hash and the square size, the last transaction returned by the celestia state machine should always be that square size and the second to last transaction should always be the data hash
PR checklist
.changelog
(we useunclog to manage our changelog)
docs/
orspec/
) and code comments