mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
beacon/light/sync: all tests working with new Module interface
This commit is contained in:
parent
7c173fc7a5
commit
426c1fb010
6 changed files with 205 additions and 225 deletions
|
|
@ -17,8 +17,6 @@
|
|||
package sync
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/ethereum/go-ethereum/beacon/light/request"
|
||||
"github.com/ethereum/go-ethereum/beacon/types"
|
||||
)
|
||||
|
|
@ -59,7 +57,6 @@ func NewHeadSync(headTracker headTracker, chain committeeChain) *HeadSync {
|
|||
s := &HeadSync{
|
||||
headTracker: headTracker,
|
||||
chain: chain,
|
||||
nextSyncPeriod: math.MaxUint64,
|
||||
unvalidatedHeads: make(map[request.Server]types.SignedHeader),
|
||||
serverHeads: make(map[request.Server]types.HeadInfo),
|
||||
headServerCount: make(map[types.HeadInfo]headServerCount),
|
||||
|
|
@ -105,6 +102,9 @@ func (s *HeadSync) newSignedHead(server request.Server, signedHead types.SignedH
|
|||
// processUnvalidatedHeads iterates the list of unvalidated heads and validates
|
||||
// those which can be validated.
|
||||
func (s *HeadSync) processUnvalidatedHeads() {
|
||||
if !s.chainInit {
|
||||
return
|
||||
}
|
||||
for server, signedHead := range s.unvalidatedHeads {
|
||||
if types.SyncPeriod(signedHead.SignatureSlot) <= s.nextSyncPeriod {
|
||||
s.headTracker.Validate(signedHead)
|
||||
|
|
|
|||
|
|
@ -19,16 +19,15 @@ package sync
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/beacon/light/request"
|
||||
"github.com/ethereum/go-ethereum/beacon/types"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
)
|
||||
|
||||
var (
|
||||
testServer1 = 1
|
||||
testServer2 = 2
|
||||
testServer3 = 3
|
||||
testServer4 = 4
|
||||
testServer1 = &TestServer{ID: 1}
|
||||
testServer2 = &TestServer{ID: 2}
|
||||
testServer3 = &TestServer{ID: 3}
|
||||
testServer4 = &TestServer{ID: 4}
|
||||
|
||||
testHead0 = types.HeadInfo{}
|
||||
testHead1 = types.HeadInfo{Slot: 123, BlockRoot: common.Hash{1}}
|
||||
|
|
@ -47,93 +46,98 @@ func TestValidatedHead(t *testing.T) {
|
|||
chain := &TestCommitteeChain{}
|
||||
ht := &TestHeadTracker{}
|
||||
headSync := NewHeadSync(ht, chain)
|
||||
ts := NewTestScheduler(t, headSync)
|
||||
|
||||
ht.ExpValidated(t, 0, nil)
|
||||
|
||||
ts.AddServer(testServer1, 1)
|
||||
ts.ServerEvent(EvNewSignedHead, testServer1, testSHead1)
|
||||
ts.Run(1, nil, nil)
|
||||
ht.ExpValidated(t, 1, nil)
|
||||
headSync.Process([]request.Event{
|
||||
{Server: testServer1, Type: request.EvRegistered},
|
||||
{Server: testServer1, Type: EvNewSignedHead, Data: testSHead1},
|
||||
})
|
||||
ht.ExpValidated(t, 2, nil)
|
||||
|
||||
chain.SetNextSyncPeriod(0)
|
||||
headSync.Process(nil)
|
||||
ht.ExpValidated(t, 3, []types.SignedHeader{testSHead1})
|
||||
ts.Run(2, nil, nil)
|
||||
ht.ExpValidated(t, 2, []types.SignedHeader{testSHead1})
|
||||
|
||||
chain.SetNextSyncPeriod(1)
|
||||
headSync.Process([]request.Event{
|
||||
{Server: testServer1, Type: EvNewSignedHead, Data: testSHead2},
|
||||
{Server: testServer2, Type: request.EvRegistered},
|
||||
{Server: testServer2, Type: EvNewSignedHead, Data: testSHead2},
|
||||
})
|
||||
ht.ExpValidated(t, 4, []types.SignedHeader{testSHead2, testSHead2})
|
||||
headSync.Process([]request.Event{
|
||||
{Server: testServer1, Type: EvNewSignedHead, Data: testSHead3},
|
||||
{Server: testServer3, Type: request.EvRegistered},
|
||||
{Server: testServer3, Type: EvNewSignedHead, Data: testSHead4},
|
||||
})
|
||||
ht.ExpValidated(t, 5, nil)
|
||||
ts.ServerEvent(EvNewSignedHead, testServer1, testSHead2)
|
||||
ts.AddServer(testServer2, 1)
|
||||
ts.ServerEvent(EvNewSignedHead, testServer2, testSHead2)
|
||||
ts.Run(3, nil, nil)
|
||||
ht.ExpValidated(t, 3, []types.SignedHeader{testSHead2, testSHead2})
|
||||
|
||||
ts.ServerEvent(EvNewSignedHead, testServer1, testSHead3)
|
||||
ts.AddServer(testServer3, 1)
|
||||
ts.ServerEvent(EvNewSignedHead, testServer3, testSHead4)
|
||||
ts.Run(4, nil, nil)
|
||||
ht.ExpValidated(t, 4, nil)
|
||||
|
||||
chain.SetNextSyncPeriod(2)
|
||||
headSync.Process(nil)
|
||||
ht.ExpValidated(t, 6, []types.SignedHeader{testSHead3})
|
||||
headSync.Process([]request.Event{
|
||||
{Server: testServer3, Type: request.EvUnregistered},
|
||||
})
|
||||
ht.ExpValidated(t, 7, nil)
|
||||
ts.Run(5, nil, nil)
|
||||
ht.ExpValidated(t, 5, []types.SignedHeader{testSHead3})
|
||||
|
||||
ts.RemoveServer(testServer3)
|
||||
ts.Run(6, nil, nil)
|
||||
ht.ExpValidated(t, 6, nil)
|
||||
|
||||
chain.SetNextSyncPeriod(3)
|
||||
headSync.Process(nil)
|
||||
ht.ExpValidated(t, 8, nil)
|
||||
headSync.Process([]request.Event{
|
||||
{Server: testServer2, Type: EvNewSignedHead, Data: testSHead4},
|
||||
})
|
||||
ht.ExpValidated(t, 9, []types.SignedHeader{testSHead4})
|
||||
ts.Run(7, nil, nil)
|
||||
ht.ExpValidated(t, 7, nil)
|
||||
|
||||
ts.ServerEvent(EvNewSignedHead, testServer2, testSHead4)
|
||||
ts.Run(8, nil, nil)
|
||||
ht.ExpValidated(t, 8, []types.SignedHeader{testSHead4})
|
||||
}
|
||||
|
||||
func TestPrefetchHead(t *testing.T) {
|
||||
chain := &TestCommitteeChain{}
|
||||
ht := &TestHeadTracker{}
|
||||
headSync := NewHeadSync(ht, chain)
|
||||
ts := NewTestScheduler(t, headSync)
|
||||
|
||||
ht.ExpPrefetch(t, 1, testHead0) // no servers registered
|
||||
headSync.Process([]request.Event{
|
||||
{Server: testServer1, Type: request.EvRegistered},
|
||||
{Server: testServer1, Type: EvNewHead, Data: testHead1},
|
||||
})
|
||||
ht.ExpPrefetch(t, 2, testHead1) // s1: h1
|
||||
headSync.Process([]request.Event{
|
||||
{Server: testServer2, Type: request.EvRegistered},
|
||||
{Server: testServer2, Type: EvNewHead, Data: testHead2},
|
||||
})
|
||||
ht.ExpPrefetch(t, 3, testHead2) // s1: h1, s2: h2
|
||||
headSync.Process([]request.Event{
|
||||
{Server: testServer1, Type: EvNewHead, Data: testHead2},
|
||||
})
|
||||
ht.ExpPrefetch(t, 4, testHead2) // s1: h2, s2: h2
|
||||
headSync.Process([]request.Event{
|
||||
{Server: testServer3, Type: request.EvRegistered},
|
||||
{Server: testServer3, Type: EvNewHead, Data: testHead3},
|
||||
})
|
||||
ht.ExpPrefetch(t, 5, testHead2) // s1: h2, s2: h2, s3: h3
|
||||
headSync.Process([]request.Event{
|
||||
{Server: testServer4, Type: request.EvRegistered},
|
||||
{Server: testServer4, Type: EvNewHead, Data: testHead4},
|
||||
})
|
||||
ht.ExpPrefetch(t, 6, testHead2) // s1: h2, s2: h2, s3: h3, s4: h4
|
||||
headSync.Process([]request.Event{
|
||||
{Server: testServer2, Type: EvNewHead, Data: testHead3},
|
||||
})
|
||||
ht.ExpPrefetch(t, 7, testHead3) // s1: h2, s2: h3, s3: h3, s4: h4
|
||||
headSync.Process([]request.Event{
|
||||
{Server: testServer3, Type: request.EvUnregistered},
|
||||
})
|
||||
ht.ExpPrefetch(t, 8, testHead4) // s1: h2, s2: h3, s4: h4
|
||||
headSync.Process([]request.Event{
|
||||
{Server: testServer1, Type: request.EvUnregistered},
|
||||
})
|
||||
ht.ExpPrefetch(t, 9, testHead4) // s2: h3, s4: h4
|
||||
headSync.Process([]request.Event{
|
||||
{Server: testServer4, Type: request.EvUnregistered},
|
||||
})
|
||||
ht.ExpPrefetch(t, 10, testHead3) // s2: h3
|
||||
headSync.Process([]request.Event{
|
||||
{Server: testServer2, Type: request.EvUnregistered},
|
||||
})
|
||||
ht.ExpPrefetch(t, 11, testHead0) // no servers registered
|
||||
ht.ExpPrefetch(t, 0, testHead0) // no servers registered
|
||||
|
||||
ts.AddServer(testServer1, 1)
|
||||
ts.ServerEvent(EvNewHead, testServer1, testHead1)
|
||||
ts.Run(1, nil, nil)
|
||||
ht.ExpPrefetch(t, 1, testHead1) // s1: h1
|
||||
|
||||
ts.AddServer(testServer2, 1)
|
||||
ts.ServerEvent(EvNewHead, testServer2, testHead2)
|
||||
ts.Run(2, nil, nil)
|
||||
ht.ExpPrefetch(t, 2, testHead2) // s1: h1, s2: h2
|
||||
|
||||
ts.ServerEvent(EvNewHead, testServer1, testHead2)
|
||||
ts.Run(3, nil, nil)
|
||||
ht.ExpPrefetch(t, 3, testHead2) // s1: h2, s2: h2
|
||||
|
||||
ts.AddServer(testServer3, 1)
|
||||
ts.ServerEvent(EvNewHead, testServer3, testHead3)
|
||||
ts.Run(4, nil, nil)
|
||||
ht.ExpPrefetch(t, 4, testHead2) // s1: h2, s2: h2, s3: h3
|
||||
|
||||
ts.AddServer(testServer4, 1)
|
||||
ts.ServerEvent(EvNewHead, testServer4, testHead4)
|
||||
ts.Run(5, nil, nil)
|
||||
ht.ExpPrefetch(t, 5, testHead2) // s1: h2, s2: h2, s3: h3, s4: h4
|
||||
|
||||
ts.ServerEvent(EvNewHead, testServer2, testHead3)
|
||||
ts.Run(6, nil, nil)
|
||||
ht.ExpPrefetch(t, 6, testHead3) // s1: h2, s2: h3, s3: h3, s4: h4
|
||||
|
||||
ts.RemoveServer(testServer3)
|
||||
ts.Run(7, nil, nil)
|
||||
ht.ExpPrefetch(t, 7, testHead4) // s1: h2, s2: h3, s4: h4
|
||||
|
||||
ts.RemoveServer(testServer1)
|
||||
ts.Run(8, nil, nil)
|
||||
ht.ExpPrefetch(t, 8, testHead4) // s2: h3, s4: h4
|
||||
|
||||
ts.RemoveServer(testServer4)
|
||||
ts.Run(9, nil, nil)
|
||||
ht.ExpPrefetch(t, 9, testHead3) // s2: h3
|
||||
|
||||
ts.RemoveServer(testServer2)
|
||||
ts.Run(10, nil, nil)
|
||||
ht.ExpPrefetch(t, 10, testHead0) // no servers registered
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,14 +62,18 @@ func (ts *TestScheduler) Run(testIndex int, expServer request.Server, expReq req
|
|||
return
|
||||
}
|
||||
if !ok {
|
||||
ts.t.Errorf("Missing request in test case #%d (expected none, got %v)", testIndex, expReqWithID)
|
||||
ts.t.Errorf("Missing request in test case #%d (expected %v, got none)", testIndex, expReqWithID)
|
||||
return
|
||||
}
|
||||
if req != expReqWithID {
|
||||
ts.t.Errorf("Wrong request in test case #%d (expected %v, got %v)", testIndex, req, expReqWithID)
|
||||
ts.t.Errorf("Wrong request in test case #%d (expected %v, got %v)", testIndex, expReqWithID, req)
|
||||
}
|
||||
}
|
||||
|
||||
func (ts *TestScheduler) Request(testIndex int) request.RequestWithID {
|
||||
return ts.sent[testIndex]
|
||||
}
|
||||
|
||||
func (ts *TestScheduler) ServerEvent(evType *request.EventType, server request.Server, data any) {
|
||||
ts.events = append(ts.events, request.Event{
|
||||
Type: evType,
|
||||
|
|
@ -98,6 +102,20 @@ func (ts *TestScheduler) RequestEvent(evType *request.EventType, testIndex int,
|
|||
func (ts *TestScheduler) AddServer(server request.Server, allowance int) {
|
||||
ts.servers = append(ts.servers, server)
|
||||
ts.allowance[server] = allowance
|
||||
ts.ServerEvent(request.EvRegistered, server, nil)
|
||||
}
|
||||
|
||||
func (ts *TestScheduler) RemoveServer(server request.Server) {
|
||||
ts.servers = append(ts.servers, server)
|
||||
for i, s := range ts.servers {
|
||||
if s == server {
|
||||
copy(ts.servers[i:len(ts.servers)-1], ts.servers[i+1:])
|
||||
ts.servers = ts.servers[:len(ts.servers)-1]
|
||||
break
|
||||
}
|
||||
}
|
||||
delete(ts.allowance, server)
|
||||
ts.ServerEvent(request.EvUnregistered, server, nil)
|
||||
}
|
||||
|
||||
func (ts *TestScheduler) AddAllowance(server request.Server, allowance int) {
|
||||
|
|
@ -129,6 +147,7 @@ func (ts *TestScheduler) tryRequest(testIndex int, requestFn func(server request
|
|||
Request: bestReq,
|
||||
}
|
||||
ts.sent[testIndex] = req
|
||||
ts.RequestEvent(request.EvRequest, testIndex, nil)
|
||||
return req, true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,12 +55,12 @@ func NewCheckpointInit(chain committeeChain, checkpointHash common.Hash) *Checkp
|
|||
func (s *CheckpointInit) Process(events []request.Event) {
|
||||
for _, event := range events {
|
||||
if !event.IsRequestEvent() {
|
||||
return
|
||||
continue
|
||||
}
|
||||
sid, req, resp := event.RequestInfo()
|
||||
if event.Type == request.EvRequest {
|
||||
s.locked = sid
|
||||
return
|
||||
continue
|
||||
}
|
||||
if s.locked == sid {
|
||||
s.locked = request.ServerAndID{}
|
||||
|
|
|
|||
|
|
@ -33,41 +33,30 @@ func TestCheckpointInit(t *testing.T) {
|
|||
ts.AddServer(testServer1, 1)
|
||||
ts.AddServer(testServer2, 1)
|
||||
|
||||
chkInit.Process([]request.Event{
|
||||
{Server: testServer1, Type: request.EvRegistered},
|
||||
{Server: testServer2, Type: request.EvRegistered},
|
||||
})
|
||||
// expect bootstrap request to server 1
|
||||
req1 := request.RequestWithID{ServerAndID: request.ServerAndID{Server: testServer1, ID: 1}, Request: ReqCheckpointData(checkpointHash)}
|
||||
ts.ExpRequests(t, 1, []request.RequestWithID{req1})
|
||||
// req1 times out; expect request to server 2
|
||||
chkInit.Process([]request.Event{
|
||||
TestReqEvent(request.EvTimeout, req1, nil),
|
||||
})
|
||||
req2 := request.RequestWithID{ServerAndID: request.ServerAndID{Server: testServer2, ID: 2}, Request: ReqCheckpointData(checkpointHash)}
|
||||
ts.ExpRequests(t, 2, []request.RequestWithID{req2})
|
||||
// invalid response to req2; expect init state to still be false
|
||||
wrongCheckpoint := &types.BootstrapData{Header: types.Header{Slot: 123456}}
|
||||
chkInit.Process([]request.Event{
|
||||
TestReqEvent(request.EvResponse, req2, wrongCheckpoint),
|
||||
})
|
||||
// req1 fails (hard timeout)
|
||||
chkInit.Process([]request.Event{
|
||||
TestReqEvent(request.EvFail, req1, nil),
|
||||
})
|
||||
ts.Run(1, testServer1, ReqCheckpointData(checkpointHash))
|
||||
|
||||
// server 1 times out; expect request to server 2
|
||||
ts.RequestEvent(request.EvTimeout, 1, nil)
|
||||
ts.Run(2, testServer2, ReqCheckpointData(checkpointHash))
|
||||
|
||||
// invalid response to server 2; expect init state to still be false
|
||||
ts.RequestEvent(request.EvResponse, 2, &types.BootstrapData{Header: types.Header{Slot: 123456}})
|
||||
ts.Run(3, nil, nil)
|
||||
chain.ExpInit(t, false)
|
||||
// server 3 is registered
|
||||
|
||||
// server 1 fails (hard timeout)
|
||||
ts.RequestEvent(request.EvFail, 1, nil)
|
||||
ts.Run(4, nil, nil)
|
||||
chain.ExpInit(t, false)
|
||||
|
||||
// server 3 is registered; expect bootstrap request to server 3
|
||||
ts.AddServer(testServer3, 1)
|
||||
chkInit.Process([]request.Event{
|
||||
{Server: testServer3, Type: request.EvRegistered},
|
||||
})
|
||||
// expect bootstrap request to server 3
|
||||
req3 := request.RequestWithID{ServerAndID: request.ServerAndID{Server: testServer3, ID: 3}, Request: ReqCheckpointData(checkpointHash)}
|
||||
ts.ExpRequests(t, 3, []request.RequestWithID{req3})
|
||||
// valid response to req3; expect chain to be initialized
|
||||
chkInit.Process([]request.Event{
|
||||
TestReqEvent(request.EvResponse, req3, checkpoint),
|
||||
})
|
||||
ts.Run(5, testServer3, ReqCheckpointData(checkpointHash))
|
||||
|
||||
// valid response from server 3; expect chain to be initialized
|
||||
ts.RequestEvent(request.EvResponse, 5, checkpoint)
|
||||
ts.Run(6, nil, nil)
|
||||
chain.ExpInit(t, true)
|
||||
}
|
||||
|
||||
|
|
@ -78,91 +67,73 @@ func TestUpdateSyncParallel(t *testing.T) {
|
|||
ts := NewTestScheduler(t, updateSync)
|
||||
// add 2 servers, head at period 100; allow 3-3 parallel requests for each
|
||||
ts.AddServer(testServer1, 3)
|
||||
ts.ServerEvent(EvNewSignedHead, testServer1, types.SignedHeader{SignatureSlot: 0x2000*100 + 0x1000})
|
||||
ts.AddServer(testServer2, 3)
|
||||
ts.ServerEvent(EvNewSignedHead, testServer2, types.SignedHeader{SignatureSlot: 0x2000*100 + 0x1000})
|
||||
|
||||
updateSync.Process([]request.Event{
|
||||
{Server: testServer1, Type: request.EvRegistered},
|
||||
{Server: testServer1, Type: EvNewSignedHead, Data: types.SignedHeader{SignatureSlot: 0x2000*100 + 0x1000}},
|
||||
{Server: testServer2, Type: request.EvRegistered},
|
||||
{Server: testServer2, Type: EvNewSignedHead, Data: types.SignedHeader{SignatureSlot: 0x2000*100 + 0x1000}},
|
||||
})
|
||||
// expect 6 requests to be sent
|
||||
req1 := request.RequestWithID{ServerAndID: request.ServerAndID{Server: testServer1, ID: 1}, Request: ReqUpdates{FirstPeriod: 0, Count: 8}}
|
||||
req2 := request.RequestWithID{ServerAndID: request.ServerAndID{Server: testServer1, ID: 2}, Request: ReqUpdates{FirstPeriod: 8, Count: 8}}
|
||||
req3 := request.RequestWithID{ServerAndID: request.ServerAndID{Server: testServer1, ID: 3}, Request: ReqUpdates{FirstPeriod: 16, Count: 8}}
|
||||
req4 := request.RequestWithID{ServerAndID: request.ServerAndID{Server: testServer2, ID: 4}, Request: ReqUpdates{FirstPeriod: 24, Count: 8}}
|
||||
req5 := request.RequestWithID{ServerAndID: request.ServerAndID{Server: testServer2, ID: 5}, Request: ReqUpdates{FirstPeriod: 32, Count: 8}}
|
||||
req6 := request.RequestWithID{ServerAndID: request.ServerAndID{Server: testServer2, ID: 6}, Request: ReqUpdates{FirstPeriod: 40, Count: 8}}
|
||||
ts.ExpRequests(t, 1, []request.RequestWithID{req1, req2, req3, req4, req5, req6})
|
||||
// valid response to request 1
|
||||
ts.Run(1, testServer1, ReqUpdates{FirstPeriod: 0, Count: 8})
|
||||
ts.Run(2, testServer1, ReqUpdates{FirstPeriod: 8, Count: 8})
|
||||
ts.Run(3, testServer1, ReqUpdates{FirstPeriod: 16, Count: 8})
|
||||
ts.Run(4, testServer2, ReqUpdates{FirstPeriod: 24, Count: 8})
|
||||
ts.Run(5, testServer2, ReqUpdates{FirstPeriod: 32, Count: 8})
|
||||
ts.Run(6, testServer2, ReqUpdates{FirstPeriod: 40, Count: 8})
|
||||
|
||||
// valid response to request 1; expect 8 periods synced and a new request started
|
||||
ts.RequestEvent(request.EvResponse, 1, testRespUpdate(ts.Request(1)))
|
||||
ts.AddAllowance(testServer1, 1)
|
||||
updateSync.Process([]request.Event{
|
||||
TestReqEvent(request.EvResponse, req1, testRespUpdate(req1)),
|
||||
})
|
||||
// expect 8 periods synced and a new request started
|
||||
ts.Run(7, testServer1, ReqUpdates{FirstPeriod: 48, Count: 8})
|
||||
chain.ExpNextSyncPeriod(t, 8)
|
||||
req7 := request.RequestWithID{ServerAndID: request.ServerAndID{Server: testServer1, ID: 7}, Request: ReqUpdates{FirstPeriod: 48, Count: 8}}
|
||||
ts.ExpRequests(t, 2, []request.RequestWithID{req7})
|
||||
|
||||
// valid response to requests 4 and 5
|
||||
ts.RequestEvent(request.EvResponse, 4, testRespUpdate(ts.Request(4)))
|
||||
ts.RequestEvent(request.EvResponse, 5, testRespUpdate(ts.Request(5)))
|
||||
ts.AddAllowance(testServer2, 2)
|
||||
updateSync.Process([]request.Event{
|
||||
TestReqEvent(request.EvResponse, req4, testRespUpdate(req4)),
|
||||
TestReqEvent(request.EvResponse, req5, testRespUpdate(req5)),
|
||||
})
|
||||
// expect 2 more requests but no sync progress (responses 4 and 5 cannot be added before 2 and 3)
|
||||
ts.Run(8, testServer2, ReqUpdates{FirstPeriod: 56, Count: 8})
|
||||
ts.Run(9, testServer2, ReqUpdates{FirstPeriod: 64, Count: 8})
|
||||
chain.ExpNextSyncPeriod(t, 8)
|
||||
req8 := request.RequestWithID{ServerAndID: request.ServerAndID{Server: testServer2, ID: 8}, Request: ReqUpdates{FirstPeriod: 56, Count: 8}}
|
||||
req9 := request.RequestWithID{ServerAndID: request.ServerAndID{Server: testServer2, ID: 9}, Request: ReqUpdates{FirstPeriod: 64, Count: 8}}
|
||||
ts.ExpRequests(t, 3, []request.RequestWithID{req8, req9})
|
||||
|
||||
// soft timeout for requests 2 and 3 (server 1 is overloaded)
|
||||
updateSync.Process([]request.Event{
|
||||
TestReqEvent(request.EvTimeout, req2, nil),
|
||||
TestReqEvent(request.EvTimeout, req3, nil),
|
||||
})
|
||||
ts.RequestEvent(request.EvTimeout, 2, nil)
|
||||
ts.RequestEvent(request.EvTimeout, 3, nil)
|
||||
// no allowance, no more requests
|
||||
ts.ExpRequests(t, 4, nil)
|
||||
ts.Run(10, nil, nil)
|
||||
|
||||
// valid response to requests 6 and 8 and 9
|
||||
ts.RequestEvent(request.EvResponse, 6, testRespUpdate(ts.Request(6)))
|
||||
ts.RequestEvent(request.EvResponse, 8, testRespUpdate(ts.Request(8)))
|
||||
ts.RequestEvent(request.EvResponse, 9, testRespUpdate(ts.Request(9)))
|
||||
ts.AddAllowance(testServer2, 3)
|
||||
updateSync.Process([]request.Event{
|
||||
TestReqEvent(request.EvResponse, req6, testRespUpdate(req6)),
|
||||
TestReqEvent(request.EvResponse, req8, testRespUpdate(req8)),
|
||||
TestReqEvent(request.EvResponse, req9, testRespUpdate(req9)),
|
||||
})
|
||||
// server 2 can now resend requests 2 and 3 (timed out by server 1) and also send a new one
|
||||
req2r := request.RequestWithID{ServerAndID: request.ServerAndID{Server: testServer2, ID: 10}, Request: ReqUpdates{FirstPeriod: 8, Count: 8}}
|
||||
req3r := request.RequestWithID{ServerAndID: request.ServerAndID{Server: testServer2, ID: 11}, Request: ReqUpdates{FirstPeriod: 16, Count: 8}}
|
||||
req10 := request.RequestWithID{ServerAndID: request.ServerAndID{Server: testServer2, ID: 12}, Request: ReqUpdates{FirstPeriod: 72, Count: 8}}
|
||||
ts.ExpRequests(t, 5, []request.RequestWithID{req2r, req3r, req10})
|
||||
ts.Run(11, testServer2, ReqUpdates{FirstPeriod: 8, Count: 8})
|
||||
ts.Run(12, testServer2, ReqUpdates{FirstPeriod: 16, Count: 8})
|
||||
ts.Run(13, testServer2, ReqUpdates{FirstPeriod: 72, Count: 8})
|
||||
|
||||
// server 1 finally answers timed out request 2
|
||||
ts.RequestEvent(request.EvResponse, 2, testRespUpdate(ts.Request(2)))
|
||||
ts.AddAllowance(testServer1, 1)
|
||||
updateSync.Process([]request.Event{
|
||||
TestReqEvent(request.EvResponse, req2, testRespUpdate(req2)),
|
||||
})
|
||||
// expect sync progress and one new request
|
||||
ts.Run(14, testServer1, ReqUpdates{FirstPeriod: 80, Count: 8})
|
||||
chain.ExpNextSyncPeriod(t, 16)
|
||||
req11 := request.RequestWithID{ServerAndID: request.ServerAndID{Server: testServer1, ID: 13}, Request: ReqUpdates{FirstPeriod: 80, Count: 8}}
|
||||
ts.ExpRequests(t, 6, []request.RequestWithID{req11})
|
||||
// server 2 answers re-sent requests 2 and 3
|
||||
|
||||
// server 2 answers requests 11 and 12 (resends of requests 2 and 3)
|
||||
ts.RequestEvent(request.EvResponse, 11, testRespUpdate(ts.Request(11)))
|
||||
ts.RequestEvent(request.EvResponse, 12, testRespUpdate(ts.Request(12)))
|
||||
ts.AddAllowance(testServer2, 2)
|
||||
updateSync.Process([]request.Event{
|
||||
TestReqEvent(request.EvResponse, req2r, testRespUpdate(req2r)),
|
||||
TestReqEvent(request.EvResponse, req3r, testRespUpdate(req3r)),
|
||||
})
|
||||
ts.Run(15, testServer2, ReqUpdates{FirstPeriod: 88, Count: 8})
|
||||
ts.Run(16, testServer2, ReqUpdates{FirstPeriod: 96, Count: 4})
|
||||
// finally the gap is filled, update can process responses up to req6
|
||||
chain.ExpNextSyncPeriod(t, 48)
|
||||
// expect 2 new requests from server 2 (now the available range is covered)
|
||||
req12 := request.RequestWithID{ServerAndID: request.ServerAndID{Server: testServer2, ID: 14}, Request: ReqUpdates{FirstPeriod: 88, Count: 8}}
|
||||
req13 := request.RequestWithID{ServerAndID: request.ServerAndID{Server: testServer2, ID: 15}, Request: ReqUpdates{FirstPeriod: 96, Count: 4}}
|
||||
ts.ExpRequests(t, 7, []request.RequestWithID{req12, req13})
|
||||
|
||||
// all remaining requests are answered
|
||||
updateSync.Process([]request.Event{
|
||||
TestReqEvent(request.EvResponse, req3, testRespUpdate(req3)),
|
||||
TestReqEvent(request.EvResponse, req7, testRespUpdate(req7)),
|
||||
TestReqEvent(request.EvResponse, req10, testRespUpdate(req10)),
|
||||
TestReqEvent(request.EvResponse, req11, testRespUpdate(req11)),
|
||||
TestReqEvent(request.EvResponse, req12, testRespUpdate(req12)),
|
||||
TestReqEvent(request.EvResponse, req13, testRespUpdate(req13)),
|
||||
})
|
||||
ts.RequestEvent(request.EvResponse, 3, testRespUpdate(ts.Request(3)))
|
||||
ts.RequestEvent(request.EvResponse, 7, testRespUpdate(ts.Request(7)))
|
||||
ts.RequestEvent(request.EvResponse, 13, testRespUpdate(ts.Request(13)))
|
||||
ts.RequestEvent(request.EvResponse, 14, testRespUpdate(ts.Request(14)))
|
||||
ts.RequestEvent(request.EvResponse, 15, testRespUpdate(ts.Request(15)))
|
||||
ts.RequestEvent(request.EvResponse, 16, testRespUpdate(ts.Request(16)))
|
||||
ts.Run(17, nil, nil)
|
||||
// expect chain to be fully synced
|
||||
chain.ExpNextSyncPeriod(t, 100)
|
||||
}
|
||||
|
|
@ -174,65 +145,53 @@ func TestUpdateSyncDifferentHeads(t *testing.T) {
|
|||
ts := NewTestScheduler(t, updateSync)
|
||||
// add 3 servers with different announced head periods
|
||||
ts.AddServer(testServer1, 1)
|
||||
ts.ServerEvent(EvNewSignedHead, testServer1, types.SignedHeader{SignatureSlot: 0x2000*15 + 0x1000})
|
||||
ts.AddServer(testServer2, 1)
|
||||
ts.ServerEvent(EvNewSignedHead, testServer2, types.SignedHeader{SignatureSlot: 0x2000*16 + 0x1000})
|
||||
ts.AddServer(testServer3, 1)
|
||||
ts.ServerEvent(EvNewSignedHead, testServer3, types.SignedHeader{SignatureSlot: 0x2000*17 + 0x1000})
|
||||
|
||||
updateSync.Process([]request.Event{
|
||||
{Server: testServer1, Type: request.EvRegistered},
|
||||
{Server: testServer1, Type: EvNewSignedHead, Data: types.SignedHeader{SignatureSlot: 0x2000*15 + 0x1000}},
|
||||
{Server: testServer2, Type: request.EvRegistered},
|
||||
{Server: testServer2, Type: EvNewSignedHead, Data: types.SignedHeader{SignatureSlot: 0x2000*16 + 0x1000}},
|
||||
{Server: testServer3, Type: request.EvRegistered},
|
||||
{Server: testServer3, Type: EvNewSignedHead, Data: types.SignedHeader{SignatureSlot: 0x2000*17 + 0x1000}},
|
||||
})
|
||||
// expect request to the best announced head
|
||||
req1 := request.RequestWithID{ServerAndID: request.ServerAndID{Server: testServer3, ID: 1}, Request: ReqUpdates{FirstPeriod: 10, Count: 7}}
|
||||
ts.ExpRequests(t, 1, []request.RequestWithID{req1})
|
||||
ts.Run(1, testServer3, ReqUpdates{FirstPeriod: 10, Count: 7})
|
||||
|
||||
// request times out, expect request to the next best head
|
||||
updateSync.Process([]request.Event{
|
||||
TestReqEvent(request.EvTimeout, req1, nil),
|
||||
})
|
||||
req2 := request.RequestWithID{ServerAndID: request.ServerAndID{Server: testServer2, ID: 2}, Request: ReqUpdates{FirstPeriod: 10, Count: 6}}
|
||||
ts.ExpRequests(t, 2, []request.RequestWithID{req2})
|
||||
ts.RequestEvent(request.EvTimeout, 1, nil)
|
||||
ts.Run(2, testServer2, ReqUpdates{FirstPeriod: 10, Count: 6})
|
||||
|
||||
// request times out, expect request to the last available server
|
||||
updateSync.Process([]request.Event{
|
||||
TestReqEvent(request.EvTimeout, req2, nil),
|
||||
})
|
||||
req3 := request.RequestWithID{ServerAndID: request.ServerAndID{Server: testServer1, ID: 3}, Request: ReqUpdates{FirstPeriod: 10, Count: 5}}
|
||||
ts.ExpRequests(t, 3, []request.RequestWithID{req3})
|
||||
ts.RequestEvent(request.EvTimeout, 2, nil)
|
||||
ts.Run(3, testServer1, ReqUpdates{FirstPeriod: 10, Count: 5})
|
||||
|
||||
// valid response to request 3, expect chain synced to period 15
|
||||
ts.RequestEvent(request.EvResponse, 3, testRespUpdate(ts.Request(3)))
|
||||
ts.AddAllowance(testServer1, 1)
|
||||
updateSync.Process([]request.Event{
|
||||
TestReqEvent(request.EvResponse, req3, testRespUpdate(req3)),
|
||||
})
|
||||
ts.Run(4, nil, nil)
|
||||
chain.ExpNextSyncPeriod(t, 15)
|
||||
|
||||
// invalid response to request 1, server can only deliver updates up to period 15 despite announced head
|
||||
req1x := request.RequestWithID{ServerAndID: req1.ServerAndID, Request: ReqUpdates{FirstPeriod: 10, Count: 5}}
|
||||
updateSync.Process([]request.Event{
|
||||
TestReqEvent(request.EvResponse, req1, testRespUpdate(req1x)),
|
||||
})
|
||||
req1x := ts.Request(1)
|
||||
req1x.Request = ReqUpdates{FirstPeriod: 10, Count: 5}
|
||||
ts.RequestEvent(request.EvResponse, 1, testRespUpdate(req1x))
|
||||
ts.Run(5, nil, nil)
|
||||
// expect no progress of chain head
|
||||
chain.ExpNextSyncPeriod(t, 15)
|
||||
|
||||
// valid response to request 2, expect chain synced to period 16
|
||||
ts.RequestEvent(request.EvResponse, 2, testRespUpdate(ts.Request(2)))
|
||||
ts.AddAllowance(testServer2, 1)
|
||||
updateSync.Process([]request.Event{
|
||||
TestReqEvent(request.EvResponse, req2, testRespUpdate(req2)),
|
||||
})
|
||||
ts.Run(6, nil, nil)
|
||||
chain.ExpNextSyncPeriod(t, 16)
|
||||
|
||||
// a new server is registered with announced head period 17
|
||||
ts.AddServer(testServer4, 1)
|
||||
updateSync.Process([]request.Event{
|
||||
{Server: testServer4, Type: request.EvRegistered},
|
||||
{Server: testServer4, Type: EvNewSignedHead, Data: types.SignedHeader{SignatureSlot: 0x2000*17 + 0x1000}},
|
||||
})
|
||||
ts.ServerEvent(EvNewSignedHead, testServer4, types.SignedHeader{SignatureSlot: 0x2000*17 + 0x1000})
|
||||
// expect request to sync one more period
|
||||
req4 := request.RequestWithID{ServerAndID: request.ServerAndID{Server: testServer4, ID: 4}, Request: ReqUpdates{FirstPeriod: 16, Count: 1}}
|
||||
ts.ExpRequests(t, 4, []request.RequestWithID{req4})
|
||||
ts.Run(7, testServer4, ReqUpdates{FirstPeriod: 16, Count: 1})
|
||||
|
||||
// valid response, expect chain synced to period 17
|
||||
ts.AddAllowance(testServer1, 1)
|
||||
updateSync.Process([]request.Event{
|
||||
TestReqEvent(request.EvResponse, req4, testRespUpdate(req4)),
|
||||
})
|
||||
ts.RequestEvent(request.EvResponse, 7, testRespUpdate(ts.Request(7)))
|
||||
ts.AddAllowance(testServer4, 1)
|
||||
ts.Run(8, nil, nil)
|
||||
chain.ExpNextSyncPeriod(t, 17)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,8 +56,6 @@ func TestBlockSync(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
ts.ServerEvent(request.EvRegistered, testServer1, nil)
|
||||
ts.ServerEvent(request.EvRegistered, testServer2, nil)
|
||||
// no block requests expected until head tracker knows about a head
|
||||
ts.Run(1, nil, nil)
|
||||
expHeadBlock(1, nil)
|
||||
|
|
|
|||
Loading…
Reference in a new issue