mirror of https://github.com/poanetwork/gecko.git
fix/add unit tests. All pass
This commit is contained in:
parent
9487340729
commit
d69a875039
File diff suppressed because it is too large
Load Diff
|
@ -2272,7 +2272,7 @@ func TestEngineBootstrappingIntoConsensus(t *testing.T) {
|
|||
panic("Unknown vertex requested")
|
||||
}
|
||||
|
||||
sender.GetF = func(inVdr ids.ShortID, reqID uint32, vtxID ids.ID) {
|
||||
sender.GetAncestorsF = func(inVdr ids.ShortID, reqID uint32, vtxID ids.ID) {
|
||||
if !vdrID.Equals(inVdr) {
|
||||
t.Fatalf("Asking wrong validator for vertex")
|
||||
}
|
||||
|
@ -2315,7 +2315,7 @@ func TestEngineBootstrappingIntoConsensus(t *testing.T) {
|
|||
panic("Unknown bytes provided")
|
||||
}
|
||||
|
||||
te.Put(vdrID, *requestID, vtxID0, vtxBytes0)
|
||||
te.MultiPut(vdrID, *requestID, [][]byte{vtxBytes0})
|
||||
|
||||
vm.ParseTxF = nil
|
||||
st.parseVertex = nil
|
||||
|
|
|
@ -72,8 +72,9 @@ func newConfig(t *testing.T) (BootstrapConfig, ids.ShortID, *common.SenderTest,
|
|||
}, peerID, sender, vm
|
||||
}
|
||||
|
||||
// Single node in the accepted frontier; no need to fecth parent
|
||||
func TestBootstrapperSingleFrontier(t *testing.T) {
|
||||
config, peerID, sender, vm := newConfig(t)
|
||||
config, _, _, vm := newConfig(t)
|
||||
|
||||
blkID0 := ids.Empty.Prefix(0)
|
||||
blkID1 := ids.Empty.Prefix(1)
|
||||
|
@ -98,6 +99,8 @@ func TestBootstrapperSingleFrontier(t *testing.T) {
|
|||
bs := bootstrapper{}
|
||||
bs.metrics.Initialize(config.Context.Log, fmt.Sprintf("gecko_%s", config.Context.ChainID), prometheus.NewRegistry())
|
||||
bs.Initialize(config)
|
||||
finished := new(bool)
|
||||
bs.onFinished = func() error { *finished = true; return nil }
|
||||
|
||||
acceptedIDs := ids.Set{}
|
||||
acceptedIDs.Add(blkID1)
|
||||
|
@ -105,57 +108,38 @@ func TestBootstrapperSingleFrontier(t *testing.T) {
|
|||
vm.GetBlockF = func(blkID ids.ID) (snowman.Block, error) {
|
||||
switch {
|
||||
case blkID.Equals(blkID1):
|
||||
return nil, errUnknownBlock
|
||||
return blk1, nil
|
||||
case blkID.Equals(blkID0):
|
||||
return blk0, nil
|
||||
default:
|
||||
t.Fatal(errUnknownBlock)
|
||||
panic(errUnknownBlock)
|
||||
}
|
||||
}
|
||||
|
||||
reqID := new(uint32)
|
||||
sender.GetF = func(vdr ids.ShortID, innerReqID uint32, blkID ids.ID) {
|
||||
if !vdr.Equals(peerID) {
|
||||
t.Fatalf("Should have requested block from %s, requested from %s", peerID, vdr)
|
||||
}
|
||||
switch {
|
||||
case blkID.Equals(blkID1):
|
||||
default:
|
||||
t.Fatalf("Requested unknown vertex")
|
||||
}
|
||||
|
||||
*reqID = innerReqID
|
||||
}
|
||||
|
||||
bs.ForceAccepted(acceptedIDs)
|
||||
|
||||
vm.GetBlockF = nil
|
||||
sender.GetF = nil
|
||||
|
||||
vm.ParseBlockF = func(blkBytes []byte) (snowman.Block, error) {
|
||||
switch {
|
||||
case bytes.Equal(blkBytes, blkBytes1):
|
||||
return blk1, nil
|
||||
case bytes.Equal(blkBytes, blkBytes0):
|
||||
return blk0, nil
|
||||
}
|
||||
t.Fatal(errUnknownBlock)
|
||||
return nil, errUnknownBlock
|
||||
}
|
||||
|
||||
finished := new(bool)
|
||||
bs.onFinished = func() error { *finished = true; return nil }
|
||||
|
||||
bs.Put(peerID, *reqID, blkID1, blkBytes1)
|
||||
|
||||
vm.ParseBlockF = nil
|
||||
bs.onFinished = nil
|
||||
|
||||
if !*finished {
|
||||
if err := bs.ForceAccepted(acceptedIDs); err != nil { // should finish
|
||||
t.Fatal(err)
|
||||
} else if !*finished {
|
||||
t.Fatalf("Bootstrapping should have finished")
|
||||
}
|
||||
if blk1.Status() != choices.Accepted {
|
||||
} else if blk1.Status() != choices.Accepted {
|
||||
t.Fatalf("Block should be accepted")
|
||||
}
|
||||
}
|
||||
|
||||
// Requests the unknown block and gets back a MultiPut with unexpected request ID.
|
||||
// Requests again and gets response from unexpected peer.
|
||||
// Requests again and gets an unexpected block.
|
||||
// Requests again and gets the expected block.
|
||||
func TestBootstrapperUnknownByzantineResponse(t *testing.T) {
|
||||
config, peerID, sender, vm := newConfig(t)
|
||||
|
||||
|
@ -167,103 +151,6 @@ func TestBootstrapperUnknownByzantineResponse(t *testing.T) {
|
|||
blkBytes1 := []byte{1}
|
||||
blkBytes2 := []byte{2}
|
||||
|
||||
blk0 := &Blk{
|
||||
id: blkID0,
|
||||
height: 0,
|
||||
status: choices.Accepted,
|
||||
bytes: blkBytes0,
|
||||
}
|
||||
blk1 := &Blk{
|
||||
parent: blk0,
|
||||
id: blkID1,
|
||||
height: 1,
|
||||
status: choices.Processing,
|
||||
bytes: blkBytes1,
|
||||
}
|
||||
blk2 := &Blk{
|
||||
parent: blk1,
|
||||
id: blkID2,
|
||||
height: 2,
|
||||
status: choices.Processing,
|
||||
bytes: blkBytes2,
|
||||
}
|
||||
|
||||
bs := bootstrapper{}
|
||||
bs.metrics.Initialize(config.Context.Log, fmt.Sprintf("gecko_%s", config.Context.ChainID), prometheus.NewRegistry())
|
||||
bs.Initialize(config)
|
||||
|
||||
acceptedIDs := ids.Set{}
|
||||
acceptedIDs.Add(blkID1)
|
||||
|
||||
vm.GetBlockF = func(blkID ids.ID) (snowman.Block, error) {
|
||||
switch {
|
||||
case blkID.Equals(blkID1):
|
||||
return nil, errUnknownBlock
|
||||
default:
|
||||
t.Fatal(errUnknownBlock)
|
||||
panic(errUnknownBlock)
|
||||
}
|
||||
}
|
||||
|
||||
requestID := new(uint32)
|
||||
sender.GetF = func(vdr ids.ShortID, reqID uint32, vtxID ids.ID) {
|
||||
if !vdr.Equals(peerID) {
|
||||
t.Fatalf("Should have requested block from %s, requested from %s", peerID, vdr)
|
||||
}
|
||||
switch {
|
||||
case vtxID.Equals(blkID1):
|
||||
default:
|
||||
t.Fatalf("Requested unknown block")
|
||||
}
|
||||
|
||||
*requestID = reqID
|
||||
}
|
||||
|
||||
bs.ForceAccepted(acceptedIDs)
|
||||
|
||||
vm.GetBlockF = nil
|
||||
|
||||
vm.ParseBlockF = func(blkBytes []byte) (snowman.Block, error) {
|
||||
switch {
|
||||
case bytes.Equal(blkBytes, blkBytes1):
|
||||
return blk1, nil
|
||||
case bytes.Equal(blkBytes, blkBytes2):
|
||||
return blk2, nil
|
||||
}
|
||||
t.Fatal(errUnknownBlock)
|
||||
return nil, errUnknownBlock
|
||||
}
|
||||
|
||||
finished := new(bool)
|
||||
bs.onFinished = func() error { *finished = true; return nil }
|
||||
|
||||
bs.Put(peerID, *requestID, blkID2, blkBytes2)
|
||||
bs.Put(peerID, *requestID, blkID1, blkBytes1)
|
||||
|
||||
vm.ParseBlockF = nil
|
||||
|
||||
if !*finished {
|
||||
t.Fatalf("Bootstrapping should have finished")
|
||||
}
|
||||
if blk1.Status() != choices.Accepted {
|
||||
t.Fatalf("Block should be accepted")
|
||||
}
|
||||
if blk2.Status() != choices.Processing {
|
||||
t.Fatalf("Block should be processing")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBootstrapperDependency(t *testing.T) {
|
||||
config, peerID, sender, vm := newConfig(t)
|
||||
|
||||
blkID0 := ids.Empty.Prefix(0)
|
||||
blkID1 := ids.Empty.Prefix(1)
|
||||
blkID2 := ids.Empty.Prefix(2)
|
||||
|
||||
blkBytes0 := []byte{0}
|
||||
blkBytes1 := []byte{1}
|
||||
blkBytes2 := []byte{2}
|
||||
|
||||
blk0 := &Blk{
|
||||
id: blkID0,
|
||||
height: 0,
|
||||
|
@ -288,42 +175,36 @@ func TestBootstrapperDependency(t *testing.T) {
|
|||
bs := bootstrapper{}
|
||||
bs.metrics.Initialize(config.Context.Log, fmt.Sprintf("gecko_%s", config.Context.ChainID), prometheus.NewRegistry())
|
||||
bs.Initialize(config)
|
||||
finished := new(bool)
|
||||
bs.onFinished = func() error { *finished = true; return nil }
|
||||
|
||||
acceptedIDs := ids.Set{}
|
||||
acceptedIDs.Add(blkID2)
|
||||
|
||||
parsedBlk1 := false
|
||||
vm.GetBlockF = func(blkID ids.ID) (snowman.Block, error) {
|
||||
switch {
|
||||
case blkID.Equals(blkID0):
|
||||
return blk0, nil
|
||||
case blkID.Equals(blkID1):
|
||||
if parsedBlk1 {
|
||||
return blk1, nil
|
||||
}
|
||||
return nil, errUnknownBlock
|
||||
case blkID.Equals(blkID2):
|
||||
return blk2, nil
|
||||
default:
|
||||
t.Fatalf("Requested unknown block")
|
||||
panic("Requested unknown block")
|
||||
t.Fatal(errUnknownBlock)
|
||||
panic(errUnknownBlock)
|
||||
}
|
||||
}
|
||||
|
||||
requestID := new(uint32)
|
||||
sender.GetF = func(vdr ids.ShortID, reqID uint32, vtxID ids.ID) {
|
||||
if !vdr.Equals(peerID) {
|
||||
t.Fatalf("Should have requested block from %s, requested from %s", peerID, vdr)
|
||||
}
|
||||
switch {
|
||||
case vtxID.Equals(blkID1):
|
||||
default:
|
||||
t.Fatalf("Requested unknown block")
|
||||
}
|
||||
|
||||
*requestID = reqID
|
||||
}
|
||||
|
||||
bs.ForceAccepted(acceptedIDs)
|
||||
|
||||
vm.GetBlockF = nil
|
||||
sender.GetF = nil
|
||||
|
||||
vm.ParseBlockF = func(blkBytes []byte) (snowman.Block, error) {
|
||||
switch {
|
||||
case bytes.Equal(blkBytes, blkBytes0):
|
||||
return blk0, nil
|
||||
case bytes.Equal(blkBytes, blkBytes1):
|
||||
blk1.status = choices.Processing
|
||||
parsedBlk1 = true
|
||||
return blk1, nil
|
||||
case bytes.Equal(blkBytes, blkBytes2):
|
||||
return blk2, nil
|
||||
|
@ -332,20 +213,315 @@ func TestBootstrapperDependency(t *testing.T) {
|
|||
return nil, errUnknownBlock
|
||||
}
|
||||
|
||||
blk1.status = choices.Processing
|
||||
requestID := new(uint32)
|
||||
sender.GetAncestorsF = func(vdr ids.ShortID, reqID uint32, vtxID ids.ID) {
|
||||
if !vdr.Equals(peerID) {
|
||||
t.Fatalf("Should have requested block from %s, requested from %s", peerID, vdr)
|
||||
}
|
||||
switch {
|
||||
case vtxID.Equals(blkID1):
|
||||
default:
|
||||
t.Fatalf("should have requested blk1")
|
||||
}
|
||||
*requestID = reqID
|
||||
}
|
||||
|
||||
if err := bs.ForceAccepted(acceptedIDs); err != nil { // should request blk1
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
oldReqID := *requestID
|
||||
if err := bs.MultiPut(peerID, *requestID+1, [][]byte{blkBytes1}); err != nil { // respond with wrong request ID
|
||||
t.Fatal(err)
|
||||
} else if oldReqID != *requestID {
|
||||
t.Fatal("should not have sent new request")
|
||||
}
|
||||
|
||||
if err := bs.MultiPut(ids.NewShortID([20]byte{1, 2, 3}), *requestID, [][]byte{blkBytes1}); err != nil { // respond from wrong peer
|
||||
t.Fatal(err)
|
||||
} else if oldReqID != *requestID {
|
||||
t.Fatal("should not have sent new request")
|
||||
}
|
||||
|
||||
if err := bs.MultiPut(peerID, *requestID, [][]byte{blkBytes0}); err != nil { // respond with wrong block
|
||||
t.Fatal(err)
|
||||
} else if oldReqID == *requestID {
|
||||
t.Fatal("should have sent new request")
|
||||
}
|
||||
|
||||
if err := bs.MultiPut(peerID, *requestID, [][]byte{blkBytes1}); err != nil { // respond with right block
|
||||
t.Fatal(err)
|
||||
} else if !*finished {
|
||||
t.Fatalf("Bootstrapping should have finished")
|
||||
} else if blk0.Status() != choices.Accepted {
|
||||
t.Fatalf("Block should be accepted")
|
||||
} else if blk1.Status() != choices.Accepted {
|
||||
t.Fatalf("Block should be accepted")
|
||||
} else if blk2.Status() != choices.Accepted {
|
||||
t.Fatalf("Block should be accepted")
|
||||
}
|
||||
}
|
||||
|
||||
// There are multiple needed blocks and MultiPut returns one at a time
|
||||
func TestBootstrapperPartialFetch(t *testing.T) {
|
||||
config, peerID, sender, vm := newConfig(t)
|
||||
|
||||
blkID0 := ids.Empty.Prefix(0)
|
||||
blkID1 := ids.Empty.Prefix(1)
|
||||
blkID2 := ids.Empty.Prefix(2)
|
||||
blkID3 := ids.Empty.Prefix(3)
|
||||
|
||||
blkBytes0 := []byte{0}
|
||||
blkBytes1 := []byte{1}
|
||||
blkBytes2 := []byte{2}
|
||||
blkBytes3 := []byte{3}
|
||||
|
||||
blk0 := &Blk{
|
||||
id: blkID0,
|
||||
height: 0,
|
||||
status: choices.Accepted,
|
||||
bytes: blkBytes0,
|
||||
}
|
||||
blk1 := &Blk{
|
||||
parent: blk0,
|
||||
id: blkID1,
|
||||
height: 1,
|
||||
status: choices.Unknown,
|
||||
bytes: blkBytes1,
|
||||
}
|
||||
blk2 := &Blk{
|
||||
parent: blk1,
|
||||
id: blkID2,
|
||||
height: 2,
|
||||
status: choices.Unknown,
|
||||
bytes: blkBytes2,
|
||||
}
|
||||
blk3 := &Blk{
|
||||
parent: blk2,
|
||||
id: blkID3,
|
||||
height: 3,
|
||||
status: choices.Processing,
|
||||
bytes: blkBytes3,
|
||||
}
|
||||
|
||||
bs := bootstrapper{}
|
||||
bs.metrics.Initialize(config.Context.Log, fmt.Sprintf("gecko_%s", config.Context.ChainID), prometheus.NewRegistry())
|
||||
bs.Initialize(config)
|
||||
finished := new(bool)
|
||||
bs.onFinished = func() error { *finished = true; return nil }
|
||||
|
||||
bs.Put(peerID, *requestID, blkID1, blkBytes1)
|
||||
acceptedIDs := ids.Set{}
|
||||
acceptedIDs.Add(blkID3)
|
||||
|
||||
parsedBlk1 := false
|
||||
parsedBlk2 := false
|
||||
vm.GetBlockF = func(blkID ids.ID) (snowman.Block, error) {
|
||||
switch {
|
||||
case blkID.Equals(blkID0):
|
||||
return blk0, nil
|
||||
case blkID.Equals(blkID1):
|
||||
if parsedBlk1 {
|
||||
return blk1, nil
|
||||
}
|
||||
return nil, errUnknownBlock
|
||||
case blkID.Equals(blkID2):
|
||||
if parsedBlk2 {
|
||||
return blk2, nil
|
||||
}
|
||||
return nil, errUnknownBlock
|
||||
case blkID.Equals(blkID3):
|
||||
return blk3, nil
|
||||
default:
|
||||
t.Fatal(errUnknownBlock)
|
||||
panic(errUnknownBlock)
|
||||
}
|
||||
}
|
||||
vm.ParseBlockF = func(blkBytes []byte) (snowman.Block, error) {
|
||||
switch {
|
||||
case bytes.Equal(blkBytes, blkBytes0):
|
||||
return blk0, nil
|
||||
case bytes.Equal(blkBytes, blkBytes1):
|
||||
blk1.status = choices.Processing
|
||||
parsedBlk1 = true
|
||||
return blk1, nil
|
||||
case bytes.Equal(blkBytes, blkBytes2):
|
||||
blk2.status = choices.Processing
|
||||
parsedBlk2 = true
|
||||
return blk2, nil
|
||||
case bytes.Equal(blkBytes, blkBytes3):
|
||||
return blk3, nil
|
||||
}
|
||||
t.Fatal(errUnknownBlock)
|
||||
return nil, errUnknownBlock
|
||||
}
|
||||
|
||||
requestID := new(uint32)
|
||||
requested := ids.Empty
|
||||
sender.GetAncestorsF = func(vdr ids.ShortID, reqID uint32, vtxID ids.ID) {
|
||||
if !vdr.Equals(peerID) {
|
||||
t.Fatalf("Should have requested block from %s, requested from %s", peerID, vdr)
|
||||
}
|
||||
switch {
|
||||
case vtxID.Equals(blkID1), vtxID.Equals(blkID2):
|
||||
default:
|
||||
t.Fatalf("should have requested blk1 or blk2")
|
||||
}
|
||||
*requestID = reqID
|
||||
requested = vtxID
|
||||
}
|
||||
|
||||
if err := bs.ForceAccepted(acceptedIDs); err != nil { // should request blk2
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := bs.MultiPut(peerID, *requestID, [][]byte{blkBytes2}); err != nil { // respond with blk2
|
||||
t.Fatal(err)
|
||||
} else if !requested.Equals(blkID1) {
|
||||
t.Fatal("should have requested blk1")
|
||||
}
|
||||
|
||||
if err := bs.MultiPut(peerID, *requestID, [][]byte{blkBytes1}); err != nil { // respond with blk1
|
||||
t.Fatal(err)
|
||||
} else if !requested.Equals(blkID1) {
|
||||
t.Fatal("should not have requested another block")
|
||||
}
|
||||
|
||||
if !*finished {
|
||||
t.Fatalf("Bootstrapping should have finished")
|
||||
}
|
||||
if blk1.Status() != choices.Accepted {
|
||||
} else if blk0.Status() != choices.Accepted {
|
||||
t.Fatalf("Block should be accepted")
|
||||
} else if blk1.Status() != choices.Accepted {
|
||||
t.Fatalf("Block should be accepted")
|
||||
} else if blk2.Status() != choices.Accepted {
|
||||
t.Fatalf("Block should be accepted")
|
||||
}
|
||||
if blk2.Status() != choices.Accepted {
|
||||
}
|
||||
|
||||
// There are multiple needed blocks and MultiPut returns all at once
|
||||
func TestBootstrapperMultiPut(t *testing.T) {
|
||||
config, peerID, sender, vm := newConfig(t)
|
||||
|
||||
blkID0 := ids.Empty.Prefix(0)
|
||||
blkID1 := ids.Empty.Prefix(1)
|
||||
blkID2 := ids.Empty.Prefix(2)
|
||||
blkID3 := ids.Empty.Prefix(3)
|
||||
|
||||
blkBytes0 := []byte{0}
|
||||
blkBytes1 := []byte{1}
|
||||
blkBytes2 := []byte{2}
|
||||
blkBytes3 := []byte{3}
|
||||
|
||||
blk0 := &Blk{
|
||||
id: blkID0,
|
||||
height: 0,
|
||||
status: choices.Accepted,
|
||||
bytes: blkBytes0,
|
||||
}
|
||||
blk1 := &Blk{
|
||||
parent: blk0,
|
||||
id: blkID1,
|
||||
height: 1,
|
||||
status: choices.Unknown,
|
||||
bytes: blkBytes1,
|
||||
}
|
||||
blk2 := &Blk{
|
||||
parent: blk1,
|
||||
id: blkID2,
|
||||
height: 2,
|
||||
status: choices.Unknown,
|
||||
bytes: blkBytes2,
|
||||
}
|
||||
blk3 := &Blk{
|
||||
parent: blk2,
|
||||
id: blkID3,
|
||||
height: 3,
|
||||
status: choices.Processing,
|
||||
bytes: blkBytes3,
|
||||
}
|
||||
|
||||
bs := bootstrapper{}
|
||||
bs.metrics.Initialize(config.Context.Log, fmt.Sprintf("gecko_%s", config.Context.ChainID), prometheus.NewRegistry())
|
||||
bs.Initialize(config)
|
||||
finished := new(bool)
|
||||
bs.onFinished = func() error { *finished = true; return nil }
|
||||
|
||||
acceptedIDs := ids.Set{}
|
||||
acceptedIDs.Add(blkID3)
|
||||
|
||||
parsedBlk1 := false
|
||||
parsedBlk2 := false
|
||||
vm.GetBlockF = func(blkID ids.ID) (snowman.Block, error) {
|
||||
switch {
|
||||
case blkID.Equals(blkID0):
|
||||
return blk0, nil
|
||||
case blkID.Equals(blkID1):
|
||||
if parsedBlk1 {
|
||||
return blk1, nil
|
||||
}
|
||||
return nil, errUnknownBlock
|
||||
case blkID.Equals(blkID2):
|
||||
if parsedBlk2 {
|
||||
return blk2, nil
|
||||
}
|
||||
return nil, errUnknownBlock
|
||||
case blkID.Equals(blkID3):
|
||||
return blk3, nil
|
||||
default:
|
||||
t.Fatal(errUnknownBlock)
|
||||
panic(errUnknownBlock)
|
||||
}
|
||||
}
|
||||
vm.ParseBlockF = func(blkBytes []byte) (snowman.Block, error) {
|
||||
switch {
|
||||
case bytes.Equal(blkBytes, blkBytes0):
|
||||
return blk0, nil
|
||||
case bytes.Equal(blkBytes, blkBytes1):
|
||||
blk1.status = choices.Processing
|
||||
parsedBlk1 = true
|
||||
return blk1, nil
|
||||
case bytes.Equal(blkBytes, blkBytes2):
|
||||
blk2.status = choices.Processing
|
||||
parsedBlk2 = true
|
||||
return blk2, nil
|
||||
case bytes.Equal(blkBytes, blkBytes3):
|
||||
return blk3, nil
|
||||
}
|
||||
t.Fatal(errUnknownBlock)
|
||||
return nil, errUnknownBlock
|
||||
}
|
||||
|
||||
requestID := new(uint32)
|
||||
requested := ids.Empty
|
||||
sender.GetAncestorsF = func(vdr ids.ShortID, reqID uint32, vtxID ids.ID) {
|
||||
if !vdr.Equals(peerID) {
|
||||
t.Fatalf("Should have requested block from %s, requested from %s", peerID, vdr)
|
||||
}
|
||||
switch {
|
||||
case vtxID.Equals(blkID1), vtxID.Equals(blkID2):
|
||||
default:
|
||||
t.Fatalf("should have requested blk1 or blk2")
|
||||
}
|
||||
*requestID = reqID
|
||||
requested = vtxID
|
||||
}
|
||||
|
||||
if err := bs.ForceAccepted(acceptedIDs); err != nil { // should request blk2
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := bs.MultiPut(peerID, *requestID, [][]byte{blkBytes2, blkBytes1}); err != nil { // respond with blk2 and blk1
|
||||
t.Fatal(err)
|
||||
} else if !requested.Equals(blkID2) {
|
||||
t.Fatal("should not have requested another block")
|
||||
}
|
||||
|
||||
if !*finished {
|
||||
t.Fatalf("Bootstrapping should have finished")
|
||||
} else if blk0.Status() != choices.Accepted {
|
||||
t.Fatalf("Block should be accepted")
|
||||
} else if blk1.Status() != choices.Accepted {
|
||||
t.Fatalf("Block should be accepted")
|
||||
} else if blk2.Status() != choices.Accepted {
|
||||
t.Fatalf("Block should be accepted")
|
||||
}
|
||||
}
|
||||
|
@ -426,164 +602,3 @@ func TestBootstrapperFilterAccepted(t *testing.T) {
|
|||
t.Fatalf("Blk shouldn't be accepted")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBootstrapperPartialFetch(t *testing.T) {
|
||||
config, _, sender, vm := newConfig(t)
|
||||
|
||||
blkID0 := ids.Empty.Prefix(0)
|
||||
blkID1 := ids.Empty.Prefix(1)
|
||||
|
||||
blkBytes0 := []byte{0}
|
||||
|
||||
blk0 := &Blk{
|
||||
id: blkID0,
|
||||
height: 0,
|
||||
status: choices.Accepted,
|
||||
bytes: blkBytes0,
|
||||
}
|
||||
|
||||
bs := bootstrapper{}
|
||||
bs.metrics.Initialize(config.Context.Log, fmt.Sprintf("gecko_%s", config.Context.ChainID), prometheus.NewRegistry())
|
||||
bs.Initialize(config)
|
||||
|
||||
acceptedIDs := ids.Set{}
|
||||
acceptedIDs.Add(
|
||||
blkID0,
|
||||
blkID1,
|
||||
)
|
||||
|
||||
vm.GetBlockF = func(blkID ids.ID) (snowman.Block, error) {
|
||||
switch {
|
||||
case blkID.Equals(blkID0):
|
||||
return blk0, nil
|
||||
case blkID.Equals(blkID1):
|
||||
return nil, errUnknownBlock
|
||||
default:
|
||||
t.Fatal(errUnknownBlock)
|
||||
panic(errUnknownBlock)
|
||||
}
|
||||
}
|
||||
|
||||
sender.CantGet = false
|
||||
bs.onFinished = func() error { return nil }
|
||||
|
||||
bs.ForceAccepted(acceptedIDs)
|
||||
|
||||
if bs.finished {
|
||||
t.Fatalf("should have requested a block")
|
||||
}
|
||||
|
||||
if bs.pending.Len() != 1 {
|
||||
t.Fatalf("wrong number pending")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBootstrapperWrongIDByzantineResponse(t *testing.T) {
|
||||
config, peerID, sender, vm := newConfig(t)
|
||||
|
||||
blkID0 := ids.Empty.Prefix(0)
|
||||
blkID1 := ids.Empty.Prefix(1)
|
||||
blkID2 := ids.Empty.Prefix(2)
|
||||
|
||||
blkBytes0 := []byte{0}
|
||||
blkBytes1 := []byte{1}
|
||||
blkBytes2 := []byte{2}
|
||||
|
||||
blk0 := &Blk{
|
||||
id: blkID0,
|
||||
height: 0,
|
||||
status: choices.Accepted,
|
||||
bytes: blkBytes0,
|
||||
}
|
||||
blk1 := &Blk{
|
||||
parent: blk0,
|
||||
id: blkID1,
|
||||
height: 1,
|
||||
status: choices.Processing,
|
||||
bytes: blkBytes1,
|
||||
}
|
||||
blk2 := &Blk{
|
||||
parent: blk1,
|
||||
id: blkID2,
|
||||
height: 2,
|
||||
status: choices.Processing,
|
||||
bytes: blkBytes2,
|
||||
}
|
||||
|
||||
bs := bootstrapper{}
|
||||
bs.metrics.Initialize(config.Context.Log, fmt.Sprintf("gecko_%s", config.Context.ChainID), prometheus.NewRegistry())
|
||||
bs.Initialize(config)
|
||||
|
||||
acceptedIDs := ids.Set{}
|
||||
acceptedIDs.Add(blkID1)
|
||||
|
||||
vm.GetBlockF = func(blkID ids.ID) (snowman.Block, error) {
|
||||
switch {
|
||||
case blkID.Equals(blkID1):
|
||||
return nil, errUnknownBlock
|
||||
default:
|
||||
t.Fatal(errUnknownBlock)
|
||||
panic(errUnknownBlock)
|
||||
}
|
||||
}
|
||||
|
||||
requestID := new(uint32)
|
||||
sender.GetF = func(vdr ids.ShortID, reqID uint32, vtxID ids.ID) {
|
||||
if !vdr.Equals(peerID) {
|
||||
t.Fatalf("Should have requested block from %s, requested from %s", peerID, vdr)
|
||||
}
|
||||
switch {
|
||||
case vtxID.Equals(blkID1):
|
||||
default:
|
||||
t.Fatalf("Requested unknown block")
|
||||
}
|
||||
|
||||
*requestID = reqID
|
||||
}
|
||||
|
||||
bs.ForceAccepted(acceptedIDs)
|
||||
|
||||
vm.GetBlockF = nil
|
||||
sender.GetF = nil
|
||||
|
||||
vm.ParseBlockF = func(blkBytes []byte) (snowman.Block, error) {
|
||||
switch {
|
||||
case bytes.Equal(blkBytes, blkBytes2):
|
||||
return blk2, nil
|
||||
}
|
||||
t.Fatal(errUnknownBlock)
|
||||
return nil, errUnknownBlock
|
||||
}
|
||||
|
||||
sender.CantGet = false
|
||||
|
||||
bs.Put(peerID, *requestID, blkID1, blkBytes2)
|
||||
|
||||
sender.CantGet = true
|
||||
|
||||
vm.ParseBlockF = func(blkBytes []byte) (snowman.Block, error) {
|
||||
switch {
|
||||
case bytes.Equal(blkBytes, blkBytes1):
|
||||
return blk1, nil
|
||||
}
|
||||
t.Fatal(errUnknownBlock)
|
||||
return nil, errUnknownBlock
|
||||
}
|
||||
|
||||
finished := new(bool)
|
||||
bs.onFinished = func() error { *finished = true; return nil }
|
||||
|
||||
bs.Put(peerID, *requestID, blkID1, blkBytes1)
|
||||
|
||||
vm.ParseBlockF = nil
|
||||
|
||||
if !*finished {
|
||||
t.Fatalf("Bootstrapping should have finished")
|
||||
}
|
||||
if blk1.Status() != choices.Accepted {
|
||||
t.Fatalf("Block should be accepted")
|
||||
}
|
||||
if blk2.Status() != choices.Processing {
|
||||
t.Fatalf("Block should be processing")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ type ExternalSenderTest struct {
|
|||
|
||||
CantGetAcceptedFrontier, CantAcceptedFrontier,
|
||||
CantGetAccepted, CantAccepted,
|
||||
CantGet, CantPut,
|
||||
CantGet, CantGetAncestors, CantPut, CantMultiPut,
|
||||
CantPullQuery, CantPushQuery, CantChits,
|
||||
CantGossip bool
|
||||
|
||||
|
@ -24,8 +24,9 @@ type ExternalSenderTest struct {
|
|||
AcceptedFrontierF func(validatorID ids.ShortID, chainID ids.ID, requestID uint32, containerIDs ids.Set)
|
||||
GetAcceptedF func(validatorIDs ids.ShortSet, chainID ids.ID, requestID uint32, containerIDs ids.Set)
|
||||
AcceptedF func(validatorID ids.ShortID, chainID ids.ID, requestID uint32, containerIDs ids.Set)
|
||||
GetF func(validatorID ids.ShortID, chainID ids.ID, requestID uint32, containerID ids.ID)
|
||||
GetF, GetAncestorsF func(validatorID ids.ShortID, chainID ids.ID, requestID uint32, containerID ids.ID)
|
||||
PutF func(validatorID ids.ShortID, chainID ids.ID, requestID uint32, containerID ids.ID, container []byte)
|
||||
MultiPutF func(validatorID ids.ShortID, chainID ids.ID, requestID uint32, containers [][]byte)
|
||||
PushQueryF func(validatorIDs ids.ShortSet, chainID ids.ID, requestID uint32, containerID ids.ID, container []byte)
|
||||
PullQueryF func(validatorIDs ids.ShortSet, chainID ids.ID, requestID uint32, containerID ids.ID)
|
||||
ChitsF func(validatorID ids.ShortID, chainID ids.ID, requestID uint32, votes ids.Set)
|
||||
|
@ -39,7 +40,9 @@ func (s *ExternalSenderTest) Default(cant bool) {
|
|||
s.CantGetAccepted = cant
|
||||
s.CantAccepted = cant
|
||||
s.CantGet = cant
|
||||
s.CantGetAncestors = cant
|
||||
s.CantPut = cant
|
||||
s.CantMultiPut = cant
|
||||
s.CantPullQuery = cant
|
||||
s.CantPushQuery = cant
|
||||
s.CantChits = cant
|
||||
|
@ -111,6 +114,19 @@ func (s *ExternalSenderTest) Get(vdr ids.ShortID, chainID ids.ID, requestID uint
|
|||
}
|
||||
}
|
||||
|
||||
// GetAncestors calls GetAncestorsF if it was initialized. If it wasn't initialized and this
|
||||
// function shouldn't be called and testing was initialized, then testing will
|
||||
// fail.
|
||||
func (s *ExternalSenderTest) GetAncestors(vdr ids.ShortID, chainID ids.ID, requestID uint32, vtxID ids.ID) {
|
||||
if s.GetAncestorsF != nil {
|
||||
s.GetAncestorsF(vdr, chainID, requestID, vtxID)
|
||||
} else if s.CantGetAncestors && s.T != nil {
|
||||
s.T.Fatalf("Unexpectedly called GetAncestors")
|
||||
} else if s.CantGetAncestors && s.B != nil {
|
||||
s.B.Fatalf("Unexpectedly called GetAncestors")
|
||||
}
|
||||
}
|
||||
|
||||
// Put calls PutF if it was initialized. If it wasn't initialized and this
|
||||
// function shouldn't be called and testing was initialized, then testing will
|
||||
// fail.
|
||||
|
@ -124,6 +140,19 @@ func (s *ExternalSenderTest) Put(vdr ids.ShortID, chainID ids.ID, requestID uint
|
|||
}
|
||||
}
|
||||
|
||||
// MultiPut calls MultiPutF if it was initialized. If it wasn't initialized and this
|
||||
// function shouldn't be called and testing was initialized, then testing will
|
||||
// fail.
|
||||
func (s *ExternalSenderTest) MultiPut(vdr ids.ShortID, chainID ids.ID, requestID uint32, vtxs [][]byte) {
|
||||
if s.MultiPutF != nil {
|
||||
s.MultiPutF(vdr, chainID, requestID, vtxs)
|
||||
} else if s.CantMultiPut && s.T != nil {
|
||||
s.T.Fatalf("Unexpectedly called MultiPut")
|
||||
} else if s.CantMultiPut && s.B != nil {
|
||||
s.B.Fatalf("Unexpectedly called MultiPut")
|
||||
}
|
||||
}
|
||||
|
||||
// PushQuery calls PushQueryF if it was initialized. If it wasn't initialized
|
||||
// and this function shouldn't be called and testing was initialized, then
|
||||
// testing will fail.
|
||||
|
|
|
@ -1551,8 +1551,9 @@ func TestBootstrapPartiallyAccepted(t *testing.T) {
|
|||
|
||||
advanceTimePreference := advanceTimeBlk.Options()[0]
|
||||
|
||||
peerID := ids.NewShortID([20]byte{1, 2, 3, 4, 5, 4, 3, 2, 1})
|
||||
vdrs := validators.NewSet()
|
||||
vdrs.Add(validators.NewValidator(ctx.NodeID, 1))
|
||||
vdrs.Add(validators.NewValidator(peerID, 1))
|
||||
beacons := vdrs
|
||||
|
||||
timeoutManager := timeout.Manager{}
|
||||
|
@ -1617,23 +1618,23 @@ func TestBootstrapPartiallyAccepted(t *testing.T) {
|
|||
|
||||
frontier := ids.Set{}
|
||||
frontier.Add(advanceTimeBlkID)
|
||||
engine.AcceptedFrontier(ctx.NodeID, *reqID, frontier)
|
||||
engine.AcceptedFrontier(peerID, *reqID, frontier)
|
||||
|
||||
externalSender.GetAcceptedF = nil
|
||||
externalSender.GetF = func(_ ids.ShortID, _ ids.ID, requestID uint32, containerID ids.ID) {
|
||||
externalSender.GetAncestorsF = func(_ ids.ShortID, _ ids.ID, requestID uint32, containerID ids.ID) {
|
||||
*reqID = requestID
|
||||
if !containerID.Equals(advanceTimeBlkID) {
|
||||
t.Fatalf("wrong block requested")
|
||||
}
|
||||
}
|
||||
|
||||
engine.Accepted(ctx.NodeID, *reqID, frontier)
|
||||
engine.Accepted(peerID, *reqID, frontier)
|
||||
|
||||
externalSender.GetF = nil
|
||||
externalSender.CantPushQuery = false
|
||||
externalSender.CantPullQuery = false
|
||||
|
||||
engine.Put(ctx.NodeID, *reqID, advanceTimeBlkID, advanceTimeBlkBytes)
|
||||
engine.MultiPut(peerID, *reqID, [][]byte{advanceTimeBlkBytes})
|
||||
|
||||
externalSender.CantPushQuery = true
|
||||
|
||||
|
|
Loading…
Reference in New Issue