forked from cerc-io/ipld-eth-server
Add cold import script
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type BlockConverter struct {
|
||||
transactionConverter TransactionConverter
|
||||
}
|
||||
|
||||
func NewBlockConverter(transactionConverter TransactionConverter) BlockConverter {
|
||||
return BlockConverter{transactionConverter: transactionConverter}
|
||||
}
|
||||
|
||||
func (bc BlockConverter) ToCoreBlock(gethBlock *types.Block) (core.Block, error) {
|
||||
transactions, err := bc.transactionConverter.ConvertTransactionsToCore(gethBlock)
|
||||
if err != nil {
|
||||
return core.Block{}, err
|
||||
}
|
||||
coreBlock := core.Block{
|
||||
Difficulty: gethBlock.Difficulty().Int64(),
|
||||
ExtraData: hexutil.Encode(gethBlock.Extra()),
|
||||
GasLimit: gethBlock.GasLimit(),
|
||||
GasUsed: gethBlock.GasUsed(),
|
||||
Hash: gethBlock.Hash().Hex(),
|
||||
Miner: strings.ToLower(gethBlock.Coinbase().Hex()),
|
||||
Nonce: hexutil.Encode(gethBlock.Header().Nonce[:]),
|
||||
Number: gethBlock.Number().Int64(),
|
||||
ParentHash: gethBlock.ParentHash().Hex(),
|
||||
Size: gethBlock.Size().String(),
|
||||
Time: gethBlock.Time().Int64(),
|
||||
Transactions: transactions,
|
||||
UncleHash: gethBlock.UncleHash().Hex(),
|
||||
}
|
||||
coreBlock.Reward = CalcBlockReward(coreBlock, gethBlock.Uncles())
|
||||
coreBlock.UnclesReward = CalcUnclesReward(coreBlock, gethBlock.Uncles())
|
||||
return coreBlock, nil
|
||||
}
|
||||
@@ -0,0 +1,398 @@
|
||||
package common_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math/big"
|
||||
"os"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
vulcCommon "github.com/vulcanize/vulcanizedb/pkg/geth/converters/common"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc"
|
||||
)
|
||||
|
||||
type FakeGethClient struct {
|
||||
receipts map[string]*types.Receipt
|
||||
err error
|
||||
}
|
||||
|
||||
type TransActionReceiptError struct{}
|
||||
|
||||
func (tarErr TransActionReceiptError) Error() string {
|
||||
return fmt.Sprintf("transaction receipt error")
|
||||
}
|
||||
|
||||
type TransactionSenderError struct{}
|
||||
|
||||
func (tasErr TransactionSenderError) Error() string {
|
||||
return fmt.Sprintf("transaction sender error")
|
||||
}
|
||||
|
||||
func NewFakeClient(err error) *FakeGethClient {
|
||||
return &FakeGethClient{
|
||||
receipts: make(map[string]*types.Receipt),
|
||||
err: err,
|
||||
}
|
||||
}
|
||||
|
||||
func (client *FakeGethClient) AddReceipts(receipts []*types.Receipt) {
|
||||
for _, receipt := range receipts {
|
||||
client.receipts[receipt.TxHash.Hex()] = receipt
|
||||
}
|
||||
}
|
||||
|
||||
func (client *FakeGethClient) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) {
|
||||
if err, ok := client.err.(TransActionReceiptError); ok {
|
||||
return &types.Receipt{}, err
|
||||
}
|
||||
if gasUsed, ok := client.receipts[txHash.Hex()]; ok {
|
||||
return gasUsed, nil
|
||||
}
|
||||
return &types.Receipt{GasUsed: uint64(0)}, nil
|
||||
}
|
||||
|
||||
func (client *FakeGethClient) TransactionSender(ctx context.Context, tx *types.Transaction, block common.Hash, index uint) (common.Address, error) {
|
||||
if err, ok := client.err.(TransactionSenderError); ok {
|
||||
return common.Address{}, err
|
||||
}
|
||||
return common.HexToAddress("0x123"), nil
|
||||
}
|
||||
|
||||
var _ = Describe("Conversion of GethBlock to core.Block", func() {
|
||||
|
||||
It("converts basic Block metadata", func() {
|
||||
difficulty := big.NewInt(1)
|
||||
gasLimit := uint64(100000)
|
||||
gasUsed := uint64(100000)
|
||||
miner := common.HexToAddress("0x0000000000000000000000000000000000000123")
|
||||
extraData, _ := hexutil.Decode("0xe4b883e5bda9e7a59ee4bb99e9b1bc")
|
||||
nonce := types.BlockNonce{10}
|
||||
number := int64(1)
|
||||
time := int64(140000000)
|
||||
|
||||
header := types.Header{
|
||||
Difficulty: difficulty,
|
||||
GasLimit: uint64(gasLimit),
|
||||
GasUsed: uint64(gasUsed),
|
||||
Extra: extraData,
|
||||
Coinbase: miner,
|
||||
Nonce: nonce,
|
||||
Number: big.NewInt(number),
|
||||
ParentHash: common.Hash{64},
|
||||
Time: big.NewInt(time),
|
||||
UncleHash: common.Hash{128},
|
||||
}
|
||||
block := types.NewBlock(&header, []*types.Transaction{}, []*types.Header{}, []*types.Receipt{})
|
||||
client := &FakeGethClient{}
|
||||
transactionConverter := rpc.NewRpcTransactionConverter(client)
|
||||
blockConverter := vulcCommon.NewBlockConverter(transactionConverter)
|
||||
|
||||
coreBlock, err := blockConverter.ToCoreBlock(block)
|
||||
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(coreBlock.Difficulty).To(Equal(difficulty.Int64()))
|
||||
Expect(coreBlock.GasLimit).To(Equal(gasLimit))
|
||||
Expect(coreBlock.Miner).To(Equal(miner.Hex()))
|
||||
Expect(coreBlock.GasUsed).To(Equal(gasUsed))
|
||||
Expect(coreBlock.Hash).To(Equal(block.Hash().Hex()))
|
||||
Expect(coreBlock.Nonce).To(Equal(hexutil.Encode(header.Nonce[:])))
|
||||
Expect(coreBlock.Number).To(Equal(number))
|
||||
Expect(coreBlock.ParentHash).To(Equal(block.ParentHash().Hex()))
|
||||
Expect(coreBlock.ExtraData).To(Equal(hexutil.Encode(block.Extra())))
|
||||
Expect(coreBlock.Size).To(Equal(block.Size().String()))
|
||||
Expect(coreBlock.Time).To(Equal(time))
|
||||
Expect(coreBlock.UncleHash).To(Equal(block.UncleHash().Hex()))
|
||||
Expect(coreBlock.IsFinal).To(BeFalse())
|
||||
})
|
||||
|
||||
Describe("The block and uncle rewards calculations", func() {
|
||||
It("calculates block rewards for a block", func() {
|
||||
transaction := types.NewTransaction(
|
||||
uint64(226823),
|
||||
common.HexToAddress("0x108fedb097c1dcfed441480170144d8e19bb217f"),
|
||||
big.NewInt(1080900090000000000),
|
||||
uint64(90000),
|
||||
big.NewInt(50000000000),
|
||||
[]byte{},
|
||||
)
|
||||
transactions := []*types.Transaction{transaction}
|
||||
|
||||
txHash := transaction.Hash()
|
||||
receipt := types.Receipt{
|
||||
TxHash: txHash,
|
||||
GasUsed: uint64(21000),
|
||||
CumulativeGasUsed: uint64(21000),
|
||||
}
|
||||
receipts := []*types.Receipt{&receipt}
|
||||
|
||||
client := NewFakeClient(nil)
|
||||
client.AddReceipts(receipts)
|
||||
|
||||
number := int64(1071819)
|
||||
header := types.Header{
|
||||
Number: big.NewInt(number),
|
||||
}
|
||||
uncles := []*types.Header{{Number: big.NewInt(1071817)}, {Number: big.NewInt(1071818)}}
|
||||
block := types.NewBlock(&header, transactions, uncles, []*types.Receipt{&receipt})
|
||||
transactionConverter := rpc.NewRpcTransactionConverter(client)
|
||||
blockConverter := vulcCommon.NewBlockConverter(transactionConverter)
|
||||
|
||||
coreBlock, err := blockConverter.ToCoreBlock(block)
|
||||
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(vulcCommon.CalcBlockReward(coreBlock, block.Uncles())).To(Equal(5.31355))
|
||||
})
|
||||
|
||||
It("calculates the uncles reward for a block", func() {
|
||||
transaction := types.NewTransaction(
|
||||
uint64(226823),
|
||||
common.HexToAddress("0x108fedb097c1dcfed441480170144d8e19bb217f"),
|
||||
big.NewInt(1080900090000000000),
|
||||
uint64(90000),
|
||||
big.NewInt(50000000000),
|
||||
[]byte{})
|
||||
transactions := []*types.Transaction{transaction}
|
||||
|
||||
receipt := types.Receipt{
|
||||
TxHash: transaction.Hash(),
|
||||
GasUsed: uint64(21000),
|
||||
CumulativeGasUsed: uint64(21000),
|
||||
}
|
||||
receipts := []*types.Receipt{&receipt}
|
||||
|
||||
header := types.Header{
|
||||
Number: big.NewInt(int64(1071819)),
|
||||
}
|
||||
uncles := []*types.Header{
|
||||
{Number: big.NewInt(1071816)},
|
||||
{Number: big.NewInt(1071817)},
|
||||
}
|
||||
block := types.NewBlock(&header, transactions, uncles, receipts)
|
||||
|
||||
client := NewFakeClient(nil)
|
||||
client.AddReceipts(receipts)
|
||||
transactionConverter := rpc.NewRpcTransactionConverter(client)
|
||||
blockConverter := vulcCommon.NewBlockConverter(transactionConverter)
|
||||
|
||||
coreBlock, err := blockConverter.ToCoreBlock(block)
|
||||
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(vulcCommon.CalcUnclesReward(coreBlock, block.Uncles())).To(Equal(6.875))
|
||||
})
|
||||
|
||||
It("decreases the static block reward from 5 to 3 for blocks after block 4,269,999", func() {
|
||||
transactionOne := types.NewTransaction(
|
||||
uint64(8072),
|
||||
common.HexToAddress("0xebd17720aeb7ac5186c5dfa7bafeb0bb14c02551 "),
|
||||
big.NewInt(0),
|
||||
uint64(500000),
|
||||
big.NewInt(42000000000),
|
||||
[]byte{},
|
||||
)
|
||||
|
||||
transactionTwo := types.NewTransaction(uint64(8071),
|
||||
common.HexToAddress("0x3cdab63d764c8c5048ed5e8f0a4e95534ba7e1ea"),
|
||||
big.NewInt(0),
|
||||
uint64(500000),
|
||||
big.NewInt(42000000000),
|
||||
[]byte{})
|
||||
|
||||
transactions := []*types.Transaction{transactionOne, transactionTwo}
|
||||
|
||||
receiptOne := types.Receipt{
|
||||
TxHash: transactionOne.Hash(),
|
||||
GasUsed: uint64(297508),
|
||||
CumulativeGasUsed: uint64(0),
|
||||
}
|
||||
receiptTwo := types.Receipt{
|
||||
TxHash: transactionTwo.Hash(),
|
||||
GasUsed: uint64(297508),
|
||||
CumulativeGasUsed: uint64(0),
|
||||
}
|
||||
receipts := []*types.Receipt{&receiptOne, &receiptTwo}
|
||||
|
||||
number := int64(4370055)
|
||||
header := types.Header{
|
||||
Number: big.NewInt(number),
|
||||
}
|
||||
var uncles []*types.Header
|
||||
block := types.NewBlock(&header, transactions, uncles, receipts)
|
||||
|
||||
client := NewFakeClient(nil)
|
||||
client.AddReceipts(receipts)
|
||||
transactionConverter := rpc.NewRpcTransactionConverter(client)
|
||||
blockConverter := vulcCommon.NewBlockConverter(transactionConverter)
|
||||
|
||||
coreBlock, err := blockConverter.ToCoreBlock(block)
|
||||
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(vulcCommon.CalcBlockReward(coreBlock, block.Uncles())).To(Equal(3.024990672))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("the converted transactions", func() {
|
||||
It("is empty", func() {
|
||||
header := types.Header{}
|
||||
block := types.NewBlock(&header, []*types.Transaction{}, []*types.Header{}, []*types.Receipt{})
|
||||
client := &FakeGethClient{}
|
||||
transactionConverter := rpc.NewRpcTransactionConverter(client)
|
||||
blockConverter := vulcCommon.NewBlockConverter(transactionConverter)
|
||||
|
||||
coreBlock, err := blockConverter.ToCoreBlock(block)
|
||||
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(len(coreBlock.Transactions)).To(Equal(0))
|
||||
})
|
||||
|
||||
It("converts a single transaction", func() {
|
||||
gethTransaction := types.NewTransaction(
|
||||
uint64(10000), common.Address{1},
|
||||
big.NewInt(10),
|
||||
uint64(5000),
|
||||
big.NewInt(3),
|
||||
hexutil.MustDecode("0xf7d8c8830000000000000000000000000000000000000000000000000000000000037788000000000000000000000000000000000000000000000000000000000003bd14"),
|
||||
)
|
||||
|
||||
gethReceipt := &types.Receipt{
|
||||
Bloom: types.BytesToBloom(hexutil.MustDecode("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")),
|
||||
ContractAddress: common.HexToAddress("x123"),
|
||||
CumulativeGasUsed: uint64(7996119),
|
||||
GasUsed: uint64(21000),
|
||||
Logs: []*types.Log{},
|
||||
Status: uint(1),
|
||||
TxHash: gethTransaction.Hash(),
|
||||
}
|
||||
|
||||
client := NewFakeClient(nil)
|
||||
client.AddReceipts([]*types.Receipt{gethReceipt})
|
||||
|
||||
header := types.Header{}
|
||||
block := types.NewBlock(
|
||||
&header,
|
||||
[]*types.Transaction{gethTransaction},
|
||||
[]*types.Header{},
|
||||
[]*types.Receipt{gethReceipt},
|
||||
)
|
||||
transactionConverter := rpc.NewRpcTransactionConverter(client)
|
||||
blockConverter := vulcCommon.NewBlockConverter(transactionConverter)
|
||||
|
||||
coreBlock, err := blockConverter.ToCoreBlock(block)
|
||||
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(len(coreBlock.Transactions)).To(Equal(1))
|
||||
coreTransaction := coreBlock.Transactions[0]
|
||||
Expect(coreTransaction.Data).To(Equal("0xf7d8c8830000000000000000000000000000000000000000000000000000000000037788000000000000000000000000000000000000000000000000000000000003bd14"))
|
||||
Expect(coreTransaction.To).To(Equal(gethTransaction.To().Hex()))
|
||||
Expect(coreTransaction.From).To(Equal("0x0000000000000000000000000000000000000123"))
|
||||
Expect(coreTransaction.GasLimit).To(Equal(gethTransaction.Gas()))
|
||||
Expect(coreTransaction.GasPrice).To(Equal(gethTransaction.GasPrice().Int64()))
|
||||
Expect(coreTransaction.Value).To(Equal(gethTransaction.Value().String()))
|
||||
Expect(coreTransaction.Nonce).To(Equal(gethTransaction.Nonce()))
|
||||
|
||||
coreReceipt := coreTransaction.Receipt
|
||||
expectedReceipt := vulcCommon.ToCoreReceipt(gethReceipt)
|
||||
Expect(coreReceipt).To(Equal(expectedReceipt))
|
||||
})
|
||||
|
||||
It("has an empty 'To' field when transaction creates a new contract", func() {
|
||||
gethTransaction := types.NewContractCreation(
|
||||
uint64(10000),
|
||||
big.NewInt(10),
|
||||
uint64(5000),
|
||||
big.NewInt(3),
|
||||
[]byte("1234"),
|
||||
)
|
||||
|
||||
gethReceipt := &types.Receipt{
|
||||
CumulativeGasUsed: uint64(1),
|
||||
GasUsed: uint64(1),
|
||||
TxHash: gethTransaction.Hash(),
|
||||
ContractAddress: common.HexToAddress("0x1023342345"),
|
||||
}
|
||||
|
||||
client := NewFakeClient(nil)
|
||||
client.AddReceipts([]*types.Receipt{gethReceipt})
|
||||
|
||||
block := types.NewBlock(
|
||||
&types.Header{},
|
||||
[]*types.Transaction{gethTransaction},
|
||||
[]*types.Header{},
|
||||
[]*types.Receipt{gethReceipt},
|
||||
)
|
||||
transactionConverter := rpc.NewRpcTransactionConverter(client)
|
||||
blockConverter := vulcCommon.NewBlockConverter(transactionConverter)
|
||||
|
||||
coreBlock, err := blockConverter.ToCoreBlock(block)
|
||||
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
coreTransaction := coreBlock.Transactions[0]
|
||||
Expect(coreTransaction.To).To(Equal(""))
|
||||
|
||||
coreReceipt := coreTransaction.Receipt
|
||||
expectedReceipt := vulcCommon.ToCoreReceipt(gethReceipt)
|
||||
Expect(coreReceipt).To(Equal(expectedReceipt))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("transaction error handling", func() {
|
||||
var gethTransaction *types.Transaction
|
||||
var gethReceipt *types.Receipt
|
||||
var header *types.Header
|
||||
var block *types.Block
|
||||
|
||||
BeforeEach(func() {
|
||||
log.SetOutput(ioutil.Discard)
|
||||
gethTransaction = types.NewTransaction(
|
||||
uint64(0),
|
||||
common.Address{},
|
||||
big.NewInt(0),
|
||||
uint64(0),
|
||||
big.NewInt(0),
|
||||
[]byte{},
|
||||
)
|
||||
gethReceipt = &types.Receipt{}
|
||||
header = &types.Header{}
|
||||
block = types.NewBlock(
|
||||
header,
|
||||
[]*types.Transaction{gethTransaction},
|
||||
[]*types.Header{},
|
||||
[]*types.Receipt{gethReceipt},
|
||||
)
|
||||
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
defer log.SetOutput(os.Stdout)
|
||||
})
|
||||
|
||||
It("returns an error when transaction sender call fails", func() {
|
||||
client := NewFakeClient(TransactionSenderError{})
|
||||
client.AddReceipts([]*types.Receipt{})
|
||||
transactionConverter := rpc.NewRpcTransactionConverter(client)
|
||||
blockConverter := vulcCommon.NewBlockConverter(transactionConverter)
|
||||
|
||||
_, err := blockConverter.ToCoreBlock(block)
|
||||
|
||||
Expect(err).To(Equal(TransactionSenderError{}))
|
||||
})
|
||||
|
||||
It("returns an error when transaction receipt call fails", func() {
|
||||
client := NewFakeClient(TransActionReceiptError{})
|
||||
client.AddReceipts([]*types.Receipt{})
|
||||
transactionConverter := rpc.NewRpcTransactionConverter(client)
|
||||
blockConverter := vulcCommon.NewBlockConverter(transactionConverter)
|
||||
|
||||
_, err := blockConverter.ToCoreBlock(block)
|
||||
|
||||
Expect(err).To(Equal(TransActionReceiptError{}))
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
@@ -0,0 +1,54 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
)
|
||||
|
||||
func CalcUnclesReward(block core.Block, uncles []*types.Header) float64 {
|
||||
var unclesReward float64
|
||||
for _, uncle := range uncles {
|
||||
blockNumber := block.Number
|
||||
staticBlockReward := float64(staticRewardByBlockNumber(blockNumber))
|
||||
unclesReward += (1.0 + float64(uncle.Number.Int64()-block.Number)/8.0) * staticBlockReward
|
||||
}
|
||||
return unclesReward
|
||||
}
|
||||
|
||||
func CalcBlockReward(block core.Block, uncles []*types.Header) float64 {
|
||||
blockNumber := block.Number
|
||||
staticBlockReward := staticRewardByBlockNumber(blockNumber)
|
||||
transactionFees := calcTransactionFees(block)
|
||||
uncleInclusionRewards := calcUncleInclusionRewards(block, uncles)
|
||||
return transactionFees + uncleInclusionRewards + staticBlockReward
|
||||
}
|
||||
|
||||
func calcTransactionFees(block core.Block) float64 {
|
||||
var transactionFees float64
|
||||
for _, transaction := range block.Transactions {
|
||||
receipt := transaction.Receipt
|
||||
transactionFees += float64(uint64(transaction.GasPrice) * receipt.GasUsed)
|
||||
}
|
||||
return transactionFees / params.Ether
|
||||
}
|
||||
|
||||
func calcUncleInclusionRewards(block core.Block, uncles []*types.Header) float64 {
|
||||
var uncleInclusionRewards float64
|
||||
staticBlockReward := staticRewardByBlockNumber(block.Number)
|
||||
for range uncles {
|
||||
uncleInclusionRewards += staticBlockReward * 1 / 32
|
||||
}
|
||||
return uncleInclusionRewards
|
||||
}
|
||||
|
||||
func staticRewardByBlockNumber(blockNumber int64) float64 {
|
||||
var staticBlockReward float64
|
||||
//https://blog.ethereum.org/2017/10/12/byzantium-hf-announcement/
|
||||
if blockNumber >= 4370000 {
|
||||
staticBlockReward = 3
|
||||
} else {
|
||||
staticBlockReward = 5
|
||||
}
|
||||
return staticBlockReward
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package common_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func TestCommon(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Common Suite")
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
)
|
||||
|
||||
func ToCoreLogs(gethLogs []types.Log) []core.Log {
|
||||
var logs []core.Log
|
||||
for _, log := range gethLogs {
|
||||
log := ToCoreLog(log)
|
||||
logs = append(logs, log)
|
||||
}
|
||||
return logs
|
||||
}
|
||||
|
||||
func makeTopics(topics []common.Hash) core.Topics {
|
||||
var hexTopics core.Topics
|
||||
for i, topic := range topics {
|
||||
hexTopics[i] = topic.Hex()
|
||||
}
|
||||
return hexTopics
|
||||
}
|
||||
|
||||
func ToCoreLog(gethLog types.Log) core.Log {
|
||||
topics := gethLog.Topics
|
||||
hexTopics := makeTopics(topics)
|
||||
return core.Log{
|
||||
Address: strings.ToLower(gethLog.Address.Hex()),
|
||||
BlockNumber: int64(gethLog.BlockNumber),
|
||||
Topics: hexTopics,
|
||||
TxHash: gethLog.TxHash.Hex(),
|
||||
Index: int64(gethLog.Index),
|
||||
Data: hexutil.Encode(gethLog.Data),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package common_test
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
vulcCommon "github.com/vulcanize/vulcanizedb/pkg/geth/converters/common"
|
||||
)
|
||||
|
||||
var _ = Describe("Conversion of GethLog to core.Log", func() {
|
||||
|
||||
It("converts geth log to internal log format", func() {
|
||||
gethLog := types.Log{
|
||||
Address: common.HexToAddress("0x448a5065aeBB8E423F0896E6c5D525C040f59af3"),
|
||||
BlockHash: common.HexToHash("0x656c34545f90a730a19008c0e7a7cd4fb3895064b48d6d69761bd5abad681056"),
|
||||
BlockNumber: 2019236,
|
||||
Data: hexutil.MustDecode("0x000000000000000000000000000000000000000000000001a055690d9db80000"),
|
||||
Index: 2,
|
||||
TxIndex: 3,
|
||||
TxHash: common.HexToHash("0x3b198bfd5d2907285af009e9ae84a0ecd63677110d89d7e030251acb87f6487e"),
|
||||
Topics: []common.Hash{
|
||||
common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"),
|
||||
common.HexToHash("0x00000000000000000000000080b2c9d7cbbf30a1b0fc8983c647d754c6525615"),
|
||||
},
|
||||
}
|
||||
|
||||
expected := core.Log{
|
||||
Address: strings.ToLower(gethLog.Address.Hex()),
|
||||
BlockNumber: int64(gethLog.BlockNumber),
|
||||
Data: hexutil.Encode(gethLog.Data),
|
||||
TxHash: gethLog.TxHash.Hex(),
|
||||
Index: 2,
|
||||
Topics: core.Topics{
|
||||
gethLog.Topics[0].Hex(),
|
||||
gethLog.Topics[1].Hex(),
|
||||
},
|
||||
}
|
||||
|
||||
coreLog := vulcCommon.ToCoreLog(gethLog)
|
||||
|
||||
Expect(coreLog.Address).To(Equal(expected.Address))
|
||||
Expect(coreLog.BlockNumber).To(Equal(expected.BlockNumber))
|
||||
Expect(coreLog.Data).To(Equal(expected.Data))
|
||||
Expect(coreLog.Index).To(Equal(expected.Index))
|
||||
Expect(coreLog.Topics[0]).To(Equal(expected.Topics[0]))
|
||||
Expect(coreLog.Topics[1]).To(Equal(expected.Topics[1]))
|
||||
Expect(coreLog.TxHash).To(Equal(expected.TxHash))
|
||||
})
|
||||
|
||||
It("converts geth log array to array of internal logs", func() {
|
||||
gethLogOne := types.Log{
|
||||
Address: common.HexToAddress("0xecf8f87f810ecf450940c9f60066b4a7a501d6a7"),
|
||||
BlockHash: common.HexToHash("0x656c34545f90a730a19008c0e7a7cd4fb3895064b48d6d69761bd5abad681056"),
|
||||
BlockNumber: 2019236,
|
||||
Data: hexutil.MustDecode("0x000000000000000000000000000000000000000000000001a055690d9db80000"),
|
||||
Index: 2,
|
||||
TxIndex: 3,
|
||||
TxHash: common.HexToHash("0x3b198bfd5d2907285af009e9ae84a0ecd63677110d89d7e030251acb87f6487e"),
|
||||
Topics: []common.Hash{
|
||||
common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"),
|
||||
common.HexToHash("0x00000000000000000000000080b2c9d7cbbf30a1b0fc8983c647d754c6525615"),
|
||||
},
|
||||
}
|
||||
|
||||
gethLogTwo := types.Log{
|
||||
Address: common.HexToAddress("0x123"),
|
||||
BlockHash: common.HexToHash("0x576"),
|
||||
BlockNumber: 2019236,
|
||||
Data: hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000001"),
|
||||
Index: 3,
|
||||
TxIndex: 4,
|
||||
TxHash: common.HexToHash("0x134"),
|
||||
Topics: []common.Hash{
|
||||
common.HexToHash("0xaaa"),
|
||||
common.HexToHash("0xbbb"),
|
||||
},
|
||||
}
|
||||
|
||||
expectedOne := vulcCommon.ToCoreLog(gethLogOne)
|
||||
expectedTwo := vulcCommon.ToCoreLog(gethLogTwo)
|
||||
|
||||
coreLogs := vulcCommon.ToCoreLogs([]types.Log{gethLogOne, gethLogTwo})
|
||||
|
||||
Expect(len(coreLogs)).To(Equal(2))
|
||||
Expect(coreLogs[0]).To(Equal(expectedOne))
|
||||
Expect(coreLogs[1]).To(Equal(expectedTwo))
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,63 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
)
|
||||
|
||||
func ToCoreReceipts(gethReceipts types.Receipts) []core.Receipt {
|
||||
var coreReceipts []core.Receipt
|
||||
for _, receipt := range gethReceipts {
|
||||
coreReceipt := ToCoreReceipt(receipt)
|
||||
coreReceipts = append(coreReceipts, coreReceipt)
|
||||
}
|
||||
return coreReceipts
|
||||
}
|
||||
|
||||
func ToCoreReceipt(gethReceipt *types.Receipt) core.Receipt {
|
||||
bloom := hexutil.Encode(gethReceipt.Bloom.Bytes())
|
||||
var postState string
|
||||
var status int
|
||||
postState, status = postStateOrStatus(gethReceipt)
|
||||
logs := dereferenceLogs(gethReceipt)
|
||||
contractAddress := setContractAddress(gethReceipt)
|
||||
|
||||
return core.Receipt{
|
||||
Bloom: bloom,
|
||||
ContractAddress: contractAddress,
|
||||
CumulativeGasUsed: gethReceipt.CumulativeGasUsed,
|
||||
GasUsed: gethReceipt.GasUsed,
|
||||
Logs: logs,
|
||||
StateRoot: postState,
|
||||
TxHash: gethReceipt.TxHash.Hex(),
|
||||
Status: status,
|
||||
}
|
||||
}
|
||||
|
||||
func setContractAddress(gethReceipt *types.Receipt) string {
|
||||
emptyAddress := common.Address{}.Bytes()
|
||||
if bytes.Equal(gethReceipt.ContractAddress.Bytes(), emptyAddress) {
|
||||
return ""
|
||||
}
|
||||
return gethReceipt.ContractAddress.Hex()
|
||||
}
|
||||
|
||||
func dereferenceLogs(gethReceipt *types.Receipt) []core.Log {
|
||||
logs := []core.Log{}
|
||||
for _, log := range gethReceipt.Logs {
|
||||
logs = append(logs, ToCoreLog(*log))
|
||||
}
|
||||
return logs
|
||||
}
|
||||
|
||||
func postStateOrStatus(gethReceipts *types.Receipt) (string, int) {
|
||||
if len(gethReceipts.PostState) != 0 {
|
||||
return hexutil.Encode(gethReceipts.PostState), -99
|
||||
}
|
||||
return "", int(gethReceipts.Status)
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package common_test
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
vulcCommon "github.com/vulcanize/vulcanizedb/pkg/geth/converters/common"
|
||||
)
|
||||
|
||||
var _ = Describe("Conversion of GethReceipt to core.Receipt", func() {
|
||||
|
||||
It(`converts geth receipt to internal receipt format (pre Byzantium has post-transaction stateroot)`, func() {
|
||||
receipt := types.Receipt{
|
||||
Bloom: types.BytesToBloom(hexutil.MustDecode("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")),
|
||||
ContractAddress: common.Address{},
|
||||
CumulativeGasUsed: uint64(25000),
|
||||
GasUsed: uint64(21000),
|
||||
Logs: []*types.Log{},
|
||||
PostState: hexutil.MustDecode("0x88abf7e73128227370aa7baa3dd4e18d0af70e92ef1f9ef426942fbe2dddb733"),
|
||||
TxHash: common.HexToHash("0x97d99bc7729211111a21b12c933c949d4f31684f1d6954ff477d0477538ff017"),
|
||||
}
|
||||
|
||||
expected := core.Receipt{
|
||||
Bloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
ContractAddress: "",
|
||||
CumulativeGasUsed: 25000,
|
||||
GasUsed: 21000,
|
||||
Logs: []core.Log{},
|
||||
StateRoot: "0x88abf7e73128227370aa7baa3dd4e18d0af70e92ef1f9ef426942fbe2dddb733",
|
||||
Status: -99,
|
||||
TxHash: receipt.TxHash.Hex(),
|
||||
}
|
||||
|
||||
coreReceipt := vulcCommon.ToCoreReceipt(&receipt)
|
||||
Expect(coreReceipt.Bloom).To(Equal(expected.Bloom))
|
||||
Expect(coreReceipt.ContractAddress).To(Equal(expected.ContractAddress))
|
||||
Expect(coreReceipt.CumulativeGasUsed).To(Equal(expected.CumulativeGasUsed))
|
||||
Expect(coreReceipt.GasUsed).To(Equal(expected.GasUsed))
|
||||
Expect(coreReceipt.Logs).To(Equal(expected.Logs))
|
||||
Expect(coreReceipt.StateRoot).To(Equal(expected.StateRoot))
|
||||
Expect(coreReceipt.Status).To(Equal(expected.Status))
|
||||
Expect(coreReceipt.TxHash).To(Equal(expected.TxHash))
|
||||
|
||||
})
|
||||
|
||||
It("converts geth receipt to internal receipt format (post Byzantium has status", func() {
|
||||
receipt := types.Receipt{
|
||||
Bloom: types.BytesToBloom(hexutil.MustDecode("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")),
|
||||
ContractAddress: common.HexToAddress("x0123"),
|
||||
CumulativeGasUsed: uint64(7996119),
|
||||
GasUsed: uint64(21000),
|
||||
Logs: []*types.Log{},
|
||||
Status: uint(1),
|
||||
TxHash: common.HexToHash("0xe340558980f89d5f86045ac11e5cc34e4bcec20f9f1e2a427aa39d87114e8223"),
|
||||
}
|
||||
|
||||
expected := core.Receipt{
|
||||
Bloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
ContractAddress: receipt.ContractAddress.Hex(),
|
||||
CumulativeGasUsed: 7996119,
|
||||
GasUsed: 21000,
|
||||
Logs: []core.Log{},
|
||||
StateRoot: "",
|
||||
Status: 1,
|
||||
TxHash: receipt.TxHash.Hex(),
|
||||
}
|
||||
|
||||
coreReceipt := vulcCommon.ToCoreReceipt(&receipt)
|
||||
Expect(coreReceipt.Bloom).To(Equal(expected.Bloom))
|
||||
Expect(coreReceipt.ContractAddress).To(Equal(""))
|
||||
Expect(coreReceipt.CumulativeGasUsed).To(Equal(expected.CumulativeGasUsed))
|
||||
Expect(coreReceipt.GasUsed).To(Equal(expected.GasUsed))
|
||||
Expect(coreReceipt.Logs).To(Equal(expected.Logs))
|
||||
Expect(coreReceipt.StateRoot).To(Equal(expected.StateRoot))
|
||||
Expect(coreReceipt.Status).To(Equal(expected.Status))
|
||||
Expect(coreReceipt.TxHash).To(Equal(expected.TxHash))
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,10 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/vulcanize/vulcanizedb/pkg/core"
|
||||
)
|
||||
|
||||
type TransactionConverter interface {
|
||||
ConvertTransactionsToCore(gethBlock *types.Block) ([]core.Transaction, error)
|
||||
}
|
||||
Reference in New Issue
Block a user