From 28307fd4c96b50519059c27b48fcf264ebbd9b15 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Mon, 3 Apr 2017 15:45:09 +0200 Subject: [PATCH] Add proof generation for one tx --- types/tx.go | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/types/tx.go b/types/tx.go index a67206d4e..e7c454f09 100644 --- a/types/tx.go +++ b/types/tx.go @@ -1,6 +1,9 @@ package types import ( + "bytes" + "errors" + "github.com/tendermint/go-merkle" ) @@ -30,3 +33,55 @@ func (txs Txs) Hash() []byte { return merkle.SimpleHashFromTwoHashes(left, right) } } + +// Index returns the index of this transaction in the list, or -1 if not found +func (txs Txs) Index(tx Tx) int { + return -1 +} + +// Proof returns a simple merkle proof for this node. +// +// Panics if i < 0 or i >= len(txs) +// +// TODO: optimize this! +func (txs Txs) Proof(i int) TxProof { + l := len(txs) + hashables := make([]merkle.Hashable, l) + for i := 0; i < l; i++ { + hashables[i] = txs[i] + } + root, proofs := merkle.SimpleProofsFromHashables(hashables) + + return TxProof{ + Index: i, + Total: l, + RootHash: root, + Data: txs[i], + Proof: *proofs[i], + } +} + +type TxProof struct { + Index, Total int + RootHash []byte + Data Tx + Proof merkle.SimpleProof +} + +func (tp TxProof) LeafHash() []byte { + return tp.Data.Hash() +} + +// Validate returns nil if it matches the dataHash, and is internally consistent +// otherwise, returns a sensible error +func (tp TxProof) Validate(dataHash []byte) error { + if !bytes.Equal(dataHash, tp.RootHash) { + return errors.New("Proof matches different data hash") + } + + valid := tp.Proof.Verify(tp.Index, tp.Total, tp.LeafHash(), tp.RootHash) + if !valid { + return errors.New("Proof is not internally consistent") + } + return nil +}