rpc: /block_results fix docs + write test + restructure response (#3615)

BREAKING

Example response:

```json
{
  "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
  }
}
```

Old result consisted of ABCIResponses struct and height. Exposing
internal ABCI structures (which we store in state package) in RPC seems
bad to me for the following reasons:

1) high risk of breaking the API when somebody changes internal structs
(HAPPENED HERE!)
2) RPC is aware of ABCI, which I'm not sure we want
This commit is contained in:
Anton Kaliaev
2019-11-14 13:34:35 +04:00
committed by GitHub
parent 7bc5e1aa00
commit 59da313bc0
13 changed files with 288 additions and 91 deletions

View File

@@ -138,7 +138,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
@@ -163,7 +163,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)
}
@@ -267,7 +267,7 @@ func execBlockOnProxyApp(
logger.Debug("Invalid tx", "code", txRes.Code, "log", txRes.Log)
invalidTxs++
}
abciResponses.DeliverTx[txIndex] = txRes
abciResponses.DeliverTxs[txIndex] = txRes
txIndex++
}
}
@@ -475,7 +475,7 @@ func fireEvents(
Height: block.Height,
Index: uint32(i),
Tx: tx,
Result: *(abciResponses.DeliverTx[i]),
Result: *(abciResponses.DeliverTxs[i]),
}})
}

View File

@@ -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) {

View File

@@ -89,8 +89,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),
}}
@@ -158,7 +158,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)

View File

@@ -115,7 +115,7 @@ 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"`
DeliverTxs []*abci.ResponseDeliverTx `json:"deliver_txs"`
EndBlock *abci.ResponseEndBlock `json:"end_block"`
BeginBlock *abci.ResponseBeginBlock `json:"begin_block"`
}
@@ -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,11 @@ 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.
//
// Exposed for testing.
func SaveABCIResponses(db dbm.DB, height int64, abciResponses *ABCIResponses) {
db.SetSync(calcABCIResponsesKey(height), abciResponses.Bytes())
}