|
|
@ -8,10 +8,13 @@ import ( |
|
|
|
"time" |
|
|
|
|
|
|
|
abci "github.com/tendermint/abci/types" |
|
|
|
"github.com/tendermint/go-wire/data" |
|
|
|
"golang.org/x/crypto/ripemd160" |
|
|
|
|
|
|
|
cmn "github.com/tendermint/tmlibs/common" |
|
|
|
dbm "github.com/tendermint/tmlibs/db" |
|
|
|
"github.com/tendermint/tmlibs/log" |
|
|
|
"github.com/tendermint/tmlibs/merkle" |
|
|
|
|
|
|
|
wire "github.com/tendermint/go-wire" |
|
|
|
|
|
|
@ -71,6 +74,10 @@ type State struct { |
|
|
|
LastConsensusParams types.ConsensusParams |
|
|
|
LastHeightConsensusParamsChanged int64 |
|
|
|
|
|
|
|
// Store LastABCIResults along with hash
|
|
|
|
LastResults ABCIResults |
|
|
|
LastResultHash []byte |
|
|
|
|
|
|
|
// The latest AppHash we've received from calling abci.Commit()
|
|
|
|
AppHash []byte |
|
|
|
|
|
|
@ -346,14 +353,16 @@ func (s *State) SetBlockAndValidators(header *types.Header, blockPartsHeader typ |
|
|
|
types.BlockID{header.Hash(), blockPartsHeader}, |
|
|
|
header.Time, |
|
|
|
nextValSet, |
|
|
|
nextParams) |
|
|
|
nextParams, |
|
|
|
NewResults(abciResponses.DeliverTx)) |
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
func (s *State) setBlockAndValidators(height int64, |
|
|
|
newTxs int64, blockID types.BlockID, blockTime time.Time, |
|
|
|
valSet *types.ValidatorSet, |
|
|
|
params types.ConsensusParams) { |
|
|
|
params types.ConsensusParams, |
|
|
|
results ABCIResults) { |
|
|
|
|
|
|
|
s.LastBlockHeight = height |
|
|
|
s.LastBlockTotalTx += newTxs |
|
|
@ -365,6 +374,9 @@ func (s *State) setBlockAndValidators(height int64, |
|
|
|
|
|
|
|
s.LastConsensusParams = s.ConsensusParams |
|
|
|
s.ConsensusParams = params |
|
|
|
|
|
|
|
s.LastResults = results |
|
|
|
s.LastResultHash = results.Hash() |
|
|
|
} |
|
|
|
|
|
|
|
// GetValidators returns the last and current validator sets.
|
|
|
@ -401,6 +413,59 @@ func (a *ABCIResponses) Bytes() []byte { |
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// ABCIResult is just the essential info to prove
|
|
|
|
// success/failure of a DeliverTx
|
|
|
|
type ABCIResult struct { |
|
|
|
Code uint32 `json:"code"` |
|
|
|
Data data.Bytes `json:"data"` |
|
|
|
} |
|
|
|
|
|
|
|
// Hash creates a canonical json hash of the ABCIResult
|
|
|
|
func (a ABCIResult) Hash() []byte { |
|
|
|
// stupid canonical json output, easy to check in any language
|
|
|
|
bs := fmt.Sprintf(`{"code":%d,"data":"%s"}`, a.Code, a.Data) |
|
|
|
var hasher = ripemd160.New() |
|
|
|
hasher.Write([]byte(bs)) |
|
|
|
return hasher.Sum(nil) |
|
|
|
} |
|
|
|
|
|
|
|
// ABCIResults wraps the deliver tx results to return a proof
|
|
|
|
type ABCIResults []ABCIResult |
|
|
|
|
|
|
|
// NewResults creates ABCIResults from ResponseDeliverTx
|
|
|
|
func NewResults(del []*abci.ResponseDeliverTx) ABCIResults { |
|
|
|
res := make(ABCIResults, len(del)) |
|
|
|
for i, d := range del { |
|
|
|
res[i] = ABCIResult{ |
|
|
|
Code: d.Code, |
|
|
|
Data: d.Data, |
|
|
|
} |
|
|
|
} |
|
|
|
return res |
|
|
|
} |
|
|
|
|
|
|
|
// Hash returns a merkle hash of all results
|
|
|
|
func (a ABCIResults) Hash() []byte { |
|
|
|
return merkle.SimpleHashFromHashables(a.toHashables()) |
|
|
|
} |
|
|
|
|
|
|
|
// ProveResult returns a merkle proof of one result from the set
|
|
|
|
func (a ABCIResults) ProveResult(i int) merkle.SimpleProof { |
|
|
|
_, proofs := merkle.SimpleProofsFromHashables(a.toHashables()) |
|
|
|
return *proofs[i] |
|
|
|
} |
|
|
|
|
|
|
|
func (a ABCIResults) toHashables() []merkle.Hashable { |
|
|
|
l := len(a) |
|
|
|
hashables := make([]merkle.Hashable, l) |
|
|
|
for i := 0; i < l; i++ { |
|
|
|
hashables[i] = a[i] |
|
|
|
} |
|
|
|
return hashables |
|
|
|
} |
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// ValidatorsInfo represents the latest validator set, or the last height it changed
|
|
|
|
type ValidatorsInfo struct { |
|
|
|
ValidatorSet *types.ValidatorSet |
|
|
|