Upgrade Tendermint to 0.25.0

parent 1eebc798
Pipeline #31054444 passed with stages
in 17 minutes and 38 seconds
......@@ -15,7 +15,7 @@ PROJECT_DESCRIPTION = A simple cryptocurrency using Tendermint
PROJECT_VERSION = 0.1.0
DEPS = abci_server datum dynarec elixir enacl erlsha2 gb_merkle_trees jiffy nist_beacon
dep_abci_server = git https://github.com/KrzysiekJ/abci_server.git v0.7.2
dep_abci_server = git https://github.com/KrzysiekJ/abci_server.git v0.8.0
dep_datum = git https://github.com/fogfish/datum.git 4.3.3
dep_dynarec = git https://github.com/dieswaytoofast/dynarec.git 1f477
dep_elixir = git https://github.com/elixir-lang/elixir.git v1.7.3
......
......@@ -18,7 +18,7 @@ For support and other ephemeral discussions, see [the #ercoin IRC channel on irc
## Development installation
1. Install [Tendermint](https://tendermint.com) (version 0.23.1).
1. Install [Tendermint](https://tendermint.com) (version 0.25.0).
2. Install [Erlang](https://www.erlang.org) (19 is the minimum version).
3. Install [libsodium](https://libsodium.org) (when using a package manager, you may need to install a separate package containing development files).
4. Clone the Ercoin’s repository and enter the created directory.
......@@ -41,7 +41,7 @@ If you want to create a custom initial state, functions exported from the `ercoi
To run the project using [Docker Compose](https://docs.docker.com/compose/):
1. `docker-compose build`
2. `docker run -it --rm -v ercoin_home:/tendermint tendermint/tendermint:0.23.1 init`
2. `docker run -it --rm -v ercoin_home:/tendermint tendermint/tendermint:0.25.0 init`
3. `docker run -it --rm -e ERCOIN_HOME=/ercoin -v ercoin_home:/ercoin ercoin_abci-server:latest /app/dev/bootstrap.sh`
4. `docker-compose up`
......
......@@ -9,7 +9,7 @@ services:
volumes:
- ercoin_home:/ercoin
tendermint:
image: tendermint/tendermint:0.23.1
image: tendermint/tendermint:0.25.0
ports:
- "26656:26656"
- "26657:26657"
......
......@@ -90,14 +90,14 @@ handle_event(
_ ->
Data
end,
{Data2, Diffs} =
Data2 =
%% Drawing of new validators.
if
Stage =:= 0 ->
{Data1#data{validators=FutureValidators, future_validators=undefined}, calculate_diffs(FutureValidators, Validators)};
Data1#data{validators=FutureValidators, future_validators=undefined};
Stage =:= EpochLength div 4 ->
Key = docile_rpc:async_call(node(), ercoin_validators, draw, [Data]),
{Data1#data{future_validators={promise, Key, app_hash(Data)}}, []};
Data1#data{future_validators={promise, Key, app_hash(Data)}};
%% The gap between locking data for the purpose of drawing and yielding the result of drawing gives us some time in case
%% entropy source is down.
Stage =:= EpochLength * 3 div 4 ->
......@@ -105,9 +105,16 @@ handle_event(
%% During normal operation, the result should be already available (some timeout may be needed anyway to deliver it),
%% but when we’re syncing, we may need to wait a bit.
{value, NewFutureValidators} = docile_rpc:nb_yield(Key, 7000),
{Data1#data{future_validators=NewFutureValidators}, []};
Data1#data{future_validators=NewFutureValidators};
true ->
{Data1, []}
Data1
end,
Diffs =
if
Stage =:= EpochLength - 1 ->
calculate_diffs(FutureValidators, Validators);
true ->
[]
end,
NewFreshTxs = lists:dropwhile(fun ({ValidSince, _}) -> ValidSince < NewHeight - EpochLength + 2 end, FreshTxs),
Data3 =
......@@ -122,7 +129,7 @@ handle_event({call, _}, _, committing, _) ->
handle_event(
{call, From},
#'abci.RequestBeginBlock'{
last_commit_info=#'abci.LastCommitInfo'{validators=SigningValidators},
last_commit_info=#'abci.LastCommitInfo'{votes=Votes},
header=#'abci.Header'{time=NewTimestampProto}},
gossiping,
Data=
......@@ -142,7 +149,7 @@ handle_event(
end,
NewValidators =
lists:foldl(
fun (#'abci.SigningValidator'{signed_last_block=Signed, validator=#'abci.Validator'{address=TendermintAddress}}, Acc) ->
fun (#'abci.VoteInfo'{signed_last_block=Signed, validator=#'abci.Validator'{address=TendermintAddress}}, Acc) ->
case Signed of
true ->
Acc;
......@@ -154,7 +161,7 @@ handle_event(
end
end,
Validators,
SigningValidators),
Votes),
NewData =
Data#data{
validators=NewValidators,
......@@ -174,7 +181,7 @@ handle_event(internal, dump_data, gossiping, Data) ->
keep_state_and_data;
handle_event({call, From}, #'abci.RequestInitChain'{app_state_bytes=AppStateJSON}, uninitialized, none) ->
Data = #data{validators=Validators} = binary_to_term(base64:decode(jiffy:decode(AppStateJSON))),
TendermintValidators = [#'abci.Validator'{pub_key=#'abci.PubKey'{data=PK, type="ed25519"}, power=Power} || {PK, <<Power, _/binary>>} <- gb_merkle_trees:to_orddict(Validators)],
TendermintValidators = [#'abci.ValidatorUpdate'{pub_key=#'abci.PubKey'{data=PK, type="ed25519"}, power=Power} || {PK, <<Power, _/binary>>} <- gb_merkle_trees:to_orddict(Validators)],
{next_state, gossiping, Data, {reply, From, #'abci.ResponseInitChain'{validators=TendermintValidators}}};
handle_event({call, From}, #'abci.RequestInfo'{}, uninitialized, _) ->
Reply = #'abci.ResponseInfo'{last_block_height=0, last_block_app_hash= <<>>},
......@@ -188,7 +195,7 @@ handle_event(enter, _, _, _) ->
handle_request(Request) ->
gen_statem:call(?MODULE, Request).
-spec calculate_diffs(gb_merkle_trees:tree(), gb_merkle_trees:tree()) -> list(#'abci.Validator'{}).
-spec calculate_diffs(gb_merkle_trees:tree(), gb_merkle_trees:tree()) -> list(#'abci.ValidatorUpdate'{}).
calculate_diffs(New, Old) ->
KeysFun =
fun (Tree) ->
......@@ -197,11 +204,11 @@ calculate_diffs(New, Old) ->
[],
Tree)
end,
DeletedEntries = [#'abci.Validator'{pub_key=#'abci.PubKey'{data=PK, type="ed25519"}, power=0} || PK <- KeysFun(Old) -- KeysFun(New)],
DeletedEntries = [#'abci.ValidatorUpdate'{pub_key=#'abci.PubKey'{data=PK, type="ed25519"}, power=0} || PK <- KeysFun(Old) -- KeysFun(New)],
NewEntries =
[begin
<<VP, _/binary>> = Value,
#'abci.Validator'{pub_key=#'abci.PubKey'{data=PK, type="ed25519"}, power=VP}
#'abci.ValidatorUpdate'{pub_key=#'abci.PubKey'{data=PK, type="ed25519"}, power=VP}
end || {PK, Value} <- gb_merkle_trees:to_orddict(New) -- gb_merkle_trees:to_orddict(Old)],
NewEntries ++ DeletedEntries.
......
......@@ -23,10 +23,10 @@ end_block(Data) ->
ercoin_abci:handle_event({call, "from"}, #'abci.RequestEndBlock'{}, committing, Data),
NewData.
-spec apply_diffs(list(#'abci.Validator'{}), gb_merkle_trees:tree()) -> gb_merkle_trees:tree().
-spec apply_diffs(list(#'abci.ValidatorUpdate'{}), gb_merkle_trees:tree()) -> gb_merkle_trees:tree().
apply_diffs([], Validators) ->
Validators;
apply_diffs([#'abci.Validator'{power=VP, pub_key=#'abci.PubKey'{data=PubKey, type="ed25519"}}|Diffs], Validators) ->
apply_diffs([#'abci.ValidatorUpdate'{power=VP, pub_key=#'abci.PubKey'{data=PubKey, type="ed25519"}}|Diffs], Validators) ->
NewValidators =
case VP of
0 ->
......@@ -60,7 +60,7 @@ prop_init_chain_sets_data_and_responds_with_validators() ->
uninitialized,
none),
ResponseData =:= Data andalso
ResponseValidators =:= [#'abci.Validator'{power=Power, pub_key=#'abci.PubKey'{data=PK, type="ed25519"}} || {PK, <<Power, _/binary>>} <- gb_merkle_trees:to_orddict(Validators)]
ResponseValidators =:= [#'abci.ValidatorUpdate'{power=Power, pub_key=#'abci.PubKey'{data=PK, type="ed25519"}} || {PK, <<Power, _/binary>>} <- gb_merkle_trees:to_orddict(Validators)]
end).
prop_validators_at_end_block() ->
......@@ -81,13 +81,22 @@ prop_validators_at_end_block() ->
[],
Validators2)
end,
case (Height + 1) rem EpochLength of
0 ->
NewValidators =:= FutureValidators andalso
NormalizationFun(apply_diffs(Diffs, Validators)) =:= NormalizationFun(NewValidators);
_ ->
NewValidators =:= Validators andalso Diffs =:= []
end
ValidatorsOK =
case (Height + 1) rem EpochLength of
0 ->
NewValidators =:= FutureValidators;
_ ->
NewValidators =:= Validators
end,
%% Changes to validator set are delayed by one block, so we need to announce them in advance.
DiffsOK =
case (Height + 2) rem EpochLength of
0 ->
NormalizationFun(apply_diffs(Diffs, Validators)) =:= NormalizationFun(FutureValidators);
_ ->
Diffs =:= []
end,
ValidatorsOK and DiffsOK
end).
prop_future_validators_at_end_block() ->
......@@ -309,7 +318,7 @@ prop_commit_responds_with_app_hash() ->
prop_begin_block_increments_absencies() ->
?FORALL(
{Data, BeginBlock=#'abci.RequestBeginBlock'{last_commit_info=#'abci.LastCommitInfo'{validators=SigningValidators}}},
{Data, BeginBlock=#'abci.RequestBeginBlock'{last_commit_info=#'abci.LastCommitInfo'{votes=Votes}}},
?LET(
Data,
data(),
......@@ -318,7 +327,7 @@ prop_begin_block_increments_absencies() ->
{next_state, committing, #data{validators=ResponseValidators}, {reply, "from", #'abci.ResponseBeginBlock'{}}} =
ercoin_abci:handle_event({call, "from"}, BeginBlock, gossiping, Data),
lists:all(
fun (#'abci.SigningValidator'{signed_last_block=Signed, validator=#'abci.Validator'{address=TendermintAddress}}) ->
fun (#'abci.VoteInfo'{signed_last_block=Signed, validator=#'abci.Validator'{address=TendermintAddress}}) ->
{PK, <<_, Absencies:3/unit:8, _/binary>>} = ercoin_validators:key_value_by_tendermint_address(TendermintAddress, Data),
<<_, ResponseAbsencies:3/unit:8, _/binary>> = gb_merkle_trees:lookup(PK, ResponseValidators),
case Signed of
......@@ -328,7 +337,7 @@ prop_begin_block_increments_absencies() ->
ResponseAbsencies =:= Absencies + 1
end
end,
SigningValidators)
Votes)
end).
prop_begin_block_updates_timestamps() ->
......
......@@ -334,12 +334,12 @@ begin_block(Data=#data{validators=Validators}) ->
{header(Data),
vector(gb_merkle_trees:size(Validators), bool())},
begin
SigningValidators =[#'abci.SigningValidator'{
Votes =[#'abci.VoteInfo'{
signed_last_block=Signed,
validator=#'abci.Validator'{address=ercoin_validators:address_to_tendermint(PK), power=Power}}
|| {{PK, <<Power, _/binary>>}, Signed} <- lists:zip(gb_merkle_trees:to_orddict(Validators), SignedList)],
#'abci.RequestBeginBlock'{
last_commit_info=#'abci.LastCommitInfo'{validators=SigningValidators},
last_commit_info=#'abci.LastCommitInfo'{votes=Votes},
header=Header}
end).
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment