code.vegaprotocol.io/vega@v0.79.0/datanode/networkhistory/initialise_test.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package networkhistory_test
    17  
    18  import (
    19  	"context"
    20  	"errors"
    21  	"testing"
    22  
    23  	"code.vegaprotocol.io/vega/datanode/networkhistory"
    24  	"code.vegaprotocol.io/vega/datanode/networkhistory/mocks"
    25  	"code.vegaprotocol.io/vega/datanode/networkhistory/segment"
    26  	"code.vegaprotocol.io/vega/datanode/sqlstore"
    27  	"code.vegaprotocol.io/vega/logging"
    28  	v2 "code.vegaprotocol.io/vega/protos/data-node/api/v2"
    29  
    30  	"github.com/golang/mock/gomock"
    31  	"github.com/stretchr/testify/assert"
    32  )
    33  
    34  func makeFullSegment(from, to int64, previous, id string) segment.Full {
    35  	return segment.Full{
    36  		MetaData: segment.MetaData{
    37  			Base: segment.Base{
    38  				HeightFrom: from,
    39  				HeightTo:   to,
    40  			},
    41  			PreviousHistorySegmentID: previous,
    42  		},
    43  		HistorySegmentID: id,
    44  	}
    45  }
    46  
    47  func TestInitialiseEmptyDataNodeWithFullHistoryWhenLoadIsLongerThanSegmentCreationInterval(t *testing.T) {
    48  	// Tests the scenario where fetching and loading the history takes longer than the segment creation interval
    49  	// requiring multiple loads to occur before the datanode is at the most recent segment height.
    50  	log := logging.NewTestLogger()
    51  	cfg := networkhistory.NewDefaultInitializationConfig()
    52  
    53  	ctrl := gomock.NewController(t)
    54  	service := mocks.NewMockNetworkHistory(ctrl)
    55  	ctx := context.Background()
    56  
    57  	peerResponse1 := &networkhistory.PeerResponse{
    58  		PeerAddr: "",
    59  		Response: &v2.GetMostRecentNetworkHistorySegmentResponse{
    60  			Segment: &v2.HistorySegment{
    61  				FromHeight:               1001,
    62  				ToHeight:                 2000,
    63  				PreviousHistorySegmentId: "segment1",
    64  				HistorySegmentId:         "segment2",
    65  			},
    66  			SwarmKeySeed: "",
    67  		},
    68  	}
    69  
    70  	peerResponse2 := &networkhistory.PeerResponse{
    71  		PeerAddr: "",
    72  		Response: &v2.GetMostRecentNetworkHistorySegmentResponse{
    73  			Segment: &v2.HistorySegment{
    74  				FromHeight:               2001,
    75  				ToHeight:                 3000,
    76  				PreviousHistorySegmentId: "segment2",
    77  				HistorySegmentId:         "segment3",
    78  			},
    79  			SwarmKeySeed: "",
    80  		},
    81  	}
    82  
    83  	segment1 := makeFullSegment(0, 1000, "", "segment1")
    84  	segment2 := makeFullSegment(1001, 2000, "segment1", "segment2")
    85  	segments1 := []segment.Full{segment1, segment2}
    86  	chunk1 := segment.ContiguousHistory[segment.Full]{
    87  		HeightFrom: 0,
    88  		HeightTo:   2000,
    89  		Segments:   segments1,
    90  	}
    91  
    92  	segment3 := makeFullSegment(2001, 3000, "segment2", "segment3")
    93  
    94  	segments2 := []segment.Full{segment3}
    95  	chunk2 := segment.ContiguousHistory[segment.Full]{
    96  		HeightFrom: 2001,
    97  		HeightTo:   3000,
    98  		Segments:   segments2,
    99  	}
   100  
   101  	cfg.MinimumBlockCount = -1
   102  	mostRecentSegment1 := service.EXPECT().GetMostRecentHistorySegmentFromBootstrapPeers(gomock.Any(), []int{}).Times(1).
   103  		Return(peerResponse1, map[string]*v2.GetMostRecentNetworkHistorySegmentResponse{"peer1": peerResponse1.Response}, nil)
   104  	mostRecentSegment2 := service.EXPECT().GetMostRecentHistorySegmentFromBootstrapPeers(gomock.Any(), []int{}).Times(2).
   105  		Return(peerResponse2, map[string]*v2.GetMostRecentNetworkHistorySegmentResponse{"peer1": peerResponse2.Response}, nil)
   106  	gomock.InOrder(mostRecentSegment1, mostRecentSegment2)
   107  
   108  	first := service.EXPECT().FetchHistorySegment(gomock.Any(), "segment2").Times(1).Return(segment2, nil)
   109  	second := service.EXPECT().FetchHistorySegment(gomock.Any(), "segment1").Times(1).Return(segment1, nil)
   110  	third := service.EXPECT().FetchHistorySegment(gomock.Any(), "segment3").Times(1).Return(segment3, nil)
   111  	gomock.InOrder(first, second, third)
   112  
   113  	firstBlockSpan := service.EXPECT().GetDatanodeBlockSpan(gomock.Any()).Times(1).Return(sqlstore.DatanodeBlockSpan{}, nil)
   114  	secondBlockSpan := service.EXPECT().GetDatanodeBlockSpan(gomock.Any()).Times(1).Return(sqlstore.DatanodeBlockSpan{FromHeight: 0, ToHeight: 2000, HasData: true}, nil)
   115  	thirdBlockSpan := service.EXPECT().GetDatanodeBlockSpan(gomock.Any()).Times(1).Return(sqlstore.DatanodeBlockSpan{FromHeight: 0, ToHeight: 3000, HasData: true}, nil)
   116  	gomock.InOrder(firstBlockSpan, secondBlockSpan, thirdBlockSpan)
   117  
   118  	listAll1 := service.EXPECT().ListAllHistorySegments().Times(1).Return(segments1, nil)
   119  	load1 := service.EXPECT().LoadNetworkHistoryIntoDatanode(gomock.Any(), chunk1, gomock.Any(), false, false).Times(1)
   120  
   121  	listAll2 := service.EXPECT().ListAllHistorySegments().Times(1).Return(segments2, nil)
   122  	load2 := service.EXPECT().LoadNetworkHistoryIntoDatanode(gomock.Any(), chunk2, gomock.Any(), true, false).Times(1)
   123  	gomock.InOrder(listAll1, listAll2)
   124  	gomock.InOrder(load1, load2)
   125  
   126  	networkhistory.InitialiseDatanodeFromNetworkHistory(ctx, cfg, log, sqlstore.NewDefaultConfig().ConnectionConfig, service, []int{}, false)
   127  }
   128  
   129  func TestInitialiseEmptyDataNodeWithFullHistory(t *testing.T) {
   130  	log := logging.NewTestLogger()
   131  	cfg := networkhistory.NewDefaultInitializationConfig()
   132  
   133  	ctrl := gomock.NewController(t)
   134  	service := mocks.NewMockNetworkHistory(ctrl)
   135  	ctx := context.Background()
   136  
   137  	peerResponse := &networkhistory.PeerResponse{
   138  		PeerAddr: "",
   139  		Response: &v2.GetMostRecentNetworkHistorySegmentResponse{
   140  			Segment: &v2.HistorySegment{
   141  				FromHeight:               1001,
   142  				ToHeight:                 2000,
   143  				PreviousHistorySegmentId: "segment1",
   144  				HistorySegmentId:         "segment2",
   145  			},
   146  			SwarmKeySeed: "",
   147  		},
   148  	}
   149  
   150  	segment1 := makeFullSegment(0, 1000, "", "segment1")
   151  	segment2 := makeFullSegment(1001, 2000, "segment1", "segment2")
   152  	segments := []segment.Full{segment1, segment2}
   153  	chunk := segment.ContiguousHistory[segment.Full]{
   154  		HeightFrom: 0,
   155  		HeightTo:   2000,
   156  		Segments:   segments,
   157  	}
   158  
   159  	cfg.MinimumBlockCount = -1
   160  	service.EXPECT().GetMostRecentHistorySegmentFromBootstrapPeers(gomock.Any(), []int{}).Times(2).
   161  		Return(peerResponse, map[string]*v2.GetMostRecentNetworkHistorySegmentResponse{"peer1": peerResponse.Response}, nil)
   162  
   163  	first := service.EXPECT().FetchHistorySegment(gomock.Any(), "segment2").Times(1).Return(segment2, nil)
   164  	second := service.EXPECT().FetchHistorySegment(gomock.Any(), "segment1").Times(1).Return(segment1, nil)
   165  
   166  	gomock.InOrder(first, second)
   167  
   168  	firstBlockSpan := service.EXPECT().GetDatanodeBlockSpan(gomock.Any()).Times(1).Return(sqlstore.DatanodeBlockSpan{}, nil)
   169  	secondBlockSpan := service.EXPECT().GetDatanodeBlockSpan(gomock.Any()).Times(1).Return(sqlstore.DatanodeBlockSpan{FromHeight: 0, ToHeight: 2000, HasData: true}, nil)
   170  	gomock.InOrder(firstBlockSpan, secondBlockSpan)
   171  
   172  	service.EXPECT().ListAllHistorySegments().Times(1).Return(segments, nil)
   173  	service.EXPECT().LoadNetworkHistoryIntoDatanode(gomock.Any(), chunk, gomock.Any(), false, false).Times(1)
   174  
   175  	networkhistory.InitialiseDatanodeFromNetworkHistory(ctx, cfg, log, sqlstore.NewDefaultConfig().ConnectionConfig, service, []int{}, false)
   176  }
   177  
   178  func TestInitialiseNonEmptyDataNode(t *testing.T) {
   179  	log := logging.NewTestLogger()
   180  	cfg := networkhistory.NewDefaultInitializationConfig()
   181  
   182  	cfg.MinimumBlockCount = 2000
   183  
   184  	ctrl := gomock.NewController(t)
   185  	service := mocks.NewMockNetworkHistory(ctrl)
   186  	ctx := context.Background()
   187  
   188  	peerResponse := &networkhistory.PeerResponse{
   189  		PeerAddr: "",
   190  		Response: &v2.GetMostRecentNetworkHistorySegmentResponse{
   191  			Segment: &v2.HistorySegment{
   192  				FromHeight:               3001,
   193  				ToHeight:                 4000,
   194  				HistorySegmentId:         "segment4",
   195  				PreviousHistorySegmentId: "segment3",
   196  			},
   197  			SwarmKeySeed: "",
   198  		},
   199  	}
   200  
   201  	segment4 := makeFullSegment(3001, 4000, "segment3", "segment4")
   202  	segment3 := makeFullSegment(2001, 3000, "segment2", "segment3")
   203  	segments := []segment.Full{segment3, segment4}
   204  	chunk := segment.ContiguousHistory[segment.Full]{
   205  		HeightFrom: 2001,
   206  		HeightTo:   4000,
   207  		Segments:   segments,
   208  	}
   209  
   210  	cfg.MinimumBlockCount = 500
   211  	service.EXPECT().GetMostRecentHistorySegmentFromBootstrapPeers(gomock.Any(), []int{}).Times(2).
   212  		Return(peerResponse, map[string]*v2.GetMostRecentNetworkHistorySegmentResponse{"peer1": peerResponse.Response}, nil)
   213  
   214  	first := service.EXPECT().FetchHistorySegment(gomock.Any(), "segment4").Times(1).Return(segment4, nil)
   215  	second := service.EXPECT().FetchHistorySegment(gomock.Any(), "segment3").Times(1).Return(segment3, nil)
   216  	gomock.InOrder(first, second)
   217  
   218  	service.EXPECT().ListAllHistorySegments().Times(1).Return(segments, nil)
   219  	service.EXPECT().LoadNetworkHistoryIntoDatanode(gomock.Any(), chunk, gomock.Any(), true, false).Times(1)
   220  
   221  	firstBlockSpan := service.EXPECT().GetDatanodeBlockSpan(gomock.Any()).Times(1).Return(sqlstore.DatanodeBlockSpan{
   222  		FromHeight: 0,
   223  		ToHeight:   2243,
   224  		HasData:    true,
   225  	}, nil)
   226  
   227  	secondBlockSpan := service.EXPECT().GetDatanodeBlockSpan(gomock.Any()).Times(1).Return(sqlstore.DatanodeBlockSpan{
   228  		FromHeight: 0,
   229  		ToHeight:   4000,
   230  		HasData:    true,
   231  	}, nil)
   232  
   233  	gomock.InOrder(firstBlockSpan, secondBlockSpan)
   234  
   235  	networkhistory.InitialiseDatanodeFromNetworkHistory(ctx, cfg, log, sqlstore.NewDefaultConfig().ConnectionConfig, service, []int{}, false)
   236  }
   237  
   238  func TestLoadingHistoryWithinDatanodeCurrentSpanDoesNothing(t *testing.T) {
   239  	log := logging.NewTestLogger()
   240  	cfg := networkhistory.NewDefaultInitializationConfig()
   241  
   242  	cfg.MinimumBlockCount = 2000
   243  
   244  	ctrl := gomock.NewController(t)
   245  	service := mocks.NewMockNetworkHistory(ctrl)
   246  	ctx := context.Background()
   247  
   248  	peerResponse := &networkhistory.PeerResponse{
   249  		PeerAddr: "",
   250  		Response: &v2.GetMostRecentNetworkHistorySegmentResponse{
   251  			Segment: &v2.HistorySegment{
   252  				FromHeight:               3001,
   253  				ToHeight:                 4000,
   254  				HistorySegmentId:         "segment4",
   255  				PreviousHistorySegmentId: "segment3",
   256  			},
   257  			SwarmKeySeed: "",
   258  		},
   259  	}
   260  
   261  	cfg.MinimumBlockCount = 500
   262  	service.EXPECT().GetMostRecentHistorySegmentFromBootstrapPeers(gomock.Any(), []int{}).Times(1).
   263  		Return(peerResponse, map[string]*v2.GetMostRecentNetworkHistorySegmentResponse{"peer1": peerResponse.Response}, nil)
   264  
   265  	service.EXPECT().GetDatanodeBlockSpan(gomock.Any()).Times(1).Return(sqlstore.DatanodeBlockSpan{
   266  		FromHeight: 0,
   267  		ToHeight:   5000,
   268  		HasData:    true,
   269  	}, nil)
   270  
   271  	assert.Nil(t, networkhistory.InitialiseDatanodeFromNetworkHistory(ctx, cfg, log, sqlstore.NewDefaultConfig().ConnectionConfig, service, []int{}, false))
   272  }
   273  
   274  func TestWhenMinimumBlockCountExceedsAvailableHistory(t *testing.T) {
   275  	log := logging.NewTestLogger()
   276  	cfg := networkhistory.NewDefaultInitializationConfig()
   277  
   278  	cfg.MinimumBlockCount = 5000
   279  
   280  	ctrl := gomock.NewController(t)
   281  	service := mocks.NewMockNetworkHistory(ctrl)
   282  	ctx := context.Background()
   283  
   284  	peerResponse := &networkhistory.PeerResponse{
   285  		PeerAddr: "",
   286  		Response: &v2.GetMostRecentNetworkHistorySegmentResponse{
   287  			Segment: &v2.HistorySegment{
   288  				FromHeight:               1001,
   289  				ToHeight:                 2000,
   290  				HistorySegmentId:         "segment2",
   291  				PreviousHistorySegmentId: "segment1",
   292  			},
   293  			SwarmKeySeed: "",
   294  		},
   295  	}
   296  
   297  	segment1 := makeFullSegment(0, 1000, "", "segment1")
   298  	segment2 := makeFullSegment(1001, 2000, "segment1", "segment2")
   299  	segments := []segment.Full{segment1, segment2}
   300  	chunk := segment.ContiguousHistory[segment.Full]{
   301  		HeightFrom: 0,
   302  		HeightTo:   2000,
   303  		Segments:   segments,
   304  	}
   305  
   306  	service.EXPECT().GetMostRecentHistorySegmentFromBootstrapPeers(gomock.Any(), []int{}).Times(2).
   307  		Return(peerResponse, map[string]*v2.GetMostRecentNetworkHistorySegmentResponse{"peer1": peerResponse.Response}, nil)
   308  
   309  	first := service.EXPECT().FetchHistorySegment(gomock.Any(), "segment2").Times(1).Return(segment2, nil)
   310  	second := service.EXPECT().FetchHistorySegment(gomock.Any(), "segment1").Times(1).Return(segment1, nil)
   311  	gomock.InOrder(first, second)
   312  
   313  	firstBlockSpan := service.EXPECT().GetDatanodeBlockSpan(gomock.Any()).Times(1).Return(sqlstore.DatanodeBlockSpan{}, nil)
   314  	secondBlockSpan := service.EXPECT().GetDatanodeBlockSpan(gomock.Any()).Times(1).Return(sqlstore.DatanodeBlockSpan{FromHeight: 0, ToHeight: 2000, HasData: true}, nil)
   315  	gomock.InOrder(firstBlockSpan, secondBlockSpan)
   316  
   317  	service.EXPECT().ListAllHistorySegments().Times(1).Return(segments, nil)
   318  	service.EXPECT().LoadNetworkHistoryIntoDatanode(gomock.Any(), chunk, gomock.Any(), false, false).Times(1)
   319  
   320  	networkhistory.InitialiseDatanodeFromNetworkHistory(ctx, cfg, log, sqlstore.NewDefaultConfig().ConnectionConfig,
   321  		service, []int{}, false)
   322  }
   323  
   324  func TestInitialiseWithASpecifiedSegment(t *testing.T) {
   325  	log := logging.NewTestLogger()
   326  	cfg := networkhistory.NewDefaultInitializationConfig()
   327  
   328  	cfg.MinimumBlockCount = 2000
   329  	cfg.ToSegment = "segment1"
   330  
   331  	ctrl := gomock.NewController(t)
   332  	service := mocks.NewMockNetworkHistory(ctrl)
   333  	ctx := context.Background()
   334  
   335  	segment1 := makeFullSegment(0, 1000, "", "segment1")
   336  	segments := []segment.Full{segment1}
   337  	chunk := segment.ContiguousHistory[segment.Full]{
   338  		HeightFrom: 0,
   339  		HeightTo:   1000,
   340  		Segments:   segments,
   341  	}
   342  
   343  	service.EXPECT().FetchHistorySegment(gomock.Any(), "segment1").Times(1).Return(segment1, nil)
   344  	service.EXPECT().GetDatanodeBlockSpan(gomock.Any()).Times(1).Return(sqlstore.DatanodeBlockSpan{}, nil)
   345  	service.EXPECT().ListAllHistorySegments().Times(1).Return(segments, nil)
   346  	service.EXPECT().LoadNetworkHistoryIntoDatanode(gomock.Any(), chunk, gomock.Any(), false, false).Times(1)
   347  
   348  	networkhistory.InitialiseDatanodeFromNetworkHistory(ctx, cfg, log, sqlstore.NewDefaultConfig().ConnectionConfig,
   349  		service, []int{}, false)
   350  }
   351  
   352  func TestAutoInitialiseWhenNoActivePeers(t *testing.T) {
   353  	log := logging.NewTestLogger()
   354  	cfg := networkhistory.NewDefaultInitializationConfig()
   355  
   356  	cfg.MinimumBlockCount = 2000
   357  
   358  	ctrl := gomock.NewController(t)
   359  	service := mocks.NewMockNetworkHistory(ctrl)
   360  	ctx := context.Background()
   361  
   362  	cfg.MinimumBlockCount = 1500
   363  	service.EXPECT().GetMostRecentHistorySegmentFromBootstrapPeers(gomock.Any(), []int{}).Times(1).
   364  		Return(nil, nil, errors.New("no peers found"))
   365  
   366  	assert.NotNil(t, networkhistory.InitialiseDatanodeFromNetworkHistory(ctx, cfg, log, sqlstore.NewDefaultConfig().ConnectionConfig,
   367  		service, []int{}, false))
   368  }
   369  
   370  func TestAutoInitialiseWhenNoHistoryAvailableFromPeers(t *testing.T) {
   371  	log := logging.NewTestLogger()
   372  	cfg := networkhistory.NewDefaultInitializationConfig()
   373  
   374  	cfg.MinimumBlockCount = 2000
   375  
   376  	ctrl := gomock.NewController(t)
   377  	service := mocks.NewMockNetworkHistory(ctrl)
   378  	ctx := context.Background()
   379  
   380  	cfg.MinimumBlockCount = 1500
   381  	service.EXPECT().GetMostRecentHistorySegmentFromBootstrapPeers(gomock.Any(), []int{}).Times(1).
   382  		Return(nil, map[string]*v2.GetMostRecentNetworkHistorySegmentResponse{}, nil)
   383  
   384  	assert.NotNil(t, networkhistory.InitialiseDatanodeFromNetworkHistory(ctx, cfg, log, sqlstore.NewDefaultConfig().ConnectionConfig,
   385  		service, []int{}, false))
   386  }
   387  
   388  func TestInitialiseEmptyDataNodeWhenMultipleContiguousHistories(t *testing.T) {
   389  	log := logging.NewTestLogger()
   390  	cfg := networkhistory.NewDefaultInitializationConfig()
   391  
   392  	ctrl := gomock.NewController(t)
   393  	service := mocks.NewMockNetworkHistory(ctrl)
   394  	ctx := context.Background()
   395  
   396  	peerResponse := &networkhistory.PeerResponse{
   397  		PeerAddr: "",
   398  		Response: &v2.GetMostRecentNetworkHistorySegmentResponse{
   399  			Segment: &v2.HistorySegment{
   400  				FromHeight:               6001,
   401  				ToHeight:                 7000,
   402  				HistorySegmentId:         "segment7",
   403  				PreviousHistorySegmentId: "segment6",
   404  			},
   405  			SwarmKeySeed: "",
   406  		},
   407  	}
   408  
   409  	cfg.MinimumBlockCount = 1500
   410  
   411  	segment3 := makeFullSegment(2001, 3000, "", "segment3")
   412  	segment4 := makeFullSegment(3001, 4000, "segment3", "segment4")
   413  
   414  	segment6 := makeFullSegment(5001, 6000, "", "segment6")
   415  	segment7 := makeFullSegment(6001, 7000, "segment6", "segment7")
   416  	allSegments := []segment.Full{segment3, segment4, segment6, segment7}
   417  	lastSegments := []segment.Full{segment6, segment7}
   418  	chunk := segment.ContiguousHistory[segment.Full]{
   419  		HeightFrom: 5001,
   420  		HeightTo:   7000,
   421  		Segments:   lastSegments,
   422  	}
   423  
   424  	service.EXPECT().GetMostRecentHistorySegmentFromBootstrapPeers(gomock.Any(), []int{}).Times(2).
   425  		Return(peerResponse, map[string]*v2.GetMostRecentNetworkHistorySegmentResponse{"peer1": peerResponse.Response}, nil)
   426  
   427  	first := service.EXPECT().FetchHistorySegment(gomock.Any(), "segment7").Times(1).Return(segment7, nil)
   428  	second := service.EXPECT().FetchHistorySegment(gomock.Any(), "segment6").Times(1).Return(segment6, nil)
   429  
   430  	gomock.InOrder(first, second)
   431  
   432  	firstBlockSpan := service.EXPECT().GetDatanodeBlockSpan(gomock.Any()).Times(1).Return(sqlstore.DatanodeBlockSpan{}, nil)
   433  	secondBlockSpan := service.EXPECT().GetDatanodeBlockSpan(gomock.Any()).Times(1).Return(sqlstore.DatanodeBlockSpan{FromHeight: 5001, ToHeight: 7000, HasData: true}, nil)
   434  	gomock.InOrder(firstBlockSpan, secondBlockSpan)
   435  
   436  	service.EXPECT().ListAllHistorySegments().Times(1).Return(allSegments, nil)
   437  	service.EXPECT().LoadNetworkHistoryIntoDatanode(gomock.Any(), chunk, gomock.Any(), false, false).Times(1)
   438  
   439  	networkhistory.InitialiseDatanodeFromNetworkHistory(ctx, cfg, log, sqlstore.NewDefaultConfig().ConnectionConfig, service, []int{}, false)
   440  }
   441  
   442  func TestSelectRootSegment(t *testing.T) {
   443  	responses := map[string]*v2.GetMostRecentNetworkHistorySegmentResponse{
   444  		"1": {Segment: &v2.HistorySegment{FromHeight: 1001, ToHeight: 2000}, SwarmKeySeed: ""},
   445  		"2": {Segment: &v2.HistorySegment{FromHeight: 1001, ToHeight: 3000}, SwarmKeySeed: ""},
   446  		"3": {Segment: &v2.HistorySegment{FromHeight: 1001, ToHeight: 4000}, SwarmKeySeed: ""},
   447  		"4": {Segment: &v2.HistorySegment{FromHeight: 1001, ToHeight: 4000}, SwarmKeySeed: ""},
   448  		"5": {Segment: &v2.HistorySegment{FromHeight: 1001, ToHeight: 3000}, SwarmKeySeed: ""},
   449  		"6": {Segment: &v2.HistorySegment{FromHeight: 1001, ToHeight: 2000}, SwarmKeySeed: ""},
   450  	}
   451  
   452  	selectedResponse := networkhistory.SelectMostRecentHistorySegmentResponse(responses, "")
   453  	assert.Equal(t, int64(4000), selectedResponse.Response.Segment.ToHeight)
   454  }
   455  
   456  func TestSelectRootSegmentWithSwarmKey(t *testing.T) {
   457  	responses := map[string]*v2.GetMostRecentNetworkHistorySegmentResponse{
   458  		"1": {Segment: &v2.HistorySegment{FromHeight: 1001, ToHeight: 2000}, SwarmKeySeed: "A"},
   459  		"2": {Segment: &v2.HistorySegment{FromHeight: 1001, ToHeight: 3000}, SwarmKeySeed: "A"},
   460  		"3": {Segment: &v2.HistorySegment{FromHeight: 1001, ToHeight: 4000}, SwarmKeySeed: "B"},
   461  		"4": {Segment: &v2.HistorySegment{FromHeight: 1001, ToHeight: 4000}, SwarmKeySeed: "D"},
   462  		"5": {Segment: &v2.HistorySegment{FromHeight: 1001, ToHeight: 3000}, SwarmKeySeed: "A"},
   463  		"6": {Segment: &v2.HistorySegment{FromHeight: 1001, ToHeight: 2000}, SwarmKeySeed: "B"},
   464  	}
   465  
   466  	selectedResponse := networkhistory.SelectMostRecentHistorySegmentResponse(responses, "A")
   467  	assert.Equal(t, int64(3000), selectedResponse.Response.Segment.ToHeight)
   468  }
   469  
   470  func TestSelectRootSegmentWithOneSegment(t *testing.T) {
   471  	responses := map[string]*v2.GetMostRecentNetworkHistorySegmentResponse{
   472  		"1": {Segment: &v2.HistorySegment{FromHeight: 1001, ToHeight: 2000}, SwarmKeySeed: ""},
   473  	}
   474  
   475  	selectedResponse := networkhistory.SelectMostRecentHistorySegmentResponse(responses, "")
   476  	assert.Equal(t, int64(2000), selectedResponse.Response.Segment.ToHeight)
   477  }
   478  
   479  func TestSelectRootSegmentWithZeroSegment(t *testing.T) {
   480  	responses := map[string]*v2.GetMostRecentNetworkHistorySegmentResponse{}
   481  
   482  	rootSegment := networkhistory.SelectMostRecentHistorySegmentResponse(responses, "")
   483  	assert.Nil(t, rootSegment)
   484  }