mirror of
https://github.com/tendermint/tendermint.git
synced 2026-01-03 19:53:58 +00:00
rpc: simplify the encoding of interface-typed arguments in JSON (#7600)
Add package jsontypes that implements a subset of the custom libs/json package. Specifically it handles encoding and decoding of interface types wrapped in "tagged" JSON objects. It omits the deep reflection on arbitrary types, preserving only the handling of type tags wrapper encoding. - Register interface types (Evidence, PubKey, PrivKey) for tagged encoding. - Update the existing implementations to satisfy the type. - Register those types with the jsontypes registry. - Add string tags to 64-bit integer fields where needed. - Add marshalers to structs that export interface-typed fields.
This commit is contained in:
@@ -2,6 +2,7 @@ package crypto
|
||||
|
||||
import (
|
||||
"github.com/tendermint/tendermint/crypto/tmhash"
|
||||
"github.com/tendermint/tendermint/internal/jsontypes"
|
||||
"github.com/tendermint/tendermint/libs/bytes"
|
||||
)
|
||||
|
||||
@@ -25,6 +26,9 @@ type PubKey interface {
|
||||
VerifySignature(msg []byte, sig []byte) bool
|
||||
Equals(PubKey) bool
|
||||
Type() string
|
||||
|
||||
// Implementations must support tagged encoding in JSON.
|
||||
jsontypes.Tagged
|
||||
}
|
||||
|
||||
type PrivKey interface {
|
||||
@@ -33,6 +37,9 @@ type PrivKey interface {
|
||||
PubKey() PubKey
|
||||
Equals(PrivKey) bool
|
||||
Type() string
|
||||
|
||||
// Implementations must support tagged encoding in JSON.
|
||||
jsontypes.Tagged
|
||||
}
|
||||
|
||||
type Symmetric interface {
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/tmhash"
|
||||
"github.com/tendermint/tendermint/internal/jsontypes"
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
)
|
||||
|
||||
@@ -58,11 +59,17 @@ const (
|
||||
func init() {
|
||||
tmjson.RegisterType(PubKey{}, PubKeyName)
|
||||
tmjson.RegisterType(PrivKey{}, PrivKeyName)
|
||||
|
||||
jsontypes.MustRegister(PubKey{})
|
||||
jsontypes.MustRegister(PrivKey{})
|
||||
}
|
||||
|
||||
// PrivKey implements crypto.PrivKey.
|
||||
type PrivKey []byte
|
||||
|
||||
// TypeTag satisfies the jsontypes.Tagged interface.
|
||||
func (PrivKey) TypeTag() string { return PrivKeyName }
|
||||
|
||||
// Bytes returns the privkey byte format.
|
||||
func (privKey PrivKey) Bytes() []byte {
|
||||
return []byte(privKey)
|
||||
@@ -151,6 +158,9 @@ var _ crypto.PubKey = PubKey{}
|
||||
// PubKeyEd25519 implements crypto.PubKey for the Ed25519 signature scheme.
|
||||
type PubKey []byte
|
||||
|
||||
// TypeTag satisfies the jsontypes.Tagged interface.
|
||||
func (PubKey) TypeTag() string { return PubKeyName }
|
||||
|
||||
// Address is the SHA256-20 of the raw pubkey bytes.
|
||||
func (pubKey PubKey) Address() crypto.Address {
|
||||
if len(pubKey) != PubKeySize {
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
secp256k1 "github.com/btcsuite/btcd/btcec"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/internal/jsontypes"
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
|
||||
// necessary for Bitcoin address format
|
||||
@@ -28,6 +29,9 @@ const (
|
||||
func init() {
|
||||
tmjson.RegisterType(PubKey{}, PubKeyName)
|
||||
tmjson.RegisterType(PrivKey{}, PrivKeyName)
|
||||
|
||||
jsontypes.MustRegister(PubKey{})
|
||||
jsontypes.MustRegister(PrivKey{})
|
||||
}
|
||||
|
||||
var _ crypto.PrivKey = PrivKey{}
|
||||
@@ -35,6 +39,9 @@ var _ crypto.PrivKey = PrivKey{}
|
||||
// PrivKey implements PrivKey.
|
||||
type PrivKey []byte
|
||||
|
||||
// TypeTag satisfies the jsontypes.Tagged interface.
|
||||
func (PrivKey) TypeTag() string { return PrivKeyName }
|
||||
|
||||
// Bytes marshalls the private key using amino encoding.
|
||||
func (privKey PrivKey) Bytes() []byte {
|
||||
return []byte(privKey)
|
||||
@@ -138,6 +145,9 @@ const PubKeySize = 33
|
||||
// This prefix is followed with the x-coordinate.
|
||||
type PubKey []byte
|
||||
|
||||
// TypeTag satisfies the jsontypes.Tagged interface.
|
||||
func (PubKey) TypeTag() string { return PubKeyName }
|
||||
|
||||
// Address returns a Bitcoin style addresses: RIPEMD160(SHA256(pubkey))
|
||||
func (pubKey PubKey) Address() crypto.Address {
|
||||
if len(pubKey) != PubKeySize {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package sr25519
|
||||
|
||||
import tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
import (
|
||||
"github.com/tendermint/tendermint/internal/jsontypes"
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
)
|
||||
|
||||
const (
|
||||
PrivKeyName = "tendermint/PrivKeySr25519"
|
||||
@@ -10,4 +13,7 @@ const (
|
||||
func init() {
|
||||
tmjson.RegisterType(PubKey{}, PubKeyName)
|
||||
tmjson.RegisterType(PrivKey{}, PrivKeyName)
|
||||
|
||||
jsontypes.MustRegister(PubKey{})
|
||||
jsontypes.MustRegister(PrivKey{})
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@ type PrivKey struct {
|
||||
kp *sr25519.KeyPair
|
||||
}
|
||||
|
||||
// TypeTag satisfies the jsontypes.Tagged interface.
|
||||
func (PrivKey) TypeTag() string { return PrivKeyName }
|
||||
|
||||
// Bytes returns the byte-encoded PrivKey.
|
||||
func (privKey PrivKey) Bytes() []byte {
|
||||
if privKey.kp == nil {
|
||||
|
||||
@@ -23,6 +23,9 @@ const (
|
||||
// PubKey implements crypto.PubKey.
|
||||
type PubKey []byte
|
||||
|
||||
// TypeTag satisfies the jsontypes.Tagged interface.
|
||||
func (PubKey) TypeTag() string { return PubKeyName }
|
||||
|
||||
// Address is the SHA256-20 of the raw pubkey bytes.
|
||||
func (pubKey PubKey) Address() crypto.Address {
|
||||
if len(pubKey) != PubKeySize {
|
||||
|
||||
109
internal/jsontypes/jsontypes.go
Normal file
109
internal/jsontypes/jsontypes.go
Normal file
@@ -0,0 +1,109 @@
|
||||
// Package jsontypes supports decoding for interface types whose concrete
|
||||
// implementations need to be stored as JSON. To do this, concrete values are
|
||||
// packaged in wrapper objects having the form:
|
||||
//
|
||||
// {
|
||||
// "type": "<type-tag>",
|
||||
// "value": <json-encoding-of-value>
|
||||
// }
|
||||
//
|
||||
// This package provides a registry for type tag strings and functions to
|
||||
// encode and decode wrapper objects.
|
||||
package jsontypes
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// The Tagged interface must be implemented by a type in order to register it
|
||||
// with the jsontypes package. The TypeTag method returns a string label that
|
||||
// is used to distinguish objects of that type.
|
||||
type Tagged interface {
|
||||
TypeTag() string
|
||||
}
|
||||
|
||||
// registry records the mapping from type tags to value types. Values in this
|
||||
// map must be normalized to non-pointer types.
|
||||
var registry = struct {
|
||||
types map[string]reflect.Type
|
||||
}{types: make(map[string]reflect.Type)}
|
||||
|
||||
// register adds v to the type registry. It reports an error if the tag
|
||||
// returned by v is already registered.
|
||||
func register(v Tagged) error {
|
||||
tag := v.TypeTag()
|
||||
if t, ok := registry.types[tag]; ok {
|
||||
return fmt.Errorf("type tag %q already registered to %v", tag, t)
|
||||
}
|
||||
typ := reflect.TypeOf(v)
|
||||
if typ.Kind() == reflect.Ptr {
|
||||
typ = typ.Elem()
|
||||
}
|
||||
registry.types[tag] = typ
|
||||
return nil
|
||||
}
|
||||
|
||||
// MustRegister adds v to the type registry. It will panic if the tag returned
|
||||
// by v is already registered. This function is meant for use during program
|
||||
// initialization.
|
||||
func MustRegister(v Tagged) {
|
||||
if err := register(v); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
type wrapper struct {
|
||||
Type string `json:"type"`
|
||||
Value json.RawMessage `json:"value"`
|
||||
}
|
||||
|
||||
// Marshal marshals a JSON wrapper object containing v. If v == nil, Marshal
|
||||
// returns the JSON "null" value without error.
|
||||
func Marshal(v Tagged) ([]byte, error) {
|
||||
if v == nil {
|
||||
return []byte("null"), nil
|
||||
}
|
||||
data, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(wrapper{
|
||||
Type: v.TypeTag(),
|
||||
Value: data,
|
||||
})
|
||||
}
|
||||
|
||||
// Unmarshal unmarshals a JSON wrapper object into v. It reports an error if
|
||||
// the data do not encode a valid wrapper object, if the wrapper's type tag is
|
||||
// not registered with jsontypes, or if the resulting value is not compatible
|
||||
// with the type of v.
|
||||
func Unmarshal(data []byte, v interface{}) error {
|
||||
// Verify that the target is some kind of pointer.
|
||||
target := reflect.ValueOf(v)
|
||||
if target.Kind() != reflect.Ptr {
|
||||
return fmt.Errorf("target %T is not a pointer", v)
|
||||
}
|
||||
|
||||
var w wrapper
|
||||
dec := json.NewDecoder(bytes.NewReader(data))
|
||||
dec.DisallowUnknownFields()
|
||||
if err := dec.Decode(&w); err != nil {
|
||||
return fmt.Errorf("invalid type wrapper: %w", err)
|
||||
}
|
||||
typ, ok := registry.types[w.Type]
|
||||
if !ok {
|
||||
return fmt.Errorf("unknown type tag: %q", w.Type)
|
||||
} else if !typ.AssignableTo(target.Elem().Type()) {
|
||||
return fmt.Errorf("type %v not assignable to %T", typ, v)
|
||||
}
|
||||
|
||||
obj := reflect.New(typ)
|
||||
if err := json.Unmarshal(w.Value, obj.Interface()); err != nil {
|
||||
return fmt.Errorf("decoding wrapped value: %w", err)
|
||||
}
|
||||
target.Elem().Set(obj.Elem())
|
||||
return nil
|
||||
}
|
||||
83
internal/jsontypes/jsontypes_test.go
Normal file
83
internal/jsontypes/jsontypes_test.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package jsontypes_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/tendermint/tendermint/internal/jsontypes"
|
||||
)
|
||||
|
||||
type testType struct {
|
||||
Field string `json:"field"`
|
||||
}
|
||||
|
||||
func (*testType) TypeTag() string { return "test/TaggedType" }
|
||||
|
||||
func TestRoundTrip(t *testing.T) {
|
||||
const wantEncoded = `{"type":"test/TaggedType","value":{"field":"hello"}}`
|
||||
|
||||
t.Run("MustRegisterOK", func(t *testing.T) {
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
t.Fatalf("Registration panicked: %v", x)
|
||||
}
|
||||
}()
|
||||
jsontypes.MustRegister((*testType)(nil))
|
||||
})
|
||||
|
||||
t.Run("MustRegisterFail", func(t *testing.T) {
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
t.Logf("Got expected panic: %v", x)
|
||||
}
|
||||
}()
|
||||
jsontypes.MustRegister((*testType)(nil))
|
||||
t.Fatal("Registration should not have succeeded")
|
||||
})
|
||||
|
||||
t.Run("MarshalNil", func(t *testing.T) {
|
||||
bits, err := jsontypes.Marshal(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Marshal failed: %v", err)
|
||||
}
|
||||
if got := string(bits); got != "null" {
|
||||
t.Errorf("Marshal nil: got %#q, want null", got)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("RoundTrip", func(t *testing.T) {
|
||||
obj := testType{Field: "hello"}
|
||||
bits, err := jsontypes.Marshal(&obj)
|
||||
if err != nil {
|
||||
t.Fatalf("Marshal %T failed: %v", obj, err)
|
||||
}
|
||||
if got := string(bits); got != wantEncoded {
|
||||
t.Errorf("Marshal %T: got %#q, want %#q", obj, got, wantEncoded)
|
||||
}
|
||||
|
||||
var cmp testType
|
||||
if err := jsontypes.Unmarshal(bits, &cmp); err != nil {
|
||||
t.Errorf("Unmarshal %#q failed: %v", string(bits), err)
|
||||
}
|
||||
if obj != cmp {
|
||||
t.Errorf("Unmarshal %#q: got %+v, want %+v", string(bits), cmp, obj)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Unregistered", func(t *testing.T) {
|
||||
obj := testType{Field: "hello"}
|
||||
bits, err := jsontypes.Marshal(&obj)
|
||||
if err != nil {
|
||||
t.Fatalf("Marshal %T failed: %v", obj, err)
|
||||
}
|
||||
if got := string(bits); got != wantEncoded {
|
||||
t.Errorf("Marshal %T: got %#q, want %#q", obj, got, wantEncoded)
|
||||
}
|
||||
|
||||
var cmp struct {
|
||||
Field string `json:"field"`
|
||||
}
|
||||
if err := jsontypes.Unmarshal(bits, &cmp); err != nil {
|
||||
t.Errorf("Unmarshal %#q: got %+v, want %+v", string(bits), cmp, obj)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -52,6 +52,7 @@ func (pk privKeyWithNilPubKey) Sign(msg []byte) ([]byte, error) { return pk.orig
|
||||
func (pk privKeyWithNilPubKey) PubKey() crypto.PubKey { return nil }
|
||||
func (pk privKeyWithNilPubKey) Equals(pk2 crypto.PrivKey) bool { return pk.orig.Equals(pk2) }
|
||||
func (pk privKeyWithNilPubKey) Type() string { return "privKeyWithNilPubKey" }
|
||||
func (privKeyWithNilPubKey) TypeTag() string { return "test/privKeyWithNilPubKey" }
|
||||
|
||||
func TestSecretConnectionHandshake(t *testing.T) {
|
||||
fooSecConn, barSecConn := makeSecretConnPair(t)
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
"github.com/tendermint/tendermint/internal/jsontypes"
|
||||
"github.com/tendermint/tendermint/internal/libs/protoio"
|
||||
"github.com/tendermint/tendermint/internal/libs/tempfile"
|
||||
tmbytes "github.com/tendermint/tendermint/libs/bytes"
|
||||
@@ -55,6 +56,22 @@ type FilePVKey struct {
|
||||
filePath string
|
||||
}
|
||||
|
||||
func (pvKey FilePVKey) MarshalJSON() ([]byte, error) {
|
||||
pubk, err := jsontypes.Marshal(pvKey.PubKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
privk, err := jsontypes.Marshal(pvKey.PrivKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(struct {
|
||||
Address types.Address `json:"address"`
|
||||
PubKey json.RawMessage `json:"pub_key"`
|
||||
PrivKey json.RawMessage `json:"priv_key"`
|
||||
}{Address: pvKey.Address, PubKey: pubk, PrivKey: privk})
|
||||
}
|
||||
|
||||
// Save persists the FilePVKey to its filePath.
|
||||
func (pvKey FilePVKey) Save() error {
|
||||
outFile := pvKey.filePath
|
||||
|
||||
@@ -510,7 +510,9 @@ func (c *baseRPCClient) BroadcastEvidence(
|
||||
ev types.Evidence,
|
||||
) (*coretypes.ResultBroadcastEvidence, error) {
|
||||
result := new(coretypes.ResultBroadcastEvidence)
|
||||
if err := c.caller.Call(ctx, "broadcast_evidence", map[string]interface{}{"evidence": ev}, result); err != nil {
|
||||
if err := c.caller.Call(ctx, "broadcast_evidence", evidenceArgs{
|
||||
Evidence: ev,
|
||||
}, result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
|
||||
@@ -4,7 +4,11 @@ package http
|
||||
// from the client to the server.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/tendermint/tendermint/internal/jsontypes"
|
||||
"github.com/tendermint/tendermint/libs/bytes"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
type abciQueryArgs struct {
|
||||
@@ -57,3 +61,19 @@ type validatorArgs struct {
|
||||
Page *int `json:"page,string,omitempty"`
|
||||
PerPage *int `json:"per_page,string,omitempty"`
|
||||
}
|
||||
|
||||
type evidenceArgs struct {
|
||||
Evidence types.Evidence
|
||||
}
|
||||
|
||||
// MarshalJSON implements json.Marshaler to encode the evidence using the
|
||||
// wrapped concrete type of the implementation.
|
||||
func (e evidenceArgs) MarshalJSON() ([]byte, error) {
|
||||
ev, err := jsontypes.Marshal(e.Evidence)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(struct {
|
||||
Evidence json.RawMessage `json:"evidence"`
|
||||
}{Evidence: ev})
|
||||
}
|
||||
|
||||
@@ -334,7 +334,7 @@ type Header struct {
|
||||
// basic block info
|
||||
Version version.Consensus `json:"version"`
|
||||
ChainID string `json:"chain_id"`
|
||||
Height int64 `json:"height"`
|
||||
Height int64 `json:"height,string"`
|
||||
Time time.Time `json:"time"`
|
||||
|
||||
// prev block info
|
||||
@@ -748,7 +748,7 @@ type Commit struct {
|
||||
// ValidatorSet order.
|
||||
// Any peer with a block can gossip signatures by index with a peer without
|
||||
// recalculating the active ValidatorSet.
|
||||
Height int64 `json:"height"`
|
||||
Height int64 `json:"height,string"`
|
||||
Round int32 `json:"round"`
|
||||
BlockID BlockID `json:"block_id"`
|
||||
Signatures []CommitSig `json:"signatures"`
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto/merkle"
|
||||
"github.com/tendermint/tendermint/crypto/tmhash"
|
||||
"github.com/tendermint/tendermint/internal/jsontypes"
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
tmrand "github.com/tendermint/tendermint/libs/rand"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
@@ -28,6 +29,9 @@ type Evidence interface {
|
||||
String() string // string format of the evidence
|
||||
Time() time.Time // time of the infraction
|
||||
ValidateBasic() error // basic consistency check
|
||||
|
||||
// Implementations must support tagged encoding in JSON.
|
||||
jsontypes.Tagged
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
@@ -38,11 +42,14 @@ type DuplicateVoteEvidence struct {
|
||||
VoteB *Vote `json:"vote_b"`
|
||||
|
||||
// abci specific information
|
||||
TotalVotingPower int64
|
||||
ValidatorPower int64
|
||||
TotalVotingPower int64 `json:",string"`
|
||||
ValidatorPower int64 `json:",string"`
|
||||
Timestamp time.Time
|
||||
}
|
||||
|
||||
// TypeTag implements the jsontypes.Tagged interface.
|
||||
func (*DuplicateVoteEvidence) TypeTag() string { return "tendermint/DuplicateVoteEvidence" }
|
||||
|
||||
var _ Evidence = &DuplicateVoteEvidence{}
|
||||
|
||||
// NewDuplicateVoteEvidence creates DuplicateVoteEvidence with right ordering given
|
||||
@@ -236,14 +243,17 @@ func DuplicateVoteEvidenceFromProto(pb *tmproto.DuplicateVoteEvidence) (*Duplica
|
||||
// height, then nodes will treat this as of the Lunatic form, else it is of the Equivocation form.
|
||||
type LightClientAttackEvidence struct {
|
||||
ConflictingBlock *LightBlock
|
||||
CommonHeight int64
|
||||
CommonHeight int64 `json:",string"`
|
||||
|
||||
// abci specific information
|
||||
ByzantineValidators []*Validator // validators in the validator set that misbehaved in creating the conflicting block
|
||||
TotalVotingPower int64 // total voting power of the validator set at the common height
|
||||
TotalVotingPower int64 `json:",string"` // total voting power of the validator set at the common height
|
||||
Timestamp time.Time // timestamp of the block at the common height
|
||||
}
|
||||
|
||||
// TypeTag implements the jsontypes.Tagged interface.
|
||||
func (*LightClientAttackEvidence) TypeTag() string { return "tendermint/LightClientAttackEvidence" }
|
||||
|
||||
var _ Evidence = &LightClientAttackEvidence{}
|
||||
|
||||
// ABCI forms an array of abci evidence for each byzantine validator
|
||||
@@ -365,10 +375,10 @@ func (l *LightClientAttackEvidence) Height() int64 {
|
||||
// String returns a string representation of LightClientAttackEvidence
|
||||
func (l *LightClientAttackEvidence) String() string {
|
||||
return fmt.Sprintf(`LightClientAttackEvidence{
|
||||
ConflictingBlock: %v,
|
||||
CommonHeight: %d,
|
||||
ByzatineValidators: %v,
|
||||
TotalVotingPower: %d,
|
||||
ConflictingBlock: %v,
|
||||
CommonHeight: %d,
|
||||
ByzatineValidators: %v,
|
||||
TotalVotingPower: %d,
|
||||
Timestamp: %v}#%X`,
|
||||
l.ConflictingBlock.String(), l.CommonHeight, l.ByzantineValidators,
|
||||
l.TotalVotingPower, l.Timestamp, l.Hash())
|
||||
@@ -630,6 +640,9 @@ func EvidenceFromProto(evidence *tmproto.Evidence) (Evidence, error) {
|
||||
func init() {
|
||||
tmjson.RegisterType(&DuplicateVoteEvidence{}, "tendermint/DuplicateVoteEvidence")
|
||||
tmjson.RegisterType(&LightClientAttackEvidence{}, "tendermint/LightClientAttackEvidence")
|
||||
|
||||
jsontypes.MustRegister((*DuplicateVoteEvidence)(nil))
|
||||
jsontypes.MustRegister((*LightClientAttackEvidence)(nil))
|
||||
}
|
||||
|
||||
//-------------------------------------------- ERRORS --------------------------------------
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/internal/jsontypes"
|
||||
tmbytes "github.com/tendermint/tendermint/libs/bytes"
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
tmtime "github.com/tendermint/tendermint/libs/time"
|
||||
@@ -29,10 +30,23 @@ const (
|
||||
type GenesisValidator struct {
|
||||
Address Address `json:"address"`
|
||||
PubKey crypto.PubKey `json:"pub_key"`
|
||||
Power int64 `json:"power"`
|
||||
Power int64 `json:"power,string"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
func (g GenesisValidator) MarshalJSON() ([]byte, error) {
|
||||
pk, err := jsontypes.Marshal(g.PubKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(struct {
|
||||
Address Address `json:"address"`
|
||||
PubKey json.RawMessage `json:"pub_key"`
|
||||
Power int64 `json:"power,string"`
|
||||
Name string `json:"name"`
|
||||
}{Address: g.Address, PubKey: pk, Power: g.Power, Name: g.Name})
|
||||
}
|
||||
|
||||
// GenesisDoc defines the initial conditions for a tendermint blockchain, in particular its validator set.
|
||||
type GenesisDoc struct {
|
||||
GenesisTime time.Time `json:"genesis_time"`
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
"github.com/tendermint/tendermint/internal/jsontypes"
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
tmos "github.com/tendermint/tendermint/libs/os"
|
||||
)
|
||||
@@ -22,14 +24,25 @@ type NodeKey struct {
|
||||
PrivKey crypto.PrivKey `json:"priv_key"`
|
||||
}
|
||||
|
||||
func (nk NodeKey) MarshalJSON() ([]byte, error) {
|
||||
pk, err := jsontypes.Marshal(nk.PrivKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(struct {
|
||||
ID NodeID `json:"id"`
|
||||
PrivKey json.RawMessage `json:"priv_key"`
|
||||
}{ID: nk.ID, PrivKey: pk})
|
||||
}
|
||||
|
||||
// PubKey returns the peer's PubKey
|
||||
func (nodeKey NodeKey) PubKey() crypto.PubKey {
|
||||
return nodeKey.PrivKey.PubKey()
|
||||
func (nk NodeKey) PubKey() crypto.PubKey {
|
||||
return nk.PrivKey.PubKey()
|
||||
}
|
||||
|
||||
// SaveAs persists the NodeKey to filePath.
|
||||
func (nodeKey NodeKey) SaveAs(filePath string) error {
|
||||
jsonBytes, err := tmjson.Marshal(nodeKey)
|
||||
func (nk NodeKey) SaveAs(filePath string) error {
|
||||
jsonBytes, err := tmjson.Marshal(nk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -2,12 +2,14 @@ package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/encoding"
|
||||
"github.com/tendermint/tendermint/internal/jsontypes"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
)
|
||||
|
||||
@@ -15,11 +17,23 @@ import (
|
||||
// NOTE: The ProposerPriority is not included in Validator.Hash();
|
||||
// make sure to update that method if changes are made here
|
||||
type Validator struct {
|
||||
Address Address `json:"address"`
|
||||
PubKey crypto.PubKey `json:"pub_key"`
|
||||
VotingPower int64 `json:"voting_power"`
|
||||
Address Address `json:"address"`
|
||||
PubKey crypto.PubKey `json:"pub_key"`
|
||||
VotingPower int64 `json:"voting_power,string"`
|
||||
ProposerPriority int64 `json:"proposer_priority,string"`
|
||||
}
|
||||
|
||||
ProposerPriority int64 `json:"proposer_priority"`
|
||||
func (v Validator) MarshalJSON() ([]byte, error) {
|
||||
pk, err := jsontypes.Marshal(v.PubKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(struct {
|
||||
Addr Address `json:"address"`
|
||||
PubKey json.RawMessage `json:"pub_key"`
|
||||
Power int64 `json:"voting_power,string"`
|
||||
Priority int64 `json:"proposer_priority,string"`
|
||||
}{Addr: v.Address, PubKey: pk, Power: v.VotingPower, Priority: v.ProposerPriority})
|
||||
}
|
||||
|
||||
// NewValidator returns a new validator with the given pubkey and voting power.
|
||||
|
||||
@@ -49,7 +49,7 @@ type Address = crypto.Address
|
||||
// consensus.
|
||||
type Vote struct {
|
||||
Type tmproto.SignedMsgType `json:"type"`
|
||||
Height int64 `json:"height"`
|
||||
Height int64 `json:"height,string"`
|
||||
Round int32 `json:"round"` // assume there will not be greater than 2_147_483_647 rounds
|
||||
BlockID BlockID `json:"block_id"` // zero if vote is nil.
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
|
||||
@@ -28,8 +28,8 @@ var (
|
||||
)
|
||||
|
||||
type Consensus struct {
|
||||
Block uint64 `json:"block"`
|
||||
App uint64 `json:"app"`
|
||||
Block uint64 `json:"block,string"`
|
||||
App uint64 `json:"app,string"`
|
||||
}
|
||||
|
||||
func (c Consensus) ToProto() tmversion.Consensus {
|
||||
|
||||
Reference in New Issue
Block a user