@@ -21,19 +21,21 @@ import (
2121 "math/big"
2222 "math/rand"
2323 "reflect"
24+ "sync"
2425 "testing"
2526
2627 "github.com/ethereum/go-ethereum/common"
2728 "github.com/ethereum/go-ethereum/core"
2829 "github.com/ethereum/go-ethereum/core/types"
30+ "github.com/ethereum/go-ethereum/rlp"
2931 "github.com/ethereum/go-ethereum/rpc"
3032 "github.com/ethereum/go-ethereum/statediff"
3133 "github.com/ethereum/go-ethereum/statediff/testhelpers/mocks"
3234)
3335
3436func TestServiceLoop (t * testing.T ) {
3537 testErrorInChainEventLoop (t )
36- // testErrorInBlockLoop(t)
38+ testErrorInBlockLoop (t )
3739}
3840
3941var (
6163 testBlock2 = types .NewBlock (& header2 , nil , nil , nil )
6264 testBlock3 = types .NewBlock (& header3 , nil , nil , nil )
6365
66+ receiptRoot1 = common .HexToHash ("0x05" )
67+ receiptRoot2 = common .HexToHash ("0x06" )
68+ receiptRoot3 = common .HexToHash ("0x07" )
69+ testReceipts1 = []* types.Receipt {types .NewReceipt (receiptRoot1 .Bytes (), false , 1000 ), types .NewReceipt (receiptRoot2 .Bytes (), false , 2000 )}
70+ testReceipts2 = []* types.Receipt {types .NewReceipt (receiptRoot3 .Bytes (), false , 3000 )}
71+
6472 event1 = core.ChainEvent {Block : testBlock1 }
6573 event2 = core.ChainEvent {Block : testBlock2 }
6674 event3 = core.ChainEvent {Block : testBlock3 }
@@ -71,25 +79,61 @@ func testErrorInChainEventLoop(t *testing.T) {
7179 builder := mocks.Builder {}
7280 blockChain := mocks.BlockChain {}
7381 service := statediff.Service {
82+ Mutex : sync.Mutex {},
7483 Builder : & builder ,
7584 BlockChain : & blockChain ,
7685 QuitChan : make (chan bool ),
7786 Subscriptions : make (map [rpc.ID ]statediff.Subscription ),
87+ StreamBlock : true ,
7888 }
79- payloadChan := make (chan statediff.Payload )
89+ payloadChan := make (chan statediff.Payload , 2 )
8090 quitChan := make (chan bool )
8191 service .Subscribe (rpc .NewID (), payloadChan , quitChan )
8292 testRoot2 = common .HexToHash ("0xTestRoot2" )
83- blockChain .SetParentBlocksToReturn ([]* types.Block {parentBlock1 , parentBlock2 })
93+ blockMapping := make (map [common.Hash ]* types.Block )
94+ blockMapping [parentBlock1 .Hash ()] = parentBlock1
95+ blockMapping [parentBlock2 .Hash ()] = parentBlock2
96+ blockChain .SetParentBlocksToReturn (blockMapping )
8497 blockChain .SetChainEvents ([]core.ChainEvent {event1 , event2 , event3 })
85- // Need to have listeners on the channels or the subscription will be closed and the processing halted
98+ blockChain .SetReceiptsForHash (testBlock1 .Hash (), testReceipts1 )
99+ blockChain .SetReceiptsForHash (testBlock2 .Hash (), testReceipts2 )
100+
101+ payloads := make ([]statediff.Payload , 0 , 2 )
102+ wg := sync.WaitGroup {}
86103 go func () {
87- select {
88- case <- payloadChan :
89- case <- quitChan :
104+ wg .Add (1 )
105+ for i := 0 ; i < 2 ; i ++ {
106+ select {
107+ case payload := <- payloadChan :
108+ payloads = append (payloads , payload )
109+ case <- quitChan :
110+ }
90111 }
112+ wg .Done ()
91113 }()
114+
92115 service .Loop (eventsChannel )
116+ wg .Wait ()
117+ if len (payloads ) != 2 {
118+ t .Error ("Test failure:" , t .Name ())
119+ t .Logf ("Actual number of payloads does not equal expected.\n actual: %+v\n expected: 3" , len (payloads ))
120+ }
121+
122+ testReceipts1Rlp , err := rlp .EncodeToBytes (testReceipts1 )
123+ if err != nil {
124+ t .Error (err )
125+ }
126+ testReceipts2Rlp , err := rlp .EncodeToBytes (testReceipts2 )
127+ if err != nil {
128+ t .Error (err )
129+ }
130+ expectedReceiptsRlp := [][]byte {testReceipts1Rlp , testReceipts2Rlp , nil }
131+ for i , payload := range payloads {
132+ if ! bytes .Equal (payload .ReceiptsRlp , expectedReceiptsRlp [i ]) {
133+ t .Error ("Test failure:" , t .Name ())
134+ t .Logf ("Actual reeipt rlp for payload %d does not equal expected.\n actual: %+v\n expected: %+v" , i , payload .ReceiptsRlp , expectedReceiptsRlp [i ])
135+ }
136+ }
93137
94138 if ! reflect .DeepEqual (builder .BlockHash , testBlock2 .Hash ()) {
95139 t .Error ("Test failure:" , t .Name ())
@@ -121,9 +165,20 @@ func testErrorInBlockLoop(t *testing.T) {
121165 QuitChan : make (chan bool ),
122166 Subscriptions : make (map [rpc.ID ]statediff.Subscription ),
123167 }
124-
125- blockChain .SetParentBlocksToReturn ([]* types.Block {parentBlock1 , nil })
168+ payloadChan := make (chan statediff.Payload )
169+ quitChan := make (chan bool )
170+ service .Subscribe (rpc .NewID (), payloadChan , quitChan )
171+ blockMapping := make (map [common.Hash ]* types.Block )
172+ blockMapping [parentBlock1 .Hash ()] = parentBlock1
173+ blockChain .SetParentBlocksToReturn (blockMapping )
126174 blockChain .SetChainEvents ([]core.ChainEvent {event1 , event2 })
175+ // Need to have listeners on the channels or the subscription will be closed and the processing halted
176+ go func () {
177+ select {
178+ case <- payloadChan :
179+ case <- quitChan :
180+ }
181+ }()
127182 service .Loop (eventsChannel )
128183
129184 if ! bytes .Equal (builder .BlockHash .Bytes (), testBlock1 .Hash ().Bytes ()) {
0 commit comments