diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index c0e25dec8..34af3432c 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -15,7 +15,7 @@ BREAKING CHANGES: * [genesis] \#2565 `consensus_params.evidence_params.max_age` is now `time.Duration` (nanosecond count) ```json "evidence_params": { - "max_age": "172800000000000" + "max_age": "48h0m0s" } ``` diff --git a/evidence/pool.go b/evidence/pool.go index 3ad715632..97fbd37d7 100644 --- a/evidence/pool.go +++ b/evidence/pool.go @@ -129,7 +129,7 @@ func (evpool *EvidencePool) MarkEvidenceAsCommitted(evidence []types.Evidence, l } // remove committed evidence from the clist - maxAge := evpool.State().ConsensusParams.EvidenceParams.MaxAge + maxAge := evpool.State().ConsensusParams.EvidenceParams.MaxAge.Duration evpool.removeEvidence(blockEvidenceMap, lastBlockTime, maxAge) } diff --git a/evidence/pool_test.go b/evidence/pool_test.go index c3ed569e1..4adb1f8ba 100644 --- a/evidence/pool_test.go +++ b/evidence/pool_test.go @@ -39,7 +39,7 @@ func initializeValidatorState(valAddr []byte, height int64) dbm.DB { LastHeightValidatorsChanged: 1, ConsensusParams: types.ConsensusParams{ EvidenceParams: types.EvidenceParams{ - MaxAge: 1000000, + MaxAge: tmtime.DurationPretty{1000000}, }, }, } diff --git a/state/state_test.go b/state/state_test.go index 3ffbb8f2b..b6bc9e767 100644 --- a/state/state_test.go +++ b/state/state_test.go @@ -13,6 +13,7 @@ import ( "github.com/tendermint/tendermint/crypto/ed25519" cmn "github.com/tendermint/tendermint/libs/common" dbm "github.com/tendermint/tendermint/libs/db" + tmtime "github.com/tendermint/tendermint/types/time" cfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/types" @@ -394,7 +395,7 @@ func makeParams(blockBytes, blockGas int64, evidenceAge time.Duration) types.Con MaxGas: blockGas, }, EvidenceParams: types.EvidenceParams{ - MaxAge: evidenceAge, + MaxAge: tmtime.DurationPretty{evidenceAge}, }, } } diff --git a/state/validation.go b/state/validation.go index 14e4ff9da..38aff6820 100644 --- a/state/validation.go +++ b/state/validation.go @@ -169,7 +169,7 @@ func validateBlock(stateDB dbm.DB, state State, block *types.Block) error { // - it was properly signed by the alleged equivocator func VerifyEvidence(stateDB dbm.DB, state State, evidence types.Evidence) error { evidenceAge := state.LastBlockTime.Sub(evidence.Time()) - maxAge := state.ConsensusParams.EvidenceParams.MaxAge + maxAge := state.ConsensusParams.EvidenceParams.MaxAge.Duration if evidenceAge > maxAge { return fmt.Errorf("Evidence from %v is too old. Expecting evidence no older than %v", evidence.Time(), state.LastBlockTime.Add(-maxAge)) diff --git a/types/params.go b/types/params.go index 85b4cf0e3..858cbd930 100644 --- a/types/params.go +++ b/types/params.go @@ -6,6 +6,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto/tmhash" cmn "github.com/tendermint/tendermint/libs/common" + tmtime "github.com/tendermint/tendermint/types/time" ) const ( @@ -31,7 +32,7 @@ type BlockSize struct { // EvidenceParams determine how we handle evidence of malfeasance type EvidenceParams struct { - MaxAge time.Duration `json:"max_age"` // only accept new evidence more recent than this + MaxAge tmtime.DurationPretty `json:"max_age"` // only accept new evidence more recent than this } // DefaultConsensusParams returns a default ConsensusParams. @@ -53,7 +54,7 @@ func DefaultBlockSize() BlockSize { // DefaultEvidenceParams Params returns a default EvidenceParams. func DefaultEvidenceParams() EvidenceParams { return EvidenceParams{ - MaxAge: 48 * time.Hour, + MaxAge: tmtime.DurationPretty{48 * time.Hour}, } } @@ -74,9 +75,9 @@ func (params *ConsensusParams) Validate() error { params.BlockSize.MaxGas) } - if params.EvidenceParams.MaxAge <= 0 { + if params.EvidenceParams.MaxAge.Duration <= 0 { return cmn.NewError("EvidenceParams.MaxAge must be greater than 0. Got %d", - params.EvidenceParams.MaxAge) + params.EvidenceParams.MaxAge.Duration) } return nil @@ -111,7 +112,7 @@ func (params ConsensusParams) Update(params2 *abci.ConsensusParams) ConsensusPar res.BlockSize.MaxGas = params2.BlockSize.MaxGas } if params2.EvidenceParams != nil { - res.EvidenceParams.MaxAge = params2.EvidenceParams.MaxAge + res.EvidenceParams.MaxAge = tmtime.DurationPretty{params2.EvidenceParams.MaxAge} } return res } diff --git a/types/params_test.go b/types/params_test.go index 5491c3464..c16c44b8f 100644 --- a/types/params_test.go +++ b/types/params_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/assert" abci "github.com/tendermint/tendermint/abci/types" + tmtime "github.com/tendermint/tendermint/types/time" ) func TestConsensusParamsValidation(t *testing.T) { @@ -44,7 +45,7 @@ func makeParams(blockBytes, blockGas int64, evidenceAge time.Duration) Consensus MaxGas: blockGas, }, EvidenceParams: EvidenceParams{ - MaxAge: evidenceAge, + MaxAge: tmtime.DurationPretty{evidenceAge}, }, } } diff --git a/types/protobuf.go b/types/protobuf.go index 332a23dc0..6d5add70a 100644 --- a/types/protobuf.go +++ b/types/protobuf.go @@ -9,6 +9,7 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/secp256k1" + tmtime "github.com/tendermint/tendermint/types/time" ) //------------------------------------------------------- @@ -119,7 +120,7 @@ func (tm2pb) ConsensusParams(params *ConsensusParams) *abci.ConsensusParams { MaxGas: params.BlockSize.MaxGas, }, EvidenceParams: &abci.EvidenceParams{ - MaxAge: params.EvidenceParams.MaxAge, + MaxAge: params.EvidenceParams.MaxAge.Duration, }, } } @@ -219,7 +220,7 @@ func (pb2tm) ConsensusParams(csp *abci.ConsensusParams) ConsensusParams { } } if csp.EvidenceParams != nil { - params.EvidenceParams.MaxAge = csp.EvidenceParams.MaxAge + params.EvidenceParams.MaxAge = tmtime.DurationPretty{csp.EvidenceParams.MaxAge} } return params diff --git a/types/protobuf_test.go b/types/protobuf_test.go index f8682abf8..32b5417f7 100644 --- a/types/protobuf_test.go +++ b/types/protobuf_test.go @@ -68,7 +68,7 @@ func TestABCIValidators(t *testing.T) { func TestABCIConsensusParams(t *testing.T) { cp := DefaultConsensusParams() - cp.EvidenceParams.MaxAge = 0 // TODO add this to ABCI + cp.EvidenceParams.MaxAge.Duration = 0 // TODO add this to ABCI abciCP := TM2PB.ConsensusParams(cp) cp2 := PB2TM.ConsensusParams(abciCP) diff --git a/types/time/duration.go b/types/time/duration.go new file mode 100644 index 000000000..3df174302 --- /dev/null +++ b/types/time/duration.go @@ -0,0 +1,41 @@ +package time + +import ( + "encoding/json" + "errors" + "time" +) + +// DurationPretty is a wrapper around time.Duration implementing custom +// marshaller/unmarshaller which make it pretty (e.g. "10s", not +// "10000000000"). +type DurationPretty struct { + time.Duration +} + +// MarshalJSON implements json.Marshaller. +func (d DurationPretty) MarshalJSON() ([]byte, error) { + return json.Marshal(d.String()) +} + +// UnmarshalJSON implements json.Unmarshaller. +func (d *DurationPretty) UnmarshalJSON(b []byte) error { + var v interface{} + if err := json.Unmarshal(b, &v); err != nil { + return err + } + switch value := v.(type) { + case float64: + d.Duration = time.Duration(value) + return nil + case string: + var err error + d.Duration, err = time.ParseDuration(value) + if err != nil { + return err + } + return nil + default: + return errors.New("invalid duration") + } +}