Files
tendermint/docs/architecture/adr-024-sign-bytes.md
Thane Thomson daaf5d6441 docs: Update all docs to prepare for v0.37 (#9243)
* Update docs references from master to main

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Update DOCS_README to reflect current reality

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Update vuepress config with current versions and updated discussions link

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Update generated docs versions

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Update docs build to use temp folder instead of home

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Document build-docs Makefile target

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Add serve-docs Makefile target to serve local build of docs

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Ensure 404 page is copied during docs build

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Redirect /master/ to /main/

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Attempt to resolve #7908

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Update OpenAPI references from master to main

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Update CHANGELOG references from master to main

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Update Docker readme references from master to main

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Update UPGRADING references from master to main

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Update package-specific documentation references from master to main

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Update spec references from master to main

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Update all code comment references to docs site from master to main

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Build v0.34.x as "latest"

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Explicitly mark v0.34 docs as latest in version selector

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Update all links from docs.tendermint.com/main to docs.tendermint.com/latest

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* ci: Redeploy docs on pushes to v0.34.x

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Temporarily copy spec directory into docs while building

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Add nav link to main and clearly mark as unstable

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Revert to only publishing docs in nav for v0.34 and v0.33 with no latest

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Link to docs.tendermint.com/v0.34 from RFCs

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Rather just use main for all docs.tendermint.com references on main branch

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Rename GitHub tree links from master to main

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Update link for ABCI Rust client

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Update github links from master to main

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Update badges in root readme

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Remove codecov badge since we do not use it any more

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Remove Java and Kotlin tutorials

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Remove specs from docs build

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Migrate spec links to GitHub repo from docs site

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Remove references to non-existent PEX reactor spec

Signed-off-by: Thane Thomson <connect@thanethomson.com>

* Fix linting badge in README

Signed-off-by: Thane Thomson <connect@thanethomson.com>

Signed-off-by: Thane Thomson <connect@thanethomson.com>
2022-08-19 13:18:33 -04:00

235 lines
6.4 KiB
Markdown

# ADR 024: SignBytes and validator types in privval
## Context
Currently, the messages exchanged between tendermint and a (potentially remote) signer/validator,
namely votes, proposals, and heartbeats, are encoded as a JSON string
(e.g., via `Vote.SignBytes(...)`) and then
signed . JSON encoding is sub-optimal for both, hardware wallets
and for usage in ethereum smart contracts. Both is laid down in detail in [issue#1622].
Also, there are currently no differences between sign-request and -replies. Also, there is no possibility
for a remote signer to include an error code or message in case something went wrong.
The messages exchanged between tendermint and a remote signer currently live in
[privval/socket.go] and encapsulate the corresponding types in [types].
[privval/socket.go]: https://github.com/tendermint/tendermint/blob/d419fffe18531317c28c29a292ad7d253f6cafdf/privval/socket.go#L496-L502
[issue#1622]: https://github.com/tendermint/tendermint/issues/1622
[types]: https://github.com/tendermint/tendermint/tree/main/types
## Decision
- restructure vote, proposal, and heartbeat such that their encoding is easily parseable by
hardware devices and smart contracts using a binary encoding format ([amino] in this case)
- split up the messages exchanged between tendermint and remote signers into requests and
responses (see details below)
- include an error type in responses
### Overview
```
+--------------+ +----------------+
| | SignXRequest | |
|Remote signer |<---------------------+ tendermint |
| (e.g. KMS) | | |
| +--------------------->| |
+--------------+ SignedXReply +----------------+
SignXRequest {
x: X
}
SignedXReply {
x: X
sig: Signature // []byte
err: Error{
code: int
desc: string
}
}
```
TODO: Alternatively, the type `X` might directly include the signature. A lot of places expect a vote with a
signature and do not necessarily deal with "Replies".
Still exploring what would work best here.
This would look like (exemplified using X = Vote):
```
Vote {
// all fields besides signature
}
SignedVote {
Vote Vote
Signature []byte
}
SignVoteRequest {
Vote Vote
}
SignedVoteReply {
Vote SignedVote
Err Error
}
```
**Note:** There was a related discussion around including a fingerprint of, or, the whole public-key
into each sign-request to tell the signer which corresponding private-key to
use to sign the message. This is particularly relevant in the context of the KMS
but is currently not considered in this ADR.
[amino]: https://github.com/tendermint/go-amino/
### Vote
As explained in [issue#1622] `Vote` will be changed to contain the following fields
(notation in protobuf-like syntax for easy readability):
```proto
// vanilla protobuf / amino encoded
message Vote {
Version fixed32
Height sfixed64
Round sfixed32
VoteType fixed32
Timestamp Timestamp // << using protobuf definition
BlockID BlockID // << as already defined
ChainID string // at the end because length could vary a lot
}
// this is an amino registered type; like currently privval.SignVoteMsg:
// registered with "tendermint/socketpv/SignVoteRequest"
message SignVoteRequest {
Vote vote
}
// amino registered type
// registered with "tendermint/socketpv/SignedVoteReply"
message SignedVoteReply {
Vote Vote
Signature Signature
Err Error
}
// we will use this type everywhere below
message Error {
Type uint // error code
Description string // optional description
}
```
The `ChainID` gets moved into the vote message directly. Previously, it was injected
using the [Signable] interface method `SignBytes(chainID string) []byte`. Also, the
signature won't be included directly, only in the corresponding `SignedVoteReply` message.
[Signable]: https://github.com/tendermint/tendermint/blob/d419fffe18531317c28c29a292ad7d253f6cafdf/types/signable.go#L9-L11
### Proposal
```proto
// vanilla protobuf / amino encoded
message Proposal {
Height sfixed64
Round sfixed32
Timestamp Timestamp // << using protobuf definition
BlockPartsHeader PartSetHeader // as already defined
POLRound sfixed32
POLBlockID BlockID // << as already defined
}
// amino registered with "tendermint/socketpv/SignProposalRequest"
message SignProposalRequest {
Proposal proposal
}
// amino registered with "tendermint/socketpv/SignProposalReply"
message SignProposalReply {
Prop Proposal
Sig Signature
Err Error // as defined above
}
```
### Heartbeat
**TODO**: clarify if heartbeat also needs a fixed offset and update the fields accordingly:
```proto
message Heartbeat {
ValidatorAddress Address
ValidatorIndex int
Height int64
Round int
Sequence int
}
// amino registered with "tendermint/socketpv/SignHeartbeatRequest"
message SignHeartbeatRequest {
Hb Heartbeat
}
// amino registered with "tendermint/socketpv/SignHeartbeatReply"
message SignHeartbeatReply {
Hb Heartbeat
Sig Signature
Err Error // as defined above
}
```
## PubKey
TBA - this needs further thoughts: e.g. what todo like in the case of the KMS which holds
several keys? How does it know with which key to reply?
## SignBytes
`SignBytes` will not require a `ChainID` parameter:
```golang
type Signable interface {
SignBytes() []byte
}
```
And the implementation for vote, heartbeat, proposal will look like:
```golang
// type T is one of vote, sign, proposal
func (tp *T) SignBytes() []byte {
bz, err := cdc.MarshalBinary(tp)
if err != nil {
panic(err)
}
return bz
}
```
## Status
Partially Accepted
## Consequences
### Positive
The most relevant positive effect is that the signing bytes can easily be parsed by a
hardware module and a smart contract. Besides that:
- clearer separation between requests and responses
- added error messages enable better error handling
### Negative
- relatively huge change / refactoring touching quite some code
- lot's of places assume a `Vote` with a signature included -> they will need to
- need to modify some interfaces
### Neutral
not even the swiss are neutral