You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

48 lines
1.2 KiB

  1. package merkle
  2. import (
  3. "sort"
  4. wire "github.com/tendermint/go-wire"
  5. "golang.org/x/crypto/ripemd160"
  6. )
  7. // NOTE: Behavior is undefined with dup keys.
  8. type KVPair struct {
  9. Key string
  10. Value interface{} // Can be Hashable or not.
  11. }
  12. func (kv KVPair) Hash() []byte {
  13. hasher, n, err := ripemd160.New(), new(int), new(error)
  14. wire.WriteString(kv.Key, hasher, n, err)
  15. if kvH, ok := kv.Value.(Hashable); ok {
  16. wire.WriteByteSlice(kvH.Hash(), hasher, n, err)
  17. } else {
  18. wire.WriteBinary(kv.Value, hasher, n, err)
  19. }
  20. if *err != nil {
  21. panic(*err)
  22. }
  23. return hasher.Sum(nil)
  24. }
  25. type KVPairs []KVPair
  26. func (kvps KVPairs) Len() int { return len(kvps) }
  27. func (kvps KVPairs) Less(i, j int) bool { return kvps[i].Key < kvps[j].Key }
  28. func (kvps KVPairs) Swap(i, j int) { kvps[i], kvps[j] = kvps[j], kvps[i] }
  29. func (kvps KVPairs) Sort() { sort.Sort(kvps) }
  30. func MakeSortedKVPairs(m map[string]interface{}) []Hashable {
  31. kvPairs := make([]KVPair, 0, len(m))
  32. for k, v := range m {
  33. kvPairs = append(kvPairs, KVPair{k, v})
  34. }
  35. KVPairs(kvPairs).Sort()
  36. kvPairsH := make([]Hashable, 0, len(kvPairs))
  37. for _, kvp := range kvPairs {
  38. kvPairsH = append(kvPairsH, kvp)
  39. }
  40. return kvPairsH
  41. }