tendermint / tmkms

Key Management service for Tendermint Validator nodes
Apache License 2.0
142 stars 42 forks source link

Off By One Error when Chain Height is 1 #369

Closed olwee closed 4 years ago

olwee commented 5 years ago

Versions Tested: Current Master (b361d1584f080807118b50059b08bd1cb1e35b43) , Commits that must be included:

Author: Tony Arcieri <tony@iqlusion.io>
Date:   Fri Aug 9 11:40:14 2019 -0700

    Double signing detection and logging improvements

Description:

tmkms creates a blank file (priv_valdiator_state.json) when no such file is present. Contents: {"height":"1","round":"0","step":0,"block_id": null}

When a request for SignProposal is sent to tmkms ( It has a step of 0 ), tmkms checks the current state file for step and finds 0, which is the int for SignProposal This gives the following error:

09:24:12 [debug] [kava-1:tcp://127.0.0.1:16659] received request: SignProposal(SignProposalRequest { proposal: Some(Proposal { msg_type: 32, height: 1, round: 0, pol_round: -1, block_id: So
me(BlockId { hash: [211, 198, 91, 105, 3, 45, 180, 184, 18, 16, 221, 97, 228, 189, 182, 173, 88, 209, 89, 239, 195, 50, 208, 156, 80, 195, 124, 27, 213, 108, 24, 22], parts_header: Some(Par
tsSetHeader { total: 1, hash: [157, 81, 158, 121, 219, 21, 93, 200, 231, 106, 44, 147, 60, 245, 37, 205, 142, 214, 77, 222, 162, 215, 63, 150, 83, 179, 161, 89, 95, 0, 78, 12] }) }), timest
amp: Some(TimeMsg { seconds: 1573464252, nanos: 665958616 }), signature: [] }) })
09:24:12 [error] [kava-1:tcp://127.0.0.1:16659] attempted double sign Proposal at h/r/s: 1/0/0 (<nil> != D3C65B6903)
09:24:12 [debug] [kava-1:tcp://127.0.0.1:16659] sending response: SignedProposal(SignedProposalResponse { proposal: None, err: Some(RemoteError { code: 2, description: "double signing reque
sted at height: 1" }) })

Fix: It should create a blank file with step - 1 Contents: {"height":"1","round":"0","step":-1,"block_id": null}

tarcieri commented 5 years ago

-1 is not a valid step value according to the KMS's current interpretation of these values:

https://github.com/tendermint/kms/blob/b361d15/src/session.rs#L252

If the issue is the block_id being assigned a value at h/r/s 1/0/0 and therefore triggering the double signing detection logic, I think the better solution would be to only write out the initial state file after signing an initial proposal/vote, rather than initializing it to an (otherwise invalid) default value.

olwee commented 5 years ago

Sounds like a better idea to not write to disk until it signs something if it does not find an existing state file.

tarcieri commented 4 years ago

FYI, I implemented a fix closer to what @olwee originally proposed on #373 (now using a default block height of 0)