83 lines
2.1 KiB
Go
83 lines
2.1 KiB
Go
package types
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"encoding/json"
|
|
"time"
|
|
|
|
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
|
|
tmtypes "github.com/tendermint/tendermint/types"
|
|
)
|
|
|
|
// SortedJSON takes any JSON and returns it sorted by keys. Also, all white-spaces
|
|
// are removed.
|
|
// This method can be used to canonicalize JSON to be returned by GetSignBytes,
|
|
// e.g. for the ledger integration.
|
|
// If the passed JSON isn't valid it will return an error.
|
|
func SortJSON(toSortJSON []byte) ([]byte, error) {
|
|
var c interface{}
|
|
err := json.Unmarshal(toSortJSON, &c)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
js, err := json.Marshal(c)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return js, nil
|
|
}
|
|
|
|
// MustSortJSON is like SortJSON but panic if an error occurs, e.g., if
|
|
// the passed JSON isn't valid.
|
|
func MustSortJSON(toSortJSON []byte) []byte {
|
|
js, err := SortJSON(toSortJSON)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return js
|
|
}
|
|
|
|
// Uint64ToBigEndian - marshals uint64 to a bigendian byte slice so it can be sorted
|
|
func Uint64ToBigEndian(i uint64) []byte {
|
|
b := make([]byte, 8)
|
|
binary.BigEndian.PutUint64(b, i)
|
|
return b
|
|
}
|
|
|
|
// Slight modification of the RFC3339Nano but it right pads all zeros and drops the time zone info
|
|
const SortableTimeFormat = "2006-01-02T15:04:05.000000000"
|
|
|
|
// Formats a time.Time into a []byte that can be sorted
|
|
func FormatTimeBytes(t time.Time) []byte {
|
|
return []byte(t.UTC().Round(0).Format(SortableTimeFormat))
|
|
}
|
|
|
|
// Parses a []byte encoded using FormatTimeKey back into a time.Time
|
|
func ParseTimeBytes(bz []byte) (time.Time, error) {
|
|
str := string(bz)
|
|
t, err := time.Parse(SortableTimeFormat, str)
|
|
if err != nil {
|
|
return t, err
|
|
}
|
|
return t.UTC().Round(0), nil
|
|
}
|
|
|
|
// DefaultChainID returns the chain ID from the genesis file if present. An
|
|
// error is returned if the file cannot be read or parsed.
|
|
//
|
|
// TODO: This should be removed and the chainID should always be provided by
|
|
// the end user.
|
|
func DefaultChainID() (string, error) {
|
|
cfg, err := tcmd.ParseConfig()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
doc, err := tmtypes.GenesisDocFromFile(cfg.GenesisFile())
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return doc.ChainID, nil
|
|
}
|