Implementation spec of Double Signing Risk Reduction [ADR-51](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-051-double-signing-risk-reduction.md) by B-Harvest - Add `DoubleSignCheckHeight` config variable to ConsensusConfig for "How many blocks looks back to check existence of the node's consensus votes when before joining consensus" - Add `consensus.double_sign_check_height` to `config.toml` and `tendermint node` as flag for set `DoubleSignCheckHeight` - Set default `consensus.double_sign_check_height` to `0` ( it could be adjustable in this PR, disable when 0 ) Refs - [ADR-51](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-051-double-signing-risk-reduction.md) - [https://github.com/tendermint/tendermint/issues/4059](https://github.com/tendermint/tendermint/issues/4059) - [https://github.com/tendermint/tendermint/pull/4262](https://github.com/tendermint/tendermint/pull/4262)pull/5297/head
@ -0,0 +1,64 @@ | |||
#! /bin/bash | |||
set -eu | |||
set -o pipefail | |||
IPV=$1 | |||
ID=$2 | |||
ASSERT_CASE=$3 | |||
ASSERT_NODE_UP=1 | |||
ASSERT_NODE_DOWN=0 | |||
MAX_TRY=10 | |||
########################################### | |||
# | |||
# Wait for peer to catchup to other peers | |||
# | |||
########################################### | |||
addr=$(test/p2p/address.sh $IPV $ID 26657) | |||
peerID=$(( $(($ID % 4)) + 1 )) # 1->2 ... 3->4 ... 4->1 | |||
peer_addr=$(test/p2p/address.sh $IPV $peerID 26657) | |||
# get another peer's height | |||
h1=`curl -s $peer_addr/status | jq .result.sync_info.latest_block_height | jq fromjson` | |||
# get another peer's state | |||
root1=`curl -s $peer_addr/status | jq .result.sync_info.latest_app_hash` | |||
echo "Other peer is on height $h1 with state $root1" | |||
echo "Waiting for peer $ID to catch up" | |||
# wait for it to sync to past its previous height | |||
set +e | |||
set +o pipefail | |||
h2="0" | |||
COUNT=0 | |||
while [[ "$h2" -lt "$(($h1+1))" ]]; do | |||
sleep 1 | |||
h2=`curl -s $addr/status --connect-timeout 1 | jq .result.sync_info.latest_block_height | jq fromjson` | |||
COUNT=$((COUNT+1)) | |||
echo "... $h2, try $COUNT" | |||
if [ "$COUNT" -ge "$MAX_TRY" ]; then | |||
if [ $ASSERT_CASE -eq $ASSERT_NODE_DOWN ]; then | |||
echo "double sign risk reduction operates normally as expected" | |||
fi | |||
if [ $ASSERT_CASE -eq $ASSERT_NODE_UP ]; then | |||
echo "double sign risk reduction fail" | |||
exit 1 | |||
fi | |||
break | |||
fi | |||
done | |||
if [ $ASSERT_CASE -eq $ASSERT_NODE_UP ]; then | |||
# check the app hash | |||
root2=`curl -s $addr/status | jq .result.sync_info.latest_app_hash` | |||
if [[ "$root1" != "$root2" ]]; then | |||
echo "App hash after restart does not match. Got $root2; expected $root1" | |||
exit 1 | |||
fi | |||
echo "... double sign risk reduction test passed" | |||
fi |
@ -0,0 +1,13 @@ | |||
#! /bin/bash | |||
set -eu | |||
DOCKER_IMAGE=$1 | |||
NETWORK_NAME=$2 | |||
IPV=$3 | |||
N=$4 | |||
PROXY_APP=$5 | |||
# run it on each of them | |||
for i in `seq 1 $N`; do | |||
bash test/p2p/dsrr/test_peer.sh $DOCKER_IMAGE $NETWORK_NAME $IPV $i $N $PROXY_APP | |||
done |
@ -0,0 +1,65 @@ | |||
#! /bin/bash | |||
set -eu | |||
set -o pipefail | |||
DOCKER_IMAGE=$1 | |||
NETWORK_NAME=$2 | |||
IPV=$3 | |||
ID=$4 | |||
N=$5 | |||
PROXY_APP=$6 | |||
ASSERT_NODE_UP=1 | |||
ASSERT_NODE_DOWN=0 | |||
###########################s#################################### | |||
# this runs on each peer: | |||
# kill peer | |||
# bring it back online with double_sign_check_height 10 | |||
# wait node is not run by double sign risk reduction | |||
# | |||
# kill peer | |||
# bring it back online with double_sign_check_height 1 | |||
# pass double sign risk reduction, wait for it to sync and check the app hash | |||
# | |||
# kill peer | |||
# bring it back online with double_sign_check_height 0 | |||
# wait for it to sync and check the app hash | |||
############################################################### | |||
echo "Testing double sign risk reduction on node $ID" | |||
# kill peer | |||
set +e | |||
docker rm -vf local_testnet_$ID | |||
set -e | |||
PERSISTENT_PEERS="$(test/p2p/address.sh $IPV 1 26656 $DOCKER_IMAGE)" | |||
for j in `seq 2 $N`; do | |||
PERSISTENT_PEERS="$PERSISTENT_PEERS,$(test/p2p/address.sh $IPV $j 26656 $DOCKER_IMAGE)" | |||
done | |||
# bring it back online with double_sign_check_height 10 | |||
# wait node is not run by double sign risk reduction | |||
DSCH=10 | |||
bash test/p2p/peer.sh $DOCKER_IMAGE $NETWORK_NAME $IPV $ID $PROXY_APP "--p2p.persistent_peers $PERSISTENT_PEERS --p2p.pex --rpc.unsafe --consensus.double_sign_check_height $DSCH" | |||
bash test/p2p/client.sh $DOCKER_IMAGE $NETWORK_NAME $IPV fs_$ID "test/p2p/dsrr/check_peer.sh $IPV $ID $ASSERT_NODE_DOWN" | |||
docker stop local_testnet_$ID | |||
docker rm local_testnet_$ID | |||
# bring it back online with double_sign_check_height 1 | |||
# pass double sign risk reduction, wait for it to sync and check the app hash | |||
DSCH=1 | |||
bash test/p2p/peer.sh $DOCKER_IMAGE $NETWORK_NAME $IPV $ID $PROXY_APP "--p2p.persistent_peers $PERSISTENT_PEERS --p2p.pex --rpc.unsafe --consensus.double_sign_check_height $DSCH" | |||
bash test/p2p/client.sh $DOCKER_IMAGE $NETWORK_NAME $IPV fs_$ID "test/p2p/dsrr/check_peer.sh $IPV $ID $ASSERT_NODE_UP" | |||
docker stop local_testnet_$ID | |||
docker rm local_testnet_$ID | |||
DSCH=0 | |||
# bring it back online with double_sign_check_height 0 | |||
# double sign risk reduction is not activated, wait for it to sync and check the app hash | |||
bash test/p2p/peer.sh $DOCKER_IMAGE $NETWORK_NAME $IPV $ID $PROXY_APP "--p2p.persistent_peers $PERSISTENT_PEERS --p2p.pex --rpc.unsafe --consensus.double_sign_check_height $DSCH" | |||
bash test/p2p/client.sh $DOCKER_IMAGE $NETWORK_NAME $IPV fs_$ID "test/p2p/dsrr/check_peer.sh $IPV $ID $ASSERT_NODE_UP" | |||
echo "" | |||
echo "PASS" | |||
echo "" |