Revision df3eee455c9d2a4a9698a35aa0dfe6d5d2efd53d authored by Callum Waters on 04 February 2020, 12:02:20 UTC, committed by GitHub on 04 February 2020, 12:02:20 UTC
Closes issue #4338 Uses a wrapper function around both the signedHeader and validatorSet calls to the primary provider which attempts to retrieve the information 5 times before deeming the provider unavailable and replacing the primary provider with the first alternative before trying recursively again (until all alternatives are depleted) Employs a mutex lock for any operations involving the providers of the light client to ensure no operations occurs whilst the new primary is chosen. Commits: * created swapProvider function * eliminates old primary provider after replacement. Uses a mutex when changing providers * renamed to replaceProvider * created wrapped functions for signed header and val set * created test for primary provider replacement * implemented suggested revisions * created Witnesses() and Primary() * modified backoffAndJitterTime * modified backoffAndJitterTime * changed backoff base and jitter to functional arguments * implemented suggested changes * removed backoff function * changed exp function to match go version * halved the backoff time * removed seeding and added comments * fixed incorrect test * extract backoff timeout calc into a function Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
1 parent 9b9f1be
pool_test.go
package evidence
import (
"os"
"sync"
"testing"
"time"
"github.com/stretchr/testify/assert"
sm "github.com/tendermint/tendermint/state"
"github.com/tendermint/tendermint/types"
tmtime "github.com/tendermint/tendermint/types/time"
dbm "github.com/tendermint/tm-db"
)
func TestMain(m *testing.M) {
types.RegisterMockEvidences(cdc)
code := m.Run()
os.Exit(code)
}
func initializeValidatorState(valAddr []byte, height int64) dbm.DB {
stateDB := dbm.NewMemDB()
// create validator set and state
valSet := &types.ValidatorSet{
Validators: []*types.Validator{
{Address: valAddr},
},
}
state := sm.State{
LastBlockHeight: 0,
LastBlockTime: tmtime.Now(),
Validators: valSet,
NextValidators: valSet.CopyIncrementProposerPriority(1),
LastHeightValidatorsChanged: 1,
ConsensusParams: types.ConsensusParams{
Evidence: types.EvidenceParams{
MaxAgeNumBlocks: 10000,
MaxAgeDuration: 48 * time.Hour,
},
},
}
// save all states up to height
for i := int64(0); i < height; i++ {
state.LastBlockHeight = i
sm.SaveState(stateDB, state)
}
return stateDB
}
func TestEvidencePool(t *testing.T) {
var (
valAddr = []byte("val1")
height = int64(5)
stateDB = initializeValidatorState(valAddr, height)
evidenceDB = dbm.NewMemDB()
pool = NewPool(stateDB, evidenceDB)
evidenceTime = time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)
)
goodEvidence := types.NewMockEvidence(height, time.Now(), 0, valAddr)
badEvidence := types.NewMockEvidence(height, evidenceTime, 0, valAddr)
// bad evidence
err := pool.AddEvidence(badEvidence)
assert.NotNil(t, err)
// err: evidence created at 2019-01-01 00:00:00 +0000 UTC has expired. Evidence can not be older than: ...
var wg sync.WaitGroup
wg.Add(1)
go func() {
<-pool.EvidenceWaitChan()
wg.Done()
}()
err = pool.AddEvidence(goodEvidence)
assert.Nil(t, err)
wg.Wait()
assert.Equal(t, 1, pool.evidenceList.Len())
// if we send it again, it shouldnt change the size
err = pool.AddEvidence(goodEvidence)
assert.Nil(t, err)
assert.Equal(t, 1, pool.evidenceList.Len())
}
func TestEvidencePoolIsCommitted(t *testing.T) {
// Initialization:
var (
valAddr = []byte("validator_address")
height = int64(42)
lastBlockTime = time.Now()
stateDB = initializeValidatorState(valAddr, height)
evidenceDB = dbm.NewMemDB()
pool = NewPool(stateDB, evidenceDB)
)
// evidence not seen yet:
evidence := types.NewMockEvidence(height, time.Now(), 0, valAddr)
assert.False(t, pool.IsCommitted(evidence))
// evidence seen but not yet committed:
assert.NoError(t, pool.AddEvidence(evidence))
assert.False(t, pool.IsCommitted(evidence))
// evidence seen and committed:
pool.MarkEvidenceAsCommitted(height, lastBlockTime, []types.Evidence{evidence})
assert.True(t, pool.IsCommitted(evidence))
}
func TestAddEvidence(t *testing.T) {
var (
valAddr = []byte("val1")
height = int64(100002)
stateDB = initializeValidatorState(valAddr, height)
evidenceDB = dbm.NewMemDB()
pool = NewPool(stateDB, evidenceDB)
evidenceTime = time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)
)
testCases := []struct {
evHeight int64
evTime time.Time
expErr bool
evDescription string
}{
{height, time.Now(), false, "valid evidence"},
{height, evidenceTime, true, "evidence created at 2019-01-01 00:00:00 +0000 UTC has expired"},
{int64(1), time.Now(), true, "evidence from height 1 is too old"},
{int64(1), evidenceTime, true,
"evidence from height 1 is too old & evidence created at 2019-01-01 00:00:00 +0000 UTC has expired"},
}
for _, tc := range testCases {
tc := tc
ev := types.NewMockEvidence(tc.evHeight, tc.evTime, 0, valAddr)
err := pool.AddEvidence(ev)
if tc.expErr {
assert.Error(t, err)
}
}
}
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...