mirror of
https://github.com/tendermint/tendermint.git
synced 2026-08-15 11:46:11 +00:00
rpc: use encoding/json rather than tmjson (#7670)
The main change here is to use encoding/json to encode and decode RPC parameters, rather than the custom tmjson package. This includes: - Update the HTTP POST handler parameter handling. - Add field tags to 64-bit integer types to get string encoding (to match amino/tmjson). - Add marshalers to struct types that mention interfaces. - Inject wrappers to decode interface arguments in RPC handlers.
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
@@ -20,7 +20,7 @@ var GenNodeKeyCmd = &cobra.Command{
|
||||
func genNodeKey(cmd *cobra.Command, args []string) error {
|
||||
nodeKey := types.GenNodeKey()
|
||||
|
||||
bz, err := tmjson.Marshal(nodeKey)
|
||||
bz, err := json.Marshal(nodeKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("nodeKey -> json: %w", err)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
"github.com/tendermint/tendermint/privval"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
@@ -29,7 +29,7 @@ func genValidator(cmd *cobra.Command, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
jsbz, err := tmjson.Marshal(pv)
|
||||
jsbz, err := json.Marshal(pv)
|
||||
if err != nil {
|
||||
return fmt.Errorf("validator -> json: %w", err)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
"github.com/tendermint/tendermint/internal/jsontypes"
|
||||
tmnet "github.com/tendermint/tendermint/libs/net"
|
||||
tmos "github.com/tendermint/tendermint/libs/os"
|
||||
"github.com/tendermint/tendermint/privval"
|
||||
@@ -70,7 +70,7 @@ func showValidator(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
}
|
||||
|
||||
bz, err := tmjson.Marshal(pubKey)
|
||||
bz, err := jsontypes.Marshal(pubKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal private validator pubkey: %w", err)
|
||||
}
|
||||
|
||||
+2
-2
@@ -2,6 +2,7 @@ package config
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
@@ -9,7 +10,6 @@ import (
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmos "github.com/tendermint/tendermint/libs/os"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
@@ -270,7 +270,7 @@ func (cfg BaseConfig) LoadNodeKeyID() (types.NodeID, error) {
|
||||
return "", err
|
||||
}
|
||||
nodeKey := types.NodeKey{}
|
||||
err = tmjson.Unmarshal(jsonBytes, &nodeKey)
|
||||
err = json.Unmarshal(jsonBytes, &nodeKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ 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"
|
||||
)
|
||||
|
||||
//-------------------------------------
|
||||
@@ -57,9 +56,6 @@ const (
|
||||
)
|
||||
|
||||
func init() {
|
||||
tmjson.RegisterType(PubKey{}, PubKeyName)
|
||||
tmjson.RegisterType(PrivKey{}, PrivKeyName)
|
||||
|
||||
jsontypes.MustRegister(PubKey{})
|
||||
jsontypes.MustRegister(PrivKey{})
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ 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
|
||||
"golang.org/x/crypto/ripemd160" // nolint
|
||||
@@ -27,9 +26,6 @@ const (
|
||||
)
|
||||
|
||||
func init() {
|
||||
tmjson.RegisterType(PubKey{}, PubKeyName)
|
||||
tmjson.RegisterType(PrivKey{}, PrivKeyName)
|
||||
|
||||
jsontypes.MustRegister(PubKey{})
|
||||
jsontypes.MustRegister(PrivKey{})
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package sr25519
|
||||
|
||||
import (
|
||||
"github.com/tendermint/tendermint/internal/jsontypes"
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -11,9 +10,6 @@ const (
|
||||
)
|
||||
|
||||
func init() {
|
||||
tmjson.RegisterType(PubKey{}, PubKeyName)
|
||||
tmjson.RegisterType(PrivKey{}, PrivKeyName)
|
||||
|
||||
jsontypes.MustRegister(PubKey{})
|
||||
jsontypes.MustRegister(PrivKey{})
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package consensus
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
@@ -9,7 +10,6 @@ import (
|
||||
cstypes "github.com/tendermint/tendermint/internal/consensus/types"
|
||||
tmsync "github.com/tendermint/tendermint/internal/libs/sync"
|
||||
"github.com/tendermint/tendermint/libs/bits"
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmtime "github.com/tendermint/tendermint/libs/time"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
@@ -96,8 +96,7 @@ func (ps *PeerState) GetRoundState() *cstypes.PeerRoundState {
|
||||
func (ps *PeerState) ToJSON() ([]byte, error) {
|
||||
ps.mtx.Lock()
|
||||
defer ps.mtx.Unlock()
|
||||
|
||||
return tmjson.Marshal(ps)
|
||||
return json.Marshal(ps)
|
||||
}
|
||||
|
||||
// GetHeight returns an atomic snapshot of the PeerRoundState's height used by
|
||||
|
||||
@@ -84,6 +84,10 @@ func Unmarshal(data []byte, v interface{}) error {
|
||||
return fmt.Errorf("target is a nil %T", v)
|
||||
}
|
||||
baseType := target.Type().Elem()
|
||||
if isNull(data) {
|
||||
target.Elem().Set(reflect.Zero(baseType))
|
||||
return nil
|
||||
}
|
||||
|
||||
var w wrapper
|
||||
dec := json.NewDecoder(bytes.NewReader(data))
|
||||
@@ -93,7 +97,7 @@ func Unmarshal(data []byte, v interface{}) error {
|
||||
}
|
||||
typ, ok := registry.types[w.Type]
|
||||
if !ok {
|
||||
return fmt.Errorf("unknown type tag: %q", w.Type)
|
||||
return fmt.Errorf("unknown type tag for %T: %q", v, w.Type)
|
||||
}
|
||||
if typ.AssignableTo(baseType) {
|
||||
// ok: registered type is directly assignable to the target
|
||||
@@ -110,3 +114,8 @@ func Unmarshal(data []byte, v interface{}) error {
|
||||
target.Elem().Set(obj.Elem())
|
||||
return nil
|
||||
}
|
||||
|
||||
// isNull reports true if data is empty or is the JSON "null" value.
|
||||
func isNull(data []byte) bool {
|
||||
return len(data) == 0 || bytes.Equal(data, []byte("null"))
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package core
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -21,7 +22,6 @@ import (
|
||||
sm "github.com/tendermint/tendermint/internal/state"
|
||||
"github.com/tendermint/tendermint/internal/state/indexer"
|
||||
"github.com/tendermint/tendermint/internal/statesync"
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
"github.com/tendermint/tendermint/libs/strings"
|
||||
"github.com/tendermint/tendermint/rpc/coretypes"
|
||||
@@ -154,7 +154,7 @@ func (env *Environment) InitGenesisChunks() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
data, err := tmjson.Marshal(env.GenDoc)
|
||||
data, err := json.Marshal(env.GenDoc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -5,25 +5,22 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/tendermint/tendermint/rpc/coretypes"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
// BroadcastEvidence broadcasts evidence of the misbehavior.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Evidence/broadcast_evidence
|
||||
func (env *Environment) BroadcastEvidence(
|
||||
ctx context.Context,
|
||||
ev types.Evidence) (*coretypes.ResultBroadcastEvidence, error) {
|
||||
|
||||
if ev == nil {
|
||||
ev coretypes.Evidence,
|
||||
) (*coretypes.ResultBroadcastEvidence, error) {
|
||||
if ev.Value == nil {
|
||||
return nil, fmt.Errorf("%w: no evidence was provided", coretypes.ErrInvalidRequest)
|
||||
}
|
||||
|
||||
if err := ev.ValidateBasic(); err != nil {
|
||||
if err := ev.Value.ValidateBasic(); err != nil {
|
||||
return nil, fmt.Errorf("evidence.ValidateBasic failed: %w", err)
|
||||
}
|
||||
|
||||
if err := env.EvidencePool.AddEvidence(ev); err != nil {
|
||||
if err := env.EvidencePool.AddEvidence(ev.Value); err != nil {
|
||||
return nil, fmt.Errorf("failed to add evidence: %w", err)
|
||||
}
|
||||
return &coretypes.ResultBroadcastEvidence{Hash: ev.Hash()}, nil
|
||||
return &coretypes.ResultBroadcastEvidence{Hash: ev.Value.Hash()}, nil
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ type RPCService interface {
|
||||
BlockResults(ctx context.Context, heightPtr *int64) (*coretypes.ResultBlockResults, error)
|
||||
BlockSearch(ctx context.Context, query string, pagePtr, perPagePtr *int, orderBy string) (*coretypes.ResultBlockSearch, error)
|
||||
BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error)
|
||||
BroadcastEvidence(ctx context.Context, ev types.Evidence) (*coretypes.ResultBroadcastEvidence, error)
|
||||
BroadcastEvidence(ctx context.Context, ev coretypes.Evidence) (*coretypes.ResultBroadcastEvidence, error)
|
||||
BroadcastTxAsync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error)
|
||||
BroadcastTxCommit(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error)
|
||||
BroadcastTxSync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error)
|
||||
|
||||
@@ -38,3 +38,7 @@ func (p proxyService) Unsubscribe(ctx context.Context, query string) (*coretypes
|
||||
func (p proxyService) UnsubscribeAll(ctx context.Context) (*coretypes.ResultUnsubscribe, error) {
|
||||
return p.UnsubscribeAllWS(ctx)
|
||||
}
|
||||
|
||||
func (p proxyService) BroadcastEvidence(ctx context.Context, ev coretypes.Evidence) (*coretypes.ResultBroadcastEvidence, error) {
|
||||
return p.Client.BroadcastEvidence(ctx, ev.Value)
|
||||
}
|
||||
|
||||
+30
-12
@@ -18,7 +18,6 @@ import (
|
||||
"github.com/tendermint/tendermint/internal/libs/protoio"
|
||||
"github.com/tendermint/tendermint/internal/libs/tempfile"
|
||||
tmbytes "github.com/tendermint/tendermint/libs/bytes"
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
tmos "github.com/tendermint/tendermint/libs/os"
|
||||
tmtime "github.com/tendermint/tendermint/libs/time"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
@@ -49,13 +48,19 @@ func voteToStep(vote *tmproto.Vote) (int8, error) {
|
||||
|
||||
// FilePVKey stores the immutable part of PrivValidator.
|
||||
type FilePVKey struct {
|
||||
Address types.Address `json:"address"`
|
||||
PubKey crypto.PubKey `json:"pub_key"`
|
||||
PrivKey crypto.PrivKey `json:"priv_key"`
|
||||
Address types.Address
|
||||
PubKey crypto.PubKey
|
||||
PrivKey crypto.PrivKey
|
||||
|
||||
filePath string
|
||||
}
|
||||
|
||||
type filePVKeyJSON struct {
|
||||
Address types.Address `json:"address"`
|
||||
PubKey json.RawMessage `json:"pub_key"`
|
||||
PrivKey json.RawMessage `json:"priv_key"`
|
||||
}
|
||||
|
||||
func (pvKey FilePVKey) MarshalJSON() ([]byte, error) {
|
||||
pubk, err := jsontypes.Marshal(pvKey.PubKey)
|
||||
if err != nil {
|
||||
@@ -65,11 +70,24 @@ func (pvKey FilePVKey) MarshalJSON() ([]byte, error) {
|
||||
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})
|
||||
return json.Marshal(filePVKeyJSON{
|
||||
Address: pvKey.Address, PubKey: pubk, PrivKey: privk,
|
||||
})
|
||||
}
|
||||
|
||||
func (pvKey *FilePVKey) UnmarshalJSON(data []byte) error {
|
||||
var key filePVKeyJSON
|
||||
if err := json.Unmarshal(data, &key); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := jsontypes.Unmarshal(key.PubKey, &pvKey.PubKey); err != nil {
|
||||
return fmt.Errorf("decoding PubKey: %w", err)
|
||||
}
|
||||
if err := jsontypes.Unmarshal(key.PrivKey, &pvKey.PrivKey); err != nil {
|
||||
return fmt.Errorf("decoding PrivKey: %w", err)
|
||||
}
|
||||
pvKey.Address = key.Address
|
||||
return nil
|
||||
}
|
||||
|
||||
// Save persists the FilePVKey to its filePath.
|
||||
@@ -79,11 +97,11 @@ func (pvKey FilePVKey) Save() error {
|
||||
return errors.New("cannot save PrivValidator key: filePath not set")
|
||||
}
|
||||
|
||||
jsonBytes, err := tmjson.MarshalIndent(pvKey, "", " ")
|
||||
data, err := json.MarshalIndent(pvKey, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tempfile.WriteFileAtomic(outFile, jsonBytes, 0600)
|
||||
return tempfile.WriteFileAtomic(outFile, data, 0600)
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
@@ -216,7 +234,7 @@ func loadFilePV(keyFilePath, stateFilePath string, loadState bool) (*FilePV, err
|
||||
return nil, err
|
||||
}
|
||||
pvKey := FilePVKey{}
|
||||
err = tmjson.Unmarshal(keyJSONBytes, &pvKey)
|
||||
err = json.Unmarshal(keyJSONBytes, &pvKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading PrivValidator key from %v: %w", keyFilePath, err)
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
"github.com/tendermint/tendermint/crypto/tmhash"
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
tmrand "github.com/tendermint/tendermint/libs/rand"
|
||||
tmtime "github.com/tendermint/tendermint/libs/time"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
@@ -143,7 +142,7 @@ func TestUnmarshalValidatorKey(t *testing.T) {
|
||||
}`, addr, pubB64, privB64)
|
||||
|
||||
val := FilePVKey{}
|
||||
err := tmjson.Unmarshal([]byte(serialized), &val)
|
||||
err := json.Unmarshal([]byte(serialized), &val)
|
||||
require.NoError(t, err)
|
||||
|
||||
// make sure the values match
|
||||
@@ -152,7 +151,7 @@ func TestUnmarshalValidatorKey(t *testing.T) {
|
||||
assert.EqualValues(t, privKey, val.PrivKey)
|
||||
|
||||
// export it and make sure it is the same
|
||||
out, err := tmjson.Marshal(val)
|
||||
out, err := json.Marshal(val)
|
||||
require.NoError(t, err)
|
||||
assert.JSONEq(t, serialized, string(out))
|
||||
}
|
||||
|
||||
@@ -512,7 +512,7 @@ func (c *baseRPCClient) BroadcastEvidence(
|
||||
) (*coretypes.ResultBroadcastEvidence, error) {
|
||||
result := new(coretypes.ResultBroadcastEvidence)
|
||||
if err := c.caller.Call(ctx, "broadcast_evidence", evidenceArgs{
|
||||
Evidence: ev,
|
||||
Evidence: coretypes.Evidence{Value: ev},
|
||||
}, result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -4,11 +4,8 @@ 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"
|
||||
"github.com/tendermint/tendermint/rpc/coretypes"
|
||||
)
|
||||
|
||||
type abciQueryArgs struct {
|
||||
@@ -64,17 +61,5 @@ type validatorArgs struct {
|
||||
}
|
||||
|
||||
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})
|
||||
Evidence coretypes.Evidence `json:"evidence"`
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
@@ -9,7 +10,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/tendermint/tendermint/internal/pubsub"
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
rpcclient "github.com/tendermint/tendermint/rpc/client"
|
||||
"github.com/tendermint/tendermint/rpc/coretypes"
|
||||
jsonrpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client"
|
||||
@@ -239,7 +239,7 @@ func (w *wsEvents) eventListener(ctx context.Context) {
|
||||
}
|
||||
|
||||
result := new(coretypes.ResultEvent)
|
||||
err := tmjson.Unmarshal(resp.Result, result)
|
||||
err := json.Unmarshal(resp.Result, result)
|
||||
if err != nil {
|
||||
w.Logger.Error("failed to unmarshal response", "err", err)
|
||||
continue
|
||||
|
||||
@@ -198,7 +198,7 @@ func (c *Local) BlockSearch(
|
||||
}
|
||||
|
||||
func (c *Local) BroadcastEvidence(ctx context.Context, ev types.Evidence) (*coretypes.ResultBroadcastEvidence, error) {
|
||||
return c.env.BroadcastEvidence(ctx, ev)
|
||||
return c.env.BroadcastEvidence(ctx, coretypes.Evidence{Value: ev})
|
||||
}
|
||||
|
||||
func (c *Local) Subscribe(
|
||||
|
||||
@@ -155,5 +155,5 @@ func (c Client) Validators(ctx context.Context, height *int64, page, perPage *in
|
||||
}
|
||||
|
||||
func (c Client) BroadcastEvidence(ctx context.Context, ev types.Evidence) (*coretypes.ResultBroadcastEvidence, error) {
|
||||
return c.env.BroadcastEvidence(ctx, ev)
|
||||
return c.env.BroadcastEvidence(ctx, coretypes.Evidence{Value: ev})
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"net/http"
|
||||
@@ -21,7 +22,6 @@ import (
|
||||
"github.com/tendermint/tendermint/crypto/encoding"
|
||||
"github.com/tendermint/tendermint/internal/mempool"
|
||||
rpccore "github.com/tendermint/tendermint/internal/rpc/core"
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmmath "github.com/tendermint/tendermint/libs/math"
|
||||
"github.com/tendermint/tendermint/libs/service"
|
||||
@@ -305,7 +305,7 @@ func TestClientMethodCalls(t *testing.T) {
|
||||
doc := []byte(strings.Join(decoded, ""))
|
||||
|
||||
var out types.GenesisDoc
|
||||
require.NoError(t, tmjson.Unmarshal(doc, &out),
|
||||
require.NoError(t, json.Unmarshal(doc, &out),
|
||||
"first: %+v, doc: %s", first, string(doc))
|
||||
})
|
||||
t.Run("ABCIQuery", func(t *testing.T) {
|
||||
@@ -582,7 +582,7 @@ func TestClientMethodCalls(t *testing.T) {
|
||||
})
|
||||
t.Run("BroadcastEmpty", func(t *testing.T) {
|
||||
_, err := c.BroadcastEvidence(ctx, nil)
|
||||
assert.Error(t, err)
|
||||
require.Error(t, err)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
+115
-39
@@ -3,10 +3,12 @@ package coretypes
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/internal/jsontypes"
|
||||
"github.com/tendermint/tendermint/libs/bytes"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
@@ -26,7 +28,7 @@ var (
|
||||
|
||||
// List of blocks
|
||||
type ResultBlockchainInfo struct {
|
||||
LastHeight int64 `json:"last_height"`
|
||||
LastHeight int64 `json:"last_height,string"`
|
||||
BlockMetas []*types.BlockMeta `json:"block_metas"`
|
||||
}
|
||||
|
||||
@@ -40,8 +42,8 @@ type ResultGenesis struct {
|
||||
// document to JSON and then splitting the resulting payload into
|
||||
// 16 megabyte blocks and then base64 encoding each block.
|
||||
type ResultGenesisChunk struct {
|
||||
ChunkNumber int `json:"chunk"`
|
||||
TotalChunks int `json:"total"`
|
||||
ChunkNumber int `json:"chunk,string"`
|
||||
TotalChunks int `json:"total,string"`
|
||||
Data string `json:"data"`
|
||||
}
|
||||
|
||||
@@ -64,9 +66,9 @@ type ResultCommit struct {
|
||||
|
||||
// ABCI results from a block
|
||||
type ResultBlockResults struct {
|
||||
Height int64 `json:"height"`
|
||||
Height int64 `json:"height,string"`
|
||||
TxsResults []*abci.ResponseDeliverTx `json:"txs_results"`
|
||||
TotalGasUsed int64 `json:"total_gas_used"`
|
||||
TotalGasUsed int64 `json:"total_gas_used,string"`
|
||||
BeginBlockEvents []abci.Event `json:"begin_block_events"`
|
||||
EndBlockEvents []abci.Event `json:"end_block_events"`
|
||||
ValidatorUpdates []abci.ValidatorUpdate `json:"validator_updates"`
|
||||
@@ -91,35 +93,64 @@ func NewResultCommit(header *types.Header, commit *types.Commit,
|
||||
type SyncInfo struct {
|
||||
LatestBlockHash bytes.HexBytes `json:"latest_block_hash"`
|
||||
LatestAppHash bytes.HexBytes `json:"latest_app_hash"`
|
||||
LatestBlockHeight int64 `json:"latest_block_height"`
|
||||
LatestBlockHeight int64 `json:"latest_block_height,string"`
|
||||
LatestBlockTime time.Time `json:"latest_block_time"`
|
||||
|
||||
EarliestBlockHash bytes.HexBytes `json:"earliest_block_hash"`
|
||||
EarliestAppHash bytes.HexBytes `json:"earliest_app_hash"`
|
||||
EarliestBlockHeight int64 `json:"earliest_block_height"`
|
||||
EarliestBlockHeight int64 `json:"earliest_block_height,string"`
|
||||
EarliestBlockTime time.Time `json:"earliest_block_time"`
|
||||
|
||||
MaxPeerBlockHeight int64 `json:"max_peer_block_height"`
|
||||
MaxPeerBlockHeight int64 `json:"max_peer_block_height,string"`
|
||||
|
||||
CatchingUp bool `json:"catching_up"`
|
||||
|
||||
TotalSyncedTime time.Duration `json:"total_synced_time"`
|
||||
RemainingTime time.Duration `json:"remaining_time"`
|
||||
TotalSyncedTime time.Duration `json:"total_synced_time,string"`
|
||||
RemainingTime time.Duration `json:"remaining_time,string"`
|
||||
|
||||
TotalSnapshots int64 `json:"total_snapshots"`
|
||||
ChunkProcessAvgTime time.Duration `json:"chunk_process_avg_time"`
|
||||
SnapshotHeight int64 `json:"snapshot_height"`
|
||||
SnapshotChunksCount int64 `json:"snapshot_chunks_count"`
|
||||
SnapshotChunksTotal int64 `json:"snapshot_chunks_total"`
|
||||
BackFilledBlocks int64 `json:"backfilled_blocks"`
|
||||
BackFillBlocksTotal int64 `json:"backfill_blocks_total"`
|
||||
TotalSnapshots int64 `json:"total_snapshots,string"`
|
||||
ChunkProcessAvgTime time.Duration `json:"chunk_process_avg_time,string"`
|
||||
SnapshotHeight int64 `json:"snapshot_height,string"`
|
||||
SnapshotChunksCount int64 `json:"snapshot_chunks_count,string"`
|
||||
SnapshotChunksTotal int64 `json:"snapshot_chunks_total,string"`
|
||||
BackFilledBlocks int64 `json:"backfilled_blocks,string"`
|
||||
BackFillBlocksTotal int64 `json:"backfill_blocks_total,string"`
|
||||
}
|
||||
|
||||
// Info about the node's validator
|
||||
type ValidatorInfo struct {
|
||||
Address bytes.HexBytes `json:"address"`
|
||||
PubKey crypto.PubKey `json:"pub_key"`
|
||||
VotingPower int64 `json:"voting_power"`
|
||||
Address bytes.HexBytes
|
||||
PubKey crypto.PubKey
|
||||
VotingPower int64
|
||||
}
|
||||
|
||||
type validatorInfoJSON struct {
|
||||
Address bytes.HexBytes `json:"address"`
|
||||
PubKey json.RawMessage `json:"pub_key"`
|
||||
VotingPower int64 `json:"voting_power,string"`
|
||||
}
|
||||
|
||||
func (v ValidatorInfo) MarshalJSON() ([]byte, error) {
|
||||
pk, err := jsontypes.Marshal(v.PubKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(validatorInfoJSON{
|
||||
Address: v.Address, PubKey: pk, VotingPower: v.VotingPower,
|
||||
})
|
||||
}
|
||||
|
||||
func (v *ValidatorInfo) UnmarshalJSON(data []byte) error {
|
||||
var val validatorInfoJSON
|
||||
if err := json.Unmarshal(data, &val); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := jsontypes.Unmarshal(val.PubKey, &v.PubKey); err != nil {
|
||||
return err
|
||||
}
|
||||
v.Address = val.Address
|
||||
v.VotingPower = val.VotingPower
|
||||
return nil
|
||||
}
|
||||
|
||||
// Node Status
|
||||
@@ -142,7 +173,7 @@ func (s *ResultStatus) TxIndexEnabled() bool {
|
||||
type ResultNetInfo struct {
|
||||
Listening bool `json:"listening"`
|
||||
Listeners []string `json:"listeners"`
|
||||
NPeers int `json:"n_peers"`
|
||||
NPeers int `json:"n_peers,string"`
|
||||
Peers []Peer `json:"peers"`
|
||||
}
|
||||
|
||||
@@ -164,12 +195,11 @@ type Peer struct {
|
||||
|
||||
// Validators for a height.
|
||||
type ResultValidators struct {
|
||||
BlockHeight int64 `json:"block_height"`
|
||||
BlockHeight int64 `json:"block_height,string"`
|
||||
Validators []*types.Validator `json:"validators"`
|
||||
// Count of actual validators in this result
|
||||
Count int `json:"count"`
|
||||
// Total number of validators
|
||||
Total int `json:"total"`
|
||||
|
||||
Count int `json:"count,string"` // Count of actual validators in this result
|
||||
Total int `json:"total,string"` // Total number of validators
|
||||
}
|
||||
|
||||
// ConsensusParams for given height
|
||||
@@ -203,8 +233,7 @@ type ResultBroadcastTx struct {
|
||||
Log string `json:"log"`
|
||||
Codespace string `json:"codespace"`
|
||||
MempoolError string `json:"mempool_error"`
|
||||
|
||||
Hash bytes.HexBytes `json:"hash"`
|
||||
Hash bytes.HexBytes `json:"hash"`
|
||||
}
|
||||
|
||||
// CheckTx and DeliverTx results
|
||||
@@ -212,7 +241,7 @@ type ResultBroadcastTxCommit struct {
|
||||
CheckTx abci.ResponseCheckTx `json:"check_tx"`
|
||||
DeliverTx abci.ResponseDeliverTx `json:"deliver_tx"`
|
||||
Hash bytes.HexBytes `json:"hash"`
|
||||
Height int64 `json:"height"`
|
||||
Height int64 `json:"height,string"`
|
||||
}
|
||||
|
||||
// ResultCheckTx wraps abci.ResponseCheckTx.
|
||||
@@ -223,7 +252,7 @@ type ResultCheckTx struct {
|
||||
// Result of querying for a tx
|
||||
type ResultTx struct {
|
||||
Hash bytes.HexBytes `json:"hash"`
|
||||
Height int64 `json:"height"`
|
||||
Height int64 `json:"height,string"`
|
||||
Index uint32 `json:"index"`
|
||||
TxResult abci.ResponseDeliverTx `json:"tx_result"`
|
||||
Tx types.Tx `json:"tx"`
|
||||
@@ -233,20 +262,20 @@ type ResultTx struct {
|
||||
// Result of searching for txs
|
||||
type ResultTxSearch struct {
|
||||
Txs []*ResultTx `json:"txs"`
|
||||
TotalCount int `json:"total_count"`
|
||||
TotalCount int `json:"total_count,string"`
|
||||
}
|
||||
|
||||
// ResultBlockSearch defines the RPC response type for a block search by events.
|
||||
type ResultBlockSearch struct {
|
||||
Blocks []*ResultBlock `json:"blocks"`
|
||||
TotalCount int `json:"total_count"`
|
||||
TotalCount int `json:"total_count,string"`
|
||||
}
|
||||
|
||||
// List of mempool txs
|
||||
type ResultUnconfirmedTxs struct {
|
||||
Count int `json:"n_txs"`
|
||||
Total int `json:"total"`
|
||||
TotalBytes int64 `json:"total_bytes"`
|
||||
Count int `json:"n_txs,string"`
|
||||
Total int `json:"total,string"`
|
||||
TotalBytes int64 `json:"total_bytes,string"`
|
||||
Txs []types.Tx `json:"txs"`
|
||||
}
|
||||
|
||||
@@ -276,8 +305,55 @@ type (
|
||||
|
||||
// Event data from a subscription
|
||||
type ResultEvent struct {
|
||||
SubscriptionID string `json:"subscription_id"`
|
||||
Query string `json:"query"`
|
||||
Data types.TMEventData `json:"data"`
|
||||
Events []abci.Event `json:"events"`
|
||||
SubscriptionID string
|
||||
Query string
|
||||
Data types.TMEventData
|
||||
Events []abci.Event
|
||||
}
|
||||
|
||||
type resultEventJSON struct {
|
||||
SubscriptionID string `json:"subscription_id"`
|
||||
Query string `json:"query"`
|
||||
Data json.RawMessage `json:"data"`
|
||||
Events []abci.Event `json:"events"`
|
||||
}
|
||||
|
||||
func (r ResultEvent) MarshalJSON() ([]byte, error) {
|
||||
data, ok := r.Data.(jsontypes.Tagged)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("type %T is not tagged", r.Data)
|
||||
}
|
||||
evt, err := jsontypes.Marshal(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(resultEventJSON{
|
||||
SubscriptionID: r.SubscriptionID,
|
||||
Query: r.Query,
|
||||
Data: evt,
|
||||
Events: r.Events,
|
||||
})
|
||||
}
|
||||
|
||||
func (r *ResultEvent) UnmarshalJSON(data []byte) error {
|
||||
var res resultEventJSON
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := jsontypes.Unmarshal(res.Data, &r.Data); err != nil {
|
||||
return err
|
||||
}
|
||||
r.SubscriptionID = res.SubscriptionID
|
||||
r.Query = res.Query
|
||||
r.Events = res.Events
|
||||
return nil
|
||||
}
|
||||
|
||||
// Evidence is an argument wrapper for a types.Evidence value, that handles
|
||||
// encoding and decoding through JSON.
|
||||
type Evidence struct {
|
||||
Value types.Evidence
|
||||
}
|
||||
|
||||
func (e Evidence) MarshalJSON() ([]byte, error) { return jsontypes.Marshal(e.Value) }
|
||||
func (e *Evidence) UnmarshalJSON(data []byte) error { return jsontypes.Unmarshal(data, &e.Value) }
|
||||
|
||||
@@ -5,7 +5,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
|
||||
)
|
||||
|
||||
@@ -26,7 +25,7 @@ func unmarshalResponseBytes(responseBytes []byte, expectedID rpctypes.JSONRPCInt
|
||||
}
|
||||
|
||||
// Unmarshal the RawMessage into the result.
|
||||
if err := tmjson.Unmarshal(response.Result, result); err != nil {
|
||||
if err := json.Unmarshal(response.Result, result); err != nil {
|
||||
return fmt.Errorf("error unmarshaling result: %w", err)
|
||||
}
|
||||
return nil
|
||||
@@ -71,7 +70,7 @@ func unmarshalResponseBytesArray(
|
||||
}
|
||||
|
||||
for i := 0; i < len(responses); i++ {
|
||||
if err := tmjson.Unmarshal(responses[i].Result, results[i]); err != nil {
|
||||
if err := json.Unmarshal(responses[i].Result, results[i]); err != nil {
|
||||
return nil, fmt.Errorf("error unmarshaling #%d result: %w", i, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package server
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -9,8 +10,8 @@ import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
"github.com/tendermint/tendermint/rpc/coretypes"
|
||||
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
|
||||
@@ -63,7 +64,12 @@ func makeJSONRPCHandler(funcMap map[string]*RPCFunc, logger log.Logger) http.Han
|
||||
continue
|
||||
}
|
||||
|
||||
args, err := parseParams(rpcFunc, hreq, req)
|
||||
req := req
|
||||
ctx := rpctypes.WithCallInfo(hreq.Context(), &rpctypes.CallInfo{
|
||||
RPCRequest: &req,
|
||||
HTTPRequest: hreq,
|
||||
})
|
||||
args, err := parseParams(ctx, rpcFunc, req.Params)
|
||||
if err != nil {
|
||||
responses = append(responses, rpctypes.RPCInvalidParamsError(
|
||||
req.ID, fmt.Errorf("converting JSON parameters: %w", err)))
|
||||
@@ -132,99 +138,101 @@ func parseRequests(data []byte) ([]rpctypes.RPCRequest, error) {
|
||||
return reqs, nil
|
||||
}
|
||||
|
||||
func mapParamsToArgs(
|
||||
rpcFunc *RPCFunc,
|
||||
params map[string]json.RawMessage,
|
||||
argsOffset int,
|
||||
) ([]reflect.Value, error) {
|
||||
|
||||
values := make([]reflect.Value, len(rpcFunc.argNames))
|
||||
for i, argName := range rpcFunc.argNames {
|
||||
argType := rpcFunc.args[i+argsOffset]
|
||||
|
||||
if p, ok := params[argName]; ok && p != nil && len(p) > 0 {
|
||||
val := reflect.New(argType)
|
||||
err := tmjson.Unmarshal(p, val.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
values[i] = val.Elem()
|
||||
} else { // use default for that type
|
||||
values[i] = reflect.Zero(argType)
|
||||
}
|
||||
}
|
||||
|
||||
return values, nil
|
||||
}
|
||||
|
||||
func arrayParamsToArgs(
|
||||
rpcFunc *RPCFunc,
|
||||
params []json.RawMessage,
|
||||
argsOffset int,
|
||||
) ([]reflect.Value, error) {
|
||||
|
||||
if len(rpcFunc.argNames) != len(params) {
|
||||
return nil, fmt.Errorf("expected %v parameters (%v), got %v (%v)",
|
||||
len(rpcFunc.argNames), rpcFunc.argNames, len(params), params)
|
||||
}
|
||||
|
||||
values := make([]reflect.Value, len(params))
|
||||
for i, p := range params {
|
||||
argType := rpcFunc.args[i+argsOffset]
|
||||
val := reflect.New(argType)
|
||||
err := tmjson.Unmarshal(p, val.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
values[i] = val.Elem()
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
// parseParams parses the JSON parameters of rpcReq into the arguments of fn,
|
||||
// returning the corresponding argument values or an error.
|
||||
func parseParams(fn *RPCFunc, httpReq *http.Request, rpcReq rpctypes.RPCRequest) ([]reflect.Value, error) {
|
||||
ctx := rpctypes.WithCallInfo(httpReq.Context(), &rpctypes.CallInfo{
|
||||
RPCRequest: &rpcReq,
|
||||
HTTPRequest: httpReq,
|
||||
})
|
||||
args := []reflect.Value{reflect.ValueOf(ctx)}
|
||||
if len(rpcReq.Params) == 0 {
|
||||
return args, nil
|
||||
}
|
||||
fargs, err := jsonParamsToArgs(fn, rpcReq.Params)
|
||||
func parseParams(ctx context.Context, fn *RPCFunc, paramData []byte) ([]reflect.Value, error) {
|
||||
params, err := parseJSONParams(fn, paramData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return append(args, fargs...), nil
|
||||
|
||||
args := make([]reflect.Value, 1+len(params))
|
||||
args[0] = reflect.ValueOf(ctx)
|
||||
for i, param := range params {
|
||||
ptype := fn.args[i+1]
|
||||
if len(param) == 0 {
|
||||
args[i+1] = reflect.Zero(ptype)
|
||||
continue
|
||||
}
|
||||
|
||||
var pval reflect.Value
|
||||
isPtr := ptype.Kind() == reflect.Ptr
|
||||
if isPtr {
|
||||
pval = reflect.New(ptype.Elem())
|
||||
} else {
|
||||
pval = reflect.New(ptype)
|
||||
}
|
||||
baseType := pval.Type().Elem()
|
||||
|
||||
if isIntType(baseType) && isStringValue(param) {
|
||||
var z int64String
|
||||
if err := json.Unmarshal(param, &z); err != nil {
|
||||
return nil, fmt.Errorf("decoding string %q: %w", fn.argNames[i], err)
|
||||
}
|
||||
pval.Elem().Set(reflect.ValueOf(z).Convert(baseType))
|
||||
} else if err := json.Unmarshal(param, pval.Interface()); err != nil {
|
||||
return nil, fmt.Errorf("decoding %q: %w", fn.argNames[i], err)
|
||||
}
|
||||
|
||||
if isPtr {
|
||||
args[i+1] = pval
|
||||
} else {
|
||||
args[i+1] = pval.Elem()
|
||||
}
|
||||
}
|
||||
return args, nil
|
||||
}
|
||||
|
||||
// raw is unparsed json (from json.RawMessage) encoding either a map or an
|
||||
// array.
|
||||
//
|
||||
// Example:
|
||||
// rpcFunc.args = [context.Context string]
|
||||
// rpcFunc.argNames = ["arg"]
|
||||
func jsonParamsToArgs(rpcFunc *RPCFunc, raw []byte) ([]reflect.Value, error) {
|
||||
const argsOffset = 1
|
||||
// parseJSONParams parses data and returns a slice of JSON values matching the
|
||||
// positional parameters of fn. It reports an error if data is not "null" and
|
||||
// does not encode an object or an array, or if the number of array parameters
|
||||
// does not match the argument list of fn (excluding the context).
|
||||
func parseJSONParams(fn *RPCFunc, data []byte) ([]json.RawMessage, error) {
|
||||
base := bytes.TrimSpace(data)
|
||||
if bytes.HasPrefix(base, []byte("{")) {
|
||||
var m map[string]json.RawMessage
|
||||
if err := json.Unmarshal(base, &m); err != nil {
|
||||
return nil, fmt.Errorf("decoding parameter object: %w", err)
|
||||
}
|
||||
out := make([]json.RawMessage, len(fn.argNames))
|
||||
for i, name := range fn.argNames {
|
||||
if p, ok := m[name]; ok {
|
||||
out[i] = p
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
|
||||
// TODO: Make more efficient, perhaps by checking the first character for '{' or '['?
|
||||
// First, try to get the map.
|
||||
var m map[string]json.RawMessage
|
||||
err := json.Unmarshal(raw, &m)
|
||||
if err == nil {
|
||||
return mapParamsToArgs(rpcFunc, m, argsOffset)
|
||||
} else if bytes.HasPrefix(base, []byte("[")) {
|
||||
var m []json.RawMessage
|
||||
if err := json.Unmarshal(base, &m); err != nil {
|
||||
return nil, fmt.Errorf("decoding parameter array: %w", err)
|
||||
}
|
||||
if len(m) != len(fn.argNames) {
|
||||
return nil, fmt.Errorf("got %d parameters, want %d", len(m), len(fn.argNames))
|
||||
}
|
||||
return m, nil
|
||||
|
||||
} else if bytes.Equal(base, []byte("null")) {
|
||||
return make([]json.RawMessage, len(fn.argNames)), nil
|
||||
}
|
||||
|
||||
// Otherwise, try an array.
|
||||
var a []json.RawMessage
|
||||
err = json.Unmarshal(raw, &a)
|
||||
if err == nil {
|
||||
return arrayParamsToArgs(rpcFunc, a, argsOffset)
|
||||
}
|
||||
return nil, errors.New("parameters must be an object or an array")
|
||||
}
|
||||
|
||||
// Otherwise, bad format, we cannot parse
|
||||
return nil, fmt.Errorf("unknown type for JSON params: %v. Expected map or array", err)
|
||||
// isStringValue reports whether data is a JSON string value.
|
||||
func isStringValue(data json.RawMessage) bool {
|
||||
return len(data) != 0 && data[0] == '"'
|
||||
}
|
||||
|
||||
type int64String int64
|
||||
|
||||
func (z *int64String) UnmarshalText(data []byte) error {
|
||||
v, err := strconv.ParseInt(string(data), 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*z = int64String(v)
|
||||
return nil
|
||||
}
|
||||
|
||||
// writes a list of available rpc endpoints as an html page
|
||||
|
||||
@@ -46,7 +46,7 @@ func TestRPCParams(t *testing.T) {
|
||||
// id not captured in JSON parsing failures
|
||||
{`{"method": "c", "id": "0", "params": a}`, "invalid character", nil},
|
||||
{`{"method": "c", "id": "0", "params": ["a"]}`, "got 1", rpctypes.JSONRPCStringID("0")},
|
||||
{`{"method": "c", "id": "0", "params": ["a", "b"]}`, "invalid character", rpctypes.JSONRPCStringID("0")},
|
||||
{`{"method": "c", "id": "0", "params": ["a", "b"]}`, "invalid syntax", rpctypes.JSONRPCStringID("0")},
|
||||
{`{"method": "c", "id": "0", "params": [1, 1]}`, "of type string", rpctypes.JSONRPCStringID("0")},
|
||||
|
||||
// no ID - notification
|
||||
|
||||
@@ -153,17 +153,17 @@ func TestParseJSONRPC(t *testing.T) {
|
||||
{`[7,"flew",100]`, 0, "", true},
|
||||
{`{"name": -12, "height": "fred"}`, 0, "", true},
|
||||
}
|
||||
ctx := context.Background()
|
||||
for idx, tc := range cases {
|
||||
i := strconv.Itoa(idx)
|
||||
data := []byte(tc.raw)
|
||||
vals, err := jsonParamsToArgs(call, data)
|
||||
vals, err := parseParams(ctx, call, []byte(tc.raw))
|
||||
if tc.fail {
|
||||
assert.Error(t, err, i)
|
||||
} else {
|
||||
assert.NoError(t, err, "%s: %+v", i, err)
|
||||
if assert.Equal(t, 2, len(vals), i) {
|
||||
assert.Equal(t, tc.height, vals[0].Int(), i)
|
||||
assert.Equal(t, tc.name, vals[1].String(), i)
|
||||
if assert.Equal(t, 3, len(vals), i) { // ctx, height, name
|
||||
assert.Equal(t, tc.height, vals[1].Int(), i)
|
||||
assert.Equal(t, tc.name, vals[2].String(), i)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"runtime/debug"
|
||||
"time"
|
||||
|
||||
@@ -371,18 +370,14 @@ func (wsc *wsConnection) readRoutine(ctx context.Context) {
|
||||
RPCRequest: &request,
|
||||
WSConn: wsc,
|
||||
})
|
||||
args := []reflect.Value{reflect.ValueOf(fctx)}
|
||||
if len(request.Params) > 0 {
|
||||
fnArgs, err := jsonParamsToArgs(rpcFunc, request.Params)
|
||||
if err != nil {
|
||||
if err := wsc.WriteRPCResponse(writeCtx,
|
||||
rpctypes.RPCInvalidParamsError(request.ID, fmt.Errorf("error converting json params to arguments: %w", err)),
|
||||
); err != nil {
|
||||
wsc.Logger.Error("error writing RPC response", "err", err)
|
||||
}
|
||||
continue
|
||||
args, err := parseParams(fctx, rpcFunc, request.Params)
|
||||
if err != nil {
|
||||
if err := wsc.WriteRPCResponse(writeCtx, rpctypes.RPCInvalidParamsError(
|
||||
request.ID, fmt.Errorf("error converting json params to arguments: %w", err)),
|
||||
); err != nil {
|
||||
wsc.Logger.Error("error writing RPC response", "err", err)
|
||||
}
|
||||
args = append(args, fnArgs...)
|
||||
continue
|
||||
}
|
||||
|
||||
returns := rpcFunc.f.Call(args)
|
||||
|
||||
@@ -7,8 +7,6 @@ import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
)
|
||||
|
||||
// a wrapper to emulate a sum type: jsonrpcid = string | int
|
||||
@@ -100,29 +98,10 @@ func (req RPCRequest) String() string {
|
||||
|
||||
// ParamsToRequest constructs a new RPCRequest with the given ID, method, and parameters.
|
||||
func ParamsToRequest(id jsonrpcid, method string, params interface{}) (RPCRequest, error) {
|
||||
var payload json.RawMessage
|
||||
var err error
|
||||
switch t := params.(type) {
|
||||
case map[string]interface{}:
|
||||
// TODO(creachadair): This special case preserves existing behavior that
|
||||
// relies on the custom JSON encoding library. Remove it once that
|
||||
// requirement has been removed.
|
||||
paramsMap := make(map[string]json.RawMessage, len(t))
|
||||
for name, value := range t {
|
||||
valueJSON, err := tmjson.Marshal(value)
|
||||
if err != nil {
|
||||
return RPCRequest{}, err
|
||||
}
|
||||
paramsMap[name] = valueJSON
|
||||
}
|
||||
payload, err = json.Marshal(paramsMap)
|
||||
default:
|
||||
payload, err = json.Marshal(params)
|
||||
}
|
||||
payload, err := json.Marshal(params)
|
||||
if err != nil {
|
||||
return RPCRequest{}, err
|
||||
}
|
||||
|
||||
return NewRPCRequest(id, method, payload), nil
|
||||
}
|
||||
|
||||
@@ -162,6 +141,7 @@ func (resp *RPCResponse) UnmarshalJSON(data []byte) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp.JSONRPC = unsafeResp.JSONRPC
|
||||
resp.Error = unsafeResp.Error
|
||||
resp.Result = unsafeResp.Result
|
||||
@@ -177,18 +157,11 @@ func (resp *RPCResponse) UnmarshalJSON(data []byte) error {
|
||||
}
|
||||
|
||||
func NewRPCSuccessResponse(id jsonrpcid, res interface{}) RPCResponse {
|
||||
var rawMsg json.RawMessage
|
||||
|
||||
if res != nil {
|
||||
var js []byte
|
||||
js, err := tmjson.Marshal(res)
|
||||
if err != nil {
|
||||
return RPCInternalError(id, fmt.Errorf("error marshaling response: %w", err))
|
||||
}
|
||||
rawMsg = json.RawMessage(js)
|
||||
result, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
return RPCInternalError(id, fmt.Errorf("error marshaling response: %w", err))
|
||||
}
|
||||
|
||||
return RPCResponse{JSONRPC: "2.0", ID: id, Result: rawMsg}
|
||||
return RPCResponse{JSONRPC: "2.0", ID: id, Result: result}
|
||||
}
|
||||
|
||||
func NewRPCErrorResponse(id jsonrpcid, code int, msg string, data string) RPCResponse {
|
||||
|
||||
@@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
@@ -13,7 +14,6 @@ import (
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/tmhash"
|
||||
"github.com/tendermint/tendermint/internal/test/factory"
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
"github.com/tendermint/tendermint/privval"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
e2e "github.com/tendermint/tendermint/test/e2e/pkg"
|
||||
@@ -241,7 +241,7 @@ func readPrivKey(keyFilePath string) (crypto.PrivKey, error) {
|
||||
return nil, err
|
||||
}
|
||||
pvKey := privval.FilePVKey{}
|
||||
err = tmjson.Unmarshal(keyJSONBytes, &pvKey)
|
||||
err = json.Unmarshal(keyJSONBytes, &pvKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading PrivValidator key from %v: %w", keyFilePath, err)
|
||||
}
|
||||
|
||||
+50
-16
@@ -6,9 +6,9 @@ import (
|
||||
"strings"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/internal/jsontypes"
|
||||
tmpubsub "github.com/tendermint/tendermint/internal/pubsub"
|
||||
tmquery "github.com/tendermint/tendermint/internal/pubsub/query"
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
)
|
||||
|
||||
// Reserved event types (alphabetically sorted).
|
||||
@@ -90,23 +90,21 @@ var (
|
||||
// ENCODING / DECODING
|
||||
|
||||
// TMEventData implements events.EventData.
|
||||
type TMEventData interface {
|
||||
// empty interface
|
||||
}
|
||||
type TMEventData interface{}
|
||||
|
||||
func init() {
|
||||
tmjson.RegisterType(EventDataNewBlock{}, "tendermint/event/NewBlock")
|
||||
tmjson.RegisterType(EventDataNewBlockHeader{}, "tendermint/event/NewBlockHeader")
|
||||
tmjson.RegisterType(EventDataNewEvidence{}, "tendermint/event/NewEvidence")
|
||||
tmjson.RegisterType(EventDataTx{}, "tendermint/event/Tx")
|
||||
tmjson.RegisterType(EventDataRoundState{}, "tendermint/event/RoundState")
|
||||
tmjson.RegisterType(EventDataNewRound{}, "tendermint/event/NewRound")
|
||||
tmjson.RegisterType(EventDataCompleteProposal{}, "tendermint/event/CompleteProposal")
|
||||
tmjson.RegisterType(EventDataVote{}, "tendermint/event/Vote")
|
||||
tmjson.RegisterType(EventDataValidatorSetUpdates{}, "tendermint/event/ValidatorSetUpdates")
|
||||
tmjson.RegisterType(EventDataString(""), "tendermint/event/ProposalString")
|
||||
tmjson.RegisterType(EventDataBlockSyncStatus{}, "tendermint/event/FastSyncStatus")
|
||||
tmjson.RegisterType(EventDataStateSyncStatus{}, "tendermint/event/StateSyncStatus")
|
||||
jsontypes.MustRegister(EventDataBlockSyncStatus{})
|
||||
jsontypes.MustRegister(EventDataCompleteProposal{})
|
||||
jsontypes.MustRegister(EventDataNewBlock{})
|
||||
jsontypes.MustRegister(EventDataNewBlockHeader{})
|
||||
jsontypes.MustRegister(EventDataNewEvidence{})
|
||||
jsontypes.MustRegister(EventDataNewRound{})
|
||||
jsontypes.MustRegister(EventDataRoundState{})
|
||||
jsontypes.MustRegister(EventDataStateSyncStatus{})
|
||||
jsontypes.MustRegister(EventDataTx{})
|
||||
jsontypes.MustRegister(EventDataValidatorSetUpdates{})
|
||||
jsontypes.MustRegister(EventDataVote{})
|
||||
jsontypes.MustRegister(EventDataString(""))
|
||||
}
|
||||
|
||||
// Most event messages are basic types (a block, a transaction)
|
||||
@@ -120,6 +118,9 @@ type EventDataNewBlock struct {
|
||||
ResultEndBlock abci.ResponseEndBlock `json:"result_end_block"`
|
||||
}
|
||||
|
||||
// TypeTag implements the required method of jsontypes.Tagged.
|
||||
func (EventDataNewBlock) TypeTag() string { return "tendermint/event/NewBlock" }
|
||||
|
||||
type EventDataNewBlockHeader struct {
|
||||
Header Header `json:"header"`
|
||||
|
||||
@@ -128,17 +129,26 @@ type EventDataNewBlockHeader struct {
|
||||
ResultEndBlock abci.ResponseEndBlock `json:"result_end_block"`
|
||||
}
|
||||
|
||||
// TypeTag implements the required method of jsontypes.Tagged.
|
||||
func (EventDataNewBlockHeader) TypeTag() string { return "tendermint/event/NewBlockHeader" }
|
||||
|
||||
type EventDataNewEvidence struct {
|
||||
Evidence Evidence `json:"evidence"`
|
||||
|
||||
Height int64 `json:"height"`
|
||||
}
|
||||
|
||||
// TypeTag implements the required method of jsontypes.Tagged.
|
||||
func (EventDataNewEvidence) TypeTag() string { return "tendermint/event/NewEvidence" }
|
||||
|
||||
// All txs fire EventDataTx
|
||||
type EventDataTx struct {
|
||||
abci.TxResult
|
||||
}
|
||||
|
||||
// TypeTag implements the required method of jsontypes.Tagged.
|
||||
func (EventDataTx) TypeTag() string { return "tendermint/event/Tx" }
|
||||
|
||||
// NOTE: This goes into the replay WAL
|
||||
type EventDataRoundState struct {
|
||||
Height int64 `json:"height"`
|
||||
@@ -146,6 +156,9 @@ type EventDataRoundState struct {
|
||||
Step string `json:"step"`
|
||||
}
|
||||
|
||||
// TypeTag implements the required method of jsontypes.Tagged.
|
||||
func (EventDataRoundState) TypeTag() string { return "tendermint/event/RoundState" }
|
||||
|
||||
type ValidatorInfo struct {
|
||||
Address Address `json:"address"`
|
||||
Index int32 `json:"index"`
|
||||
@@ -159,6 +172,9 @@ type EventDataNewRound struct {
|
||||
Proposer ValidatorInfo `json:"proposer"`
|
||||
}
|
||||
|
||||
// TypeTag implements the required method of jsontypes.Tagged.
|
||||
func (EventDataNewRound) TypeTag() string { return "tendermint/event/NewRound" }
|
||||
|
||||
type EventDataCompleteProposal struct {
|
||||
Height int64 `json:"height"`
|
||||
Round int32 `json:"round"`
|
||||
@@ -167,16 +183,28 @@ type EventDataCompleteProposal struct {
|
||||
BlockID BlockID `json:"block_id"`
|
||||
}
|
||||
|
||||
// TypeTag implements the required method of jsontypes.Tagged.
|
||||
func (EventDataCompleteProposal) TypeTag() string { return "tendermint/event/CompleteProposal" }
|
||||
|
||||
type EventDataVote struct {
|
||||
Vote *Vote
|
||||
}
|
||||
|
||||
// TypeTag implements the required method of jsontypes.Tagged.
|
||||
func (EventDataVote) TypeTag() string { return "tendermint/event/Vote" }
|
||||
|
||||
type EventDataString string
|
||||
|
||||
// TypeTag implements the required method of jsontypes.Tagged.
|
||||
func (EventDataString) TypeTag() string { return "tendermint/event/ProposalString" }
|
||||
|
||||
type EventDataValidatorSetUpdates struct {
|
||||
ValidatorUpdates []*Validator `json:"validator_updates"`
|
||||
}
|
||||
|
||||
// TypeTag implements the required method of jsontypes.Tagged.
|
||||
func (EventDataValidatorSetUpdates) TypeTag() string { return "tendermint/event/ValidatorSetUpdates" }
|
||||
|
||||
// EventDataBlockSyncStatus shows the fastsync status and the
|
||||
// height when the node state sync mechanism changes.
|
||||
type EventDataBlockSyncStatus struct {
|
||||
@@ -184,6 +212,9 @@ type EventDataBlockSyncStatus struct {
|
||||
Height int64 `json:"height"`
|
||||
}
|
||||
|
||||
// TypeTag implements the required method of jsontypes.Tagged.
|
||||
func (EventDataBlockSyncStatus) TypeTag() string { return "tendermint/event/FastSyncStatus" }
|
||||
|
||||
// EventDataStateSyncStatus shows the statesync status and the
|
||||
// height when the node state sync mechanism changes.
|
||||
type EventDataStateSyncStatus struct {
|
||||
@@ -191,6 +222,9 @@ type EventDataStateSyncStatus struct {
|
||||
Height int64 `json:"height"`
|
||||
}
|
||||
|
||||
// TypeTag implements the required method of jsontypes.Tagged.
|
||||
func (EventDataStateSyncStatus) TypeTag() string { return "tendermint/event/StateSyncStatus" }
|
||||
|
||||
// PUBSUB
|
||||
|
||||
const (
|
||||
|
||||
+28
-4
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
@@ -14,7 +15,6 @@ import (
|
||||
"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"
|
||||
)
|
||||
@@ -554,6 +554,33 @@ func LightClientAttackEvidenceFromProto(lpb *tmproto.LightClientAttackEvidence)
|
||||
// EvidenceList is a list of Evidence. Evidences is not a word.
|
||||
type EvidenceList []Evidence
|
||||
|
||||
func (evl EvidenceList) MarshalJSON() ([]byte, error) {
|
||||
lst := make([]json.RawMessage, len(evl))
|
||||
for i, ev := range evl {
|
||||
bits, err := jsontypes.Marshal(ev)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lst[i] = bits
|
||||
}
|
||||
return json.Marshal(lst)
|
||||
}
|
||||
|
||||
func (evl *EvidenceList) UnmarshalJSON(data []byte) error {
|
||||
var lst []json.RawMessage
|
||||
if err := json.Unmarshal(data, &lst); err != nil {
|
||||
return err
|
||||
}
|
||||
out := make([]Evidence, len(lst))
|
||||
for i, elt := range lst {
|
||||
if err := jsontypes.Unmarshal(elt, &out[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*evl = EvidenceList(out)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Hash returns the simple merkle root hash of the EvidenceList.
|
||||
func (evl EvidenceList) Hash() []byte {
|
||||
// These allocations are required because Evidence is not of type Bytes, and
|
||||
@@ -638,9 +665,6 @@ 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))
|
||||
}
|
||||
|
||||
+31
-14
@@ -11,7 +11,6 @@ import (
|
||||
"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"
|
||||
)
|
||||
|
||||
@@ -28,10 +27,17 @@ const (
|
||||
|
||||
// GenesisValidator is an initial validator.
|
||||
type GenesisValidator struct {
|
||||
Address Address `json:"address"`
|
||||
PubKey crypto.PubKey `json:"pub_key"`
|
||||
Power int64 `json:"power,string"`
|
||||
Name string `json:"name"`
|
||||
Address Address
|
||||
PubKey crypto.PubKey
|
||||
Power int64
|
||||
Name string
|
||||
}
|
||||
|
||||
type genesisValidatorJSON struct {
|
||||
Address Address `json:"address"`
|
||||
PubKey json.RawMessage `json:"pub_key"`
|
||||
Power int64 `json:"power,string"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
func (g GenesisValidator) MarshalJSON() ([]byte, error) {
|
||||
@@ -39,19 +45,30 @@ func (g GenesisValidator) MarshalJSON() ([]byte, error) {
|
||||
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})
|
||||
return json.Marshal(genesisValidatorJSON{
|
||||
Address: g.Address, PubKey: pk, Power: g.Power, Name: g.Name,
|
||||
})
|
||||
}
|
||||
|
||||
func (g *GenesisValidator) UnmarshalJSON(data []byte) error {
|
||||
var gv genesisValidatorJSON
|
||||
if err := json.Unmarshal(data, &gv); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := jsontypes.Unmarshal(gv.PubKey, &g.PubKey); err != nil {
|
||||
return err
|
||||
}
|
||||
g.Address = gv.Address
|
||||
g.Power = gv.Power
|
||||
g.Name = gv.Name
|
||||
return nil
|
||||
}
|
||||
|
||||
// GenesisDoc defines the initial conditions for a tendermint blockchain, in particular its validator set.
|
||||
type GenesisDoc struct {
|
||||
GenesisTime time.Time `json:"genesis_time"`
|
||||
ChainID string `json:"chain_id"`
|
||||
InitialHeight int64 `json:"initial_height"`
|
||||
InitialHeight int64 `json:"initial_height,string"`
|
||||
ConsensusParams *ConsensusParams `json:"consensus_params,omitempty"`
|
||||
Validators []GenesisValidator `json:"validators,omitempty"`
|
||||
AppHash tmbytes.HexBytes `json:"app_hash"`
|
||||
@@ -60,7 +77,7 @@ type GenesisDoc struct {
|
||||
|
||||
// SaveAs is a utility method for saving GenensisDoc as a JSON file.
|
||||
func (genDoc *GenesisDoc) SaveAs(file string) error {
|
||||
genDocBytes, err := tmjson.MarshalIndent(genDoc, "", " ")
|
||||
genDocBytes, err := json.MarshalIndent(genDoc, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -125,7 +142,7 @@ func (genDoc *GenesisDoc) ValidateAndComplete() error {
|
||||
// GenesisDocFromJSON unmarshalls JSON data into a GenesisDoc.
|
||||
func GenesisDocFromJSON(jsonBlob []byte) (*GenesisDoc, error) {
|
||||
genDoc := GenesisDoc{}
|
||||
err := tmjson.Unmarshal(jsonBlob, &genDoc)
|
||||
err := json.Unmarshal(jsonBlob, &genDoc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
@@ -8,7 +9,6 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
tmtime "github.com/tendermint/tendermint/libs/time"
|
||||
)
|
||||
|
||||
@@ -82,7 +82,7 @@ func TestGenesisGood(t *testing.T) {
|
||||
ChainID: "abc",
|
||||
Validators: []GenesisValidator{{pubkey.Address(), pubkey, 10, "myval"}},
|
||||
}
|
||||
genDocBytes, err = tmjson.Marshal(baseGenDoc)
|
||||
genDocBytes, err = json.Marshal(baseGenDoc)
|
||||
assert.NoError(t, err, "error marshaling genDoc")
|
||||
|
||||
// test base gendoc and check consensus params were filled
|
||||
@@ -94,14 +94,14 @@ func TestGenesisGood(t *testing.T) {
|
||||
assert.NotNil(t, genDoc.Validators[0].Address, "expected validator's address to be filled in")
|
||||
|
||||
// create json with consensus params filled
|
||||
genDocBytes, err = tmjson.Marshal(genDoc)
|
||||
genDocBytes, err = json.Marshal(genDoc)
|
||||
assert.NoError(t, err, "error marshaling genDoc")
|
||||
genDoc, err = GenesisDocFromJSON(genDocBytes)
|
||||
assert.NoError(t, err, "expected no error for valid genDoc json")
|
||||
|
||||
// test with invalid consensus params
|
||||
genDoc.ConsensusParams.Block.MaxBytes = 0
|
||||
genDocBytes, err = tmjson.Marshal(genDoc)
|
||||
genDocBytes, err = json.Marshal(genDoc)
|
||||
assert.NoError(t, err, "error marshaling genDoc")
|
||||
_, err = GenesisDocFromJSON(genDocBytes)
|
||||
assert.Error(t, err, "expected error for genDoc json with block size of 0")
|
||||
|
||||
+3
-3
@@ -24,9 +24,9 @@ func MaxNodeInfoSize() int {
|
||||
|
||||
// ProtocolVersion contains the protocol versions for the software.
|
||||
type ProtocolVersion struct {
|
||||
P2P uint64 `json:"p2p"`
|
||||
Block uint64 `json:"block"`
|
||||
App uint64 `json:"app"`
|
||||
P2P uint64 `json:"p2p,string"`
|
||||
Block uint64 `json:"block,string"`
|
||||
App uint64 `json:"app,string"`
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
|
||||
+25
-9
@@ -7,7 +7,6 @@ import (
|
||||
"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"
|
||||
)
|
||||
|
||||
@@ -19,9 +18,14 @@ import (
|
||||
// It contains the nodes private key for authentication.
|
||||
type NodeKey struct {
|
||||
// Canonical ID - hex-encoded pubkey's address (IDByteLength bytes)
|
||||
ID NodeID `json:"id"`
|
||||
ID NodeID
|
||||
// Private key
|
||||
PrivKey crypto.PrivKey `json:"priv_key"`
|
||||
PrivKey crypto.PrivKey
|
||||
}
|
||||
|
||||
type nodeKeyJSON struct {
|
||||
ID NodeID `json:"id"`
|
||||
PrivKey json.RawMessage `json:"priv_key"`
|
||||
}
|
||||
|
||||
func (nk NodeKey) MarshalJSON() ([]byte, error) {
|
||||
@@ -29,10 +33,22 @@ func (nk NodeKey) MarshalJSON() ([]byte, error) {
|
||||
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})
|
||||
return json.Marshal(nodeKeyJSON{
|
||||
ID: nk.ID, PrivKey: pk,
|
||||
})
|
||||
}
|
||||
|
||||
func (nk *NodeKey) UnmarshalJSON(data []byte) error {
|
||||
var nkjson nodeKeyJSON
|
||||
if err := json.Unmarshal(data, &nkjson); err != nil {
|
||||
return err
|
||||
}
|
||||
var pk crypto.PrivKey
|
||||
if err := jsontypes.Unmarshal(nkjson.PrivKey, &pk); err != nil {
|
||||
return err
|
||||
}
|
||||
*nk = NodeKey{ID: nkjson.ID, PrivKey: pk}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PubKey returns the peer's PubKey
|
||||
@@ -42,7 +58,7 @@ func (nk NodeKey) PubKey() crypto.PubKey {
|
||||
|
||||
// SaveAs persists the NodeKey to filePath.
|
||||
func (nk NodeKey) SaveAs(filePath string) error {
|
||||
jsonBytes, err := tmjson.Marshal(nk)
|
||||
jsonBytes, err := json.Marshal(nk)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -85,7 +101,7 @@ func LoadNodeKey(filePath string) (NodeKey, error) {
|
||||
return NodeKey{}, err
|
||||
}
|
||||
nodeKey := NodeKey{}
|
||||
err = tmjson.Unmarshal(jsonBytes, &nodeKey)
|
||||
err = json.Unmarshal(jsonBytes, &nodeKey)
|
||||
if err != nil {
|
||||
return NodeKey{}, err
|
||||
}
|
||||
|
||||
+6
-6
@@ -54,15 +54,15 @@ type HashedParams struct {
|
||||
// BlockParams define limits on the block size and gas plus minimum time
|
||||
// between blocks.
|
||||
type BlockParams struct {
|
||||
MaxBytes int64 `json:"max_bytes"`
|
||||
MaxGas int64 `json:"max_gas"`
|
||||
MaxBytes int64 `json:"max_bytes,string"`
|
||||
MaxGas int64 `json:"max_gas,string"`
|
||||
}
|
||||
|
||||
// EvidenceParams determine how we handle evidence of malfeasance.
|
||||
type EvidenceParams struct {
|
||||
MaxAgeNumBlocks int64 `json:"max_age_num_blocks"` // only accept new evidence more recent than this
|
||||
MaxAgeDuration time.Duration `json:"max_age_duration"`
|
||||
MaxBytes int64 `json:"max_bytes"`
|
||||
MaxAgeNumBlocks int64 `json:"max_age_num_blocks,string"` // only accept new evidence more recent than this
|
||||
MaxAgeDuration time.Duration `json:"max_age_duration,string"`
|
||||
MaxBytes int64 `json:"max_bytes,string"`
|
||||
}
|
||||
|
||||
// ValidatorParams restrict the public key types validators can use.
|
||||
@@ -72,7 +72,7 @@ type ValidatorParams struct {
|
||||
}
|
||||
|
||||
type VersionParams struct {
|
||||
AppVersion uint64 `json:"app_version"`
|
||||
AppVersion uint64 `json:"app_version,string"`
|
||||
}
|
||||
|
||||
// DefaultConsensusParams returns a default ConsensusParams.
|
||||
|
||||
+37
-13
@@ -17,23 +17,47 @@ 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,string"`
|
||||
ProposerPriority int64 `json:"proposer_priority,string"`
|
||||
Address Address
|
||||
PubKey crypto.PubKey
|
||||
VotingPower int64
|
||||
ProposerPriority int64
|
||||
}
|
||||
|
||||
type validatorJSON struct {
|
||||
Address Address `json:"address"`
|
||||
PubKey json.RawMessage `json:"pub_key,omitempty"`
|
||||
VotingPower int64 `json:"voting_power,string"`
|
||||
ProposerPriority int64 `json:"proposer_priority,string"`
|
||||
}
|
||||
|
||||
func (v Validator) MarshalJSON() ([]byte, error) {
|
||||
pk, err := jsontypes.Marshal(v.PubKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
val := validatorJSON{
|
||||
Address: v.Address,
|
||||
VotingPower: v.VotingPower,
|
||||
ProposerPriority: v.ProposerPriority,
|
||||
}
|
||||
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})
|
||||
if v.PubKey != nil {
|
||||
pk, err := jsontypes.Marshal(v.PubKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
val.PubKey = pk
|
||||
}
|
||||
return json.Marshal(val)
|
||||
}
|
||||
|
||||
func (v *Validator) UnmarshalJSON(data []byte) error {
|
||||
var val validatorJSON
|
||||
if err := json.Unmarshal(data, &val); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := jsontypes.Unmarshal(val.PubKey, &v.PubKey); err != nil {
|
||||
return err
|
||||
}
|
||||
v.Address = val.Address
|
||||
v.VotingPower = val.VotingPower
|
||||
v.ProposerPriority = val.ProposerPriority
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewValidator returns a new validator with the given pubkey and voting power.
|
||||
|
||||
Reference in New Issue
Block a user