mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 01:43:47 +00:00
swarm: time for chunk at node in snapshot_sync_test
This commit is contained in:
parent
5ca0180e8e
commit
6b45dd22da
6 changed files with 82 additions and 50 deletions
|
|
@ -52,6 +52,7 @@ var (
|
||||||
defaultSkipCheck bool
|
defaultSkipCheck bool
|
||||||
waitPeerErrC chan error
|
waitPeerErrC chan error
|
||||||
chunkSize = 4096
|
chunkSize = 4096
|
||||||
|
registries map[discover.NodeID]*TestRegistry
|
||||||
)
|
)
|
||||||
|
|
||||||
var services = adapters.Services{
|
var services = adapters.Services{
|
||||||
|
|
@ -92,7 +93,9 @@ func NewStreamerService(ctx *adapters.ServiceContext) (node.Service, error) {
|
||||||
waitPeerErrC <- waitForPeers(r, 1*time.Second, peerCount(id))
|
waitPeerErrC <- waitForPeers(r, 1*time.Second, peerCount(id))
|
||||||
}()
|
}()
|
||||||
dpa := storage.NewDPA(storage.NewNetStore(store, nil), storage.NewDPAParams())
|
dpa := storage.NewDPA(storage.NewNetStore(store, nil), storage.NewDPAParams())
|
||||||
return &TestRegistry{Registry: r, dpa: dpa}, nil
|
testRegistry := &TestRegistry{Registry: r, dpa: dpa}
|
||||||
|
registries[id] = testRegistry
|
||||||
|
return testRegistry, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//create a local store for the given node
|
//create a local store for the given node
|
||||||
|
|
@ -112,12 +115,18 @@ func createTestLocalStorageForId(id discover.NodeID, addr *network.BzzAddr) (sto
|
||||||
return store, nil
|
return store, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func datadirsCleanup() {
|
||||||
|
for _, id := range ids {
|
||||||
|
os.RemoveAll(datadirs[id])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//local stores need to be cleaned up after the sim is done
|
//local stores need to be cleaned up after the sim is done
|
||||||
func localStoreCleanup() {
|
func localStoreCleanup() {
|
||||||
log.Info("Cleaning up...")
|
log.Info("Cleaning up...")
|
||||||
for i := 0; i < len(ids); i++ {
|
for _, id := range ids {
|
||||||
stores[ids[i]].Close()
|
registries[id].Close()
|
||||||
os.RemoveAll(datadirs[ids[i]])
|
stores[id].Close()
|
||||||
}
|
}
|
||||||
log.Info("Local store cleanup done")
|
log.Info("Local store cleanup done")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,15 +74,6 @@ func (p *Peer) handleRequestSubscription(req *RequestSubscriptionMsg) (err error
|
||||||
return p.streamer.Subscribe(p.ID(), req.Stream, req.History, req.Priority)
|
return p.streamer.Subscribe(p.ID(), req.Stream, req.History, req.Priority)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Peer) handleRequestSubscription(req *RequestSubscriptionMsg) (err error) {
|
|
||||||
log.Debug(fmt.Sprintf("handleRequestSubscription: streamer %s to subscribe to %s with stream %s", p.streamer.addr.ID(), p.ID(), req.Stream))
|
|
||||||
err = p.streamer.Subscribe(p.ID(), req.Stream, req.History, req.Priority)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Peer) handleSubscribeMsg(req *SubscribeMsg) (err error) {
|
func (p *Peer) handleSubscribeMsg(req *SubscribeMsg) (err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
|
"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
|
||||||
"github.com/ethereum/go-ethereum/pot"
|
"github.com/ethereum/go-ethereum/pot"
|
||||||
"github.com/ethereum/go-ethereum/swarm/network"
|
"github.com/ethereum/go-ethereum/swarm/network"
|
||||||
streamTesting "github.com/ethereum/go-ethereum/swarm/network/stream/testing"
|
//streamTesting "github.com/ethereum/go-ethereum/swarm/network/stream/testing"
|
||||||
"github.com/ethereum/go-ethereum/swarm/storage"
|
"github.com/ethereum/go-ethereum/swarm/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -47,6 +47,8 @@ var (
|
||||||
datadirs map[discover.NodeID]string
|
datadirs map[discover.NodeID]string
|
||||||
conf *synctestConfig
|
conf *synctestConfig
|
||||||
ppmap map[discover.NodeID]*network.PeerPot
|
ppmap map[discover.NodeID]*network.PeerPot
|
||||||
|
|
||||||
|
printed bool
|
||||||
)
|
)
|
||||||
|
|
||||||
type synctestConfig struct {
|
type synctestConfig struct {
|
||||||
|
|
@ -84,6 +86,8 @@ func initSyncTest() {
|
||||||
datadirs = make(map[discover.NodeID]string)
|
datadirs = make(map[discover.NodeID]string)
|
||||||
//deliveries for each node
|
//deliveries for each node
|
||||||
deliveries = make(map[discover.NodeID]*Delivery)
|
deliveries = make(map[discover.NodeID]*Delivery)
|
||||||
|
//registries, map of discover.NodeID to its streamer
|
||||||
|
registries = make(map[discover.NodeID]*TestRegistry)
|
||||||
|
|
||||||
//channel to wait for peers connected
|
//channel to wait for peers connected
|
||||||
waitPeerErrC = make(chan error)
|
waitPeerErrC = make(chan error)
|
||||||
|
|
@ -194,12 +198,32 @@ func runSyncTest(chunkCount int, nodeCount int) error {
|
||||||
//map of overlay address to discover ID
|
//map of overlay address to discover ID
|
||||||
conf.addrToIdMap = make(map[string]discover.NodeID)
|
conf.addrToIdMap = make(map[string]discover.NodeID)
|
||||||
//First load the snapshot from the file
|
//First load the snapshot from the file
|
||||||
|
var actionTicker *time.Ticker
|
||||||
|
var timingTicker *time.Ticker
|
||||||
|
trigger := make(chan discover.NodeID)
|
||||||
|
// channel to signal simulation initialisation with action call complete
|
||||||
|
// or node disconnections
|
||||||
|
disconnectC := make(chan error)
|
||||||
|
quitC := make(chan struct{})
|
||||||
|
|
||||||
net, err := initNetWithSnapshot(nodeCount)
|
net, err := initNetWithSnapshot(nodeCount)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer net.Shutdown()
|
cleanup := func() {
|
||||||
|
timingTicker.Stop()
|
||||||
|
actionTicker.Stop()
|
||||||
|
//close(trigger)
|
||||||
|
close(quitC)
|
||||||
|
close(disconnectC)
|
||||||
|
close(waitPeerErrC)
|
||||||
|
//after the test, clean up local stores initialized with createLocalStoreForId
|
||||||
|
localStoreCleanup()
|
||||||
|
//shutdown the snapshot network
|
||||||
|
net.Shutdown()
|
||||||
|
//datadirsCleanup()
|
||||||
|
}
|
||||||
|
defer cleanup()
|
||||||
//get the nodes of the network
|
//get the nodes of the network
|
||||||
nodes := net.GetNodes()
|
nodes := net.GetNodes()
|
||||||
//select one index at random...
|
//select one index at random...
|
||||||
|
|
@ -226,13 +250,6 @@ func runSyncTest(chunkCount int, nodeCount int) error {
|
||||||
log.Info("Test config successfully initialized")
|
log.Info("Test config successfully initialized")
|
||||||
|
|
||||||
ppmap = network.NewPeerPot(testMinProxBinSize, ids, conf.addrs)
|
ppmap = network.NewPeerPot(testMinProxBinSize, ids, conf.addrs)
|
||||||
// channel to signal simulation initialisation with action call complete
|
|
||||||
// or node disconnections
|
|
||||||
disconnectC := make(chan error)
|
|
||||||
quitC := make(chan struct{})
|
|
||||||
|
|
||||||
//after the test, clean up local stores initialized with createLocalStoreForId
|
|
||||||
defer localStoreCleanup()
|
|
||||||
|
|
||||||
//define the action to be performed before the test checks: start syncing
|
//define the action to be performed before the test checks: start syncing
|
||||||
action := func(ctx context.Context) error {
|
action := func(ctx context.Context) error {
|
||||||
|
|
@ -286,10 +303,10 @@ func runSyncTest(chunkCount int, nodeCount int) error {
|
||||||
log.Debug(kt)
|
log.Debug(kt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = streamTesting.WatchDisconnections(id, client, disconnectC, quitC)
|
//err = streamTesting.WatchDisconnections(id, client, disconnectC, quitC)
|
||||||
if err != nil {
|
//if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
//}
|
||||||
err = client.CallContext(ctx, nil, "stream_startSyncing")
|
err = client.CallContext(ctx, nil, "stream_startSyncing")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -309,10 +326,19 @@ func runSyncTest(chunkCount int, nodeCount int) error {
|
||||||
//finally map chunks to the closest addresses
|
//finally map chunks to the closest addresses
|
||||||
mapKeysToNodes(conf)
|
mapKeysToNodes(conf)
|
||||||
|
|
||||||
|
//periodically check if chunks have arrived at nodes
|
||||||
|
actionTicker = time.NewTicker(time.Second / 100)
|
||||||
|
go func() {
|
||||||
|
startTime = time.Now()
|
||||||
|
for range actionTicker.C {
|
||||||
|
checkChunkIsAtNode(conf)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
log.Info("Action terminated")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
trigger := make(chan discover.NodeID)
|
|
||||||
//check defines what will be checked during the test
|
//check defines what will be checked during the test
|
||||||
check := func(ctx context.Context, id discover.NodeID) (bool, error) {
|
check := func(ctx context.Context, id discover.NodeID) (bool, error) {
|
||||||
select {
|
select {
|
||||||
|
|
@ -323,7 +349,6 @@ func runSyncTest(chunkCount int, nodeCount int) error {
|
||||||
return false, ctx.Err()
|
return false, ctx.Err()
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Trace(fmt.Sprintf("Checking node: %s", id))
|
log.Trace(fmt.Sprintf("Checking node: %s", id))
|
||||||
//select the local store for the given node
|
//select the local store for the given node
|
||||||
lstore := stores[id]
|
lstore := stores[id]
|
||||||
|
|
@ -353,25 +378,16 @@ func runSyncTest(chunkCount int, nodeCount int) error {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
|
timingTicker = time.NewTicker(time.Second * 1)
|
||||||
//for each tick, run the checks on all nodes
|
//for each tick, run the checks on all nodes
|
||||||
go func() {
|
go func() {
|
||||||
ticker := time.NewTicker(time.Second * 1)
|
for range timingTicker.C {
|
||||||
for range ticker.C {
|
|
||||||
for i := 0; i < len(ids); i++ {
|
for i := 0; i < len(ids); i++ {
|
||||||
log.Trace(fmt.Sprintf("triggering step %d, id %s", i, ids[i]))
|
log.Trace(fmt.Sprintf("triggering step %d, id %s", i, ids[i]))
|
||||||
trigger <- ids[i]
|
trigger <- ids[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
/*
|
|
||||||
go func() {
|
|
||||||
startTime = time.Now()
|
|
||||||
ticker := time.NewTicker(time.Second / 10)
|
|
||||||
for range ticker.C {
|
|
||||||
checkChunkIsAtNode(conf)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
*/
|
|
||||||
|
|
||||||
log.Info("Starting simulation run...")
|
log.Info("Starting simulation run...")
|
||||||
//run the simulation
|
//run the simulation
|
||||||
|
|
@ -383,11 +399,9 @@ func runSyncTest(chunkCount int, nodeCount int) error {
|
||||||
Check: check,
|
Check: check,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
close(quitC)
|
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
return result.Error
|
return result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("Simulation terminated")
|
log.Info("Simulation terminated")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -432,7 +446,6 @@ func (r *TestRegistry) StartSyncing(ctx context.Context) error {
|
||||||
|
|
||||||
//iterate over each bin and solicit needed subscription to bins
|
//iterate over each bin and solicit needed subscription to bins
|
||||||
kad.EachBin(r.addr.Over(), pof, 0, func(po, size int, f func(func(val pot.Val, i int) bool) bool) bool {
|
kad.EachBin(r.addr.Over(), pof, 0, func(po, size int, f func(func(val pot.Val, i int) bool) bool) bool {
|
||||||
|
|
||||||
//identify begin and start index of the bin(s) we want to subscribe to
|
//identify begin and start index of the bin(s) we want to subscribe to
|
||||||
if po < kadDepth {
|
if po < kadDepth {
|
||||||
//not nn
|
//not nn
|
||||||
|
|
@ -471,28 +484,45 @@ func (r *TestRegistry) StartSyncing(ctx context.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//periodically check if chunks have arrived at nodes
|
||||||
func checkChunkIsAtNode(conf *synctestConfig) {
|
func checkChunkIsAtNode(conf *synctestConfig) {
|
||||||
allOk := true
|
allOk := true
|
||||||
|
if printed {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//for every chunk, get the array of nodes it should have arrived to
|
||||||
for chunk, nodes := range conf.chunksToNodesMap {
|
for chunk, nodes := range conf.chunksToNodesMap {
|
||||||
|
//for every of those nodes
|
||||||
for _, node := range nodes {
|
for _, node := range nodes {
|
||||||
|
//check that the chunk is in that localstore
|
||||||
if ok, _ := stores[conf.addrToIdMap[string(conf.addrs[node])]].Get([]byte(chunk)); ok != nil {
|
if ok, _ := stores[conf.addrToIdMap[string(conf.addrs[node])]].Get([]byte(chunk)); ok != nil {
|
||||||
|
//if it is there, write the amount of time passed in the retrievalMap
|
||||||
|
//first create the map for the chunk if it is not there yet
|
||||||
if len(conf.retrievalMap[chunk]) == 0 {
|
if len(conf.retrievalMap[chunk]) == 0 {
|
||||||
conf.retrievalMap[chunk] = make(map[string]time.Duration)
|
conf.retrievalMap[chunk] = make(map[string]time.Duration)
|
||||||
}
|
}
|
||||||
conf.retrievalMap[chunk][string(conf.addrs[node])] = time.Since(startTime)
|
//if the time value for the chunk at this node has not been recorded yet...
|
||||||
|
if _, ok := conf.retrievalMap[chunk][string(conf.addrs[node])]; !ok {
|
||||||
|
//...record it
|
||||||
|
conf.retrievalMap[chunk][string(conf.addrs[node])] = time.Since(startTime)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
allOk = false
|
||||||
}
|
}
|
||||||
|
//if one of the chunks hasn't arrived yet, don't print
|
||||||
if conf.retrievalMap[chunk][string(conf.addrs[node])] == 0 {
|
if conf.retrievalMap[chunk][string(conf.addrs[node])] == 0 {
|
||||||
allOk = false
|
allOk = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if allOk {
|
if allOk && !printed {
|
||||||
log.Info("All chunks arrived at destination")
|
log.Info("All chunks arrived at destination")
|
||||||
for ch, n := range conf.retrievalMap {
|
for ch, n := range conf.retrievalMap {
|
||||||
for a, t := range n {
|
for a, t := range n {
|
||||||
log.Info(fmt.Sprintf("Chunk %s at node %s took %v ms", string(ch), string(a), t.Seconds()*1e3))
|
log.Info(fmt.Sprintf("Chunk %v at node %s took %v ms", storage.Key([]byte((ch))).String()[:8], conf.addrToIdMap[string(a)].String()[0:8], t.Seconds()*1e3))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
printed = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -529,7 +559,7 @@ func mapKeysToNodes(conf *synctestConfig) {
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
kmap[conf.chunks[i].String()] = nns
|
kmap[string(conf.chunks[i])] = nns
|
||||||
//log.Debug(fmt.Sprintf("Length for id %s: %d",ids[i],len(kmap[ids[i]])))
|
//log.Debug(fmt.Sprintf("Length for id %s: %d",ids[i],len(kmap[ids[i]])))
|
||||||
}
|
}
|
||||||
if log.Lvl(*loglevel) == log.LvlTrace {
|
if log.Lvl(*loglevel) == log.LvlTrace {
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -228,7 +228,9 @@ func WatchDisconnections(id discover.NodeID, client *rpc.Client, errc chan error
|
||||||
case <-quitC:
|
case <-quitC:
|
||||||
return
|
return
|
||||||
case e := <-events:
|
case e := <-events:
|
||||||
errc <- fmt.Errorf("peerEvent for node %v: %v", id, e)
|
if e.Type == p2p.PeerEventTypeDrop {
|
||||||
|
errc <- fmt.Errorf("peerEvent for node %v: %v", id, e)
|
||||||
|
}
|
||||||
case err := <-sub.Err():
|
case err := <-sub.Err():
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errc <- fmt.Errorf("error getting peer events for node %v: %v", id, err)
|
errc <- fmt.Errorf("error getting peer events for node %v: %v", id, err)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue