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.

138 lines
4.0 KiB

  1. package merkle
  2. import (
  3. "bytes"
  4. "github.com/pkg/errors"
  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 len(keys) == 0 {
  38. return errors.Errorf("key path has insufficient # of parts: expected no more keys but got %+v", string(key))
  39. }
  40. lastKey := keys[len(keys)-1]
  41. if !bytes.Equal(lastKey, key) {
  42. return errors.Errorf("key mismatch on operation #%d: expected %+v but got %+v", i, string(lastKey), string(key))
  43. }
  44. keys = keys[:len(keys)-1]
  45. }
  46. args, err = op.Run(args)
  47. if err != nil {
  48. return
  49. }
  50. }
  51. if !bytes.Equal(root, args[0]) {
  52. return errors.Errorf("calculated root hash is invalid: expected %+v but got %+v", root, args[0])
  53. }
  54. if len(keys) != 0 {
  55. return errors.New("keypath not consumed all")
  56. }
  57. return nil
  58. }
  59. //----------------------------------------
  60. // ProofRuntime - main entrypoint
  61. type OpDecoder func(ProofOp) (ProofOperator, error)
  62. type ProofRuntime struct {
  63. decoders map[string]OpDecoder
  64. }
  65. func NewProofRuntime() *ProofRuntime {
  66. return &ProofRuntime{
  67. decoders: make(map[string]OpDecoder),
  68. }
  69. }
  70. func (prt *ProofRuntime) RegisterOpDecoder(typ string, dec OpDecoder) {
  71. _, ok := prt.decoders[typ]
  72. if ok {
  73. panic("already registered for type " + typ)
  74. }
  75. prt.decoders[typ] = dec
  76. }
  77. func (prt *ProofRuntime) Decode(pop ProofOp) (ProofOperator, error) {
  78. decoder := prt.decoders[pop.Type]
  79. if decoder == nil {
  80. return nil, errors.Errorf("unrecognized proof type %v", pop.Type)
  81. }
  82. return decoder(pop)
  83. }
  84. func (prt *ProofRuntime) DecodeProof(proof *Proof) (ProofOperators, error) {
  85. poz := make(ProofOperators, 0, len(proof.Ops))
  86. for _, pop := range proof.Ops {
  87. operator, err := prt.Decode(pop)
  88. if err != nil {
  89. return nil, errors.Wrap(err, "decoding a proof operator")
  90. }
  91. poz = append(poz, operator)
  92. }
  93. return poz, nil
  94. }
  95. func (prt *ProofRuntime) VerifyValue(proof *Proof, root []byte, keypath string, value []byte) (err error) {
  96. return prt.Verify(proof, root, keypath, [][]byte{value})
  97. }
  98. // TODO In the long run we'll need a method of classifcation of ops,
  99. // whether existence or absence or perhaps a third?
  100. func (prt *ProofRuntime) VerifyAbsence(proof *Proof, root []byte, keypath string) (err error) {
  101. return prt.Verify(proof, root, keypath, nil)
  102. }
  103. func (prt *ProofRuntime) Verify(proof *Proof, root []byte, keypath string, args [][]byte) (err error) {
  104. poz, err := prt.DecodeProof(proof)
  105. if err != nil {
  106. return errors.Wrap(err, "decoding proof")
  107. }
  108. return poz.Verify(root, keypath, args)
  109. }
  110. // DefaultProofRuntime only knows about Simple value
  111. // proofs.
  112. // To use e.g. IAVL proofs, register op-decoders as
  113. // defined in the IAVL package.
  114. func DefaultProofRuntime() (prt *ProofRuntime) {
  115. prt = NewProofRuntime()
  116. prt.RegisterOpDecoder(ProofOpSimpleValue, SimpleValueOpDecoder)
  117. return
  118. }