Skip to content

Commit

Permalink
include total difficulty to the payload
Browse files Browse the repository at this point in the history
  • Loading branch information
i-norden committed Jan 16, 2020
1 parent 99ea05e commit 2a980ec
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 77 deletions.
3 changes: 3 additions & 0 deletions statediff/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package statediff
import (
"bytes"
"fmt"
"math/big"
"sync"
"sync/atomic"

Expand All @@ -42,6 +43,7 @@ type blockChain interface {
GetBlockByNumber(number uint64) *types.Block
AddToStateDiffProcessedCollection(hash common.Hash)
GetReceiptsByHash(hash common.Hash) types.Receipts
GetTdByHash(hash common.Hash) *big.Int
}

// IService is the state-diffing service interface
Expand Down Expand Up @@ -172,6 +174,7 @@ func (sds *Service) processStateDiff(currentBlock, parentBlock *types.Block) (*P
return nil, err
}
payload.BlockRlp = blockBuff.Bytes()
payload.TotalDifficulty = sds.BlockChain.GetTdByHash(currentBlock.Hash())
receiptBuff := new(bytes.Buffer)
receipts := sds.BlockChain.GetReceiptsByHash(currentBlock.Hash())
if err = rlp.Encode(receiptBuff, receipts); err != nil {
Expand Down
7 changes: 7 additions & 0 deletions statediff/testhelpers/mocks/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,13 @@ func (sds *MockStateDiffService) processStateDiff(currentBlock, parentBlock *typ
return nil, err
}
payload.BlockRlp = rlpBuff.Bytes()
payload.TotalDifficulty = sds.BlockChain.GetTdByHash(currentBlock.Hash())
receiptBuff := new(bytes.Buffer)
receipts := sds.BlockChain.GetReceiptsByHash(currentBlock.Hash())
if err = rlp.Encode(receiptBuff, receipts); err != nil {
return nil, err
}
payload.ReceiptsRlp = receiptBuff.Bytes()
}
return &payload, nil
}
Expand Down
168 changes: 97 additions & 71 deletions statediff/testhelpers/mocks/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,63 +32,49 @@ import (
"github.com/ethereum/go-ethereum/statediff/testhelpers"
)

var block0, block1 *types.Block
var burnLeafKey = testhelpers.AddressToLeafKey(common.HexToAddress("0x0"))
var emptyAccountDiffEventualMap = make([]statediff.AccountDiff, 0)
var account1, _ = rlp.EncodeToBytes(state.Account{
Nonce: uint64(0),
Balance: big.NewInt(10000),
CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(),
Root: common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"),
})
var burnAccount1, _ = rlp.EncodeToBytes(state.Account{
Nonce: uint64(0),
Balance: big.NewInt(2000000000000000000),
CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(),
Root: common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"),
})
var bankAccount1, _ = rlp.EncodeToBytes(state.Account{
Nonce: uint64(1),
Balance: big.NewInt(testhelpers.TestBankFunds.Int64() - 10000),
CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(),
Root: common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"),
})
var (
block0, block1 *types.Block
burnLeafKey = testhelpers.AddressToLeafKey(common.HexToAddress("0x0"))
emptyAccountDiffEventualMap = make([]statediff.AccountDiff, 0)
account1, _ = rlp.EncodeToBytes(state.Account{
Nonce: uint64(0),
Balance: big.NewInt(10000),
CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(),
Root: common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"),
})
burnAccount1, _ = rlp.EncodeToBytes(state.Account{
Nonce: uint64(0),
Balance: big.NewInt(2000000000000000000),
CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(),
Root: common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"),
})
bankAccount1, _ = rlp.EncodeToBytes(state.Account{
Nonce: uint64(1),
Balance: big.NewInt(testhelpers.TestBankFunds.Int64() - 10000),
CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(),
Root: common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"),
})
mockTotalDifficulty = big.NewInt(1337)
)

func TestAPI(t *testing.T) {
testSubscriptionAPI(t)
testHTTPAPI(t)
}

func testSubscriptionAPI(t *testing.T) {
_, blockMap, chain := testhelpers.MakeChain(3, testhelpers.Genesis)
defer chain.Stop()
block0Hash := common.HexToHash("0xd1721cfd0b29c36fd7a68f25c128e86413fb666a6e1d68e89b875bd299262661")
block1Hash := common.HexToHash("0xbbe88de60ba33a3f18c0caa37d827bfb70252e19e40a07cd34041696c35ecb1a")
block0 = blockMap[block0Hash]
block1 = blockMap[block1Hash]
blockChan := make(chan *types.Block)
parentBlockChain := make(chan *types.Block)
serviceQuitChan := make(chan bool)
config := statediff.Config{
PathsAndProofs: true,
IntermediateNodes: false,
}
mockService := MockStateDiffService{
Mutex: sync.Mutex{},
Builder: statediff.NewBuilder(testhelpers.Testdb, chain, config),
BlockChan: blockChan,
ParentBlockChan: parentBlockChain,
QuitChan: serviceQuitChan,
Subscriptions: make(map[rpc.ID]statediff.Subscription),
streamBlock: true,
}
mockService.Start(nil)
id := rpc.NewID()
payloadChan := make(chan statediff.Payload)
quitChan := make(chan bool)
mockService.Subscribe(id, payloadChan, quitChan)
blockChan <- block1
parentBlockChain <- block0
expectedBlockRlp, _ := rlp.EncodeToBytes(block1)
mockReceipt := &types.Receipt{
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
}
expectedReceiptBytes, _ := rlp.EncodeToBytes(types.Receipts{mockReceipt})
expectedStateDiff := statediff.StateDiff{
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
Expand Down Expand Up @@ -125,20 +111,50 @@ func testSubscriptionAPI(t *testing.T) {
},
},
}
expectedStateDiffBytes, err := rlp.EncodeToBytes(expectedStateDiff)
if err != nil {
t.Error(err)
expectedStateDiffBytes, _ := rlp.EncodeToBytes(expectedStateDiff)
blockChan := make(chan *types.Block)
parentBlockChain := make(chan *types.Block)
serviceQuitChan := make(chan bool)
config := statediff.Config{
PathsAndProofs: true,
IntermediateNodes: false,
}
sort.Slice(expectedStateDiffBytes, func(i, j int) bool { return expectedStateDiffBytes[i] < expectedStateDiffBytes[j] })
mockBlockChain := &BlockChain{}
mockBlockChain.SetReceiptsForHash(block1Hash, types.Receipts{mockReceipt})
mockBlockChain.SetTdByHash(block1Hash, mockTotalDifficulty)
mockService := MockStateDiffService{
Mutex: sync.Mutex{},
Builder: statediff.NewBuilder(testhelpers.Testdb, chain, config),
BlockChan: blockChan,
BlockChain: mockBlockChain,
ParentBlockChan: parentBlockChain,
QuitChan: serviceQuitChan,
Subscriptions: make(map[rpc.ID]statediff.Subscription),
streamBlock: true,
}
mockService.Start(nil)
id := rpc.NewID()
payloadChan := make(chan statediff.Payload)
quitChan := make(chan bool)
mockService.Subscribe(id, payloadChan, quitChan)
blockChan <- block1
parentBlockChain <- block0

sort.Slice(expectedStateDiffBytes, func(i, j int) bool { return expectedStateDiffBytes[i] < expectedStateDiffBytes[j] })
select {
case payload := <-payloadChan:
if !bytes.Equal(payload.BlockRlp, expectedBlockRlp) {
t.Errorf("payload does not have expected block\r\actual block rlp: %v\r\nexpected block rlp: %v", payload.BlockRlp, expectedBlockRlp)
t.Errorf("payload does not have expected block\r\nactual block rlp: %v\r\nexpected block rlp: %v", payload.BlockRlp, expectedBlockRlp)
}
sort.Slice(payload.StateDiffRlp, func(i, j int) bool { return payload.StateDiffRlp[i] < payload.StateDiffRlp[j] })
if !bytes.Equal(payload.StateDiffRlp, expectedStateDiffBytes) {
t.Errorf("payload does not have expected state diff\r\actual state diff rlp: %v\r\nexpected state diff rlp: %v", payload.StateDiffRlp, expectedStateDiffBytes)
t.Errorf("payload does not have expected state diff\r\nactual state diff rlp: %v\r\nexpected state diff rlp: %v", payload.StateDiffRlp, expectedStateDiffBytes)
}
if !bytes.Equal(expectedReceiptBytes, payload.ReceiptsRlp) {
t.Errorf("payload does not have expected receipts\r\nactual receipt rlp: %v\r\nexpected receipt rlp: %v", payload.ReceiptsRlp, expectedReceiptBytes)
}
if !bytes.Equal(payload.TotalDifficulty.Bytes(), mockTotalDifficulty.Bytes()) {
t.Errorf("payload does not have expected total difficulty\r\nactual td: %d\r\nexpected td: %d", payload.TotalDifficulty.Int64(), mockTotalDifficulty.Int64())
}
case <-quitChan:
t.Errorf("channel quit before delivering payload")
Expand All @@ -152,27 +168,12 @@ func testHTTPAPI(t *testing.T) {
block1Hash := common.HexToHash("0xbbe88de60ba33a3f18c0caa37d827bfb70252e19e40a07cd34041696c35ecb1a")
block0 = blockMap[block0Hash]
block1 = blockMap[block1Hash]
config := statediff.Config{
PathsAndProofs: true,
IntermediateNodes: false,
}
mockBlockChain := &BlockChain{}
mockBlockChain.SetBlocksForHashes(blockMap)
mockBlockChain.SetBlockForNumber(block1, block1.Number().Uint64())
mockService := MockStateDiffService{
Mutex: sync.Mutex{},
Builder: statediff.NewBuilder(testhelpers.Testdb, chain, config),
BlockChain: mockBlockChain,
streamBlock: true,
}
payload, err := mockService.StateDiffAt(block1.Number().Uint64())
if err != nil {
t.Error(err)
}
expectedBlockRlp, _ := rlp.EncodeToBytes(block1)
if !bytes.Equal(payload.BlockRlp, expectedBlockRlp) {
t.Errorf("payload does not have expected block\r\actual block rlp: %v\r\nexpected block rlp: %v", payload.BlockRlp, expectedBlockRlp)
mockReceipt := &types.Receipt{
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
}
expectedReceiptBytes, _ := rlp.EncodeToBytes(types.Receipts{mockReceipt})
expectedStateDiff := statediff.StateDiff{
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
Expand Down Expand Up @@ -209,13 +210,38 @@ func testHTTPAPI(t *testing.T) {
},
},
}
expectedStateDiffBytes, err := rlp.EncodeToBytes(expectedStateDiff)
expectedStateDiffBytes, _ := rlp.EncodeToBytes(expectedStateDiff)
config := statediff.Config{
PathsAndProofs: true,
IntermediateNodes: false,
}
mockBlockChain := &BlockChain{}
mockBlockChain.SetBlocksForHashes(blockMap)
mockBlockChain.SetBlockForNumber(block1, block1.Number().Uint64())
mockBlockChain.SetReceiptsForHash(block1Hash, types.Receipts{mockReceipt})
mockBlockChain.SetTdByHash(block1Hash, big.NewInt(1337))
mockService := MockStateDiffService{
Mutex: sync.Mutex{},
Builder: statediff.NewBuilder(testhelpers.Testdb, chain, config),
BlockChain: mockBlockChain,
streamBlock: true,
}
payload, err := mockService.StateDiffAt(block1.Number().Uint64())
if err != nil {
t.Error(err)
}
sort.Slice(payload.StateDiffRlp, func(i, j int) bool { return payload.StateDiffRlp[i] < payload.StateDiffRlp[j] })
sort.Slice(expectedStateDiffBytes, func(i, j int) bool { return expectedStateDiffBytes[i] < expectedStateDiffBytes[j] })
if !bytes.Equal(payload.BlockRlp, expectedBlockRlp) {
t.Errorf("payload does not have expected block\r\nactual block rlp: %v\r\nexpected block rlp: %v", payload.BlockRlp, expectedBlockRlp)
}
if !bytes.Equal(payload.StateDiffRlp, expectedStateDiffBytes) {
t.Errorf("payload does not have expected state diff\r\actual state diff rlp: %v\r\nexpected state diff rlp: %v", payload.StateDiffRlp, expectedStateDiffBytes)
t.Errorf("payload does not have expected state diff\r\nactual state diff rlp: %v\r\nexpected state diff rlp: %v", payload.StateDiffRlp, expectedStateDiffBytes)
}
if !bytes.Equal(expectedReceiptBytes, payload.ReceiptsRlp) {
t.Errorf("payload does not have expected receipts\r\nactual receipt rlp: %v\r\nexpected receipt rlp: %v", payload.ReceiptsRlp, expectedReceiptBytes)
}
if !bytes.Equal(payload.TotalDifficulty.Bytes(), mockTotalDifficulty.Bytes()) {
t.Errorf("paylaod does not have the expected total difficulty\r\nactual td: %d\r\nexpected td: %d", payload.TotalDifficulty.Int64(), mockTotalDifficulty.Int64())
}
}
19 changes: 16 additions & 3 deletions statediff/testhelpers/mocks/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ package mocks

import (
"errors"

"math/big"
"time"

"github.com/ethereum/go-ethereum/common"
Expand All @@ -35,6 +35,7 @@ type BlockChain struct {
callCount int
ChainEvents []core.ChainEvent
Receipts map[common.Hash]types.Receipts
TDByHash map[common.Hash]*big.Int
}

// AddToStateDiffProcessedCollection mock method
Expand Down Expand Up @@ -89,7 +90,7 @@ func (blockChain *BlockChain) SubscribeChainEvent(ch chan<- core.ChainEvent) eve
return subscription
}

// SetReceiptsForHash mock method
// SetReceiptsForHash test method
func (blockChain *BlockChain) SetReceiptsForHash(hash common.Hash, receipts types.Receipts) {
if blockChain.Receipts == nil {
blockChain.Receipts = make(map[common.Hash]types.Receipts)
Expand All @@ -102,7 +103,7 @@ func (blockChain *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts
return blockChain.Receipts[hash]
}

// SetBlockForNumber mock method
// SetBlockForNumber test method
func (blockChain *BlockChain) SetBlockForNumber(block *types.Block, number uint64) {
if blockChain.blocksToReturnByNumber == nil {
blockChain.blocksToReturnByNumber = make(map[uint64]*types.Block)
Expand All @@ -114,3 +115,15 @@ func (blockChain *BlockChain) SetBlockForNumber(block *types.Block, number uint6
func (blockChain *BlockChain) GetBlockByNumber(number uint64) *types.Block {
return blockChain.blocksToReturnByNumber[number]
}

// GetTdByHash mock method
func (blockChain *BlockChain) GetTdByHash(hash common.Hash) *big.Int {
return blockChain.TDByHash[hash]
}

func (blockChain *BlockChain) SetTdByHash(hash common.Hash, td *big.Int) {
if blockChain.TDByHash == nil {
blockChain.TDByHash = make(map[common.Hash]*big.Int)
}
blockChain.TDByHash[hash] = td
}
7 changes: 4 additions & 3 deletions statediff/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ type Subscription struct {

// Payload packages the data to send to statediff subscriptions
type Payload struct {
BlockRlp []byte `json:"blockRlp"`
ReceiptsRlp []byte `json:"receiptsRlp"`
StateDiffRlp []byte `json:"stateDiff" gencodec:"required"`
BlockRlp []byte `json:"blockRlp"`
TotalDifficulty *big.Int `json:"totalDifficulty"`
ReceiptsRlp []byte `json:"receiptsRlp"`
StateDiffRlp []byte `json:"stateDiff" gencodec:"required"`

encoded []byte
err error
Expand Down

0 comments on commit 2a980ec

Please sign in to comment.