mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-03 08:31:20 +00:00
abci/examples: switch from hex to base64 pubkey in kvstore (#3641)
* abci/example: use base64 for update validator set * update kvstore/README.md * update CHANGELOG_PENDING.md and abci/example/kvstore/README.md
This commit is contained in:
parent
866b343c0c
commit
2e5b2a9537
@ -34,6 +34,7 @@
|
|||||||
### IMPROVEMENTS:
|
### IMPROVEMENTS:
|
||||||
- [p2p] \#3666 Add per channel telemetry to improve reactor observability
|
- [p2p] \#3666 Add per channel telemetry to improve reactor observability
|
||||||
- [rpc] [\#3686](https://github.com/tendermint/tendermint/pull/3686) `HTTPClient#Call` returns wrapped errors, so a caller could use `errors.Cause` to retrieve an error code. (@wooparadog)
|
- [rpc] [\#3686](https://github.com/tendermint/tendermint/pull/3686) `HTTPClient#Call` returns wrapped errors, so a caller could use `errors.Cause` to retrieve an error code. (@wooparadog)
|
||||||
|
- [abci/examples] \#3659 Change validator update tx format (incl. expected pubkey format, which is base64 now) (@needkane)
|
||||||
|
|
||||||
### BUG FIXES:
|
### BUG FIXES:
|
||||||
- [libs/db] \#3717 Fixed the BoltDB backend's Batch.Delete implementation (@Yawning)
|
- [libs/db] \#3717 Fixed the BoltDB backend's Batch.Delete implementation (@Yawning)
|
||||||
|
@ -22,10 +22,10 @@ and the Handshake allows any necessary blocks to be replayed.
|
|||||||
Validator set changes are effected using the following transaction format:
|
Validator set changes are effected using the following transaction format:
|
||||||
|
|
||||||
```
|
```
|
||||||
val:pubkey1/power1,addr2/power2,addr3/power3"
|
"val:pubkey1!power1,pubkey2!power2,pubkey3!power3"
|
||||||
```
|
```
|
||||||
|
|
||||||
where `power1` is the new voting power for the validator with `pubkey1` (possibly a new one).
|
where `pubkeyN` is a base64-encoded 32-byte ed25519 key and `powerN` is a new voting power for the validator with `pubkeyN` (possibly a new one).
|
||||||
|
To remove a validator from the validator set, set power to `0`.
|
||||||
There is no sybil protection against new validators joining.
|
There is no sybil protection against new validators joining.
|
||||||
Validators can be removed by setting their power to `0`.
|
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ package kvstore
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/hex"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -60,10 +60,10 @@ func (app *PersistentKVStoreApplication) SetOption(req types.RequestSetOption) t
|
|||||||
return app.app.SetOption(req)
|
return app.app.SetOption(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
// tx is either "val:pubkey/power" or "key=value" or just arbitrary bytes
|
// tx is either "val:pubkey!power" or "key=value" or just arbitrary bytes
|
||||||
func (app *PersistentKVStoreApplication) DeliverTx(req types.RequestDeliverTx) types.ResponseDeliverTx {
|
func (app *PersistentKVStoreApplication) DeliverTx(req types.RequestDeliverTx) types.ResponseDeliverTx {
|
||||||
// if it starts with "val:", update the validator set
|
// if it starts with "val:", update the validator set
|
||||||
// format is "val:pubkey/power"
|
// format is "val:pubkey!power"
|
||||||
if isValidatorTx(req.Tx) {
|
if isValidatorTx(req.Tx) {
|
||||||
// update validators in the merkle tree
|
// update validators in the merkle tree
|
||||||
// and in app.ValUpdates
|
// and in app.ValUpdates
|
||||||
@ -129,33 +129,34 @@ func (app *PersistentKVStoreApplication) Validators() (validators []types.Valida
|
|||||||
}
|
}
|
||||||
|
|
||||||
func MakeValSetChangeTx(pubkey types.PubKey, power int64) []byte {
|
func MakeValSetChangeTx(pubkey types.PubKey, power int64) []byte {
|
||||||
return []byte(fmt.Sprintf("val:%X/%d", pubkey.Data, power))
|
pubStr := base64.StdEncoding.EncodeToString(pubkey.Data)
|
||||||
|
return []byte(fmt.Sprintf("val:%s!%d", pubStr, power))
|
||||||
}
|
}
|
||||||
|
|
||||||
func isValidatorTx(tx []byte) bool {
|
func isValidatorTx(tx []byte) bool {
|
||||||
return strings.HasPrefix(string(tx), ValidatorSetChangePrefix)
|
return strings.HasPrefix(string(tx), ValidatorSetChangePrefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
// format is "val:pubkey/power"
|
// format is "val:pubkey!power"
|
||||||
// pubkey is raw 32-byte ed25519 key
|
// pubkey is a base64-encoded 32-byte ed25519 key
|
||||||
func (app *PersistentKVStoreApplication) execValidatorTx(tx []byte) types.ResponseDeliverTx {
|
func (app *PersistentKVStoreApplication) execValidatorTx(tx []byte) types.ResponseDeliverTx {
|
||||||
tx = tx[len(ValidatorSetChangePrefix):]
|
tx = tx[len(ValidatorSetChangePrefix):]
|
||||||
|
|
||||||
//get the pubkey and power
|
//get the pubkey and power
|
||||||
pubKeyAndPower := strings.Split(string(tx), "/")
|
pubKeyAndPower := strings.Split(string(tx), "!")
|
||||||
if len(pubKeyAndPower) != 2 {
|
if len(pubKeyAndPower) != 2 {
|
||||||
return types.ResponseDeliverTx{
|
return types.ResponseDeliverTx{
|
||||||
Code: code.CodeTypeEncodingError,
|
Code: code.CodeTypeEncodingError,
|
||||||
Log: fmt.Sprintf("Expected 'pubkey/power'. Got %v", pubKeyAndPower)}
|
Log: fmt.Sprintf("Expected 'pubkey!power'. Got %v", pubKeyAndPower)}
|
||||||
}
|
}
|
||||||
pubkeyS, powerS := pubKeyAndPower[0], pubKeyAndPower[1]
|
pubkeyS, powerS := pubKeyAndPower[0], pubKeyAndPower[1]
|
||||||
|
|
||||||
// decode the pubkey
|
// decode the pubkey
|
||||||
pubkey, err := hex.DecodeString(pubkeyS)
|
pubkey, err := base64.StdEncoding.DecodeString(pubkeyS)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.ResponseDeliverTx{
|
return types.ResponseDeliverTx{
|
||||||
Code: code.CodeTypeEncodingError,
|
Code: code.CodeTypeEncodingError,
|
||||||
Log: fmt.Sprintf("Pubkey (%s) is invalid hex", pubkeyS)}
|
Log: fmt.Sprintf("Pubkey (%s) is invalid base64", pubkeyS)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode the power
|
// decode the power
|
||||||
@ -176,9 +177,10 @@ func (app *PersistentKVStoreApplication) updateValidator(v types.ValidatorUpdate
|
|||||||
if v.Power == 0 {
|
if v.Power == 0 {
|
||||||
// remove validator
|
// remove validator
|
||||||
if !app.app.state.db.Has(key) {
|
if !app.app.state.db.Has(key) {
|
||||||
|
pubStr := base64.StdEncoding.EncodeToString(v.PubKey.Data)
|
||||||
return types.ResponseDeliverTx{
|
return types.ResponseDeliverTx{
|
||||||
Code: code.CodeTypeUnauthorized,
|
Code: code.CodeTypeUnauthorized,
|
||||||
Log: fmt.Sprintf("Cannot remove non-existent validator %X", key)}
|
Log: fmt.Sprintf("Cannot remove non-existent validator %s", pubStr)}
|
||||||
}
|
}
|
||||||
app.app.state.db.Delete(key)
|
app.app.state.db.Delete(key)
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user