Merge pull request #746 from srmo/701-add-dev-docs-in-java

701 add dev docs in java
This commit is contained in:
Zach 2017-10-15 11:02:36 -04:00 committed by GitHub
commit 4c1f1e4e57
4 changed files with 342 additions and 70 deletions

View File

@ -0,0 +1,17 @@
.toggle {
padding-bottom: 1em ;
}
.toggle .header {
display: block;
clear: both;
cursor: pointer;
}
.toggle .header:after {
content: " ▼";
}
.toggle .header.open:after {
content: " ▲";
}

10
docs/_static/custom_collapsible_code.js vendored Normal file
View File

@ -0,0 +1,10 @@
let makeCodeBlocksCollapsible = function() {
$(".toggle > *").hide();
$(".toggle .header").show();
$(".toggle .header").click(function() {
$(this).parent().children().not(".header").toggle({"duration": 400});
$(this).parent().children(".header").toggleClass("open");
});
};
// we could use the }(); way if we would have access to jQuery in HEAD, i.e. we would need to force the theme
// to load jQuery before our custom scripts

20
docs/_templates/layout.html vendored Normal file
View File

@ -0,0 +1,20 @@
{% extends "!layout.html" %}
{% set css_files = css_files + ["_static/custom_collapsible_code.css"] %}
# sadly, I didn't find a css style way to add custom JS to a list that is automagically added to head like CSS (above) #}
{% block extrahead %}
<script type="text/javascript" src="_static/custom_collapsible_code.js"></script>
{% endblock %}
{% block footer %}
<script type="text/javascript">
$(document).ready(function() {
// using this approach as we don't have access to the jQuery selectors
// when executing the function on load in HEAD
makeCodeBlocksCollapsible();
});
</script>
{% endblock %}

View File

@ -194,12 +194,38 @@ through all transactions in the mempool, removing any that were included
in the block, and re-run the rest using CheckTx against the post-Commit in the block, and re-run the rest using CheckTx against the post-Commit
mempool state. mempool state.
:: .. container:: toggle
.. container:: header
**Show/Hide Go Example**
.. code-block:: go
func (app *DummyApplication) CheckTx(tx []byte) types.Result { func (app *DummyApplication) CheckTx(tx []byte) types.Result {
return types.OK return types.OK
} }
.. container:: toggle
.. container:: header
**Show/Hide Java Example**
.. code-block:: java
ResponseCheckTx requestCheckTx(RequestCheckTx req) {
byte[] transaction = req.getTx().toByteArray();
// validate transaction
if (notValid) {
return ResponseCheckTx.newBuilder().setCode(CodeType.BadNonce).setLog("invalid tx").build();
} else {
return ResponseCheckTx.newBuilder().setCode(CodeType.OK).build();
}
}
Consensus Connection Consensus Connection
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~
@ -228,7 +254,13 @@ The block header will be updated (TODO) to include some commitment to
the results of DeliverTx, be it a bitarray of non-OK transactions, or a the results of DeliverTx, be it a bitarray of non-OK transactions, or a
merkle root of the data returned by the DeliverTx requests, or both. merkle root of the data returned by the DeliverTx requests, or both.
:: .. container:: toggle
.. container:: header
**Show/Hide Go Example**
.. code-block:: go
// tx is either "key=value" or just arbitrary bytes // tx is either "key=value" or just arbitrary bytes
func (app *DummyApplication) DeliverTx(tx []byte) types.Result { func (app *DummyApplication) DeliverTx(tx []byte) types.Result {
@ -241,6 +273,30 @@ merkle root of the data returned by the DeliverTx requests, or both.
return types.OK return types.OK
} }
.. container:: toggle
.. container:: header
**Show/Hide Java Example**
.. code-block:: java
/**
* Using Protobuf types from the protoc compiler, we always start with a byte[]
*/
ResponseDeliverTx deliverTx(RequestDeliverTx request) {
byte[] transaction = request.getTx().toByteArray();
// validate your transaction
if (notValid) {
return ResponseDeliverTx.newBuilder().setCode(CodeType.BadNonce).setLog("transaction was invalid").build();
} else {
ResponseDeliverTx.newBuilder().setCode(CodeType.OK).build();
}
}
Commit Commit
^^^^^^ ^^^^^^
@ -263,13 +319,36 @@ It is expected that the app will persist state to disk on Commit. The
option to have all transactions replayed from some previous block is the option to have all transactions replayed from some previous block is the
job of the `Handshake <#handshake>`__. job of the `Handshake <#handshake>`__.
:: .. container:: toggle
.. container:: header
**Show/Hide Go Example**
.. code-block:: go
func (app *DummyApplication) Commit() types.Result { func (app *DummyApplication) Commit() types.Result {
hash := app.state.Hash() hash := app.state.Hash()
return types.NewResultOK(hash, "") return types.NewResultOK(hash, "")
} }
.. container:: toggle
.. container:: header
**Show/Hide Java Example**
.. code-block:: java
ResponseCommit requestCommit(RequestCommit requestCommit) {
// update the internal app-state
byte[] newAppState = calculateAppState();
// and return it to the node
return ResponseCommit.newBuilder().setCode(CodeType.OK).setData(ByteString.copyFrom(newAppState)).build();
}
BeginBlock BeginBlock
^^^^^^^^^^ ^^^^^^^^^^
@ -281,7 +360,13 @@ The app should remember the latest height and header (ie. from which it
has run a successful Commit) so that it can tell Tendermint where to has run a successful Commit) so that it can tell Tendermint where to
pick up from when it restarts. See information on the Handshake, below. pick up from when it restarts. See information on the Handshake, below.
:: .. container:: toggle
.. container:: header
**Show/Hide Go Example**
.. code-block:: go
// Track the block hash and header information // Track the block hash and header information
func (app *PersistentDummyApplication) BeginBlock(params types.RequestBeginBlock) { func (app *PersistentDummyApplication) BeginBlock(params types.RequestBeginBlock) {
@ -292,6 +377,29 @@ pick up from when it restarts. See information on the Handshake, below.
app.changes = make([]*types.Validator, 0) app.changes = make([]*types.Validator, 0)
} }
.. container:: toggle
.. container:: header
**Show/Hide Java Example**
.. code-block:: java
/*
* all types come from protobuf definition
*/
ResponseBeginBlock requestBeginBlock(RequestBeginBlock req) {
Header header = req.getHeader();
byte[] prevAppHash = header.getAppHash().toByteArray();
long prevHeight = header.getHeight();
long numTxs = header.getNumTxs();
// run your pre-block logic. Maybe prepare a state snapshot, message components, etc
return ResponseBeginBlock.newBuilder().build();
}
EndBlock EndBlock
^^^^^^^^ ^^^^^^^^
@ -304,13 +412,40 @@ EndBlock response. To remove one, include it in the list with a
validator set. Note validator set changes are only available in v0.8.0 validator set. Note validator set changes are only available in v0.8.0
and up. and up.
:: .. container:: toggle
.. container:: header
**Show/Hide Go Example**
.. code-block:: go
// Update the validator set // Update the validator set
func (app *PersistentDummyApplication) EndBlock(height uint64) (resEndBlock types.ResponseEndBlock) { func (app *PersistentDummyApplication) EndBlock(height uint64) (resEndBlock types.ResponseEndBlock) {
return types.ResponseEndBlock{Diffs: app.changes} return types.ResponseEndBlock{Diffs: app.changes}
} }
.. container:: toggle
.. container:: header
**Show/Hide Java Example**
.. code-block:: java
/*
* Assume that one validator changes. The new validator has a power of 10
*/
ResponseEndBlock requestEndBlock(RequestEndBlock req) {
final long currentHeight = req.getHeight();
final byte[] validatorPubKey = getValPubKey();
ResponseEndBlock.Builder builder = ResponseEndBlock.newBuilder();
builder.addDiffs(1, Types.Validator.newBuilder().setPower(10L).setPubKey(ByteString.copyFrom(validatorPubKey)).build());
return builder.build();
}
Query Connection Query Connection
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
@ -332,7 +467,13 @@ cause Tendermint to not connect to the corresponding peer:
Note: these query formats are subject to change! Note: these query formats are subject to change!
:: .. container:: toggle
.. container:: header
**Show/Hide Go Example**
.. code-block:: go
func (app *DummyApplication) Query(reqQuery types.RequestQuery) (resQuery types.ResponseQuery) { func (app *DummyApplication) Query(reqQuery types.RequestQuery) (resQuery types.ResponseQuery) {
if reqQuery.Prove { if reqQuery.Prove {
@ -360,6 +501,39 @@ Note: these query formats are subject to change!
} }
} }
.. container:: toggle
.. container:: header
**Show/Hide Java Example**
.. code-block:: java
ResponseQuery requestQuery(RequestQuery req) {
final boolean isProveQuery = req.getProve();
final ResponseQuery.Builder responseBuilder = ResponseQuery.newBuilder();
if (isProveQuery) {
com.app.example.ProofResult proofResult = generateProof(req.getData().toByteArray());
final byte[] proofAsByteArray = proofResult.getAsByteArray();
responseBuilder.setProof(ByteString.copyFrom(proofAsByteArray));
responseBuilder.setKey(req.getData());
responseBuilder.setValue(ByteString.copyFrom(proofResult.getData()));
responseBuilder.setLog(result.getLogValue());
} else {
byte[] queryData = req.getData().toByteArray();
final com.app.example.QueryResult result = generateQueryResult(queryData);
responseBuilder.setIndex(result.getIndex());
responseBuilder.setValue(ByteString.copyFrom(result.getValue()));
responseBuilder.setLog(result.getLogValue());
}
return responseBuilder.build();
}
Handshake Handshake
~~~~~~~~~ ~~~~~~~~~
@ -377,12 +551,32 @@ the app are synced to the latest block height.
If the app returns a LastBlockHeight of 0, Tendermint will just replay If the app returns a LastBlockHeight of 0, Tendermint will just replay
all blocks. all blocks.
:: .. container:: toggle
.. container:: header
**Show/Hide Go Example**
.. code-block:: go
func (app *DummyApplication) Info(req types.RequestInfo) (resInfo types.ResponseInfo) { func (app *DummyApplication) Info(req types.RequestInfo) (resInfo types.ResponseInfo) {
return types.ResponseInfo{Data: cmn.Fmt("{\"size\":%v}", app.state.Size())} return types.ResponseInfo{Data: cmn.Fmt("{\"size\":%v}", app.state.Size())}
} }
.. container:: toggle
.. container:: header
**Show/Hide Java Example**
.. code-block:: java
ResponseInfo requestInfo(RequestInfo req) {
final byte[] lastAppHash = getLastAppHash();
final long lastHeight = getLastHeight();
return ResponseInfo.newBuilder().setLastBlockAppHash(ByteString.copyFrom(lastAppHash)).setLastBlockHeight(lastHeight).build();
}
Genesis Genesis
~~~~~~~ ~~~~~~~
@ -390,7 +584,13 @@ Genesis
initial validator set. Later on, it may be extended to take parts of the initial validator set. Later on, it may be extended to take parts of the
consensus params. consensus params.
:: .. container:: toggle
.. container:: header
**Show/Hide Go Example**
.. code-block:: go
// Save the validators in the merkle tree // Save the validators in the merkle tree
func (app *PersistentDummyApplication) InitChain(params types.RequestInitChain) { func (app *PersistentDummyApplication) InitChain(params types.RequestInitChain) {
@ -401,3 +601,28 @@ consensus params.
} }
} }
} }
.. container:: toggle
.. container:: header
**Show/Hide Java Example**
.. code-block:: java
/*
* all types come from protobuf definition
*/
ResponseInitChain requestInitChain(RequestInitChain req) {
final int validatorsCount = req.getValidatorsCount();
final List<Types.Validator> validatorsList = req.getValidatorsList();
validatorsList.forEach((validator) -> {
long power = validator.getPower();
byte[] validatorPubKey = validator.getPubKey().toByteArray();
// do somehing for validator setup in app
});
return ResponseInitChain.newBuilder().build();
}