|
|
@ -8,13 +8,10 @@ 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" |
|
|
|
|
|
|
@ -79,9 +76,9 @@ type State struct { |
|
|
|
LastHeightConsensusParamsChanged int64 |
|
|
|
|
|
|
|
// Store LastABCIResults along with hash
|
|
|
|
LastResults ABCIResults // TODO: remove??
|
|
|
|
LastResultHash []byte // this is the one for the next block to propose
|
|
|
|
LastLastResultHash []byte // this verifies the last block?
|
|
|
|
LastResults types.ABCIResults // TODO: remove??
|
|
|
|
LastResultHash []byte // this is the one for the next block to propose
|
|
|
|
LastLastResultHash []byte // this verifies the last block?
|
|
|
|
|
|
|
|
// The latest AppHash we've received from calling abci.Commit()
|
|
|
|
AppHash []byte |
|
|
@ -311,8 +308,8 @@ func (s *State) saveConsensusParamsInfo() { |
|
|
|
s.db.SetSync(calcConsensusParamsKey(nextHeight), paramsInfo.Bytes()) |
|
|
|
} |
|
|
|
|
|
|
|
// LoadResults loads the ABCIResults for a given height.
|
|
|
|
func (s *State) LoadResults(height int64) (ABCIResults, error) { |
|
|
|
// LoadResults loads the types.ABCIResults for a given height.
|
|
|
|
func (s *State) LoadResults(height int64) (types.ABCIResults, error) { |
|
|
|
resInfo := s.loadResults(height) |
|
|
|
if resInfo == nil { |
|
|
|
return nil, ErrNoResultsForHeight{height} |
|
|
@ -320,13 +317,13 @@ func (s *State) LoadResults(height int64) (ABCIResults, error) { |
|
|
|
return resInfo, nil |
|
|
|
} |
|
|
|
|
|
|
|
func (s *State) loadResults(height int64) ABCIResults { |
|
|
|
func (s *State) loadResults(height int64) types.ABCIResults { |
|
|
|
buf := s.db.Get(calcResultsKey(height)) |
|
|
|
if len(buf) == 0 { |
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
v := new(ABCIResults) |
|
|
|
v := new(types.ABCIResults) |
|
|
|
err := wire.ReadBinaryBytes(buf, v) |
|
|
|
if err != nil { |
|
|
|
// DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
|
|
|
@ -396,7 +393,7 @@ func (s *State) SetBlockAndValidators(header *types.Header, blockPartsHeader typ |
|
|
|
header.Time, |
|
|
|
nextValSet, |
|
|
|
nextParams, |
|
|
|
NewResults(abciResponses.DeliverTx)) |
|
|
|
types.NewResults(abciResponses.DeliverTx)) |
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
@ -404,7 +401,7 @@ func (s *State) setBlockAndValidators(height int64, |
|
|
|
newTxs int64, blockID types.BlockID, blockTime time.Time, |
|
|
|
valSet *types.ValidatorSet, |
|
|
|
params types.ConsensusParams, |
|
|
|
results ABCIResults) { |
|
|
|
results types.ABCIResults) { |
|
|
|
|
|
|
|
s.LastBlockHeight = height |
|
|
|
s.LastBlockTotalTx += newTxs |
|
|
@ -455,64 +452,6 @@ 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 |
|
|
|
} |
|
|
|
|
|
|
|
// Bytes serializes the ABCIResponse using go-wire
|
|
|
|
func (a ABCIResults) Bytes() []byte { |
|
|
|
return wire.BinaryBytes(a) |
|
|
|
} |
|
|
|
|
|
|
|
// 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 |
|
|
|