@ -1,426 +0,0 @@ | |||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. | |||
[[projects]] | |||
branch = "master" | |||
name = "github.com/btcsuite/btcd" | |||
packages = ["btcec"] | |||
revision = "2be2f12b358dc57d70b8f501b00be450192efbc3" | |||
[[projects]] | |||
name = "github.com/davecgh/go-spew" | |||
packages = ["spew"] | |||
revision = "346938d642f2ec3594ed81d874461961cd0faa76" | |||
version = "v1.1.0" | |||
[[projects]] | |||
branch = "master" | |||
name = "github.com/ebuchman/fail-test" | |||
packages = ["."] | |||
revision = "95f809107225be108efcf10a3509e4ea6ceef3c4" | |||
[[projects]] | |||
name = "github.com/fortytw2/leaktest" | |||
packages = ["."] | |||
revision = "a5ef70473c97b71626b9abeda80ee92ba2a7de9e" | |||
version = "v1.2.0" | |||
[[projects]] | |||
name = "github.com/fsnotify/fsnotify" | |||
packages = ["."] | |||
revision = "c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9" | |||
version = "v1.4.7" | |||
[[projects]] | |||
name = "github.com/go-kit/kit" | |||
packages = [ | |||
"log", | |||
"log/level", | |||
"log/term" | |||
] | |||
revision = "4dc7be5d2d12881735283bcab7352178e190fc71" | |||
version = "v0.6.0" | |||
[[projects]] | |||
name = "github.com/go-logfmt/logfmt" | |||
packages = ["."] | |||
revision = "390ab7935ee28ec6b286364bba9b4dd6410cb3d5" | |||
version = "v0.3.0" | |||
[[projects]] | |||
name = "github.com/go-stack/stack" | |||
packages = ["."] | |||
revision = "259ab82a6cad3992b4e21ff5cac294ccb06474bc" | |||
version = "v1.7.0" | |||
[[projects]] | |||
name = "github.com/gogo/protobuf" | |||
packages = [ | |||
"gogoproto", | |||
"jsonpb", | |||
"proto", | |||
"protoc-gen-gogo/descriptor", | |||
"sortkeys", | |||
"types" | |||
] | |||
revision = "1adfc126b41513cc696b209667c8656ea7aac67c" | |||
version = "v1.0.0" | |||
[[projects]] | |||
name = "github.com/golang/protobuf" | |||
packages = [ | |||
"proto", | |||
"ptypes", | |||
"ptypes/any", | |||
"ptypes/duration", | |||
"ptypes/timestamp" | |||
] | |||
revision = "925541529c1fa6821df4e44ce2723319eb2be768" | |||
version = "v1.0.0" | |||
[[projects]] | |||
branch = "master" | |||
name = "github.com/golang/snappy" | |||
packages = ["."] | |||
revision = "553a641470496b2327abcac10b36396bd98e45c9" | |||
[[projects]] | |||
name = "github.com/gorilla/websocket" | |||
packages = ["."] | |||
revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b" | |||
version = "v1.2.0" | |||
[[projects]] | |||
branch = "master" | |||
name = "github.com/hashicorp/hcl" | |||
packages = [ | |||
".", | |||
"hcl/ast", | |||
"hcl/parser", | |||
"hcl/printer", | |||
"hcl/scanner", | |||
"hcl/strconv", | |||
"hcl/token", | |||
"json/parser", | |||
"json/scanner", | |||
"json/token" | |||
] | |||
<<<<<<< HEAD | |||
revision = "f40e974e75af4e271d97ce0fc917af5898ae7bda" | |||
======= | |||
revision = "ef8a98b0bbce4a65b5aa4c368430a80ddc533168" | |||
>>>>>>> develop | |||
[[projects]] | |||
name = "github.com/inconshreveable/mousetrap" | |||
packages = ["."] | |||
revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75" | |||
version = "v1.0" | |||
[[projects]] | |||
branch = "master" | |||
name = "github.com/jmhodges/levigo" | |||
packages = ["."] | |||
revision = "c42d9e0ca023e2198120196f842701bb4c55d7b9" | |||
[[projects]] | |||
branch = "master" | |||
name = "github.com/kr/logfmt" | |||
packages = ["."] | |||
revision = "b84e30acd515aadc4b783ad4ff83aff3299bdfe0" | |||
[[projects]] | |||
name = "github.com/magiconair/properties" | |||
packages = ["."] | |||
revision = "c3beff4c2358b44d0493c7dda585e7db7ff28ae6" | |||
version = "v1.7.6" | |||
[[projects]] | |||
branch = "master" | |||
name = "github.com/mitchellh/mapstructure" | |||
packages = ["."] | |||
revision = "00c29f56e2386353d58c599509e8dc3801b0d716" | |||
[[projects]] | |||
name = "github.com/pelletier/go-toml" | |||
packages = ["."] | |||
revision = "acdc4509485b587f5e675510c4f2c63e90ff68a8" | |||
version = "v1.1.0" | |||
[[projects]] | |||
name = "github.com/pkg/errors" | |||
packages = ["."] | |||
revision = "645ef00459ed84a119197bfb8d8205042c6df63d" | |||
version = "v0.8.0" | |||
[[projects]] | |||
name = "github.com/pmezard/go-difflib" | |||
packages = ["difflib"] | |||
revision = "792786c7400a136282c1664665ae0a8db921c6c2" | |||
version = "v1.0.0" | |||
[[projects]] | |||
branch = "master" | |||
name = "github.com/rcrowley/go-metrics" | |||
packages = ["."] | |||
revision = "8732c616f52954686704c8645fe1a9d59e9df7c1" | |||
[[projects]] | |||
name = "github.com/spf13/afero" | |||
packages = [ | |||
".", | |||
"mem" | |||
] | |||
revision = "63644898a8da0bc22138abf860edaf5277b6102e" | |||
version = "v1.1.0" | |||
[[projects]] | |||
name = "github.com/spf13/cast" | |||
packages = ["."] | |||
revision = "8965335b8c7107321228e3e3702cab9832751bac" | |||
version = "v1.2.0" | |||
[[projects]] | |||
name = "github.com/spf13/cobra" | |||
packages = ["."] | |||
revision = "a1f051bc3eba734da4772d60e2d677f47cf93ef4" | |||
version = "v0.0.2" | |||
[[projects]] | |||
branch = "master" | |||
name = "github.com/spf13/jwalterweatherman" | |||
packages = ["."] | |||
revision = "7c0cea34c8ece3fbeb2b27ab9b59511d360fb394" | |||
[[projects]] | |||
name = "github.com/spf13/pflag" | |||
packages = ["."] | |||
revision = "e57e3eeb33f795204c1ca35f56c44f83227c6e66" | |||
version = "v1.0.0" | |||
[[projects]] | |||
name = "github.com/spf13/viper" | |||
packages = ["."] | |||
revision = "b5e8006cbee93ec955a89ab31e0e3ce3204f3736" | |||
version = "v1.0.2" | |||
[[projects]] | |||
name = "github.com/stretchr/testify" | |||
packages = [ | |||
"assert", | |||
"require" | |||
] | |||
revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71" | |||
version = "v1.2.1" | |||
[[projects]] | |||
branch = "master" | |||
name = "github.com/syndtr/goleveldb" | |||
packages = [ | |||
"leveldb", | |||
"leveldb/cache", | |||
"leveldb/comparer", | |||
"leveldb/errors", | |||
"leveldb/filter", | |||
"leveldb/iterator", | |||
"leveldb/journal", | |||
"leveldb/memdb", | |||
"leveldb/opt", | |||
"leveldb/storage", | |||
"leveldb/table", | |||
"leveldb/util" | |||
] | |||
<<<<<<< HEAD | |||
revision = "169b1b37be738edb2813dab48c97a549bcf99bb5" | |||
======= | |||
revision = "714f901b98fdb3aa954b4193d8cbd64a28d80cad" | |||
>>>>>>> develop | |||
[[projects]] | |||
name = "github.com/tendermint/abci" | |||
packages = [ | |||
"client", | |||
"example/code", | |||
"example/counter", | |||
"example/kvstore", | |||
"server", | |||
"types" | |||
] | |||
<<<<<<< HEAD | |||
revision = "c62aed95f2ce399ec815b0cafe478af002cdc4e6" | |||
version = "v0.10.3-dev" | |||
======= | |||
revision = "46686763ba8ea595ede16530ed4a40fb38f49f94" | |||
version = "v0.10.2" | |||
>>>>>>> develop | |||
[[projects]] | |||
branch = "master" | |||
name = "github.com/tendermint/ed25519" | |||
packages = [ | |||
".", | |||
"edwards25519", | |||
"extra25519" | |||
] | |||
revision = "d8387025d2b9d158cf4efb07e7ebf814bcce2057" | |||
[[projects]] | |||
name = "github.com/tendermint/go-amino" | |||
packages = ["."] | |||
revision = "42246108ff925a457fb709475070a03dfd3e2b5c" | |||
version = "0.9.6" | |||
[[projects]] | |||
name = "github.com/tendermint/go-crypto" | |||
packages = ["."] | |||
revision = "5d5f580f49ca66c13400938c64334186068c8b7c" | |||
version = "v0.6.1" | |||
[[projects]] | |||
name = "github.com/tendermint/go-wire" | |||
packages = ["."] | |||
revision = "fa721242b042ecd4c6ed1a934ee740db4f74e45c" | |||
version = "v0.7.3" | |||
[[projects]] | |||
name = "github.com/tendermint/tmlibs" | |||
packages = [ | |||
"autofile", | |||
"cli", | |||
"cli/flags", | |||
"clist", | |||
"common", | |||
"db", | |||
"flowrate", | |||
"log", | |||
"merkle", | |||
"pubsub", | |||
"pubsub/query", | |||
"test" | |||
] | |||
revision = "2e24b64fc121dcdf1cabceab8dc2f7257675483c" | |||
version = "0.8.1" | |||
[[projects]] | |||
branch = "master" | |||
name = "golang.org/x/crypto" | |||
packages = [ | |||
"curve25519", | |||
"nacl/box", | |||
"nacl/secretbox", | |||
"openpgp/armor", | |||
"openpgp/errors", | |||
"poly1305", | |||
"ripemd160", | |||
"salsa20/salsa" | |||
] | |||
<<<<<<< HEAD | |||
revision = "88942b9c40a4c9d203b82b3731787b672d6e809b" | |||
======= | |||
revision = "b2aa35443fbc700ab74c586ae79b81c171851023" | |||
>>>>>>> develop | |||
[[projects]] | |||
branch = "master" | |||
name = "golang.org/x/net" | |||
packages = [ | |||
"context", | |||
"http2", | |||
"http2/hpack", | |||
"idna", | |||
"internal/timeseries", | |||
"lex/httplex", | |||
"trace" | |||
] | |||
<<<<<<< HEAD | |||
revision = "6078986fec03a1dcc236c34816c71b0e05018fda" | |||
======= | |||
revision = "b3c676e531a6dc479fa1b35ac961c13f5e2b4d2e" | |||
>>>>>>> develop | |||
[[projects]] | |||
branch = "master" | |||
name = "golang.org/x/sys" | |||
packages = ["unix"] | |||
<<<<<<< HEAD | |||
revision = "91ee8cde435411ca3f1cd365e8f20131aed4d0a1" | |||
======= | |||
revision = "1d206c9fa8975fb4cf00df1dc8bf3283dc24ba0e" | |||
>>>>>>> develop | |||
[[projects]] | |||
name = "golang.org/x/text" | |||
packages = [ | |||
"collate", | |||
"collate/build", | |||
"internal/colltab", | |||
"internal/gen", | |||
"internal/tag", | |||
"internal/triegen", | |||
"internal/ucd", | |||
"language", | |||
"secure/bidirule", | |||
"transform", | |||
"unicode/bidi", | |||
"unicode/cldr", | |||
"unicode/norm", | |||
"unicode/rangetable" | |||
] | |||
revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0" | |||
version = "v0.3.0" | |||
[[projects]] | |||
branch = "master" | |||
name = "google.golang.org/genproto" | |||
packages = ["googleapis/rpc/status"] | |||
<<<<<<< HEAD | |||
revision = "ab0870e398d5dd054b868c0db1481ab029b9a9f2" | |||
======= | |||
revision = "35de2414665fc36f56b72d982c5af480d86de5ab" | |||
>>>>>>> develop | |||
[[projects]] | |||
name = "google.golang.org/grpc" | |||
packages = [ | |||
".", | |||
"balancer", | |||
"codes", | |||
"connectivity", | |||
"credentials", | |||
"grpclb/grpc_lb_v1/messages", | |||
"grpclog", | |||
"internal", | |||
"keepalive", | |||
"metadata", | |||
"naming", | |||
"peer", | |||
"resolver", | |||
"stats", | |||
"status", | |||
"tap", | |||
"transport" | |||
] | |||
revision = "5b3c4e850e90a4cf6a20ebd46c8b32a0a3afcb9e" | |||
version = "v1.7.5" | |||
[[projects]] | |||
name = "gopkg.in/yaml.v2" | |||
packages = ["."] | |||
<<<<<<< HEAD | |||
revision = "7f97868eec74b32b0982dd158a51a446d1da7eb5" | |||
version = "v2.1.1" | |||
======= | |||
revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183" | |||
version = "v2.2.1" | |||
>>>>>>> develop | |||
[solve-meta] | |||
analyzer-name = "dep" | |||
analyzer-version = 1 | |||
<<<<<<< HEAD | |||
inputs-digest = "ed1149ed5293b7b28b7505627648c6a1152aaff0ed06a3849995b29751ae00f3" | |||
======= | |||
inputs-digest = "b7c02a311569ec5fe2197614444fb231ea60f3e65a11a20e318421f1752054d7" | |||
>>>>>>> develop | |||
solver-name = "gps-cdcl" | |||
solver-version = 1 |
@ -1,238 +0,0 @@ | |||
package types | |||
import ( | |||
"bytes" | |||
"encoding/json" | |||
"errors" | |||
"fmt" | |||
"time" | |||
crypto "github.com/tendermint/go-crypto" | |||
"github.com/tendermint/tendermint/types" | |||
cmn "github.com/tendermint/tmlibs/common" | |||
) | |||
// TODO: type ? | |||
const ( | |||
stepNone int8 = 0 // Used to distinguish the initial state | |||
stepPropose int8 = 1 | |||
stepPrevote int8 = 2 | |||
stepPrecommit int8 = 3 | |||
) | |||
func voteToStep(vote *types.Vote) int8 { | |||
switch vote.Type { | |||
case types.VoteTypePrevote: | |||
return stepPrevote | |||
case types.VoteTypePrecommit: | |||
return stepPrecommit | |||
default: | |||
panic("Unknown vote type") | |||
} | |||
} | |||
//------------------------------------- | |||
// LastSignedInfo contains information about the latest | |||
// data signed by a validator to help prevent double signing. | |||
type LastSignedInfo struct { | |||
Height int64 `json:"height"` | |||
Round int `json:"round"` | |||
Step int8 `json:"step"` | |||
Signature crypto.Signature `json:"signature,omitempty"` // so we dont lose signatures | |||
SignBytes cmn.HexBytes `json:"signbytes,omitempty"` // so we dont lose signatures | |||
} | |||
func NewLastSignedInfo() *LastSignedInfo { | |||
return &LastSignedInfo{ | |||
Step: stepNone, | |||
} | |||
} | |||
func (lsi *LastSignedInfo) String() string { | |||
return fmt.Sprintf("LH:%v, LR:%v, LS:%v", lsi.Height, lsi.Round, lsi.Step) | |||
} | |||
// Verify returns an error if there is a height/round/step regression | |||
// or if the HRS matches but there are no LastSignBytes. | |||
// It returns true if HRS matches exactly and the LastSignature exists. | |||
// It panics if the HRS matches, the LastSignBytes are not empty, but the LastSignature is empty. | |||
func (lsi LastSignedInfo) Verify(height int64, round int, step int8) (bool, error) { | |||
if lsi.Height > height { | |||
return false, errors.New("Height regression") | |||
} | |||
if lsi.Height == height { | |||
if lsi.Round > round { | |||
return false, errors.New("Round regression") | |||
} | |||
if lsi.Round == round { | |||
if lsi.Step > step { | |||
return false, errors.New("Step regression") | |||
} else if lsi.Step == step { | |||
if lsi.SignBytes != nil { | |||
if lsi.Signature.Empty() { | |||
panic("info: LastSignature is nil but LastSignBytes is not!") | |||
} | |||
return true, nil | |||
} | |||
return false, errors.New("No LastSignature found") | |||
} | |||
} | |||
} | |||
return false, nil | |||
} | |||
// Set height/round/step and signature on the info | |||
func (lsi *LastSignedInfo) Set(height int64, round int, step int8, | |||
signBytes []byte, sig crypto.Signature) { | |||
lsi.Height = height | |||
lsi.Round = round | |||
lsi.Step = step | |||
lsi.Signature = sig | |||
lsi.SignBytes = signBytes | |||
} | |||
// Reset resets all the values. | |||
// XXX: Unsafe. | |||
func (lsi *LastSignedInfo) Reset() { | |||
lsi.Height = 0 | |||
lsi.Round = 0 | |||
lsi.Step = 0 | |||
lsi.Signature = crypto.Signature{} | |||
lsi.SignBytes = nil | |||
} | |||
// SignVote checks the height/round/step (HRS) are greater than the latest state of the LastSignedInfo. | |||
// If so, it signs the vote, updates the LastSignedInfo, and sets the signature on the vote. | |||
// If the HRS are equal and the only thing changed is the timestamp, it sets the vote.Timestamp to the previous | |||
// value and the Signature to the LastSignedInfo.Signature. | |||
// Else it returns an error. | |||
func (lsi *LastSignedInfo) SignVote(signer types.Signer, chainID string, vote *types.Vote) error { | |||
height, round, step := vote.Height, vote.Round, voteToStep(vote) | |||
signBytes := vote.SignBytes(chainID) | |||
sameHRS, err := lsi.Verify(height, round, step) | |||
if err != nil { | |||
return err | |||
} | |||
// We might crash before writing to the wal, | |||
// causing us to try to re-sign for the same HRS. | |||
// If signbytes are the same, use the last signature. | |||
// If they only differ by timestamp, use last timestamp and signature | |||
// Otherwise, return error | |||
if sameHRS { | |||
if bytes.Equal(signBytes, lsi.SignBytes) { | |||
vote.Signature = lsi.Signature | |||
} else if timestamp, ok := checkVotesOnlyDifferByTimestamp(lsi.SignBytes, signBytes); ok { | |||
vote.Timestamp = timestamp | |||
vote.Signature = lsi.Signature | |||
} else { | |||
err = fmt.Errorf("Conflicting data") | |||
} | |||
return err | |||
} | |||
sig, err := signer.Sign(signBytes) | |||
if err != nil { | |||
return err | |||
} | |||
lsi.Set(height, round, step, signBytes, sig) | |||
vote.Signature = sig | |||
return nil | |||
} | |||
// SignProposal checks if the height/round/step (HRS) are greater than the latest state of the LastSignedInfo. | |||
// If so, it signs the proposal, updates the LastSignedInfo, and sets the signature on the proposal. | |||
// If the HRS are equal and the only thing changed is the timestamp, it sets the timestamp to the previous | |||
// value and the Signature to the LastSignedInfo.Signature. | |||
// Else it returns an error. | |||
func (lsi *LastSignedInfo) SignProposal(signer types.Signer, chainID string, proposal *types.Proposal) error { | |||
height, round, step := proposal.Height, proposal.Round, stepPropose | |||
signBytes := proposal.SignBytes(chainID) | |||
sameHRS, err := lsi.Verify(height, round, step) | |||
if err != nil { | |||
return err | |||
} | |||
// We might crash before writing to the wal, | |||
// causing us to try to re-sign for the same HRS. | |||
// If signbytes are the same, use the last signature. | |||
// If they only differ by timestamp, use last timestamp and signature | |||
// Otherwise, return error | |||
if sameHRS { | |||
if bytes.Equal(signBytes, lsi.SignBytes) { | |||
proposal.Signature = lsi.Signature | |||
} else if timestamp, ok := checkProposalsOnlyDifferByTimestamp(lsi.SignBytes, signBytes); ok { | |||
proposal.Timestamp = timestamp | |||
proposal.Signature = lsi.Signature | |||
} else { | |||
err = fmt.Errorf("Conflicting data") | |||
} | |||
return err | |||
} | |||
sig, err := signer.Sign(signBytes) | |||
if err != nil { | |||
return err | |||
} | |||
lsi.Set(height, round, step, signBytes, sig) | |||
proposal.Signature = sig | |||
return nil | |||
} | |||
//------------------------------------- | |||
// returns the timestamp from the lastSignBytes. | |||
// returns true if the only difference in the votes is their timestamp. | |||
func checkVotesOnlyDifferByTimestamp(lastSignBytes, newSignBytes []byte) (time.Time, bool) { | |||
var lastVote, newVote types.CanonicalJSONOnceVote | |||
if err := json.Unmarshal(lastSignBytes, &lastVote); err != nil { | |||
panic(fmt.Sprintf("LastSignBytes cannot be unmarshalled into vote: %v", err)) | |||
} | |||
if err := json.Unmarshal(newSignBytes, &newVote); err != nil { | |||
panic(fmt.Sprintf("signBytes cannot be unmarshalled into vote: %v", err)) | |||
} | |||
lastTime, err := time.Parse(types.TimeFormat, lastVote.Vote.Timestamp) | |||
if err != nil { | |||
panic(err) | |||
} | |||
// set the times to the same value and check equality | |||
now := types.CanonicalTime(time.Now()) | |||
lastVote.Vote.Timestamp = now | |||
newVote.Vote.Timestamp = now | |||
lastVoteBytes, _ := json.Marshal(lastVote) | |||
newVoteBytes, _ := json.Marshal(newVote) | |||
return lastTime, bytes.Equal(newVoteBytes, lastVoteBytes) | |||
} | |||
// returns the timestamp from the lastSignBytes. | |||
// returns true if the only difference in the proposals is their timestamp | |||
func checkProposalsOnlyDifferByTimestamp(lastSignBytes, newSignBytes []byte) (time.Time, bool) { | |||
var lastProposal, newProposal types.CanonicalJSONOnceProposal | |||
if err := json.Unmarshal(lastSignBytes, &lastProposal); err != nil { | |||
panic(fmt.Sprintf("LastSignBytes cannot be unmarshalled into proposal: %v", err)) | |||
} | |||
if err := json.Unmarshal(newSignBytes, &newProposal); err != nil { | |||
panic(fmt.Sprintf("signBytes cannot be unmarshalled into proposal: %v", err)) | |||
} | |||
lastTime, err := time.Parse(types.TimeFormat, lastProposal.Proposal.Timestamp) | |||
if err != nil { | |||
panic(err) | |||
} | |||
// set the times to the same value and check equality | |||
now := types.CanonicalTime(time.Now()) | |||
lastProposal.Proposal.Timestamp = now | |||
newProposal.Proposal.Timestamp = now | |||
lastProposalBytes, _ := json.Marshal(lastProposal) | |||
newProposalBytes, _ := json.Marshal(newProposal) | |||
return lastTime, bytes.Equal(newProposalBytes, lastProposalBytes) | |||
} |