diff --git a/types/block.go b/types/block.go index 6aa97c2d6..b9b541a96 100644 --- a/types/block.go +++ b/types/block.go @@ -12,6 +12,7 @@ import ( "github.com/tendermint/go-wire/data" cmn "github.com/tendermint/tmlibs/common" "github.com/tendermint/tmlibs/merkle" + "golang.org/x/crypto/ripemd160" ) // Block defines the atomic unit of a Tendermint blockchain. @@ -179,20 +180,20 @@ func (h *Header) Hash() data.Bytes { if len(h.ValidatorsHash) == 0 { return nil } - return merkle.SimpleHashFromMap(map[string]interface{}{ - "ChainID": h.ChainID, - "Height": h.Height, - "Time": h.Time, - "NumTxs": h.NumTxs, - "TotalTxs": h.TotalTxs, - "LastBlockID": h.LastBlockID, - "LastCommit": h.LastCommitHash, - "Data": h.DataHash, - "Validators": h.ValidatorsHash, - "App": h.AppHash, - "Consensus": h.ConsensusHash, - "Results": h.LastResultsHash, - "Evidence": h.EvidenceHash, + return merkle.SimpleHashFromMap(map[string]merkle.Hasher{ + "ChainID": wireHasher(h.ChainID), + "Height": wireHasher(h.Height), + "Time": wireHasher(h.Time), + "NumTxs": wireHasher(h.NumTxs), + "TotalTxs": wireHasher(h.TotalTxs), + "LastBlockID": wireHasher(h.LastBlockID), + "LastCommit": wireHasher(h.LastCommitHash), + "Data": wireHasher(h.DataHash), + "Validators": wireHasher(h.ValidatorsHash), + "App": wireHasher(h.AppHash), + "Consensus": wireHasher(h.ConsensusHash), + "Results": wireHasher(h.LastResultsHash), + "Evidence": wireHasher(h.EvidenceHash), }) } @@ -356,11 +357,11 @@ func (commit *Commit) ValidateBasic() error { // Hash returns the hash of the commit func (commit *Commit) Hash() data.Bytes { if commit.hash == nil { - bs := make([]interface{}, len(commit.Precommits)) + bs := make([]merkle.Hasher, len(commit.Precommits)) for i, precommit := range commit.Precommits { - bs[i] = precommit + bs[i] = wireHasher(precommit) } - commit.hash = merkle.SimpleHashFromBinaries(bs) + commit.hash = merkle.SimpleHashFromHashers(bs) } return commit.hash } @@ -510,3 +511,23 @@ func (blockID BlockID) WriteSignBytes(w io.Writer, n *int, err *error) { func (blockID BlockID) String() string { return fmt.Sprintf(`%v:%v`, blockID.Hash, blockID.PartsHeader) } + +//------------------------------------------------------- + +type hasher struct { + item interface{} +} + +func (h hasher) Hash() []byte { + hasher, n, err := ripemd160.New(), new(int), new(error) + wire.WriteBinary(h.item, hasher, n, err) + if *err != nil { + panic(err) + } + return hasher.Sum(nil) + +} + +func wireHasher(item interface{}) merkle.Hasher { + return hasher{item} +} diff --git a/types/event_bus.go b/types/event_bus.go index 6b6069b90..4edaea588 100644 --- a/types/event_bus.go +++ b/types/event_bus.go @@ -4,7 +4,6 @@ import ( "context" "fmt" - abci "github.com/tendermint/abci/types" cmn "github.com/tendermint/tmlibs/common" "github.com/tendermint/tmlibs/log" tmpubsub "github.com/tendermint/tmlibs/pubsub" @@ -98,17 +97,11 @@ func (b *EventBus) PublishEventTx(event EventDataTx) error { // validate and fill tags from tx result for _, tag := range event.Result.Tags { // basic validation - if tag.Key == "" { + if len(tag.Key) == 0 { b.Logger.Info("Got tag with an empty key (skipping)", "tag", tag, "tx", event.Tx) continue } - - switch tag.ValueType { - case abci.KVPair_STRING: - tags[tag.Key] = tag.ValueString - case abci.KVPair_INT: - tags[tag.Key] = tag.ValueInt - } + tags[string(tag.Key)] = tag.Value } // add predefined tags diff --git a/types/evidence.go b/types/evidence.go index 3ae3e40b1..9973c62e6 100644 --- a/types/evidence.go +++ b/types/evidence.go @@ -120,7 +120,7 @@ func (dve *DuplicateVoteEvidence) Index() int { // Hash returns the hash of the evidence. func (dve *DuplicateVoteEvidence) Hash() []byte { - return merkle.SimpleHashFromBinary(dve) + return wireHasher(dve).Hash() } // Verify returns an error if the two votes aren't conflicting. @@ -165,7 +165,9 @@ func (dve *DuplicateVoteEvidence) Equal(ev Evidence) bool { } // just check their hashes - return bytes.Equal(merkle.SimpleHashFromBinary(dve), merkle.SimpleHashFromBinary(ev)) + dveHash := wireHasher(dve).Hash() + evHash := wireHasher(ev).Hash() + return bytes.Equal(dveHash, evHash) } //----------------------------------------------------------------- diff --git a/types/params.go b/types/params.go index 90ab5f659..0e8ac577f 100644 --- a/types/params.go +++ b/types/params.go @@ -106,13 +106,13 @@ func (params *ConsensusParams) Validate() error { // Hash returns a merkle hash of the parameters to store // in the block header func (params *ConsensusParams) Hash() []byte { - return merkle.SimpleHashFromMap(map[string]interface{}{ - "block_gossip_part_size_bytes": params.BlockGossip.BlockPartSizeBytes, - "block_size_max_bytes": params.BlockSize.MaxBytes, - "block_size_max_gas": params.BlockSize.MaxGas, - "block_size_max_txs": params.BlockSize.MaxTxs, - "tx_size_max_bytes": params.TxSize.MaxBytes, - "tx_size_max_gas": params.TxSize.MaxGas, + return merkle.SimpleHashFromMap(map[string]merkle.Hasher{ + "block_gossip_part_size_bytes": wireHasher(params.BlockGossip.BlockPartSizeBytes), + "block_size_max_bytes": wireHasher(params.BlockSize.MaxBytes), + "block_size_max_gas": wireHasher(params.BlockSize.MaxGas), + "block_size_max_txs": wireHasher(params.BlockSize.MaxTxs), + "tx_size_max_bytes": wireHasher(params.TxSize.MaxBytes), + "tx_size_max_gas": wireHasher(params.TxSize.MaxGas), }) } diff --git a/types/part_set.go b/types/part_set.go index e8a0997c0..d922e34d6 100644 --- a/types/part_set.go +++ b/types/part_set.go @@ -96,7 +96,7 @@ func NewPartSetFromData(data []byte, partSize int) *PartSet { // divide data into 4kb parts. total := (len(data) + partSize - 1) / partSize parts := make([]*Part, total) - parts_ := make([]merkle.Hashable, total) + parts_ := make([]merkle.Hasher, total) partsBitArray := cmn.NewBitArray(total) for i := 0; i < total; i++ { part := &Part{ @@ -108,7 +108,7 @@ func NewPartSetFromData(data []byte, partSize int) *PartSet { partsBitArray.SetIndex(i, true) } // Compute merkle proofs - root, proofs := merkle.SimpleProofsFromHashables(parts_) + root, proofs := merkle.SimpleProofsFromHashers(parts_) for i := 0; i < total; i++ { parts[i].Proof = *proofs[i] } diff --git a/types/protobuf.go b/types/protobuf.go index 43c8f4505..bac5b799e 100644 --- a/types/protobuf.go +++ b/types/protobuf.go @@ -23,15 +23,15 @@ func (tm2pb) Header(header *Header) *types.Header { } } -func (tm2pb) BlockID(blockID BlockID) *types.BlockID { - return &types.BlockID{ +func (tm2pb) BlockID(blockID BlockID) types.BlockID { + return types.BlockID{ Hash: blockID.Hash, Parts: TM2PB.PartSetHeader(blockID.PartsHeader), } } -func (tm2pb) PartSetHeader(partSetHeader PartSetHeader) *types.PartSetHeader { - return &types.PartSetHeader{ +func (tm2pb) PartSetHeader(partSetHeader PartSetHeader) types.PartSetHeader { + return types.PartSetHeader{ Total: int32(partSetHeader.Total), // XXX: overflow Hash: partSetHeader.Hash, } diff --git a/types/results.go b/types/results.go index 29420fbc0..8e79e1ac7 100644 --- a/types/results.go +++ b/types/results.go @@ -47,20 +47,20 @@ func (a ABCIResults) Bytes() []byte { // Hash returns a merkle hash of all results func (a ABCIResults) Hash() []byte { - return merkle.SimpleHashFromHashables(a.toHashables()) + return merkle.SimpleHashFromHashers(a.toHashers()) } // ProveResult returns a merkle proof of one result from the set func (a ABCIResults) ProveResult(i int) merkle.SimpleProof { - _, proofs := merkle.SimpleProofsFromHashables(a.toHashables()) + _, proofs := merkle.SimpleProofsFromHashers(a.toHashers()) return *proofs[i] } -func (a ABCIResults) toHashables() []merkle.Hashable { +func (a ABCIResults) toHashers() []merkle.Hasher { l := len(a) - hashables := make([]merkle.Hashable, l) + hashers := make([]merkle.Hasher, l) for i := 0; i < l; i++ { - hashables[i] = a[i] + hashers[i] = a[i] } - return hashables + return hashers } diff --git a/types/signable.go b/types/signable.go index 2134f6300..bfdf9faa1 100644 --- a/types/signable.go +++ b/types/signable.go @@ -5,7 +5,6 @@ import ( "io" cmn "github.com/tendermint/tmlibs/common" - "github.com/tendermint/tmlibs/merkle" ) // Signable is an interface for all signable things. @@ -23,8 +22,3 @@ func SignBytes(chainID string, o Signable) []byte { } return buf.Bytes() } - -// HashSignBytes is a convenience method for getting the hash of the bytes of a signable -func HashSignBytes(chainID string, o Signable) []byte { - return merkle.SimpleHashFromBinary(SignBytes(chainID, o)) -} diff --git a/types/tx.go b/types/tx.go index 4cf5843ae..db42ed8e7 100644 --- a/types/tx.go +++ b/types/tx.go @@ -18,7 +18,7 @@ type Tx []byte // Hash computes the RIPEMD160 hash of the go-wire encoded transaction. func (tx Tx) Hash() []byte { - return merkle.SimpleHashFromBinary(tx) + return wireHasher(tx).Hash() } // String returns the hex-encoded transaction as a string. @@ -72,11 +72,11 @@ func (txs Txs) IndexByHash(hash []byte) int { // TODO: optimize this! func (txs Txs) Proof(i int) TxProof { l := len(txs) - hashables := make([]merkle.Hashable, l) + hashers := make([]merkle.Hasher, l) for i := 0; i < l; i++ { - hashables[i] = txs[i] + hashers[i] = txs[i] } - root, proofs := merkle.SimpleProofsFromHashables(hashables) + root, proofs := merkle.SimpleProofsFromHashers(hashers) return TxProof{ Index: i, diff --git a/types/validator_set.go b/types/validator_set.go index 7e895aba0..0d6c3249e 100644 --- a/types/validator_set.go +++ b/types/validator_set.go @@ -54,7 +54,7 @@ func (valSet *ValidatorSet) IncrementAccum(times int) { for _, val := range valSet.Validators { // check for overflow both multiplication and sum val.Accum = safeAddClip(val.Accum, safeMulClip(val.VotingPower, int64(times))) - validatorsHeap.Push(val, accumComparable{val}) + validatorsHeap.PushComparable(val, accumComparable{val}) } // Decrement the validator with most accum times times @@ -150,11 +150,11 @@ func (valSet *ValidatorSet) Hash() []byte { if len(valSet.Validators) == 0 { return nil } - hashables := make([]merkle.Hashable, len(valSet.Validators)) + hashers := make([]merkle.Hasher, len(valSet.Validators)) for i, val := range valSet.Validators { - hashables[i] = val + hashers[i] = val } - return merkle.SimpleHashFromHashables(hashables) + return merkle.SimpleHashFromHashers(hashers) } func (valSet *ValidatorSet) Add(val *Validator) (added bool) {