mirror of
https://github.com/fluencelabs/tendermint
synced 2025-08-01 04:31:57 +00:00
Compare commits
9 Commits
v0.32.3
...
anton/bloc
Author | SHA1 | Date | |
---|---|---|---|
|
f0327d9c61 | ||
|
26b81fb4d4 | ||
|
56a5176f23 | ||
|
486d23b575 | ||
|
9c8238c8ee | ||
|
d2db47cc4a | ||
|
94611e1f81 | ||
|
73295be21d | ||
|
6a369b69b8 |
@@ -10,11 +10,25 @@ program](https://hackerone.com/tendermint).
|
||||
### BREAKING CHANGES:
|
||||
|
||||
- CLI/RPC/Config
|
||||
- [rpc] `/block_results` response format updated (see RPC docs for details)
|
||||
```
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "",
|
||||
"result": {
|
||||
"height": "2109",
|
||||
"txs_results": null,
|
||||
"begin_block_events": null,
|
||||
"end_block_events": null,
|
||||
"validator_updates": null,
|
||||
"consensus_param_updates": null
|
||||
}
|
||||
}
|
||||
|
||||
- Apps
|
||||
|
||||
- Go API
|
||||
- [libs] \#3811 Remove `db` from libs in favor of `https://github.com/tendermint/tm-cmn`
|
||||
- [libs] \#3811 Remove `db` from libs in favor of `https://github.com/tendermint/tm-cmn`
|
||||
|
||||
### FEATURES:
|
||||
|
||||
@@ -25,3 +39,4 @@ program](https://hackerone.com/tendermint).
|
||||
- [p2p] \#3664 p2p/conn: reuse buffer when write/read from secret connection
|
||||
|
||||
### BUG FIXES:
|
||||
|
||||
|
@@ -516,7 +516,7 @@ type mockProxyApp struct {
|
||||
}
|
||||
|
||||
func (mock *mockProxyApp) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx {
|
||||
r := mock.abciResponses.DeliverTx[mock.txCount]
|
||||
r := mock.abciResponses.DeliverTxs[mock.txCount]
|
||||
mock.txCount++
|
||||
if r == nil { //it could be nil because of amino unMarshall, it will cause an empty ResponseDeliverTx to become nil
|
||||
return abci.ResponseDeliverTx{}
|
||||
|
@@ -529,8 +529,8 @@ func TestMockProxyApp(t *testing.T) {
|
||||
|
||||
assert.NotPanics(t, func() {
|
||||
abciResWithEmptyDeliverTx := new(sm.ABCIResponses)
|
||||
abciResWithEmptyDeliverTx.DeliverTx = make([]*abci.ResponseDeliverTx, 0)
|
||||
abciResWithEmptyDeliverTx.DeliverTx = append(abciResWithEmptyDeliverTx.DeliverTx, &abci.ResponseDeliverTx{})
|
||||
abciResWithEmptyDeliverTx.DeliverTxs = make([]*abci.ResponseDeliverTx, 0)
|
||||
abciResWithEmptyDeliverTx.DeliverTxs = append(abciResWithEmptyDeliverTx.DeliverTxs, &abci.ResponseDeliverTx{})
|
||||
|
||||
// called when saveABCIResponses:
|
||||
bytes := cdc.MustMarshalBinaryBare(abciResWithEmptyDeliverTx)
|
||||
@@ -543,7 +543,7 @@ func TestMockProxyApp(t *testing.T) {
|
||||
mock := newMockProxyApp([]byte("mock_hash"), loadedAbciRes)
|
||||
|
||||
abciRes := new(sm.ABCIResponses)
|
||||
abciRes.DeliverTx = make([]*abci.ResponseDeliverTx, len(loadedAbciRes.DeliverTx))
|
||||
abciRes.DeliverTxs = make([]*abci.ResponseDeliverTx, len(loadedAbciRes.DeliverTxs))
|
||||
// Execute transactions and get hash.
|
||||
proxyCb := func(req *abci.Request, res *abci.Response) {
|
||||
switch r := res.Value.(type) {
|
||||
@@ -558,7 +558,7 @@ func TestMockProxyApp(t *testing.T) {
|
||||
logger.Debug("Invalid tx", "code", txRes.Code, "log", txRes.Log)
|
||||
invalidTxs++
|
||||
}
|
||||
abciRes.DeliverTx[txIndex] = txRes
|
||||
abciRes.DeliverTxs[txIndex] = txRes
|
||||
txIndex++
|
||||
}
|
||||
}
|
||||
|
@@ -209,9 +209,9 @@ func TestAppCalls(t *testing.T) {
|
||||
blockResults, err := c.BlockResults(&txh)
|
||||
require.Nil(err, "%d: %+v", i, err)
|
||||
assert.Equal(txh, blockResults.Height)
|
||||
if assert.Equal(1, len(blockResults.Results.DeliverTx)) {
|
||||
if assert.Equal(1, len(blockResults.TxsResults)) {
|
||||
// check success code
|
||||
assert.EqualValues(0, blockResults.Results.DeliverTx[0].Code)
|
||||
assert.EqualValues(0, blockResults.TxsResults[0].Code)
|
||||
}
|
||||
|
||||
// check blockchain info, now that we know there is info
|
||||
|
@@ -364,25 +364,41 @@ func Commit(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultCommit, erro
|
||||
// "jsonrpc": "2.0",
|
||||
// "id": "",
|
||||
// "result": {
|
||||
// "height": "39",
|
||||
// "results": {
|
||||
// "deliver_tx": [
|
||||
// {
|
||||
// "tags": [
|
||||
// {
|
||||
// "key": "YXBwLmNyZWF0b3I=",
|
||||
// "value": "Q29zbW9zaGkgTmV0b3dva28="
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// ],
|
||||
// "end_block": {
|
||||
// "validator_updates": null
|
||||
// "height": "437",
|
||||
// "txs_results": [
|
||||
// {
|
||||
// "gas_wanted": 1,
|
||||
// "gas_used": 1,
|
||||
// "events": [
|
||||
// {
|
||||
// "type": "app",
|
||||
// "attributes": [
|
||||
// {
|
||||
// "key": "Y3JlYXRvcg==",
|
||||
// "value": "Q29zbW9zaGkgTmV0b3dva28="
|
||||
// },
|
||||
// {
|
||||
// "key": "a2V5",
|
||||
// "value": "MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA3NDZhOTQ0NDQ1N2Y2NDE4YmY3MmEyOWExNTkwNThlZDg1YmVjNWU5MDUwMDAwMDBkNmUyZWVhY2VjN2RhOTk4ZjRlNDU3MWEyZWU5NmNhYmU2NGEzNmI0MjljZTQ5NjBkZDRjMWY5ZmJlYTQyNTdlZTUxMDk1NDc3MDYyMDY1Mzg4Yjk4MGIwYWU2ZmRkYzM5YWUzNDhhZjQ3MjczOTM0YWExMTNhNTdkNmEyZDY3OWQ0ZmMyNzlkYjg5Y2I1MTM3OTNmZTYxNTc0M2E3N2Y4NzZkODUwMTkxODAzY2Y5ZGU2NjBhMWVjOThmMDcwNTI3YjJjYThkYWIwNzI5NjRhMmQ0ODI2MzU4OWM5ZGFkNWI3OTI2ODA3OWM3Mjg1YTdhMWNmODIzODllZmY2Y2ExMzczMzk5ZWFiOTI5ZmY0NGZiOGE5NGU0YjY5NGU2NDZlM2UyYmZmN2Y1MTAxN2NhNWE1NjA4YzFlZTFkZWQzMzJhNTYwYzczYmM5MzFmYjJhOTM2NjY0NzBhOTA3MDc5NGNiYzU3ODIyN2NmZDViZGVlYTQwNjcyNzhhYmI2N2ZiNzUxYTg1MzBkZDBhNGFkNDgyN2U1ZjU0MmFjZjY4OWE5N2Y="
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// "begin_block": {}
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// {
|
||||
// "code": 1,
|
||||
// "codespace": "ibc",
|
||||
// "log": "not enough gas",
|
||||
// "gas_wanted": 1,
|
||||
// "gas_used": 2,
|
||||
// },
|
||||
// ],
|
||||
// "begin_block_events": null,
|
||||
// "end_block_events": null,
|
||||
// "validator_updates": null,
|
||||
// "consensus_param_updates": null,
|
||||
// }
|
||||
//}
|
||||
// ```
|
||||
func BlockResults(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultBlockResults, error) {
|
||||
storeHeight := blockStore.Height()
|
||||
@@ -396,11 +412,14 @@ func BlockResults(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultBlockR
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := &ctypes.ResultBlockResults{
|
||||
Height: height,
|
||||
Results: results,
|
||||
}
|
||||
return res, nil
|
||||
return &ctypes.ResultBlockResults{
|
||||
Height: height,
|
||||
TxsResults: results.DeliverTxs,
|
||||
BeginBlockEvents: results.BeginBlock.Events,
|
||||
EndBlockEvents: results.EndBlock.Events,
|
||||
ValidatorUpdates: results.EndBlock.ValidatorUpdates,
|
||||
ConsensusParamUpdates: results.EndBlock.ConsensusParamUpdates,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getHeight(currentHeight int64, heightPtr *int64) (int64, error) {
|
||||
|
@@ -4,11 +4,18 @@ import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
rpctypes "github.com/tendermint/tendermint/rpc/lib/types"
|
||||
sm "github.com/tendermint/tendermint/state"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
dbm "github.com/tendermint/tm-cmn/db"
|
||||
)
|
||||
|
||||
func TestBlockchainInfo(t *testing.T) {
|
||||
|
||||
cases := []struct {
|
||||
min, max int64
|
||||
height int64
|
||||
@@ -54,5 +61,61 @@ func TestBlockchainInfo(t *testing.T) {
|
||||
require.Equal(t, 1+max-min, c.resultLength, caseString)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestBlockResults(t *testing.T) {
|
||||
results := &sm.ABCIResponses{
|
||||
DeliverTxs: []*abci.ResponseDeliverTx{
|
||||
{Code: 0, Data: []byte{0x01}, Log: "ok"},
|
||||
{Code: 0, Data: []byte{0x02}, Log: "ok"},
|
||||
{Code: 1, Log: "not ok"},
|
||||
},
|
||||
EndBlock: &abci.ResponseEndBlock{},
|
||||
BeginBlock: &abci.ResponseBeginBlock{},
|
||||
}
|
||||
|
||||
stateDB = dbm.NewMemDB()
|
||||
sm.SaveABCIResponses(stateDB, 100, results)
|
||||
blockStore = mockBlockStore{height: 100}
|
||||
|
||||
testCases := []struct {
|
||||
height int64
|
||||
wantErr bool
|
||||
wantRes *ctypes.ResultBlockResults
|
||||
}{
|
||||
{-1, true, nil},
|
||||
{0, true, nil},
|
||||
{101, true, nil},
|
||||
{100, false, &ctypes.ResultBlockResults{
|
||||
Height: 100,
|
||||
TxsResults: results.DeliverTxs,
|
||||
BeginBlockEvents: results.BeginBlock.Events,
|
||||
EndBlockEvents: results.EndBlock.Events,
|
||||
ValidatorUpdates: results.EndBlock.ValidatorUpdates,
|
||||
ConsensusParamUpdates: results.EndBlock.ConsensusParamUpdates,
|
||||
}},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
res, err := BlockResults(&rpctypes.Context{}, &tc.height)
|
||||
if tc.wantErr {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tc.wantRes, res)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type mockBlockStore struct {
|
||||
height int64
|
||||
}
|
||||
|
||||
func (store mockBlockStore) Height() int64 { return store.height }
|
||||
func (mockBlockStore) LoadBlockMeta(height int64) *types.BlockMeta { return nil }
|
||||
func (mockBlockStore) LoadBlock(height int64) *types.Block { return nil }
|
||||
func (mockBlockStore) LoadBlockPart(height int64, index int) *types.Part { return nil }
|
||||
func (mockBlockStore) LoadBlockCommit(height int64) *types.Commit { return nil }
|
||||
func (mockBlockStore) LoadSeenCommit(height int64) *types.Commit { return nil }
|
||||
func (mockBlockStore) SaveBlock(block *types.Block, blockParts *types.PartSet, seenCommit *types.Commit) {
|
||||
}
|
||||
|
@@ -9,7 +9,6 @@ import (
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
|
||||
"github.com/tendermint/tendermint/p2p"
|
||||
"github.com/tendermint/tendermint/state"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
@@ -38,8 +37,12 @@ type ResultCommit struct {
|
||||
|
||||
// ABCI results from a block
|
||||
type ResultBlockResults struct {
|
||||
Height int64 `json:"height"`
|
||||
Results *state.ABCIResponses `json:"results"`
|
||||
Height int64 `json:"height"`
|
||||
TxsResults []*abci.ResponseDeliverTx `json:"txs_results"`
|
||||
BeginBlockEvents []abci.Event `json:"begin_block_events"`
|
||||
EndBlockEvents []abci.Event `json:"end_block_events"`
|
||||
ValidatorUpdates []abci.ValidatorUpdate `json:"validator_updates"`
|
||||
ConsensusParamUpdates *abci.ConsensusParams `json:"consensus_param_updates"`
|
||||
}
|
||||
|
||||
// NewResultCommit is a helper to initialize the ResultCommit with
|
||||
|
@@ -131,7 +131,7 @@ func (blockExec *BlockExecutor) ApplyBlock(state State, blockID types.BlockID, b
|
||||
fail.Fail() // XXX
|
||||
|
||||
// Save the results before we commit.
|
||||
saveABCIResponses(blockExec.db, block.Height, abciResponses)
|
||||
SaveABCIResponses(blockExec.db, block.Height, abciResponses)
|
||||
|
||||
fail.Fail() // XXX
|
||||
|
||||
@@ -156,7 +156,7 @@ func (blockExec *BlockExecutor) ApplyBlock(state State, blockID types.BlockID, b
|
||||
}
|
||||
|
||||
// Lock mempool, commit app state, update mempoool.
|
||||
appHash, err := blockExec.Commit(state, block, abciResponses.DeliverTx)
|
||||
appHash, err := blockExec.Commit(state, block, abciResponses.DeliverTxs)
|
||||
if err != nil {
|
||||
return state, fmt.Errorf("Commit failed for application: %v", err)
|
||||
}
|
||||
@@ -261,7 +261,7 @@ func execBlockOnProxyApp(
|
||||
logger.Debug("Invalid tx", "code", txRes.Code, "log", txRes.Log)
|
||||
invalidTxs++
|
||||
}
|
||||
abciResponses.DeliverTx[txIndex] = txRes
|
||||
abciResponses.DeliverTxs[txIndex] = txRes
|
||||
txIndex++
|
||||
}
|
||||
}
|
||||
@@ -463,7 +463,7 @@ func fireEvents(logger log.Logger, eventBus types.BlockEventPublisher, block *ty
|
||||
Height: block.Height,
|
||||
Index: uint32(i),
|
||||
Tx: tx,
|
||||
Result: *(abciResponses.DeliverTx[i]),
|
||||
Result: *(abciResponses.DeliverTxs[i]),
|
||||
}})
|
||||
}
|
||||
|
||||
|
@@ -43,12 +43,6 @@ func CalcValidatorsKey(height int64) []byte {
|
||||
return calcValidatorsKey(height)
|
||||
}
|
||||
|
||||
// SaveABCIResponses is an alias for the private saveABCIResponses method in
|
||||
// store.go, exported exclusively and explicitly for testing.
|
||||
func SaveABCIResponses(db dbm.DB, height int64, abciResponses *ABCIResponses) {
|
||||
saveABCIResponses(db, height, abciResponses)
|
||||
}
|
||||
|
||||
// SaveConsensusParamsInfo is an alias for the private saveConsensusParamsInfo
|
||||
// method in store.go, exported exclusively and explicitly for testing.
|
||||
func SaveConsensusParamsInfo(db dbm.DB, nextHeight, changeHeight int64, params types.ConsensusParams) {
|
||||
|
@@ -92,8 +92,8 @@ func TestABCIResponsesSaveLoad1(t *testing.T) {
|
||||
// Build mock responses.
|
||||
block := makeBlock(state, 2)
|
||||
abciResponses := sm.NewABCIResponses(block)
|
||||
abciResponses.DeliverTx[0] = &abci.ResponseDeliverTx{Data: []byte("foo"), Events: nil}
|
||||
abciResponses.DeliverTx[1] = &abci.ResponseDeliverTx{Data: []byte("bar"), Log: "ok", Events: nil}
|
||||
abciResponses.DeliverTxs[0] = &abci.ResponseDeliverTx{Data: []byte("foo"), Events: nil}
|
||||
abciResponses.DeliverTxs[1] = &abci.ResponseDeliverTx{Data: []byte("bar"), Log: "ok", Events: nil}
|
||||
abciResponses.EndBlock = &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{
|
||||
types.TM2PB.NewValidatorUpdate(ed25519.GenPrivKey().PubKey(), 10),
|
||||
}}
|
||||
@@ -162,7 +162,7 @@ func TestABCIResponsesSaveLoad2(t *testing.T) {
|
||||
for i, tc := range cases {
|
||||
h := int64(i + 1) // last block height, one below what we save
|
||||
responses := &sm.ABCIResponses{
|
||||
DeliverTx: tc.added,
|
||||
DeliverTxs: tc.added,
|
||||
EndBlock: &abci.ResponseEndBlock{},
|
||||
}
|
||||
sm.SaveABCIResponses(stateDB, h, responses)
|
||||
|
@@ -115,9 +115,9 @@ func saveState(db dbm.DB, state State, key []byte) {
|
||||
// of the various ABCI calls during block processing.
|
||||
// It is persisted to disk for each height before calling Commit.
|
||||
type ABCIResponses struct {
|
||||
DeliverTx []*abci.ResponseDeliverTx `json:"deliver_tx"`
|
||||
EndBlock *abci.ResponseEndBlock `json:"end_block"`
|
||||
BeginBlock *abci.ResponseBeginBlock `json:"begin_block"`
|
||||
DeliverTxs []*abci.ResponseDeliverTx
|
||||
EndBlock *abci.ResponseEndBlock
|
||||
BeginBlock *abci.ResponseBeginBlock
|
||||
}
|
||||
|
||||
// NewABCIResponses returns a new ABCIResponses
|
||||
@@ -128,7 +128,7 @@ func NewABCIResponses(block *types.Block) *ABCIResponses {
|
||||
resDeliverTxs = nil
|
||||
}
|
||||
return &ABCIResponses{
|
||||
DeliverTx: resDeliverTxs,
|
||||
DeliverTxs: resDeliverTxs,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ func (arz *ABCIResponses) Bytes() []byte {
|
||||
}
|
||||
|
||||
func (arz *ABCIResponses) ResultsHash() []byte {
|
||||
results := types.NewResults(arz.DeliverTx)
|
||||
results := types.NewResults(arz.DeliverTxs)
|
||||
return results.Hash()
|
||||
}
|
||||
|
||||
@@ -165,8 +165,9 @@ func LoadABCIResponses(db dbm.DB, height int64) (*ABCIResponses, error) {
|
||||
|
||||
// SaveABCIResponses persists the ABCIResponses to the database.
|
||||
// This is useful in case we crash after app.Commit and before s.Save().
|
||||
// Responses are indexed by height so they can also be loaded later to produce Merkle proofs.
|
||||
func saveABCIResponses(db dbm.DB, height int64, abciResponses *ABCIResponses) {
|
||||
// Responses are indexed by height so they can also be loaded later to produce
|
||||
// Merkle proofs.
|
||||
func SaveABCIResponses(db dbm.DB, height int64, abciResponses *ABCIResponses) {
|
||||
db.SetSync(calcABCIResponsesKey(height), abciResponses.Bytes())
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user