Skip to content

Commit f7e973d

Browse files
committed
relay receipts with the rest of the data (don't know why I didn't realize to do this earlier)
1 parent 8173de2 commit f7e973d

File tree

4 files changed

+102
-23
lines changed

4 files changed

+102
-23
lines changed

statediff/service.go

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ type blockChain interface {
4040
SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription
4141
GetBlockByHash(hash common.Hash) *types.Block
4242
AddToStateDiffProcessedCollection(hash common.Hash)
43+
GetReceiptsByHash(hash common.Hash) types.Receipts
4344
}
4445

4546
// IService is the state-diffing service interface
@@ -69,7 +70,7 @@ type Service struct {
6970
// Cache the last block so that we can avoid having to lookup the next block's parent
7071
lastBlock *types.Block
7172
// Whether or not the block data is streamed alongside the state diff data in the subscription payload
72-
streamBlock bool
73+
StreamBlock bool
7374
// Whether or not we have any subscribers; only if we do, do we processes state diffs
7475
subscribers int32
7576
}
@@ -82,7 +83,7 @@ func NewStateDiffService(db ethdb.Database, blockChain *core.BlockChain, config
8283
Builder: NewBuilder(db, blockChain, config),
8384
QuitChan: make(chan bool),
8485
Subscriptions: make(map[rpc.ID]Subscription),
85-
streamBlock: config.StreamBlock,
86+
StreamBlock: config.StreamBlock,
8687
}, nil
8788
}
8889

@@ -108,7 +109,6 @@ func (sds *Service) Loop(chainEventCh chan core.ChainEvent) {
108109
chainEventSub := sds.BlockChain.SubscribeChainEvent(chainEventCh)
109110
defer chainEventSub.Unsubscribe()
110111
errCh := chainEventSub.Err()
111-
112112
for {
113113
select {
114114
//Notify chain event channel of events
@@ -161,12 +161,19 @@ func (sds *Service) processStateDiff(currentBlock, parentBlock *types.Block) err
161161
StateDiffRlp: stateDiffRlp,
162162
Err: err,
163163
}
164-
if sds.streamBlock {
165-
rlpBuff := new(bytes.Buffer)
166-
if err = currentBlock.EncodeRLP(rlpBuff); err != nil {
164+
if sds.StreamBlock {
165+
blockBuff := new(bytes.Buffer)
166+
if err = currentBlock.EncodeRLP(blockBuff); err != nil {
167+
return err
168+
}
169+
payload.BlockRlp = blockBuff.Bytes()
170+
receiptBuff := new(bytes.Buffer)
171+
receipts := sds.BlockChain.GetReceiptsByHash(currentBlock.Hash())
172+
if err = rlp.Encode(receiptBuff, receipts); err != nil {
173+
println(err.Error())
167174
return err
168175
}
169-
payload.BlockRlp = rlpBuff.Bytes()
176+
payload.ReceiptsRlp = receiptBuff.Bytes()
170177
}
171178

172179
// If we have any websocket subscriptions listening in, send the data to them

statediff/service_test.go

Lines changed: 64 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -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

3436
func TestServiceLoop(t *testing.T) {
3537
testErrorInChainEventLoop(t)
36-
//testErrorInBlockLoop(t)
38+
testErrorInBlockLoop(t)
3739
}
3840

3941
var (
@@ -61,6 +63,12 @@ var (
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.\nactual: %+v\nexpected: 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.\nactual: %+v\nexpected: %+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()) {

statediff/testhelpers/mocks/blockchain.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,20 @@ import (
3030
// BlockChain is a mock blockchain for testing
3131
type BlockChain struct {
3232
ParentHashesLookedUp []common.Hash
33-
parentBlocksToReturn []*types.Block
33+
parentBlocksToReturn map[common.Hash]*types.Block
3434
callCount int
3535
ChainEvents []core.ChainEvent
36+
Receipts map[common.Hash]types.Receipts
3637
}
3738

3839
// AddToStateDiffProcessedCollection mock method
3940
func (blockChain *BlockChain) AddToStateDiffProcessedCollection(hash common.Hash) {}
4041

4142
// SetParentBlocksToReturn mock method
42-
func (blockChain *BlockChain) SetParentBlocksToReturn(blocks []*types.Block) {
43+
func (blockChain *BlockChain) SetParentBlocksToReturn(blocks map[common.Hash]*types.Block) {
44+
if blockChain.parentBlocksToReturn == nil {
45+
blockChain.parentBlocksToReturn = make(map[common.Hash]*types.Block)
46+
}
4347
blockChain.parentBlocksToReturn = blocks
4448
}
4549

@@ -49,10 +53,9 @@ func (blockChain *BlockChain) GetBlockByHash(hash common.Hash) *types.Block {
4953

5054
var parentBlock *types.Block
5155
if len(blockChain.parentBlocksToReturn) > 0 {
52-
parentBlock = blockChain.parentBlocksToReturn[blockChain.callCount]
56+
parentBlock = blockChain.parentBlocksToReturn[hash]
5357
}
5458

55-
blockChain.callCount++
5659
return parentBlock
5760
}
5861

@@ -84,3 +87,16 @@ func (blockChain *BlockChain) SubscribeChainEvent(ch chan<- core.ChainEvent) eve
8487

8588
return subscription
8689
}
90+
91+
// SetReceiptsForHash mock method
92+
func (blockChain *BlockChain) SetReceiptsForHash(hash common.Hash, receipts types.Receipts) {
93+
if blockChain.Receipts == nil {
94+
blockChain.Receipts = make(map[common.Hash]types.Receipts)
95+
}
96+
blockChain.Receipts[hash] = receipts
97+
}
98+
99+
// GetReceiptsByHash mock method
100+
func (blockChain *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts {
101+
return blockChain.Receipts[hash]
102+
}

statediff/types.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,16 @@ type Subscription struct {
3636

3737
// Payload packages the data to send to StateDiffingService subscriptions
3838
type Payload struct {
39-
BlockRlp []byte `json:"blockRlp" gencodec:"required"`
39+
BlockRlp []byte `json:"blockRlp"`
40+
ReceiptsRlp []byte `json:"receiptsRlp"`
4041
StateDiffRlp []byte `json:"stateDiff" gencodec:"required"`
4142
Err error `json:"error"`
4243
}
4344

4445
// StateDiff is the final output structure from the builder
4546
type StateDiff struct {
46-
BlockNumber *big.Int `json:"blockNumber" gencodec:"required"`
47-
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
47+
BlockNumber *big.Int `json:"blockNumber" gencodec:"required"`
48+
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
4849
CreatedAccounts []AccountDiff `json:"createdAccounts" gencodec:"required"`
4950
DeletedAccounts []AccountDiff `json:"deletedAccounts" gencodec:"required"`
5051
UpdatedAccounts []AccountDiff `json:"updatedAccounts" gencodec:"required"`

0 commit comments

Comments
 (0)