@ -233,7 +233,7 @@ func TestClient(t *testing.T) {
chainID ,
chainID ,
trustOptions ,
trustOptions ,
mockNode ,
mockNode ,
[ ] provider . Provider { mockNode } ,
nil ,
dbs . New ( dbm . NewMemDB ( ) ) ,
dbs . New ( dbm . NewMemDB ( ) ) ,
light . SequentialVerification ( ) ,
light . SequentialVerification ( ) ,
light . Logger ( logger ) ,
light . Logger ( logger ) ,
@ -360,7 +360,7 @@ func TestClient(t *testing.T) {
chainID ,
chainID ,
trustOptions ,
trustOptions ,
mockNode ,
mockNode ,
[ ] provider . Provider { mockNode } ,
nil ,
dbs . New ( dbm . NewMemDB ( ) ) ,
dbs . New ( dbm . NewMemDB ( ) ) ,
light . SkippingVerification ( light . DefaultTrustLevel ) ,
light . SkippingVerification ( light . DefaultTrustLevel ) ,
light . Logger ( logger ) ,
light . Logger ( logger ) ,
@ -416,7 +416,7 @@ func TestClient(t *testing.T) {
Hash : trustedLightBlock . Hash ( ) ,
Hash : trustedLightBlock . Hash ( ) ,
} ,
} ,
mockNode ,
mockNode ,
[ ] provider . Provider { mockNode } ,
nil ,
dbs . New ( dbm . NewMemDB ( ) ) ,
dbs . New ( dbm . NewMemDB ( ) ) ,
light . SkippingVerification ( light . DefaultTrustLevel ) ,
light . SkippingVerification ( light . DefaultTrustLevel ) ,
)
)
@ -445,7 +445,7 @@ func TestClient(t *testing.T) {
Hash : h1 . Hash ( ) ,
Hash : h1 . Hash ( ) ,
} ,
} ,
mockFullNode ,
mockFullNode ,
[ ] provider . Provider { mockFullNode } ,
nil ,
dbs . New ( dbm . NewMemDB ( ) ) ,
dbs . New ( dbm . NewMemDB ( ) ) ,
light . SkippingVerification ( light . DefaultTrustLevel ) ,
light . SkippingVerification ( light . DefaultTrustLevel ) ,
)
)
@ -475,7 +475,7 @@ func TestClient(t *testing.T) {
chainID ,
chainID ,
trustOptions ,
trustOptions ,
mockFullNode ,
mockFullNode ,
[ ] provider . Provider { mockFullNode } ,
nil ,
dbs . New ( dbm . NewMemDB ( ) ) ,
dbs . New ( dbm . NewMemDB ( ) ) ,
light . Logger ( logger ) ,
light . Logger ( logger ) ,
)
)
@ -515,7 +515,7 @@ func TestClient(t *testing.T) {
chainID ,
chainID ,
trustOptions ,
trustOptions ,
mockNode ,
mockNode ,
[ ] provider . Provider { mockNode } ,
nil ,
trustedStore ,
trustedStore ,
light . Logger ( logger ) ,
light . Logger ( logger ) ,
)
)
@ -554,7 +554,7 @@ func TestClient(t *testing.T) {
Hash : header1 . Hash ( ) ,
Hash : header1 . Hash ( ) ,
} ,
} ,
mockNode ,
mockNode ,
[ ] provider . Provider { mockNode } ,
nil ,
trustedStore ,
trustedStore ,
light . Logger ( logger ) ,
light . Logger ( logger ) ,
)
)
@ -575,9 +575,14 @@ func TestClient(t *testing.T) {
defer cancel ( )
defer cancel ( )
mockFullNode := & provider_mocks . Provider { }
mockFullNode := & provider_mocks . Provider { }
mockFullNode . On ( "ID" ) . Return ( "mockFullNode" )
mockFullNode . On ( "LightBlock" , mock . Anything , int64 ( 0 ) ) . Return ( l3 , nil )
mockFullNode . On ( "LightBlock" , mock . Anything , int64 ( 0 ) ) . Return ( l3 , nil )
mockFullNode . On ( "LightBlock" , mock . Anything , int64 ( 1 ) ) . Return ( l1 , nil )
mockFullNode . On ( "LightBlock" , mock . Anything , int64 ( 1 ) ) . Return ( l1 , nil )
mockFullNode . On ( "LightBlock" , mock . Anything , int64 ( 3 ) ) . Return ( l3 , nil )
mockWitnessNode := & provider_mocks . Provider { }
mockWitnessNode . On ( "ID" ) . Return ( "mockWitnessNode" )
mockWitnessNode . On ( "LightBlock" , mock . Anything , int64 ( 1 ) ) . Return ( l1 , nil )
mockWitnessNode . On ( "LightBlock" , mock . Anything , int64 ( 3 ) ) . Return ( l3 , nil )
logger := log . NewTestingLogger ( t )
logger := log . NewTestingLogger ( t )
@ -586,7 +591,7 @@ func TestClient(t *testing.T) {
chainID ,
chainID ,
trustOptions ,
trustOptions ,
mockFullNode ,
mockFullNode ,
[ ] provider . Provider { mockFull Node } ,
[ ] provider . Provider { mockWitness Node } ,
dbs . New ( dbm . NewMemDB ( ) ) ,
dbs . New ( dbm . NewMemDB ( ) ) ,
light . Logger ( logger ) ,
light . Logger ( logger ) ,
)
)
@ -600,6 +605,7 @@ func TestClient(t *testing.T) {
assert . NoError ( t , l . ValidateBasic ( chainID ) )
assert . NoError ( t , l . ValidateBasic ( chainID ) )
}
}
mockFullNode . AssertExpectations ( t )
mockFullNode . AssertExpectations ( t )
mockWitnessNode . AssertExpectations ( t )
} )
} )
t . Run ( "Concurrency" , func ( t * testing . T ) {
t . Run ( "Concurrency" , func ( t * testing . T ) {
@ -615,7 +621,7 @@ func TestClient(t *testing.T) {
chainID ,
chainID ,
trustOptions ,
trustOptions ,
mockFullNode ,
mockFullNode ,
[ ] provider . Provider { mockFullNode } ,
nil ,
dbs . New ( dbm . NewMemDB ( ) ) ,
dbs . New ( dbm . NewMemDB ( ) ) ,
light . Logger ( logger ) ,
light . Logger ( logger ) ,
)
)
@ -665,7 +671,7 @@ func TestClient(t *testing.T) {
chainID ,
chainID ,
trustOptions ,
trustOptions ,
mockFullNode ,
mockFullNode ,
[ ] provider . Provider { mockFullNode } ,
nil ,
dbs . New ( dbm . NewMemDB ( ) ) ,
dbs . New ( dbm . NewMemDB ( ) ) ,
light . Logger ( logger ) ,
light . Logger ( logger ) ,
)
)
@ -679,9 +685,8 @@ func TestClient(t *testing.T) {
close ( closeCh )
close ( closeCh )
} ( )
} ( )
// NOTE: the light client doesn't check uniqueness of providers
c . AddProvider ( mockFullNode )
c . AddProvider ( mockFullNode )
require . Len ( t , c . Witnesses ( ) , 2 )
require . Len ( t , c . Witnesses ( ) , 1 )
select {
select {
case <- closeCh :
case <- closeCh :
case <- time . After ( 5 * time . Second ) :
case <- time . After ( 5 * time . Second ) :
@ -695,9 +700,10 @@ func TestClient(t *testing.T) {
mockFullNode := & provider_mocks . Provider { }
mockFullNode := & provider_mocks . Provider { }
mockFullNode . On ( "LightBlock" , mock . Anything , mock . Anything ) . Return ( l1 , nil )
mockFullNode . On ( "LightBlock" , mock . Anything , mock . Anything ) . Return ( l1 , nil )
mockFullNode . On ( "ID" ) . Return ( "mockFullNode" )
mockDeadNode := & provider_mocks . Provider { }
mockDeadNode := & provider_mocks . Provider { }
mockDeadNode . On ( "LightBlock" , mock . Anything , mock . Anything ) . Return ( nil , provider . ErrNoResponse )
mockDeadNode . On ( "LightBlock" , mock . Anything , mock . Anything ) . Return ( nil , provider . ErrNoResponse )
mockDeadNode . On ( "ID" ) . Return ( "mockDeadNode" )
logger := log . NewTestingLogger ( t )
logger := log . NewTestingLogger ( t )
@ -706,7 +712,7 @@ func TestClient(t *testing.T) {
chainID ,
chainID ,
trustOptions ,
trustOptions ,
mockDeadNode ,
mockDeadNode ,
[ ] provider . Provider { mockDeadNode , mock FullNode } ,
[ ] provider . Provider { mockFullNode } ,
dbs . New ( dbm . NewMemDB ( ) ) ,
dbs . New ( dbm . NewMemDB ( ) ) ,
light . Logger ( logger ) ,
light . Logger ( logger ) ,
)
)
@ -720,7 +726,7 @@ func TestClient(t *testing.T) {
// we should still have the dead node as a witness because it
// we should still have the dead node as a witness because it
// hasn't repeatedly been unresponsive yet
// hasn't repeatedly been unresponsive yet
assert . Equal ( t , 2 , len ( c . Witnesses ( ) ) )
assert . Equal ( t , 1 , len ( c . Witnesses ( ) ) )
mockDeadNode . AssertExpectations ( t )
mockDeadNode . AssertExpectations ( t )
mockFullNode . AssertExpectations ( t )
mockFullNode . AssertExpectations ( t )
} )
} )
@ -730,17 +736,24 @@ func TestClient(t *testing.T) {
mockFullNode := & provider_mocks . Provider { }
mockFullNode := & provider_mocks . Provider { }
mockFullNode . On ( "LightBlock" , mock . Anything , mock . Anything ) . Return ( l1 , nil )
mockFullNode . On ( "LightBlock" , mock . Anything , mock . Anything ) . Return ( l1 , nil )
mockFullNode . On ( "ID" ) . Return ( "mockFullNode" )
logger := log . NewTestingLogger ( t )
logger := log . NewTestingLogger ( t )
mockDeadNode := & provider_mocks . Provider { }
mockDeadNode . On ( "LightBlock" , mock . Anything , mock . Anything ) . Return ( nil , provider . ErrLightBlockNotFound )
mockDeadNode1 := & provider_mocks . Provider { }
mockDeadNode1 . On ( "LightBlock" , mock . Anything , mock . Anything ) . Return ( nil , provider . ErrLightBlockNotFound )
mockDeadNode1 . On ( "ID" ) . Return ( "mockDeadNode1" )
mockDeadNode2 := & provider_mocks . Provider { }
mockDeadNode2 . On ( "LightBlock" , mock . Anything , mock . Anything ) . Return ( nil , provider . ErrLightBlockNotFound )
mockDeadNode2 . On ( "ID" ) . Return ( "mockDeadNode2" )
c , err := light . NewClient (
c , err := light . NewClient (
ctx ,
ctx ,
chainID ,
chainID ,
trustOptions ,
trustOptions ,
mockDeadNode ,
[ ] provider . Provider { mockDeadNode , mockFullNode } ,
mockDeadNode1 ,
[ ] provider . Provider { mockFullNode , mockDeadNode2 } ,
dbs . New ( dbm . NewMemDB ( ) ) ,
dbs . New ( dbm . NewMemDB ( ) ) ,
light . Logger ( logger ) ,
light . Logger ( logger ) ,
)
)
@ -751,7 +764,7 @@ func TestClient(t *testing.T) {
// we should still have the dead node as a witness because it
// we should still have the dead node as a witness because it
// hasn't repeatedly been unresponsive yet
// hasn't repeatedly been unresponsive yet
assert . Equal ( t , 2 , len ( c . Witnesses ( ) ) )
assert . Equal ( t , 2 , len ( c . Witnesses ( ) ) )
mockDeadNode . AssertExpectations ( t )
mockDeadNode1 . AssertExpectations ( t )
mockFullNode . AssertExpectations ( t )
mockFullNode . AssertExpectations ( t )
} )
} )
t . Run ( "BackwardsVerification" , func ( t * testing . T ) {
t . Run ( "BackwardsVerification" , func ( t * testing . T ) {
@ -777,7 +790,7 @@ func TestClient(t *testing.T) {
Hash : trustHeader . Hash ( ) ,
Hash : trustHeader . Hash ( ) ,
} ,
} ,
mockLargeFullNode ,
mockLargeFullNode ,
[ ] provider . Provider { mockLargeFullNode } ,
nil ,
dbs . New ( dbm . NewMemDB ( ) ) ,
dbs . New ( dbm . NewMemDB ( ) ) ,
light . Logger ( logger ) ,
light . Logger ( logger ) ,
)
)
@ -836,7 +849,7 @@ func TestClient(t *testing.T) {
Hash : h3 . Hash ( ) ,
Hash : h3 . Hash ( ) ,
} ,
} ,
mockNode ,
mockNode ,
[ ] provider . Provider { mockNode } ,
nil ,
dbs . New ( dbm . NewMemDB ( ) ) ,
dbs . New ( dbm . NewMemDB ( ) ) ,
light . Logger ( logger ) ,
light . Logger ( logger ) ,
)
)
@ -852,13 +865,15 @@ func TestClient(t *testing.T) {
db := dbs . New ( dbm . NewMemDB ( ) )
db := dbs . New ( dbm . NewMemDB ( ) )
err := db . SaveLightBlock ( l1 )
err := db . SaveLightBlock ( l1 )
require . NoError ( t , err )
require . NoError ( t , err )
mockNode := & provider_mocks . Provider { }
mockPrimary := & provider_mocks . Provider { }
mockPrimary . On ( "ID" ) . Return ( "mockPrimary" )
mockWitness := & provider_mocks . Provider { }
mockWitness . On ( "ID" ) . Return ( "mockWitness" )
c , err := light . NewClientFromTrustedStore (
c , err := light . NewClientFromTrustedStore (
chainID ,
chainID ,
trustPeriod ,
trustPeriod ,
mockNode ,
[ ] provider . Provider { mockNode } ,
mockPrimary ,
[ ] provider . Provider { mockWitness } ,
db ,
db ,
)
)
require . NoError ( t , err )
require . NoError ( t , err )
@ -867,7 +882,8 @@ func TestClient(t *testing.T) {
h , err := c . TrustedLightBlock ( 1 )
h , err := c . TrustedLightBlock ( 1 )
assert . NoError ( t , err )
assert . NoError ( t , err )
assert . EqualValues ( t , l1 . Height , h . Height )
assert . EqualValues ( t , l1 . Height , h . Height )
mockNode . AssertExpectations ( t )
mockPrimary . AssertExpectations ( t )
mockWitness . AssertExpectations ( t )
} )
} )
t . Run ( "RemovesWitnessIfItSendsUsIncorrectHeader" , func ( t * testing . T ) {
t . Run ( "RemovesWitnessIfItSendsUsIncorrectHeader" , func ( t * testing . T ) {
logger := log . NewTestingLogger ( t )
logger := log . NewTestingLogger ( t )
@ -885,6 +901,7 @@ func TestClient(t *testing.T) {
}
}
mockBadNode1 := mockNodeFromHeadersAndVals ( headers1 , vals1 )
mockBadNode1 := mockNodeFromHeadersAndVals ( headers1 , vals1 )
mockBadNode1 . On ( "LightBlock" , mock . Anything , mock . Anything ) . Return ( nil , provider . ErrLightBlockNotFound )
mockBadNode1 . On ( "LightBlock" , mock . Anything , mock . Anything ) . Return ( nil , provider . ErrLightBlockNotFound )
mockBadNode1 . On ( "ID" ) . Return ( "mockBadNode1" )
// header is empty
// header is empty
headers2 := map [ int64 ] * types . SignedHeader {
headers2 := map [ int64 ] * types . SignedHeader {
@ -897,8 +914,10 @@ func TestClient(t *testing.T) {
}
}
mockBadNode2 := mockNodeFromHeadersAndVals ( headers2 , vals2 )
mockBadNode2 := mockNodeFromHeadersAndVals ( headers2 , vals2 )
mockBadNode2 . On ( "LightBlock" , mock . Anything , mock . Anything ) . Return ( nil , provider . ErrLightBlockNotFound )
mockBadNode2 . On ( "LightBlock" , mock . Anything , mock . Anything ) . Return ( nil , provider . ErrLightBlockNotFound )
mockBadNode2 . On ( "ID" ) . Return ( "mockBadNode2" )
mockFullNode := mockNodeFromHeadersAndVals ( headerSet , valSet )
mockFullNode := mockNodeFromHeadersAndVals ( headerSet , valSet )
mockFullNode . On ( "ID" ) . Return ( "mockFullNode" )
ctx , cancel := context . WithCancel ( context . Background ( ) )
ctx , cancel := context . WithCancel ( context . Background ( ) )
defer cancel ( )
defer cancel ( )
@ -956,6 +975,8 @@ func TestClient(t *testing.T) {
1 : vals ,
1 : vals ,
2 : differentVals ,
2 : differentVals ,
} )
} )
mockBadValSetNode . On ( "ID" ) . Return ( "mockBadValSetNode" )
mockFullNode := mockNodeFromHeadersAndVals (
mockFullNode := mockNodeFromHeadersAndVals (
map [ int64 ] * types . SignedHeader {
map [ int64 ] * types . SignedHeader {
1 : h1 ,
1 : h1 ,
@ -965,13 +986,25 @@ func TestClient(t *testing.T) {
1 : vals ,
1 : vals ,
2 : vals ,
2 : vals ,
} )
} )
mockFullNode . On ( "ID" ) . Return ( "mockFullNode" )
mockGoodWitness := mockNodeFromHeadersAndVals (
map [ int64 ] * types . SignedHeader {
1 : h1 ,
2 : h2 ,
} ,
map [ int64 ] * types . ValidatorSet {
1 : vals ,
2 : vals ,
} )
mockGoodWitness . On ( "ID" ) . Return ( "mockGoodWitness" )
c , err := light . NewClient (
c , err := light . NewClient (
ctx ,
ctx ,
chainID ,
chainID ,
trustOptions ,
trustOptions ,
mockFullNode ,
mockFullNode ,
[ ] provider . Provider { mockBadValSetNode , mockFullNode } ,
[ ] provider . Provider { mockBadValSetNode , mockGoodWitness } ,
dbs . New ( dbm . NewMemDB ( ) ) ,
dbs . New ( dbm . NewMemDB ( ) ) ,
light . Logger ( logger ) ,
light . Logger ( logger ) ,
)
)
@ -988,15 +1021,26 @@ func TestClient(t *testing.T) {
mockFullNode := mockNodeFromHeadersAndVals (
mockFullNode := mockNodeFromHeadersAndVals (
map [ int64 ] * types . SignedHeader {
map [ int64 ] * types . SignedHeader {
1 : h1 ,
1 : h1 ,
3 : h3 ,
0 : h3 ,
0 : h3 ,
} ,
} ,
map [ int64 ] * types . ValidatorSet {
map [ int64 ] * types . ValidatorSet {
1 : vals ,
1 : vals ,
3 : vals ,
0 : vals ,
0 : vals ,
} )
} )
mockFullNode . On ( "ID" ) . Return ( "mockFullNode" )
mockGoodWitness := mockNodeFromHeadersAndVals (
map [ int64 ] * types . SignedHeader {
1 : h1 ,
3 : h3 ,
} ,
map [ int64 ] * types . ValidatorSet {
1 : vals ,
3 : vals ,
} )
mockGoodWitness . On ( "ID" ) . Return ( "mockGoodWitness" )
ctx , cancel := context . WithCancel ( context . Background ( ) )
ctx , cancel := context . WithCancel ( context . Background ( ) )
defer cancel ( )
defer cancel ( )
logger := log . NewTestingLogger ( t )
logger := log . NewTestingLogger ( t )
@ -1006,7 +1050,7 @@ func TestClient(t *testing.T) {
chainID ,
chainID ,
trustOptions ,
trustOptions ,
mockFullNode ,
mockFullNode ,
[ ] provider . Provider { mockFullNode } ,
[ ] provider . Provider { mockGoodWitness } ,
dbs . New ( dbm . NewMemDB ( ) ) ,
dbs . New ( dbm . NewMemDB ( ) ) ,
light . Logger ( logger ) ,
light . Logger ( logger ) ,
light . PruningSize ( 1 ) ,
light . PruningSize ( 1 ) ,
@ -1022,6 +1066,7 @@ func TestClient(t *testing.T) {
_ , err = c . TrustedLightBlock ( 1 )
_ , err = c . TrustedLightBlock ( 1 )
assert . Error ( t , err )
assert . Error ( t , err )
mockFullNode . AssertExpectations ( t )
mockFullNode . AssertExpectations ( t )
mockGoodWitness . AssertExpectations ( t )
} )
} )
t . Run ( "EnsureValidHeadersAndValSets" , func ( t * testing . T ) {
t . Run ( "EnsureValidHeadersAndValSets" , func ( t * testing . T ) {
emptyValSet := & types . ValidatorSet {
emptyValSet := & types . ValidatorSet {
@ -1098,7 +1143,7 @@ func TestClient(t *testing.T) {
chainID ,
chainID ,
trustOptions ,
trustOptions ,
mockBadNode ,
mockBadNode ,
[ ] provider . Provider { mockBadNode , mockBadNode } ,
nil ,
dbs . New ( dbm . NewMemDB ( ) ) ,
dbs . New ( dbm . NewMemDB ( ) ) ,
)
)
require . NoError ( t , err )
require . NoError ( t , err )