mirror of
https://github.com/tendermint/tendermint.git
synced 2026-08-19 21:56:22 +00:00
remove Must* proof and hash functions
This commit is contained in:
+7
-14
@@ -8,7 +8,6 @@ import (
|
||||
|
||||
"github.com/gogo/protobuf/jsonpb"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto/merkle"
|
||||
types "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
)
|
||||
|
||||
@@ -171,16 +170,6 @@ func RespondVerifyVoteExtension(ok bool) ResponseVerifyVoteExtension {
|
||||
}
|
||||
}
|
||||
|
||||
func MustHashResults(r []*ExecTxResult) []byte {
|
||||
return merkle.HashFromByteSlices(mustResultsToByteSlices(r))
|
||||
}
|
||||
|
||||
// ProveResult returns a merkle proof of one result from the set
|
||||
func MustProveResult(r []*ExecTxResult, i int) merkle.Proof {
|
||||
_, proofs := merkle.ProofsFromByteSlices(mustResultsToByteSlices(r))
|
||||
return *proofs[i]
|
||||
}
|
||||
|
||||
// deterministicExecTxResult strips non-deterministic fields from
|
||||
// ResponseDeliverTx and returns another ResponseDeliverTx.
|
||||
func deterministicExecTxResult(response *ExecTxResult) *ExecTxResult {
|
||||
@@ -192,17 +181,21 @@ func deterministicExecTxResult(response *ExecTxResult) *ExecTxResult {
|
||||
}
|
||||
}
|
||||
|
||||
func mustResultsToByteSlices(r []*ExecTxResult) [][]byte {
|
||||
// TxResultsToByteSlices encodes the the TxResults as a list of byte
|
||||
// slices. It strips off the non-deterministic pieces of the TxResults
|
||||
// so that the resulting data can be used for hash comparisons and used
|
||||
// in Merkle proofs.
|
||||
func TxResultsToByteSlices(r []*ExecTxResult) ([][]byte, error) {
|
||||
s := make([][]byte, len(r))
|
||||
for i, e := range r {
|
||||
d := deterministicExecTxResult(e)
|
||||
b, err := d.Marshal()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return nil, err
|
||||
}
|
||||
s[i] = b
|
||||
}
|
||||
return s
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (tr *TxRecord) IsIncluded() bool {
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto/merkle"
|
||||
)
|
||||
|
||||
func TestHashAndProveResults(t *testing.T) {
|
||||
@@ -28,15 +29,17 @@ func TestHashAndProveResults(t *testing.T) {
|
||||
require.Equal(t, bz0, bz1)
|
||||
|
||||
// Make sure that we can get a root hash from results and verify proofs.
|
||||
root := abci.MustHashResults(trs)
|
||||
rs, err := abci.TxResultsToByteSlices(trs)
|
||||
require.NoError(t, err)
|
||||
root := merkle.HashFromByteSlices(rs)
|
||||
assert.NotEmpty(t, root)
|
||||
|
||||
_, proofs := merkle.ProofsFromByteSlices(rs)
|
||||
for i, tr := range trs {
|
||||
bz, err := tr.Marshal()
|
||||
require.NoError(t, err)
|
||||
|
||||
proof := abci.MustProveResult(trs, i)
|
||||
valid := proof.Verify(root, bz)
|
||||
valid := proofs[i].Verify(root, bz)
|
||||
assert.NoError(t, valid, "%d", i)
|
||||
}
|
||||
}
|
||||
|
||||
+16
-8
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto/merkle"
|
||||
tmquery "github.com/tendermint/tendermint/internal/pubsub/query"
|
||||
"github.com/tendermint/tendermint/internal/state/indexer"
|
||||
"github.com/tendermint/tendermint/libs/bytes"
|
||||
@@ -36,19 +37,21 @@ func (env *Environment) Tx(ctx context.Context, hash bytes.HexBytes, prove bool)
|
||||
return nil, fmt.Errorf("tx (%X) not found, err: %w", hash, err)
|
||||
}
|
||||
|
||||
height := r.Height
|
||||
index := r.Index
|
||||
|
||||
var proof types.TxProof
|
||||
if prove {
|
||||
block := env.BlockStore.LoadBlock(height)
|
||||
proof = block.Data.Txs.Proof(int(index)) // XXX: overflow on 32-bit machines
|
||||
block := env.BlockStore.LoadBlock(r.Height)
|
||||
root, proofs := merkle.ProofsFromByteSlices(block.Data.Txs.ToSliceOfBytes())
|
||||
proof = types.TxProof{
|
||||
RootHash: root,
|
||||
Proof: *proofs[int(r.Index)],
|
||||
Data: block.Data.Txs[int(r.Index)],
|
||||
}
|
||||
}
|
||||
|
||||
return &coretypes.ResultTx{
|
||||
Hash: hash,
|
||||
Height: height,
|
||||
Index: index,
|
||||
Height: r.Height,
|
||||
Index: r.Index,
|
||||
TxResult: r.Result,
|
||||
Tx: r.Tx,
|
||||
Proof: proof,
|
||||
@@ -127,7 +130,12 @@ func (env *Environment) TxSearch(
|
||||
var proof types.TxProof
|
||||
if prove {
|
||||
block := env.BlockStore.LoadBlock(r.Height)
|
||||
proof = block.Data.Txs.Proof(int(r.Index)) // XXX: overflow on 32-bit machines
|
||||
root, proofs := merkle.ProofsFromByteSlices(block.Data.Txs.ToSliceOfBytes())
|
||||
proof = types.TxProof{
|
||||
RootHash: root,
|
||||
Proof: *proofs[int(r.Index)],
|
||||
Data: block.Data.Txs[int(r.Index)],
|
||||
}
|
||||
}
|
||||
|
||||
apiResults = append(apiResults, &coretypes.ResultTx{
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
abciclient "github.com/tendermint/tendermint/abci/client"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto/encoding"
|
||||
"github.com/tendermint/tendermint/crypto/merkle"
|
||||
"github.com/tendermint/tendermint/internal/eventbus"
|
||||
"github.com/tendermint/tendermint/internal/mempool"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
@@ -261,7 +262,12 @@ func (blockExec *BlockExecutor) ApplyBlock(
|
||||
}
|
||||
|
||||
// Update the state with the block and responses.
|
||||
state, err = state.Update(blockID, &block.Header, abci.MustHashResults(finalizeBlockResponse.TxResults), finalizeBlockResponse.ConsensusParamUpdates, validatorUpdates)
|
||||
rs, err := abci.TxResultsToByteSlices(finalizeBlockResponse.TxResults)
|
||||
if err != nil {
|
||||
return state, fmt.Errorf("marshaling TxResults: %w", err)
|
||||
}
|
||||
h := merkle.HashFromByteSlices(rs)
|
||||
state, err = state.Update(blockID, &block.Header, h, finalizeBlockResponse.ConsensusParamUpdates, validatorUpdates)
|
||||
if err != nil {
|
||||
return state, fmt.Errorf("commit failed for application: %w", err)
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/crypto/ed25519"
|
||||
"github.com/tendermint/tendermint/crypto/encoding"
|
||||
"github.com/tendermint/tendermint/crypto/merkle"
|
||||
sm "github.com/tendermint/tendermint/internal/state"
|
||||
statefactory "github.com/tendermint/tendermint/internal/state/test/factory"
|
||||
tmstate "github.com/tendermint/tendermint/proto/tendermint/state"
|
||||
@@ -204,7 +205,13 @@ func TestABCIResponsesSaveLoad2(t *testing.T) {
|
||||
res, err := stateStore.LoadABCIResponses(h)
|
||||
if assert.NoError(t, err, "%d", i) {
|
||||
t.Log(res)
|
||||
assert.Equal(t, abci.MustHashResults(tc.expected), abci.MustHashResults(res.FinalizeBlock.TxResults), "%d", i)
|
||||
e, err := abci.TxResultsToByteSlices(tc.expected)
|
||||
require.NoError(t, err)
|
||||
he := merkle.HashFromByteSlices(e)
|
||||
rs, err := abci.TxResultsToByteSlices(res.FinalizeBlock.TxResults)
|
||||
hrs := merkle.HashFromByteSlices(rs)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, he, hrs, "%d", i)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -270,9 +277,12 @@ func TestOneValidatorChangesSaveLoad(t *testing.T) {
|
||||
header, blockID, responses := makeHeaderPartsResponsesValPowerChange(t, state, power)
|
||||
validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.FinalizeBlock.ValidatorUpdates)
|
||||
require.NoError(t, err)
|
||||
state, err = state.Update(blockID, &header, abci.MustHashResults(responses.FinalizeBlock.TxResults), responses.FinalizeBlock.ConsensusParamUpdates, validatorUpdates)
|
||||
rs, err := abci.TxResultsToByteSlices(responses.FinalizeBlock.TxResults)
|
||||
require.NoError(t, err)
|
||||
err := stateStore.Save(state)
|
||||
h := merkle.HashFromByteSlices(rs)
|
||||
state, err = state.Update(blockID, &header, h, responses.FinalizeBlock.ConsensusParamUpdates, validatorUpdates)
|
||||
require.NoError(t, err)
|
||||
err = stateStore.Save(state)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -452,7 +462,10 @@ func TestProposerPriorityDoesNotGetResetToZero(t *testing.T) {
|
||||
}
|
||||
validatorUpdates, err := types.PB2TM.ValidatorUpdates(fb.ValidatorUpdates)
|
||||
require.NoError(t, err)
|
||||
updatedState, err := state.Update(blockID, &block.Header, abci.MustHashResults(fb.TxResults), fb.ConsensusParamUpdates, validatorUpdates)
|
||||
rs, err := abci.TxResultsToByteSlices(fb.TxResults)
|
||||
require.NoError(t, err)
|
||||
h := merkle.HashFromByteSlices(rs)
|
||||
updatedState, err := state.Update(blockID, &block.Header, h, fb.ConsensusParamUpdates, validatorUpdates)
|
||||
assert.NoError(t, err)
|
||||
curTotal := val1VotingPower
|
||||
// one increment step and one validator: 0 + power - total_power == 0
|
||||
@@ -467,7 +480,10 @@ func TestProposerPriorityDoesNotGetResetToZero(t *testing.T) {
|
||||
updateAddVal := abci.ValidatorUpdate{PubKey: fvp, Power: val2VotingPower}
|
||||
validatorUpdates, err = types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{updateAddVal})
|
||||
assert.NoError(t, err)
|
||||
updatedState2, err := updatedState.Update(blockID, &block.Header, abci.MustHashResults(fb.TxResults), fb.ConsensusParamUpdates, validatorUpdates)
|
||||
rs, err = abci.TxResultsToByteSlices(fb.TxResults)
|
||||
require.NoError(t, err)
|
||||
h = merkle.HashFromByteSlices(rs)
|
||||
updatedState2, err := updatedState.Update(blockID, &block.Header, h, fb.ConsensusParamUpdates, validatorUpdates)
|
||||
assert.NoError(t, err)
|
||||
|
||||
require.Equal(t, len(updatedState2.NextValidators.Validators), 2)
|
||||
@@ -506,7 +522,10 @@ func TestProposerPriorityDoesNotGetResetToZero(t *testing.T) {
|
||||
|
||||
// this will cause the diff of priorities (77)
|
||||
// to be larger than threshold == 2*totalVotingPower (22):
|
||||
updatedState3, err := updatedState2.Update(blockID, &block.Header, abci.MustHashResults(fb.TxResults), fb.ConsensusParamUpdates, validatorUpdates)
|
||||
rs, err = abci.TxResultsToByteSlices(fb.TxResults)
|
||||
require.NoError(t, err)
|
||||
h = merkle.HashFromByteSlices(rs)
|
||||
updatedState3, err := updatedState2.Update(blockID, &block.Header, h, fb.ConsensusParamUpdates, validatorUpdates)
|
||||
assert.NoError(t, err)
|
||||
|
||||
require.Equal(t, len(updatedState3.NextValidators.Validators), 2)
|
||||
@@ -569,7 +588,10 @@ func TestProposerPriorityProposerAlternates(t *testing.T) {
|
||||
validatorUpdates, err := types.PB2TM.ValidatorUpdates(fb.ValidatorUpdates)
|
||||
require.NoError(t, err)
|
||||
|
||||
updatedState, err := state.Update(blockID, &block.Header, abci.MustHashResults(fb.TxResults), fb.ConsensusParamUpdates, validatorUpdates)
|
||||
rs, err := abci.TxResultsToByteSlices(fb.TxResults)
|
||||
require.NoError(t, err)
|
||||
h := merkle.HashFromByteSlices(rs)
|
||||
updatedState, err := state.Update(blockID, &block.Header, h, fb.ConsensusParamUpdates, validatorUpdates)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 0 + 10 (initial prio) - 10 (avg) - 10 (mostest - total) = -10
|
||||
@@ -586,7 +608,10 @@ func TestProposerPriorityProposerAlternates(t *testing.T) {
|
||||
validatorUpdates, err = types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{updateAddVal})
|
||||
assert.NoError(t, err)
|
||||
|
||||
updatedState2, err := updatedState.Update(blockID, &block.Header, abci.MustHashResults(fb.TxResults), fb.ConsensusParamUpdates, validatorUpdates)
|
||||
rs, err = abci.TxResultsToByteSlices(fb.TxResults)
|
||||
require.NoError(t, err)
|
||||
h = merkle.HashFromByteSlices(rs)
|
||||
updatedState2, err := updatedState.Update(blockID, &block.Header, h, fb.ConsensusParamUpdates, validatorUpdates)
|
||||
assert.NoError(t, err)
|
||||
|
||||
require.Equal(t, len(updatedState2.NextValidators.Validators), 2)
|
||||
@@ -629,7 +654,10 @@ func TestProposerPriorityProposerAlternates(t *testing.T) {
|
||||
validatorUpdates, err = types.PB2TM.ValidatorUpdates(fb.ValidatorUpdates)
|
||||
require.NoError(t, err)
|
||||
|
||||
updatedState3, err := updatedState2.Update(blockID, &block.Header, abci.MustHashResults(fb.TxResults), fb.ConsensusParamUpdates, validatorUpdates)
|
||||
rs, err = abci.TxResultsToByteSlices(fb.TxResults)
|
||||
require.NoError(t, err)
|
||||
h = merkle.HashFromByteSlices(rs)
|
||||
updatedState3, err := updatedState2.Update(blockID, &block.Header, h, fb.ConsensusParamUpdates, validatorUpdates)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, updatedState3.Validators.Proposer.Address, updatedState3.NextValidators.Proposer.Address)
|
||||
@@ -671,7 +699,10 @@ func TestProposerPriorityProposerAlternates(t *testing.T) {
|
||||
validatorUpdates, err = types.PB2TM.ValidatorUpdates(fb.ValidatorUpdates)
|
||||
require.NoError(t, err)
|
||||
|
||||
oldState, err = oldState.Update(blockID, &block.Header, abci.MustHashResults(fb.TxResults), fb.ConsensusParamUpdates, validatorUpdates)
|
||||
rs, err = abci.TxResultsToByteSlices(fb.TxResults)
|
||||
require.NoError(t, err)
|
||||
h = merkle.HashFromByteSlices(rs)
|
||||
oldState, err = oldState.Update(blockID, &block.Header, h, fb.ConsensusParamUpdates, validatorUpdates)
|
||||
assert.NoError(t, err)
|
||||
expectedVal1Prio2 = 1
|
||||
expectedVal2Prio2 = -1
|
||||
@@ -686,7 +717,10 @@ func TestProposerPriorityProposerAlternates(t *testing.T) {
|
||||
validatorUpdates, err = types.PB2TM.ValidatorUpdates(fb.ValidatorUpdates)
|
||||
require.NoError(t, err)
|
||||
|
||||
updatedState, err := oldState.Update(blockID, &block.Header, abci.MustHashResults(fb.TxResults), fb.ConsensusParamUpdates, validatorUpdates)
|
||||
rs, err := abci.TxResultsToByteSlices(fb.TxResults)
|
||||
require.NoError(t, err)
|
||||
h := merkle.HashFromByteSlices(rs)
|
||||
updatedState, err := oldState.Update(blockID, &block.Header, h, fb.ConsensusParamUpdates, validatorUpdates)
|
||||
assert.NoError(t, err)
|
||||
// alternate (and cyclic priorities):
|
||||
assert.NotEqual(
|
||||
@@ -748,7 +782,10 @@ func TestLargeGenesisValidator(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
|
||||
|
||||
updatedState, err := oldState.Update(blockID, &block.Header, abci.MustHashResults(fb.TxResults), fb.ConsensusParamUpdates, validatorUpdates)
|
||||
rs, err := abci.TxResultsToByteSlices(fb.TxResults)
|
||||
require.NoError(t, err)
|
||||
h := merkle.HashFromByteSlices(rs)
|
||||
updatedState, err := oldState.Update(blockID, &block.Header, h, fb.ConsensusParamUpdates, validatorUpdates)
|
||||
require.NoError(t, err)
|
||||
// no changes in voting power (ProposerPrio += VotingPower == Voting in 1st round; than shiftByAvg == 0,
|
||||
// than -Total == -Voting)
|
||||
@@ -779,7 +816,10 @@ func TestLargeGenesisValidator(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
|
||||
updatedState, err := oldState.Update(blockID, &block.Header, abci.MustHashResults(fb.TxResults), fb.ConsensusParamUpdates, validatorUpdates)
|
||||
rs, err := abci.TxResultsToByteSlices(fb.TxResults)
|
||||
require.NoError(t, err)
|
||||
h := merkle.HashFromByteSlices(rs)
|
||||
updatedState, err := oldState.Update(blockID, &block.Header, h, fb.ConsensusParamUpdates, validatorUpdates)
|
||||
require.NoError(t, err)
|
||||
|
||||
lastState := updatedState
|
||||
@@ -798,7 +838,10 @@ func TestLargeGenesisValidator(t *testing.T) {
|
||||
|
||||
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
|
||||
|
||||
updatedStateInner, err := lastState.Update(blockID, &block.Header, abci.MustHashResults(fb.TxResults), fb.ConsensusParamUpdates, validatorUpdates)
|
||||
rs, err := abci.TxResultsToByteSlices(fb.TxResults)
|
||||
require.NoError(t, err)
|
||||
h := merkle.HashFromByteSlices(rs)
|
||||
updatedStateInner, err := lastState.Update(blockID, &block.Header, h, fb.ConsensusParamUpdates, validatorUpdates)
|
||||
require.NoError(t, err)
|
||||
lastState = updatedStateInner
|
||||
}
|
||||
@@ -832,7 +875,10 @@ func TestLargeGenesisValidator(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
|
||||
state, err = state.Update(blockID, &block.Header, abci.MustHashResults(fb.TxResults), fb.ConsensusParamUpdates, validatorUpdates)
|
||||
rs, err := abci.TxResultsToByteSlices(fb.TxResults)
|
||||
require.NoError(t, err)
|
||||
h := merkle.HashFromByteSlices(rs)
|
||||
state, err = state.Update(blockID, &block.Header, h, fb.ConsensusParamUpdates, validatorUpdates)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
require.Equal(t, 10+2, len(state.NextValidators.Validators))
|
||||
@@ -854,7 +900,10 @@ func TestLargeGenesisValidator(t *testing.T) {
|
||||
blockID = types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
|
||||
validatorUpdates, err = types.PB2TM.ValidatorUpdates(fb.ValidatorUpdates)
|
||||
require.NoError(t, err)
|
||||
updatedState, err = state.Update(blockID, &block.Header, abci.MustHashResults(fb.TxResults), fb.ConsensusParamUpdates, validatorUpdates)
|
||||
rs, err = abci.TxResultsToByteSlices(fb.TxResults)
|
||||
require.NoError(t, err)
|
||||
h = merkle.HashFromByteSlices(rs)
|
||||
updatedState, err = state.Update(blockID, &block.Header, h, fb.ConsensusParamUpdates, validatorUpdates)
|
||||
require.NoError(t, err)
|
||||
// only the first added val (not the genesis val) should be left
|
||||
assert.Equal(t, 11, len(updatedState.NextValidators.Validators))
|
||||
@@ -876,7 +925,10 @@ func TestLargeGenesisValidator(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
blockID = types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
|
||||
curState, err = curState.Update(blockID, &block.Header, abci.MustHashResults(fb.TxResults), fb.ConsensusParamUpdates, validatorUpdates)
|
||||
rs, err := abci.TxResultsToByteSlices(fb.TxResults)
|
||||
require.NoError(t, err)
|
||||
h := merkle.HashFromByteSlices(rs)
|
||||
curState, err = curState.Update(blockID, &block.Header, h, fb.ConsensusParamUpdates, validatorUpdates)
|
||||
require.NoError(t, err)
|
||||
if !bytes.Equal(curState.Validators.Proposer.Address, curState.NextValidators.Proposer.Address) {
|
||||
isProposerUnchanged = false
|
||||
@@ -905,7 +957,10 @@ func TestLargeGenesisValidator(t *testing.T) {
|
||||
|
||||
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
|
||||
|
||||
updatedState, err = updatedState.Update(blockID, &block.Header, abci.MustHashResults(fb.TxResults), fb.ConsensusParamUpdates, validatorUpdates)
|
||||
rs, err := abci.TxResultsToByteSlices(fb.TxResults)
|
||||
require.NoError(t, err)
|
||||
h := merkle.HashFromByteSlices(rs)
|
||||
updatedState, err = updatedState.Update(blockID, &block.Header, h, fb.ConsensusParamUpdates, validatorUpdates)
|
||||
require.NoError(t, err)
|
||||
if i > numVals { // expect proposers to cycle through after the first iteration (of numVals blocks):
|
||||
if proposers[i%numVals] == nil {
|
||||
@@ -964,7 +1019,10 @@ func TestManyValidatorChangesSaveLoad(t *testing.T) {
|
||||
var validatorUpdates []*types.Validator
|
||||
validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.FinalizeBlock.ValidatorUpdates)
|
||||
require.NoError(t, err)
|
||||
state, err = state.Update(blockID, &header, abci.MustHashResults(responses.FinalizeBlock.TxResults), responses.FinalizeBlock.ConsensusParamUpdates, validatorUpdates)
|
||||
rs, err := abci.TxResultsToByteSlices(responses.FinalizeBlock.TxResults)
|
||||
require.NoError(t, err)
|
||||
h := merkle.HashFromByteSlices(rs)
|
||||
state, err = state.Update(blockID, &header, h, responses.FinalizeBlock.ConsensusParamUpdates, validatorUpdates)
|
||||
require.NoError(t, err)
|
||||
nextHeight := state.LastBlockHeight + 1
|
||||
err = stateStore.Save(state)
|
||||
@@ -1041,10 +1099,13 @@ func TestConsensusParamsChangesSaveLoad(t *testing.T) {
|
||||
header, blockID, responses := makeHeaderPartsResponsesParams(t, state, &cp)
|
||||
validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.FinalizeBlock.ValidatorUpdates)
|
||||
require.NoError(t, err)
|
||||
state, err = state.Update(blockID, &header, abci.MustHashResults(responses.FinalizeBlock.TxResults), responses.FinalizeBlock.ConsensusParamUpdates, validatorUpdates)
|
||||
rs, err := abci.TxResultsToByteSlices(responses.FinalizeBlock.TxResults)
|
||||
require.NoError(t, err)
|
||||
h := merkle.HashFromByteSlices(rs)
|
||||
state, err = state.Update(blockID, &header, h, responses.FinalizeBlock.ConsensusParamUpdates, validatorUpdates)
|
||||
|
||||
require.NoError(t, err)
|
||||
err := stateStore.Save(state)
|
||||
err = stateStore.Save(state)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -459,7 +459,11 @@ func (c *Client) BlockResults(ctx context.Context, height *int64) (*coretypes.Re
|
||||
}
|
||||
|
||||
// Build a Merkle tree out of the slice.
|
||||
rH := merkle.HashFromByteSlices([][]byte{bbeBytes, abci.MustHashResults(res.TxsResults)})
|
||||
rs, err := abci.TxResultsToByteSlices(res.TxsResults)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rH := merkle.HashFromByteSlices(append([][]byte{bbeBytes}, rs...))
|
||||
|
||||
// Verify block results.
|
||||
if !bytes.Equal(rH, trustedBlock.LastResultsHash) {
|
||||
|
||||
-18
@@ -62,24 +62,6 @@ func (txs Txs) IndexByHash(hash []byte) 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)
|
||||
bzs := make([][]byte, l)
|
||||
for i := 0; i < l; i++ {
|
||||
bzs[i] = txs[i].Hash()
|
||||
}
|
||||
root, proofs := merkle.ProofsFromByteSlices(bzs)
|
||||
|
||||
return TxProof{
|
||||
RootHash: root,
|
||||
Data: txs[i],
|
||||
Proof: *proofs[i],
|
||||
}
|
||||
}
|
||||
|
||||
// ToSliceOfBytes converts a Txs to slice of byte slices.
|
||||
//
|
||||
// NOTE: This method should become obsolete once Txs is switched to [][]byte.
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
mrand "math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
ctest "github.com/tendermint/tendermint/internal/libs/test"
|
||||
tmrand "github.com/tendermint/tendermint/libs/rand"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
)
|
||||
|
||||
func makeTxs(cnt, size int) Txs {
|
||||
@@ -51,102 +47,3 @@ func TestTxIndexByHash(t *testing.T) {
|
||||
assert.Equal(t, -1, txs.IndexByHash(Tx("foodnwkf").Hash()))
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidTxProof(t *testing.T) {
|
||||
cases := []struct {
|
||||
txs Txs
|
||||
}{
|
||||
{Txs{{1, 4, 34, 87, 163, 1}}},
|
||||
{Txs{{5, 56, 165, 2}, {4, 77}}},
|
||||
{Txs{Tx("foo"), Tx("bar"), Tx("baz")}},
|
||||
{makeTxs(20, 5)},
|
||||
{makeTxs(7, 81)},
|
||||
{makeTxs(61, 15)},
|
||||
}
|
||||
|
||||
for h, tc := range cases {
|
||||
txs := tc.txs
|
||||
root := txs.Hash()
|
||||
// make sure valid proof for every tx
|
||||
for i := range txs {
|
||||
tx := []byte(txs[i])
|
||||
proof := txs.Proof(i)
|
||||
assert.EqualValues(t, i, proof.Proof.Index, "%d: %d", h, i)
|
||||
assert.EqualValues(t, len(txs), proof.Proof.Total, "%d: %d", h, i)
|
||||
assert.EqualValues(t, root, proof.RootHash, "%d: %d", h, i)
|
||||
assert.EqualValues(t, tx, proof.Data, "%d: %d", h, i)
|
||||
assert.EqualValues(t, txs[i].Hash(), proof.Leaf(), "%d: %d", h, i)
|
||||
assert.Nil(t, proof.Validate(root), "%d: %d", h, i)
|
||||
assert.NotNil(t, proof.Validate([]byte("foobar")), "%d: %d", h, i)
|
||||
|
||||
// read-write must also work
|
||||
var (
|
||||
p2 TxProof
|
||||
pb2 tmproto.TxProof
|
||||
)
|
||||
pbProof := proof.ToProto()
|
||||
bin, err := pbProof.Marshal()
|
||||
require.NoError(t, err)
|
||||
|
||||
err = pb2.Unmarshal(bin)
|
||||
require.NoError(t, err)
|
||||
|
||||
p2, err = TxProofFromProto(pb2)
|
||||
if assert.NoError(t, err, "%d: %d: %+v", h, i, err) {
|
||||
assert.Nil(t, p2.Validate(root), "%d: %d", h, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTxProofUnchangable(t *testing.T) {
|
||||
// run the other test a bunch...
|
||||
for i := 0; i < 40; i++ {
|
||||
testTxProofUnchangable(t)
|
||||
}
|
||||
}
|
||||
|
||||
func testTxProofUnchangable(t *testing.T) {
|
||||
// make some proof
|
||||
txs := makeTxs(randInt(2, 100), randInt(16, 128))
|
||||
root := txs.Hash()
|
||||
i := randInt(0, len(txs)-1)
|
||||
proof := txs.Proof(i)
|
||||
|
||||
// make sure it is valid to start with
|
||||
assert.Nil(t, proof.Validate(root))
|
||||
pbProof := proof.ToProto()
|
||||
bin, err := pbProof.Marshal()
|
||||
require.NoError(t, err)
|
||||
|
||||
// try mutating the data and make sure nothing breaks
|
||||
for j := 0; j < 500; j++ {
|
||||
bad := ctest.MutateByteSlice(bin)
|
||||
if !bytes.Equal(bad, bin) {
|
||||
assertBadProof(t, root, bad, proof)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This makes sure that the proof doesn't deserialize into something valid.
|
||||
func assertBadProof(t *testing.T, root []byte, bad []byte, good TxProof) {
|
||||
|
||||
var (
|
||||
proof TxProof
|
||||
pbProof tmproto.TxProof
|
||||
)
|
||||
err := pbProof.Unmarshal(bad)
|
||||
if err == nil {
|
||||
proof, err = TxProofFromProto(pbProof)
|
||||
if err == nil {
|
||||
err = proof.Validate(root)
|
||||
if err == nil {
|
||||
// XXX Fix simple merkle proofs so the following is *not* OK.
|
||||
// This can happen if we have a slightly different total (where the
|
||||
// path ends up the same). If it is something else, we have a real
|
||||
// problem.
|
||||
assert.NotEqual(t, proof.Proof.Total, good.Proof.Total, "bad: %#v\ngood: %#v", proof, good)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user