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.

134 lines
3.8 KiB

  1. package merkle
  2. import (
  3. "bytes"
  4. cmn "github.com/tendermint/tendermint/libs/common"
  5. )
  6. //----------------------------------------
  7. // ProofOp gets converted to an instance of ProofOperator:
  8. // ProofOperator is a layer for calculating intermediate Merkle roots
  9. // when a series of Merkle trees are chained together.
  10. // Run() takes leaf values from a tree and returns the Merkle
  11. // root for the corresponding tree. It takes and returns a list of bytes
  12. // to allow multiple leaves to be part of a single proof, for instance in a range proof.
  13. // ProofOp() encodes the ProofOperator in a generic way so it can later be
  14. // decoded with OpDecoder.
  15. type ProofOperator interface {
  16. Run([][]byte) ([][]byte, error)
  17. GetKey() []byte
  18. ProofOp() ProofOp
  19. }
  20. //----------------------------------------
  21. // Operations on a list of ProofOperators
  22. // ProofOperators is a slice of ProofOperator(s).
  23. // Each operator will be applied to the input value sequentially
  24. // and the last Merkle root will be verified with already known data
  25. type ProofOperators []ProofOperator
  26. func (poz ProofOperators) VerifyValue(root []byte, keypath string, value []byte) (err error) {
  27. return poz.Verify(root, keypath, [][]byte{value})
  28. }
  29. func (poz ProofOperators) Verify(root []byte, keypath string, args [][]byte) (err error) {
  30. keys, err := KeyPathToKeys(keypath)
  31. if err != nil {
  32. return
  33. }
  34. for i, op := range poz {
  35. key := op.GetKey()
  36. if len(key) != 0 {
  37. if !bytes.Equal(keys[0], key) {
  38. return cmn.NewError("Key mismatch on operation #%d: expected %+v but %+v", i, []byte(keys[0]), []byte(key))
  39. }
  40. keys = keys[1:]
  41. }
  42. args, err = op.Run(args)
  43. if err != nil {
  44. return
  45. }
  46. }
  47. if !bytes.Equal(root, args[0]) {
  48. return cmn.NewError("Calculated root hash is invalid: expected %+v but %+v", root, args[0])
  49. }
  50. if len(keys) != 0 {
  51. return cmn.NewError("Keypath not consumed all")
  52. }
  53. return nil
  54. }
  55. //----------------------------------------
  56. // ProofRuntime - main entrypoint
  57. type OpDecoder func(ProofOp) (ProofOperator, error)
  58. type ProofRuntime struct {
  59. decoders map[string]OpDecoder
  60. }
  61. func NewProofRuntime() *ProofRuntime {
  62. return &ProofRuntime{
  63. decoders: make(map[string]OpDecoder),
  64. }
  65. }
  66. func (prt *ProofRuntime) RegisterOpDecoder(typ string, dec OpDecoder) {
  67. _, ok := prt.decoders[typ]
  68. if ok {
  69. panic("already registered for type " + typ)
  70. }
  71. prt.decoders[typ] = dec
  72. }
  73. func (prt *ProofRuntime) Decode(pop ProofOp) (ProofOperator, error) {
  74. decoder := prt.decoders[pop.Type]
  75. if decoder == nil {
  76. return nil, cmn.NewError("unrecognized proof type %v", pop.Type)
  77. }
  78. return decoder(pop)
  79. }
  80. func (prt *ProofRuntime) DecodeProof(proof *Proof) (ProofOperators, error) {
  81. var poz ProofOperators
  82. for _, pop := range proof.Ops {
  83. operator, err := prt.Decode(pop)
  84. if err != nil {
  85. return nil, cmn.ErrorWrap(err, "decoding a proof operator")
  86. }
  87. poz = append(poz, operator)
  88. }
  89. return poz, nil
  90. }
  91. func (prt *ProofRuntime) VerifyValue(proof *Proof, root []byte, keypath string, value []byte) (err error) {
  92. return prt.Verify(proof, root, keypath, [][]byte{value})
  93. }
  94. // TODO In the long run we'll need a method of classifcation of ops,
  95. // whether existence or absence or perhaps a third?
  96. func (prt *ProofRuntime) VerifyAbsence(proof *Proof, root []byte, keypath string) (err error) {
  97. return prt.Verify(proof, root, keypath, nil)
  98. }
  99. func (prt *ProofRuntime) Verify(proof *Proof, root []byte, keypath string, args [][]byte) (err error) {
  100. poz, err := prt.DecodeProof(proof)
  101. if err != nil {
  102. return cmn.ErrorWrap(err, "decoding proof")
  103. }
  104. return poz.Verify(root, keypath, args)
  105. }
  106. // DefaultProofRuntime only knows about Simple value
  107. // proofs.
  108. // To use e.g. IAVL proofs, register op-decoders as
  109. // defined in the IAVL package.
  110. func DefaultProofRuntime() (prt *ProofRuntime) {
  111. prt = NewProofRuntime()
  112. prt.RegisterOpDecoder(ProofOpSimpleValue, SimpleValueOpDecoder)
  113. return
  114. }