Add light sync command

- Only syncs block headers (excludes block bodies, transactions, receipts, and logs)
- Modifies validation window to include the most recent block
- Isolates validation window to the variable defined in the cmd directory (blocks
  have a separate variable defined in the block_repository for determining when
  to set a block as final)
This commit is contained in:
Rob Mulholand
2018-07-18 16:34:12 -05:00
parent a620fc6a51
commit 1355271011
43 changed files with 1092 additions and 272 deletions
+31 -30
View File
@@ -1,13 +1,11 @@
package geth
import (
"math/big"
"log"
"math/big"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/rpc"
"golang.org/x/net/context"
@@ -18,31 +16,30 @@ import (
"github.com/vulcanize/vulcanizedb/pkg/geth/node"
)
type Blockchain struct {
client *ethclient.Client
blockConverter vulcCommon.BlockConverter
readGethHeaders chan *types.Header
outputBlocks chan core.Block
newHeadSubscription ethereum.Subscription
node core.Node
type BlockChain struct {
client *ethclient.Client
blockConverter vulcCommon.BlockConverter
headerConverter vulcCommon.HeaderConverter
node core.Node
}
func NewBlockchain(ipcPath string) *Blockchain {
blockchain := Blockchain{}
func NewBlockChain(ipcPath string) *BlockChain {
rpcClient, err := rpc.Dial(ipcPath)
if err != nil {
log.Fatal(err)
}
client := ethclient.NewClient(rpcClient)
clientWrapper := node.ClientWrapper{ContextCaller: rpcClient, IPCPath: ipcPath}
blockchain.node = node.MakeNode(clientWrapper)
blockchain.client = client
transactionConverter := vulcRpc.NewRpcTransactionConverter(client)
blockchain.blockConverter = vulcCommon.NewBlockConverter(transactionConverter)
return &blockchain
return &BlockChain{
client: client,
blockConverter: vulcCommon.NewBlockConverter(transactionConverter),
headerConverter: vulcCommon.HeaderConverter{},
node: node.MakeNode(clientWrapper),
}
}
func (blockchain *Blockchain) GetLogs(contract core.Contract, startingBlockNumber *big.Int, endingBlockNumber *big.Int) ([]core.Log, error) {
func (blockChain *BlockChain) GetLogs(contract core.Contract, startingBlockNumber, endingBlockNumber *big.Int) ([]core.Log, error) {
if endingBlockNumber == nil {
endingBlockNumber = startingBlockNumber
}
@@ -52,7 +49,7 @@ func (blockchain *Blockchain) GetLogs(contract core.Contract, startingBlockNumbe
ToBlock: endingBlockNumber,
Addresses: []common.Address{contractAddress},
}
gethLogs, err := blockchain.client.FilterLogs(context.Background(), fc)
gethLogs, err := blockChain.client.FilterLogs(context.Background(), fc)
if err != nil {
return []core.Log{}, err
}
@@ -60,23 +57,27 @@ func (blockchain *Blockchain) GetLogs(contract core.Contract, startingBlockNumbe
return logs, nil
}
func (blockchain *Blockchain) Node() core.Node {
return blockchain.node
func (blockChain *BlockChain) Node() core.Node {
return blockChain.node
}
func (blockchain *Blockchain) GetBlockByNumber(blockNumber int64) (core.Block, error) {
gethBlock, err := blockchain.client.BlockByNumber(context.Background(), big.NewInt(blockNumber))
func (blockChain *BlockChain) GetBlockByNumber(blockNumber int64) (block core.Block, err error) {
gethBlock, err := blockChain.client.BlockByNumber(context.Background(), big.NewInt(blockNumber))
if err != nil {
return core.Block{}, err
return block, err
}
block, err := blockchain.blockConverter.ToCoreBlock(gethBlock)
if err != nil {
return core.Block{}, err
}
return block, nil
return blockChain.blockConverter.ToCoreBlock(gethBlock)
}
func (blockchain *Blockchain) LastBlock() *big.Int {
block, _ := blockchain.client.HeaderByNumber(context.Background(), nil)
func (blockChain *BlockChain) GetHeaderByNumber(blockNumber int64) (header core.Header, err error) {
gethHeader, err := blockChain.client.HeaderByNumber(context.Background(), big.NewInt(blockNumber))
if err != nil {
return header, err
}
return blockChain.headerConverter.Convert(gethHeader)
}
func (blockChain *BlockChain) LastBlock() *big.Int {
block, _ := blockChain.client.HeaderByNumber(context.Background(), nil)
return block.Number
}
+4 -4
View File
@@ -14,7 +14,7 @@ var (
ErrInvalidStateAttribute = errors.New("invalid state attribute")
)
func (blockchain *Blockchain) FetchContractData(abiJSON string, address string, method string, methodArg interface{}, result interface{}, blockNumber int64) error {
func (blockChain *BlockChain) FetchContractData(abiJSON string, address string, method string, methodArg interface{}, result interface{}, blockNumber int64) error {
parsed, err := ParseAbi(abiJSON)
if err != nil {
return err
@@ -28,15 +28,15 @@ func (blockchain *Blockchain) FetchContractData(abiJSON string, address string,
if err != nil {
return err
}
output, err := blockchain.callContract(address, input, big.NewInt(blockNumber))
output, err := blockChain.callContract(address, input, big.NewInt(blockNumber))
if err != nil {
return err
}
return parsed.Unpack(result, method, output)
}
func (blockchain *Blockchain) callContract(contractHash string, input []byte, blockNumber *big.Int) ([]byte, error) {
func (blockChain *BlockChain) callContract(contractHash string, input []byte, blockNumber *big.Int) ([]byte, error) {
to := common.HexToAddress(contractHash)
msg := ethereum.CallMsg{To: &to, Data: input}
return blockchain.client.CallContract(context.Background(), msg, blockNumber)
return blockChain.client.CallContract(context.Background(), msg, blockNumber)
}
@@ -20,6 +20,7 @@ func (bc BlockConverter) ToCoreBlock(gethBlock *types.Block) (core.Block, error)
if err != nil {
return core.Block{}, err
}
coreBlock := core.Block{
Difficulty: gethBlock.Difficulty().Int64(),
ExtraData: hexutil.Encode(gethBlock.Extra()),
@@ -0,0 +1,24 @@
package common
import (
"bytes"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
"github.com/vulcanize/vulcanizedb/pkg/core"
)
type HeaderConverter struct{}
func (converter HeaderConverter) Convert(gethHeader *types.Header) (core.Header, error) {
writer := new(bytes.Buffer)
err := rlp.Encode(writer, &gethHeader)
if err != nil {
panic(err)
}
coreHeader := core.Header{
Hash: gethHeader.Hash().Hex(),
BlockNumber: gethHeader.Number.Int64(),
Raw: writer.Bytes(),
}
return coreHeader, nil
}
@@ -0,0 +1,47 @@
package common_test
import (
"bytes"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
common2 "github.com/vulcanize/vulcanizedb/pkg/geth/converters/common"
"math/big"
)
var _ = Describe("Block header converter", func() {
It("converts geth header to core header", func() {
gethHeader := &types.Header{
Difficulty: big.NewInt(1),
Number: big.NewInt(2),
ParentHash: common.HexToHash("0xParent"),
ReceiptHash: common.HexToHash("0xReceipt"),
Root: common.HexToHash("0xRoot"),
Time: big.NewInt(3),
TxHash: common.HexToHash("0xTransaction"),
UncleHash: common.HexToHash("0xUncle"),
}
converter := common2.HeaderConverter{}
coreHeader, err := converter.Convert(gethHeader)
Expect(err).NotTo(HaveOccurred())
Expect(coreHeader.BlockNumber).To(Equal(gethHeader.Number.Int64()))
Expect(coreHeader.Hash).To(Equal(gethHeader.Hash().Hex()))
})
It("includes raw bytes for header", func() {
headerRLP := []byte{249, 2, 23, 160, 180, 251, 173, 248, 234, 69, 43, 19, 151, 24, 226, 112, 13, 193, 19, 92, 252, 129, 20, 80, 49, 200, 75, 122, 178, 124, 215, 16, 57, 79, 123, 56, 160, 29, 204, 77, 232, 222, 199, 93, 122, 171, 133, 181, 103, 182, 204, 212, 26, 211, 18, 69, 27, 148, 138, 116, 19, 240, 161, 66, 253, 64, 212, 147, 71, 148, 42, 101, 172, 164, 213, 252, 91, 92, 133, 144, 144, 166, 195, 77, 22, 65, 53, 57, 130, 38, 160, 14, 6, 111, 60, 34, 151, 165, 203, 48, 5, 147, 5, 38, 23, 209, 188, 165, 148, 111, 12, 170, 6, 53, 253, 177, 184, 90, 199, 229, 35, 111, 52, 160, 101, 186, 136, 127, 203, 8, 38, 246, 22, 208, 31, 115, 108, 29, 45, 103, 123, 202, 189, 226, 247, 252, 37, 170, 145, 207, 188, 11, 59, 173, 92, 179, 160, 32, 227, 83, 69, 64, 202, 241, 99, 120, 230, 232, 106, 43, 241, 35, 109, 159, 135, 109, 50, 24, 251, 192, 57, 88, 230, 219, 28, 99, 75, 35, 51, 185, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 134, 11, 105, 222, 129, 162, 43, 131, 15, 66, 64, 131, 47, 239, 216, 130, 196, 68, 132, 86, 191, 180, 21, 152, 215, 131, 1, 3, 3, 132, 71, 101, 116, 104, 135, 103, 111, 49, 46, 53, 46, 49, 133, 108, 105, 110, 117, 120, 160, 146, 196, 18, 154, 10, 226, 54, 27, 69, 42, 158, 222, 236, 229, 92, 18, 236, 238, 171, 134, 99, 22, 25, 94, 61, 135, 252, 27, 0, 91, 102, 69, 136, 205, 76, 85, 185, 65, 207, 144, 21}
var gethHeader types.Header
err := rlp.Decode(bytes.NewReader(headerRLP), &gethHeader)
Expect(err).NotTo(HaveOccurred())
converter := common2.HeaderConverter{}
coreHeader, err := converter.Convert(&gethHeader)
Expect(err).NotTo(HaveOccurred())
Expect(coreHeader.Raw).To(Equal(headerRLP))
})
})