Refactoring

* Move flip kick files pkg/transformers/flip_kick

* Consolidate test database setup

* Pull ganache ipcPath from config

* Update README to include info about using a Ganache chain
This commit is contained in:
Elizabeth
2018-08-07 15:17:29 -05:00
committed by GitHub
parent c617cd9c9d
commit b37324bf3d
257 changed files with 188 additions and 173 deletions
+1
View File
@@ -76,6 +76,7 @@ var _ = Describe("Postgres DB", func() {
}
node := core.Node{GenesisBlock: "GENESIS", NetworkID: 1, ID: "x123", ClientName: "geth"}
db := test_config.NewTestDB(node)
test_config.CleanTestDB(db)
blocksRepository := repositories.NewBlockRepository(db)
_, err1 := blocksRepository.CreateOrUpdateBlock(badBlock)
@@ -26,6 +26,7 @@ var _ = Describe("Saving blocks", func() {
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
}
db = test_config.NewTestDB(node)
test_config.CleanTestDB(db)
blockRepository = repositories.NewBlockRepository(db)
})
@@ -42,6 +43,7 @@ var _ = Describe("Saving blocks", func() {
ClientName: "Geth",
}
dbTwo := test_config.NewTestDB(nodeTwo)
test_config.CleanTestDB(dbTwo)
repositoryTwo := repositories.NewBlockRepository(dbTwo)
_, err := repositoryTwo.GetBlock(123)
@@ -168,6 +170,7 @@ var _ = Describe("Saving blocks", func() {
NetworkID: 1,
}
dbTwo := test_config.NewTestDB(nodeTwo)
test_config.CleanTestDB(dbTwo)
repositoryTwo := repositories.NewBlockRepository(dbTwo)
blockRepository.CreateOrUpdateBlock(blockOne)
@@ -25,6 +25,7 @@ var _ = Describe("Creating contracts", func() {
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
}
db = test_config.NewTestDB(node)
test_config.CleanTestDB(db)
contractRepository = repositories.ContractRepository{DB: db}
})
@@ -17,6 +17,7 @@ var _ = Describe("Block header repository", func() {
It("adds a header", func() {
node := core.Node{}
db := test_config.NewTestDB(node)
test_config.CleanTestDB(db)
repo := repositories.NewHeaderRepository(db)
header := core.Header{
BlockNumber: 100,
@@ -38,6 +39,7 @@ var _ = Describe("Block header repository", func() {
It("adds node data to header", func() {
node := core.Node{ID: "EthNodeFingerprint"}
db := test_config.NewTestDB(node)
test_config.CleanTestDB(db)
repo := repositories.NewHeaderRepository(db)
header := core.Header{BlockNumber: 100}
@@ -57,6 +59,7 @@ var _ = Describe("Block header repository", func() {
It("does not duplicate headers", func() {
node := core.Node{}
db := test_config.NewTestDB(node)
test_config.CleanTestDB(db)
repo := repositories.NewHeaderRepository(db)
header := core.Header{
BlockNumber: 100,
@@ -79,6 +82,7 @@ var _ = Describe("Block header repository", func() {
It("replaces header if hash is different", func() {
node := core.Node{}
db := test_config.NewTestDB(node)
test_config.CleanTestDB(db)
repo := repositories.NewHeaderRepository(db)
header := core.Header{
BlockNumber: 100,
@@ -106,6 +110,7 @@ var _ = Describe("Block header repository", func() {
It("does not replace header if node fingerprint is different", func() {
node := core.Node{ID: "Fingerprint"}
db := test_config.NewTestDB(node)
test_config.CleanTestDB(db)
repo := repositories.NewHeaderRepository(db)
header := core.Header{
BlockNumber: 100,
@@ -176,6 +181,7 @@ var _ = Describe("Block header repository", func() {
It("returns header if it exists", func() {
node := core.Node{}
db := test_config.NewTestDB(node)
test_config.CleanTestDB(db)
repo := repositories.NewHeaderRepository(db)
header := core.Header{
BlockNumber: 100,
@@ -194,6 +200,7 @@ var _ = Describe("Block header repository", func() {
It("does not return header for a different node fingerprint", func() {
node := core.Node{}
db := test_config.NewTestDB(node)
test_config.CleanTestDB(db)
repo := repositories.NewHeaderRepository(db)
header := core.Header{
BlockNumber: 100,
@@ -218,6 +225,7 @@ var _ = Describe("Block header repository", func() {
It("returns block numbers for headers not in the database", func() {
node := core.Node{}
db := test_config.NewTestDB(node)
test_config.CleanTestDB(db)
repo := repositories.NewHeaderRepository(db)
repo.CreateOrUpdateHeader(core.Header{BlockNumber: 1})
repo.CreateOrUpdateHeader(core.Header{BlockNumber: 3})
@@ -231,6 +239,7 @@ var _ = Describe("Block header repository", func() {
It("does not count headers created by a different node fingerprint", func() {
node := core.Node{ID: "NodeFingerprint"}
db := test_config.NewTestDB(node)
test_config.CleanTestDB(db)
repo := repositories.NewHeaderRepository(db)
repo.CreateOrUpdateHeader(core.Header{BlockNumber: 1})
repo.CreateOrUpdateHeader(core.Header{BlockNumber: 3})
@@ -23,6 +23,7 @@ var _ = Describe("Log Filters Repository", func() {
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
}
db = test_config.NewTestDB(node)
test_config.CleanTestDB(db)
filterRepository = repositories.FilterRepository{DB: db}
})
@@ -28,6 +28,7 @@ var _ = Describe("Logs Repository", func() {
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
}
db = test_config.NewTestDB(node)
test_config.CleanTestDB(db)
blockRepository = repositories.NewBlockRepository(db)
logsRepository = repositories.LogRepository{DB: db}
receiptRepository = repositories.ReceiptRepository{DB: db}
@@ -24,6 +24,7 @@ var _ = Describe("Receipts Repository", func() {
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
}
db = test_config.NewTestDB(node)
test_config.CleanTestDB(db)
blockRepository = repositories.NewBlockRepository(db)
logRepository = repositories.LogRepository{DB: db}
receiptRepository = repositories.ReceiptRepository{DB: db}
@@ -21,6 +21,7 @@ var _ = Describe("Watched Events Repository", func() {
BeforeEach(func() {
db = test_config.NewTestDB(core.Node{})
test_config.CleanTestDB(db)
blocksRepository = repositories.NewBlockRepository(db)
filterRepository = repositories.FilterRepository{DB: db}
logRepository = repositories.LogRepository{DB: db}
-46
View File
@@ -1,46 +0,0 @@
// Copyright 2018 Vulcanize
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package test_helpers
import (
. "github.com/onsi/gomega"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
"github.com/vulcanize/vulcanizedb/test_config"
)
func CreateNewDatabase() *postgres.DB {
var node core.Node
node = core.Node{
GenesisBlock: "GENESIS",
NetworkID: 1,
ID: "b6f90c0fdd8ec9607aed8ee45c69322e47b7063f0bfb7a29c8ecafab24d0a22d24dd2329b5ee6ed4125a03cb14e57fd584e67f9e53e6c631055cbbd82f080845",
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
}
db := test_config.NewTestDB(node)
_, err := db.Exec(`DELETE FROM logs`)
Expect(err).NotTo(HaveOccurred())
return db
}
func CreateBlock(blockNumber int64, repository repositories.BlockRepository) (blockId int64) {
blockId, err := repository.CreateOrUpdateBlock(core.Block{Number: blockNumber})
Expect(err).NotTo(HaveOccurred())
return blockId
}
+31
View File
@@ -0,0 +1,31 @@
// Copyright 2018 Vulcanize
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package flip_kick
type TransformerConfig struct {
ContractAddress string
ContractAbi string
Topics []string
StartingBlockNumber int64
EndingBlockNumber int64
}
var FlipKickConfig = TransformerConfig{
ContractAddress: "0x08cb6176addcca2e1d1ffe21bee464b72ee4cd8d", //this is a temporary address deployed locally
ContractAbi: FlipperABI,
Topics: []string{FlipKickSignature},
StartingBlockNumber: 0,
EndingBlockNumber: 100,
}
File diff suppressed because one or more lines are too long
+107
View File
@@ -0,0 +1,107 @@
// Copyright 2018 Vulcanize
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package flip_kick
import (
"errors"
"math/big"
"strings"
"time"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/vulcanize/vulcanizedb/pkg/geth"
)
type Converter interface {
ToEntity(contractAddress string, contractAbi string, ethLog types.Log) (*FlipKickEntity, error)
ToModel(flipKick FlipKickEntity) (FlipKickModel, error)
}
type FlipKickConverter struct{}
func (FlipKickConverter) ToEntity(contractAddress string, contractAbi string, ethLog types.Log) (*FlipKickEntity, error) {
entity := &FlipKickEntity{}
address := common.HexToAddress(contractAddress)
abi, err := geth.ParseAbi(contractAbi)
if err != nil {
return entity, err
}
contract := bind.NewBoundContract(address, abi, nil, nil, nil)
err = contract.UnpackLog(entity, "FlipKick", ethLog)
if err != nil {
return entity, err
}
return entity, nil
}
func (FlipKickConverter) ToModel(flipKick FlipKickEntity) (FlipKickModel, error) {
//TODO: Confirm if the following values can be/ever will be nil
if flipKick.Id == nil {
return FlipKickModel{}, errors.New("FlipKick log ID cannot be nil.")
}
id := flipKick.Id.String()
mom := strings.ToLower(flipKick.Mom.String())
vat := strings.ToLower(flipKick.Vat.String())
ilk := strings.ToLower(common.ToHex(flipKick.Ilk[:]))
lot := convertNilToEmptyString(flipKick.Lot.String())
bid := convertNilToEmptyString(flipKick.Bid.String())
guy := strings.ToLower(flipKick.Guy.String())
gal := strings.ToLower(flipKick.Gal.String())
endValue := convertNilToZeroTimeValue(flipKick.End)
end := time.Unix(endValue, 0)
eraValue := convertNilToZeroTimeValue(flipKick.Era)
era := time.Unix(eraValue, 0)
lad := strings.ToLower(flipKick.Lad.String())
tab := convertNilToEmptyString(flipKick.Tab.String())
return FlipKickModel{
Id: id,
Mom: mom,
Vat: vat,
Ilk: ilk,
Lot: lot,
Bid: bid,
Guy: guy,
Gal: gal,
End: end,
Era: era,
Lad: lad,
Tab: tab,
}, nil
}
func convertNilToZeroTimeValue(value *big.Int) int64 {
if value == nil {
return int64(0)
} else {
return value.Int64()
}
}
func convertNilToEmptyString(value string) string {
if value == "<nil>" {
return ""
} else {
return value
}
}
@@ -0,0 +1,110 @@
// Copyright 2018 Vulcanize
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package flip_kick_test
import (
"math/big"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/vulcanize/vulcanizedb/pkg/transformers/flip_kick"
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
)
var _ = Describe("FlipKickEntity Converter", func() {
It("converts an Eth Log to and Entity", func() {
converter := flip_kick.FlipKickConverter{}
entity, err := converter.ToEntity(test_data.TemporaryFlipAddress, flip_kick.FlipperABI, test_data.EthFlipKickLog)
Expect(err).NotTo(HaveOccurred())
Expect(entity.Id).To(Equal(test_data.FlipKickEntity.Id))
Expect(entity.Mom).To(Equal(test_data.FlipKickEntity.Mom))
Expect(entity.Vat).To(Equal(test_data.FlipKickEntity.Vat))
Expect(entity.Ilk).To(Equal(test_data.FlipKickEntity.Ilk))
Expect(entity.Lot).To(Equal(test_data.FlipKickEntity.Lot))
Expect(entity.Bid).To(Equal(test_data.FlipKickEntity.Bid))
Expect(entity.Guy).To(Equal(test_data.FlipKickEntity.Guy))
Expect(entity.Gal).To(Equal(test_data.FlipKickEntity.Gal))
Expect(entity.End).To(Equal(test_data.FlipKickEntity.End))
Expect(entity.Era).To(Equal(test_data.FlipKickEntity.Era))
Expect(entity.Lad).To(Equal(test_data.FlipKickEntity.Lad))
Expect(entity.Tab).To(Equal(test_data.FlipKickEntity.Tab))
})
It("returns an error if converting log to entity fails", func() {
converter := flip_kick.FlipKickConverter{}
_, err := converter.ToEntity(test_data.TemporaryFlipAddress, "error abi", test_data.EthFlipKickLog)
Expect(err).To(HaveOccurred())
})
It("converts and Entity to a Model", func() {
converter := flip_kick.FlipKickConverter{}
model, err := converter.ToModel(test_data.FlipKickEntity)
Expect(err).NotTo(HaveOccurred())
Expect(model).To(Equal(test_data.FlipKickModel))
})
It("handles nil", func() {
emptyAddressHex := "0x0000000000000000000000000000000000000000"
emptyByteArrayHex := "0x0000000000000000000000000000000000000000000000000000000000000000"
emptyString := ""
emptyTime := time.Unix(0, 0)
converter := flip_kick.FlipKickConverter{}
emptyEntity := flip_kick.FlipKickEntity{
Id: big.NewInt(1),
Mom: common.Address{},
Vat: common.Address{},
Ilk: [32]byte{},
Lot: nil,
Bid: nil,
Guy: common.Address{},
Gal: common.Address{},
End: nil,
Era: nil,
Lad: common.Address{},
Tab: nil,
Raw: types.Log{},
}
model, err := converter.ToModel(emptyEntity)
Expect(err).NotTo(HaveOccurred())
Expect(model.Id).To(Equal("1"))
Expect(model.Mom).To(Equal(emptyAddressHex))
Expect(model.Vat).To(Equal(emptyAddressHex))
Expect(model.Ilk).To(Equal(emptyByteArrayHex))
Expect(model.Lot).To(Equal(emptyString))
Expect(model.Bid).To(Equal(emptyString))
Expect(model.Guy).To(Equal(emptyAddressHex))
Expect(model.Gal).To(Equal(emptyAddressHex))
Expect(model.End).To(Equal(emptyTime))
Expect(model.Era).To(Equal(emptyTime))
Expect(model.Lad).To(Equal(emptyAddressHex))
Expect(model.Tab).To(Equal(emptyString))
})
It("returns an error of the flip kick event id is nil", func() {
converter := flip_kick.FlipKickConverter{}
emptyEntity := flip_kick.FlipKickEntity{}
_, err := converter.ToModel(emptyEntity)
Expect(err).To(HaveOccurred())
})
})
+38
View File
@@ -0,0 +1,38 @@
// Copyright 2018 Vulcanize
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package flip_kick
import (
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
)
type FlipKickEntity struct {
Id *big.Int
Mom common.Address
Vat common.Address
Ilk [32]byte
Lot *big.Int
Bid *big.Int
Guy common.Address
Gal common.Address
End *big.Int
Era *big.Int
Lad common.Address
Tab *big.Int
Raw types.Log
}
@@ -0,0 +1,33 @@
// Copyright 2018 Vulcanize
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package flip_kick
import (
"io/ioutil"
"log"
"testing"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
func TestEveryBlock(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "EveryBlock Suite")
}
var _ = BeforeSuite(func() {
log.SetOutput(ioutil.Discard)
})
+52
View File
@@ -0,0 +1,52 @@
// Copyright 2018 Vulcanize
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package flip_kick
import (
"math/big"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/vulcanize/vulcanizedb/pkg/core"
)
type LogFetcher interface {
FetchLogs(contractAddress string, topics [][]common.Hash, blockNumber int64) ([]types.Log, error)
}
type Fetcher struct {
Blockchain core.BlockChain
}
func NewFetcher(blockchain core.BlockChain) Fetcher {
return Fetcher{
Blockchain: blockchain,
}
}
func (f Fetcher) FetchLogs(contractAddress string, topicZeros [][]common.Hash, blockNumber int64) ([]types.Log, error) {
block := big.NewInt(blockNumber)
address := common.HexToAddress(contractAddress)
query := ethereum.FilterQuery{
FromBlock: block,
ToBlock: block,
Addresses: []common.Address{address},
Topics: topicZeros,
}
return f.Blockchain.GetEthLogsWithCustomQuery(query)
}
@@ -0,0 +1,62 @@
// Copyright 2018 Vulcanize
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package flip_kick_test
import (
"math/big"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/vulcanize/vulcanizedb/pkg/fakes"
"github.com/vulcanize/vulcanizedb/pkg/transformers/flip_kick"
)
var _ = Describe("Fetcher", func() {
Describe("FetchLogs", func() {
var blockChain *fakes.MockBlockChain
var fetcher flip_kick.Fetcher
BeforeEach(func() {
blockChain = fakes.NewMockBlockChain()
fetcher = flip_kick.Fetcher{Blockchain: blockChain}
})
It("fetches logs based on the given query", func() {
blockNumber := int64(3)
address := "0x4D2"
topicZeros := [][]common.Hash{{common.HexToHash("0x")}}
query := ethereum.FilterQuery{
FromBlock: big.NewInt(blockNumber),
ToBlock: big.NewInt(blockNumber),
Addresses: []common.Address{common.HexToAddress(address)},
Topics: topicZeros,
}
fetcher.FetchLogs(address, topicZeros, blockNumber)
blockChain.AssertGetEthLogsWithCustomQueryCalledWith(query)
})
It("returns an error if fetching the logs fails", func() {
blockChain.SetGetLogsErr(fakes.FakeError)
_, err := fetcher.FetchLogs("", [][]common.Hash{}, int64(1))
Expect(err).To(HaveOccurred())
Expect(err).To(MatchError(fakes.FakeError))
})
})
})
@@ -0,0 +1,89 @@
// Copyright 2018 Vulcanize
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package flip_kick_test
import (
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/rpc"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/vulcanize/vulcanizedb/pkg/geth"
"github.com/vulcanize/vulcanizedb/pkg/geth/client"
rpc2 "github.com/vulcanize/vulcanizedb/pkg/geth/converters/rpc"
"github.com/vulcanize/vulcanizedb/pkg/geth/node"
"github.com/vulcanize/vulcanizedb/pkg/transformers/flip_kick"
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
"github.com/vulcanize/vulcanizedb/test_config"
)
var _ = Describe("Integration tests", func() {
It("Fetches FlipKickEntity event logs from a local test chain", func() {
ipcPath := test_config.TestClient.IPCPath
rawRpcClient, err := rpc.Dial(ipcPath)
Expect(err).NotTo(HaveOccurred())
rpcClient := client.NewRpcClient(rawRpcClient, ipcPath)
ethClient := ethclient.NewClient(rawRpcClient)
blockChainClient := client.NewEthClient(ethClient)
realNode := node.MakeNode(rpcClient)
transactionConverter := rpc2.NewRpcTransactionConverter(ethClient)
realBlockChain := geth.NewBlockChain(blockChainClient, realNode, transactionConverter)
realFetcher := flip_kick.NewFetcher(realBlockChain)
topic0 := common.HexToHash(flip_kick.FlipKickSignature)
topics := [][]common.Hash{{topic0}}
result, err := realFetcher.FetchLogs(test_data.TemporaryFlipAddress, topics, int64(10))
Expect(err).NotTo(HaveOccurred())
Expect(len(result) > 0).To(BeTrue())
Expect(result[0].Address).To(Equal(test_data.EthFlipKickLog.Address))
Expect(result[0].TxHash).To(Equal(test_data.EthFlipKickLog.TxHash))
Expect(result[0].BlockNumber).To(Equal(test_data.EthFlipKickLog.BlockNumber))
Expect(result[0].Topics).To(Equal(test_data.EthFlipKickLog.Topics))
Expect(result[0].Index).To(Equal(test_data.EthFlipKickLog.Index))
Expect(result[0].Data).To(Equal(test_data.EthFlipKickLog.Data))
})
It("unpacks an event log", func() {
address := common.HexToAddress(test_data.TemporaryFlipAddress)
abi, err := geth.ParseAbi(flip_kick.FlipperABI)
Expect(err).NotTo(HaveOccurred())
contract := bind.NewBoundContract(address, abi, nil, nil, nil)
entity := &flip_kick.FlipKickEntity{}
var eventLog = test_data.EthFlipKickLog
err = contract.UnpackLog(entity, "FlipKick", eventLog)
Expect(err).NotTo(HaveOccurred())
expectedEntity := test_data.FlipKickEntity
Expect(entity.Id).To(Equal(expectedEntity.Id))
Expect(entity.Mom).To(Equal(expectedEntity.Mom))
Expect(entity.Vat).To(Equal(expectedEntity.Vat))
Expect(entity.Ilk).To(Equal(expectedEntity.Ilk))
Expect(entity.Lot).To(Equal(expectedEntity.Lot))
Expect(entity.Bid.String()).To(Equal(expectedEntity.Bid.String())) //FIXME
Expect(entity.Guy).To(Equal(expectedEntity.Guy))
Expect(entity.Gal).To(Equal(expectedEntity.Gal))
Expect(entity.End).To(Equal(expectedEntity.End))
Expect(entity.Era).To(Equal(expectedEntity.Era))
Expect(entity.Lad).To(Equal(expectedEntity.Lad))
Expect(entity.Tab).To(Equal(expectedEntity.Tab))
})
})
+32
View File
@@ -0,0 +1,32 @@
// Copyright 2018 Vulcanize
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package flip_kick
import "time"
type FlipKickModel struct {
Id string
Mom string
Vat string
Ilk string
Lot string
Bid string
Guy string
Gal string
End time.Time
Era time.Time
Lad string
Tab string
}
+71
View File
@@ -0,0 +1,71 @@
// Copyright 2018 Vulcanize
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package flip_kick
import (
"fmt"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
)
type Repository interface {
Create(headerId int64, flipKick FlipKickModel) error
MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error)
}
type FlipKickRepository struct {
DB *postgres.DB
}
func NewFlipKickRepository(db *postgres.DB) FlipKickRepository {
return FlipKickRepository{DB: db}
}
func (fkr FlipKickRepository) Create(headerId int64, flipKick FlipKickModel) error {
_, err := fkr.DB.Exec(
`INSERT into maker.flip_kick (header_id, id, mom, vat, ilk, lot, bid, guy, gal, "end", era, lad, tab)
VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)`,
headerId, flipKick.Id, flipKick.Mom, flipKick.Vat, flipKick.Ilk, flipKick.Lot, flipKick.Bid, flipKick.Guy, flipKick.Gal, flipKick.End, flipKick.Era, flipKick.Lad, flipKick.Tab,
)
if err != nil {
return err
}
return nil
}
func (fkr FlipKickRepository) MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) {
var result []core.Header
err := fkr.DB.Select(
&result,
`SELECT headers.id, headers.block_number FROM headers
LEFT JOIN maker.flip_kick on headers.id = header_id
WHERE header_id ISNULL
AND headers.block_number >= $1
AND headers.block_number <= $2
AND headers.eth_node_fingerprint = $3`,
startingBlockNumber,
endingBlockNumber,
fkr.DB.Node.ID,
)
if err != nil {
fmt.Println("Error:", err)
return result, err
}
return result, nil
}
@@ -0,0 +1,177 @@
// Copyright 2018 Vulcanize
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package flip_kick_test
import (
"math/rand"
"github.com/ethereum/go-ethereum/common"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres/repositories"
"github.com/vulcanize/vulcanizedb/pkg/transformers/flip_kick"
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
"github.com/vulcanize/vulcanizedb/test_config"
)
var _ = Describe("FlipKick Repository", func() {
var db *postgres.DB
var flipKickRepository flip_kick.FlipKickRepository
var headerId int64
var blockNumber int64
var flipKick = test_data.FlipKickModel
BeforeEach(func() {
node := test_config.NewTestNode()
db = test_config.NewTestDB(node)
test_config.CleanTestDB(db)
flipKickRepository = flip_kick.FlipKickRepository{DB: db}
blockNumber = rand.Int63()
headerId = createHeader(db, blockNumber)
_, err := db.Exec(`DELETE from maker.flip_kick;`)
Expect(err).NotTo(HaveOccurred())
})
Describe("Create", func() {
AfterEach(func() {
_, err := db.Exec(`DELETE from headers;`)
Expect(err).NotTo(HaveOccurred())
})
It("persists a flip_kick record", func() {
err := flipKickRepository.Create(headerId, flipKick)
Expect(err).NotTo(HaveOccurred())
assertDBRecordCount(db, "maker.flip_kick", 1)
dbResult := test_data.FlipKickDBRow{}
err = flipKickRepository.DB.QueryRowx(`SELECT * FROM maker.flip_kick`).StructScan(&dbResult)
Expect(err).NotTo(HaveOccurred())
Expect(dbResult.HeaderId).To(Equal(headerId))
Expect(dbResult.Id).To(Equal(flipKick.Id))
Expect(dbResult.Mom).To(Equal(flipKick.Mom))
Expect(dbResult.Vat).To(Equal(flipKick.Vat))
Expect(dbResult.Ilk).To(Equal(flipKick.Ilk))
Expect(dbResult.Lot).To(Equal(flipKick.Lot))
Expect(dbResult.Bid).To(Equal(flipKick.Bid))
Expect(dbResult.Guy).To(Equal(flipKick.Guy))
Expect(dbResult.Gal).To(Equal(flipKick.Gal))
Expect(dbResult.End.Equal(flipKick.End)).To(BeTrue())
Expect(dbResult.Era.Equal(flipKick.Era)).To(BeTrue())
Expect(dbResult.Lad).To(Equal(flipKick.Lad))
Expect(dbResult.Tab).To(Equal(flipKick.Tab))
})
It("returns an error if inserting the flip_kick record fails", func() {
err := flipKickRepository.Create(headerId, test_data.FlipKickModel)
Expect(err).NotTo(HaveOccurred())
err = flipKickRepository.Create(headerId, test_data.FlipKickModel)
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("pq: duplicate key value violates unique constraint"))
})
It("deletes the flip_kick records if its corresponding header record is deleted", func() {
err := flipKickRepository.Create(headerId, test_data.FlipKickModel)
Expect(err).NotTo(HaveOccurred())
assertDBRecordCount(db, "maker.flip_kick", 1)
assertDBRecordCount(db, "headers", 1)
_, err = db.Exec(`DELETE FROM headers where id = $1`, headerId)
Expect(err).NotTo(HaveOccurred())
assertDBRecordCount(db, "headers", 0)
assertDBRecordCount(db, "maker.flip_kick", 0)
})
})
Describe("When there are multiple nodes", func() {
var db2 *postgres.DB
var flipKickRepository2 flip_kick.FlipKickRepository
var headerId2 int64
BeforeEach(func() {
//create database for the second node
node2 := core.Node{
GenesisBlock: "GENESIS",
NetworkID: 1,
ID: "node2",
ClientName: "Geth/v1.7.2-stable-1db4ecdc/darwin-amd64/go1.9",
}
db2 = test_config.NewTestDB(node2)
flipKickRepository2 = flip_kick.FlipKickRepository{DB: db2}
headerId2 = createHeader(db2, blockNumber)
_, err := db2.Exec(`DELETE from maker.flip_kick;`)
Expect(err).NotTo(HaveOccurred())
})
It("only includes missing headers for the current node", func() {
node1missingHeaders, err := flipKickRepository.MissingHeaders(blockNumber, blockNumber)
Expect(err).NotTo(HaveOccurred())
Expect(len(node1missingHeaders)).To(Equal(1))
node2MissingHeaders, err := flipKickRepository2.MissingHeaders(blockNumber, blockNumber)
Expect(err).NotTo(HaveOccurred())
Expect(len(node2MissingHeaders)).To(Equal(1))
})
})
Describe("MissingHeaders", func() {
It("returns headers for which there isn't an associated flip_kick record", func() {
startingBlock := blockNumber - 3
endingBlock := blockNumber + 3
err := flipKickRepository.Create(headerId, test_data.FlipKickModel)
Expect(err).NotTo(HaveOccurred())
newBlockNumber := blockNumber + 3
newHeaderId := createHeader(db, newBlockNumber)
createHeader(db, blockNumber+10) //this one is out of the block range and shouldn't be included
headers, err := flipKickRepository.MissingHeaders(startingBlock, endingBlock)
Expect(len(headers)).To(Equal(1))
Expect(headers[0].Id).To(Equal(newHeaderId))
Expect(headers[0].BlockNumber).To(Equal(newBlockNumber))
})
})
})
func assertDBRecordCount(db *postgres.DB, dbTable string, expectedCount int) {
var count int
query := `SELECT count(*) FROM ` + dbTable
err := db.QueryRow(query).Scan(&count)
Expect(err).NotTo(HaveOccurred())
Expect(count).To(Equal(expectedCount))
}
func createHeader(db *postgres.DB, blockNumber int64) (headerId int64) {
headerRepository := repositories.NewHeaderRepository(db)
header := core.Header{
BlockNumber: blockNumber,
Hash: common.BytesToHash([]byte{1, 2, 3, 4, 5}).Hex(),
Raw: []byte{1, 2, 3, 4, 5},
}
_, err := headerRepository.CreateOrUpdateHeader(header)
Expect(err).NotTo(HaveOccurred())
var dbHeader core.Header
err = db.Get(&dbHeader, `SELECT id, block_number, hash, raw FROM public.headers WHERE block_number = $1 AND eth_node_id = $2`, header.BlockNumber, db.NodeID)
Expect(err).NotTo(HaveOccurred())
return dbHeader.Id
}
+126
View File
@@ -0,0 +1,126 @@
// Copyright 2018 Vulcanize
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package flip_kick
import (
"errors"
"fmt"
"log"
"github.com/ethereum/go-ethereum/common"
"github.com/vulcanize/vulcanizedb/libraries/shared"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/datastore/postgres"
)
type FlipKickTransformer struct {
Fetcher LogFetcher
Converter Converter
Repository Repository
Config TransformerConfig
}
type FlipKickTransformerInitializer struct {
Config TransformerConfig
}
func (i FlipKickTransformerInitializer) NewFlipKickTransformer(db *postgres.DB, blockChain core.BlockChain) shared.Transformer {
fetcher := NewFetcher(blockChain)
repository := NewFlipKickRepository(db)
transformer := FlipKickTransformer{
Fetcher: fetcher,
Repository: repository,
Converter: FlipKickConverter{},
Config: i.Config,
}
return transformer
}
func (fkt *FlipKickTransformer) SetConfig(config TransformerConfig) {
fkt.Config = config
}
const (
FetcherError = "Error fetching FlipKick log events for block number %d: %s"
LogToEntityError = "Error converting eth log to FlipKick entity for block number %d: %s"
EntityToModelError = "Error converting eth log to FlipKick entity for block number %d: %s"
RepositoryError = "Error creating flip_kick record for block number %d: %s"
TransformerError = "There has been %d error(s) transforming FlipKick event logs, see the logs for more details."
)
type transformerError struct {
err string
blockNumber int64
msg string
}
func (te *transformerError) Error() string {
return fmt.Sprintf(te.msg, te.blockNumber, te.err)
}
func newTransformerError(err error, blockNumber int64, msg string) error {
e := transformerError{err.Error(), blockNumber, msg}
log.Println(e.Error())
return &e
}
func (fkt FlipKickTransformer) Execute() error {
config := fkt.Config
topics := [][]common.Hash{{common.HexToHash(FlipKickSignature)}}
headers, err := fkt.Repository.MissingHeaders(config.StartingBlockNumber, config.EndingBlockNumber)
if err != nil {
log.Println("Error:", err)
return err
}
log.Printf("Fetching event logs for %d headers \n", len(headers))
var resultingErrors []error
for _, header := range headers {
ethLogs, err := fkt.Fetcher.FetchLogs(config.ContractAddress, topics, header.BlockNumber)
if err != nil {
resultingErrors = append(resultingErrors, newTransformerError(err, header.BlockNumber, FetcherError))
}
for _, ethLog := range ethLogs {
entity, err := fkt.Converter.ToEntity(config.ContractAddress, config.ContractAbi, ethLog)
if err != nil {
resultingErrors = append(resultingErrors, newTransformerError(err, header.BlockNumber, LogToEntityError))
}
model, err := fkt.Converter.ToModel(*entity)
if err != nil {
resultingErrors = append(resultingErrors, newTransformerError(err, header.BlockNumber, EntityToModelError))
}
err = fkt.Repository.Create(header.Id, model)
if err != nil {
resultingErrors = append(resultingErrors, newTransformerError(err, header.BlockNumber, RepositoryError))
}
}
}
if len(resultingErrors) > 0 {
for _, err := range resultingErrors {
log.Println(err)
}
msg := fmt.Sprintf(TransformerError, len(resultingErrors))
return errors.New(msg)
}
return nil
}
@@ -0,0 +1,142 @@
// Copyright 2018 Vulcanize
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package flip_kick_test
import (
"math/rand"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/fakes"
"github.com/vulcanize/vulcanizedb/pkg/transformers/flip_kick"
"github.com/vulcanize/vulcanizedb/pkg/transformers/test_data"
)
var _ = Describe("FlipKick Transformer", func() {
var transformer flip_kick.FlipKickTransformer
var fetcher test_data.MockLogFetcher
var converter test_data.MockFlipKickConverter
var repository test_data.MockFlipKickRepository
var testConfig flip_kick.TransformerConfig
var blockNumber int64
var headerId int64
var headers []core.Header
var logs []types.Log
BeforeEach(func() {
fetcher = test_data.MockLogFetcher{}
converter = test_data.MockFlipKickConverter{}
repository = test_data.MockFlipKickRepository{}
transformer = flip_kick.FlipKickTransformer{
Fetcher: &fetcher,
Converter: &converter,
Repository: &repository,
}
startingBlockNumber := rand.Int63()
testConfig = flip_kick.TransformerConfig{
ContractAddress: "0x12345",
ContractAbi: "test abi",
Topics: []string{flip_kick.FlipKickSignature},
StartingBlockNumber: startingBlockNumber,
EndingBlockNumber: startingBlockNumber + 5,
}
transformer.SetConfig(testConfig)
blockNumber = rand.Int63()
headerId = rand.Int63()
headers = []core.Header{{
Id: headerId,
BlockNumber: blockNumber,
Hash: "0x",
Raw: nil,
}}
repository.SetHeadersToReturn(headers)
logs = []types.Log{test_data.EthFlipKickLog}
fetcher.SetFetchedLogs(logs)
})
It("fetches logs with the configured contract and topic(s) for each block", func() {
expectedTopics := [][]common.Hash{{common.HexToHash(flip_kick.FlipKickSignature)}}
err := transformer.Execute()
Expect(err).NotTo(HaveOccurred())
Expect(fetcher.FetchedContractAddress).To(Equal(testConfig.ContractAddress))
Expect(fetcher.FetchedTopics).To(Equal(expectedTopics))
Expect(fetcher.FetchedBlocks).To(Equal([]int64{blockNumber}))
})
It("returns an error if the fetcher fails", func() {
fetcher.SetFetcherError(fakes.FakeError)
err := transformer.Execute()
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("error(s) transforming FlipKick event logs"))
})
It("converts the logs", func() {
err := transformer.Execute()
Expect(err).NotTo(HaveOccurred())
Expect(converter.ConverterContract).To(Equal(testConfig.ContractAddress))
Expect(converter.ConverterAbi).To(Equal(testConfig.ContractAbi))
Expect(converter.LogsToConvert).To(Equal(logs))
Expect(converter.EntitiesToConvert).To(Equal([]flip_kick.FlipKickEntity{test_data.FlipKickEntity}))
})
It("returns an error if converting the geth log fails", func() {
converter.SetConverterError(fakes.FakeError)
err := transformer.Execute()
Expect(err).To(HaveOccurred())
})
It("persists a flip_kick record", func() {
err := transformer.Execute()
Expect(err).NotTo(HaveOccurred())
Expect(repository.HeaderIds).To(Equal([]int64{headerId}))
Expect(repository.FlipKicksCreated).To(Equal([]flip_kick.FlipKickModel{test_data.FlipKickModel}))
})
It("returns an error if persisting a record fails", func() {
repository.SetCreateRecordError(fakes.FakeError)
err := transformer.Execute()
Expect(err).To(HaveOccurred())
})
It("returns an error if fetching missing headers fails", func() {
repository.SetMissingHeadersError(fakes.FakeError)
err := transformer.Execute()
Expect(err).To(HaveOccurred())
})
It("gets missing headers for blocks between the configured block number range", func() {
err := transformer.Execute()
Expect(err).NotTo(HaveOccurred())
Expect(repository.StartingBlockNumber).To(Equal(testConfig.StartingBlockNumber))
Expect(repository.EndingBlockNumber).To(Equal(testConfig.EndingBlockNumber))
})
})
+10
View File
@@ -0,0 +1,10 @@
#!/bin/bash
MNEMONIC_PHRASE="whisper ordinary mystery awesome wood fox auction february blind volcano spare soft"
PORT=7545
DATABASE_PATH=pkg/transformers/test_data/test_chain/
echo Starting ganache chain on port $PORT...
ganache-cli --port $PORT \
--db $DATABASE_PATH \
2>&1 > ganache-output.log &
+4
View File
@@ -0,0 +1,4 @@
#!/bin/bash
echo "Stopping ganache chain on port 7545"
ps -ef | grep ganache | grep -v grep | awk '{print $2}' | xargs kill
+98
View File
@@ -0,0 +1,98 @@
// Copyright 2018 Vulcanize
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package test_data
import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"math/big"
"github.com/vulcanize/vulcanizedb/pkg/transformers/flip_kick"
"time"
)
var TemporaryFlipAddress = "0x08cb6176addcca2e1d1ffe21bee464b72ee4cd8d"
var TemporaryFlipKickTransaction = "0x6b155a55fd77b751195deeebf7abfd8691ca01ee588817a920f19d5b27f65191"
var Topic0Hex = "0xc2d733c352a325d6ecf23d1cf0a189dbcc236b0636388b8c5e6953c061d7f0b3"
var TemporaryFlipKickData = "0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000008cb6176addcca2e1d1ffe21bee464b72ee4cd8d00000000000000000000000038219779a699d67d7e7740b8c8f43d3e2dae218266616b6520696c6b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064d922894153be9eef7b7218dc565d1d0ce2a09200000000000000000000000007fa9ef6609ca7921112231f8f195138ebba2977000000000000000000000000000000000000000000000000000000005b69b8e7000000000000000000000000000000000000000000000000000000005b607e670000000000000000000000007340e006f4135ba6970d43bf43d88dcad4e7a8ca0000000000000000000000000000000000000000000000000000000000000032"
var TempBlockNumber = int64(10)
var TemporaryFlipKickBlockNumber = int64(TempBlockNumber)
var TemporaryFlipKickBlockHash = "0x32f8b12023b3a1b4c73f9a46da976931b0355714ada8b8044ebcb2cd295751a9"
var idString = "1"
var id, _ = new(big.Int).SetString(idString, 10)
var mom = "0x08cb6176addcca2e1d1ffe21bee464b72ee4cd8d"
var vat = "0x38219779a699d67d7e7740b8c8f43d3e2dae2182"
var ilk = [32]byte{102, 97, 107, 101, 32, 105, 108, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
var lotString = "100"
var lot, _ = new(big.Int).SetString(lotString, 10)
var bidString = "0"
var bid = new(big.Int).SetBytes([]byte{0})
var guy = "0x64d922894153be9eef7b7218dc565d1d0ce2a092"
var gal = "0x07fa9ef6609ca7921112231f8f195138ebba2977"
var end = int64(1533655271)
var era = int64(1533050471)
var lad = "0x7340e006f4135ba6970d43bf43d88dcad4e7a8ca"
var tabString = "50"
var tab, _ = new(big.Int).SetString(tabString, 10)
var EthFlipKickLog = types.Log{
Address: common.HexToAddress(TemporaryFlipAddress),
Topics: []common.Hash{common.HexToHash(flip_kick.FlipKickSignature)},
Data: hexutil.MustDecode(TemporaryFlipKickData),
BlockNumber: uint64(TempBlockNumber),
TxHash: common.HexToHash(TemporaryFlipKickTransaction),
TxIndex: 0,
BlockHash: common.HexToHash(TemporaryFlipKickBlockHash),
Index: 0,
Removed: false,
}
var FlipKickEntity = flip_kick.FlipKickEntity{
Id: id,
Mom: common.HexToAddress(mom),
Vat: common.HexToAddress(vat),
Ilk: ilk,
Lot: lot,
Bid: bid,
Guy: common.HexToAddress(guy),
Gal: common.HexToAddress(gal),
End: big.NewInt(end),
Era: big.NewInt(era),
Lad: common.HexToAddress(lad),
Tab: tab,
}
var FlipKickModel = flip_kick.FlipKickModel{
Id: idString,
Mom: mom,
Vat: vat,
Ilk: "0x" + common.Bytes2Hex(ilk[:]),
Lot: lotString,
Bid: bidString,
Guy: guy,
Gal: gal,
End: time.Unix(end, 0),
Era: time.Unix(era, 0),
Lad: lad,
Tab: tabString,
}
type FlipKickDBRow struct {
DbID int64 `db:"db_id"`
HeaderId int64 `db:"header_id"`
flip_kick.FlipKickModel
}
+105
View File
@@ -0,0 +1,105 @@
// Copyright 2018 Vulcanize
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package test_data
import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/vulcanize/vulcanizedb/pkg/core"
"github.com/vulcanize/vulcanizedb/pkg/transformers/flip_kick"
)
type MockLogFetcher struct {
FetchedContractAddress string
FetchedTopics [][]common.Hash
FetchedBlocks []int64
FetcherError error
FetchedLogs []types.Log
}
func (mlf *MockLogFetcher) FetchLogs(contractAddress string, topics [][]common.Hash, blockNumber int64) ([]types.Log, error) {
mlf.FetchedContractAddress = contractAddress
mlf.FetchedTopics = topics
mlf.FetchedBlocks = append(mlf.FetchedBlocks, blockNumber)
return mlf.FetchedLogs, mlf.FetcherError
}
func (mlf *MockLogFetcher) SetFetcherError(err error) {
mlf.FetcherError = err
}
func (mlf *MockLogFetcher) SetFetchedLogs(logs []types.Log) {
mlf.FetchedLogs = logs
}
type MockFlipKickConverter struct {
ConverterContract string
ConverterAbi string
LogsToConvert []types.Log
EntitiesToConvert []flip_kick.FlipKickEntity
ConverterError error
}
func (mfkc *MockFlipKickConverter) ToEntity(contractAddress string, contractAbi string, ethLog types.Log) (*flip_kick.FlipKickEntity, error) {
mfkc.ConverterContract = contractAddress
mfkc.ConverterAbi = contractAbi
mfkc.LogsToConvert = append(mfkc.LogsToConvert, ethLog)
return &FlipKickEntity, mfkc.ConverterError
}
func (mfkc *MockFlipKickConverter) ToModel(flipKick flip_kick.FlipKickEntity) (flip_kick.FlipKickModel, error) {
mfkc.EntitiesToConvert = append(mfkc.EntitiesToConvert, flipKick)
return FlipKickModel, nil
}
func (mfkc *MockFlipKickConverter) SetConverterError(err error) {
mfkc.ConverterError = err
}
type MockFlipKickRepository struct {
HeaderIds []int64
HeadersToReturn []core.Header
StartingBlockNumber int64
EndingBlockNumber int64
FlipKicksCreated []flip_kick.FlipKickModel
CreateRecordError error
MissingHeadersError error
}
func (mfkr *MockFlipKickRepository) Create(headerId int64, flipKick flip_kick.FlipKickModel) error {
mfkr.HeaderIds = append(mfkr.HeaderIds, headerId)
mfkr.FlipKicksCreated = append(mfkr.FlipKicksCreated, flipKick)
return mfkr.CreateRecordError
}
func (mfkr *MockFlipKickRepository) MissingHeaders(startingBlockNumber, endingBlockNumber int64) ([]core.Header, error) {
mfkr.StartingBlockNumber = startingBlockNumber
mfkr.EndingBlockNumber = endingBlockNumber
return mfkr.HeadersToReturn, mfkr.MissingHeadersError
}
func (mfkr *MockFlipKickRepository) SetHeadersToReturn(headers []core.Header) {
mfkr.HeadersToReturn = headers
}
func (mfkr *MockFlipKickRepository) SetCreateRecordError(err error) {
mfkr.CreateRecordError = err
}
func (mfkr *MockFlipKickRepository) SetMissingHeadersError(err error) {
mfkr.MissingHeadersError = err
}
@@ -0,0 +1 @@
[]
@@ -0,0 +1 @@
[]
@@ -0,0 +1 @@
[{"logIndex":"0x0","transactionIndex":"0x0","transactionHash":"0x6b155a55fd77b751195deeebf7abfd8691ca01ee588817a920f19d5b27f65191","blockHash":"0x59d43865d29b1ddf0baff73a78e06849c015249fd1884bd5a93e83d5be9c05dd","blockNumber":"0xa","address":"0x08cb6176addcca2e1d1ffe21bee464b72ee4cd8d","data":"0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000008cb6176addcca2e1d1ffe21bee464b72ee4cd8d00000000000000000000000038219779a699d67d7e7740b8c8f43d3e2dae218266616b6520696c6b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064d922894153be9eef7b7218dc565d1d0ce2a09200000000000000000000000007fa9ef6609ca7921112231f8f195138ebba2977000000000000000000000000000000000000000000000000000000005b69b8e7000000000000000000000000000000000000000000000000000000005b607e670000000000000000000000007340e006f4135ba6970d43bf43d88dcad4e7a8ca0000000000000000000000000000000000000000000000000000000000000032","topics":["0xc2d733c352a325d6ecf23d1cf0a189dbcc236b0636388b8c5e6953c061d7f0b3"],"type":"mined"}]
@@ -0,0 +1 @@
[]
@@ -0,0 +1 @@
[]
@@ -0,0 +1 @@
[]
@@ -0,0 +1 @@
[]
@@ -0,0 +1 @@
[]
@@ -0,0 +1 @@
[]
@@ -0,0 +1 @@
[]
@@ -0,0 +1 @@
[]
@@ -0,0 +1 @@
11
@@ -0,0 +1 @@
{"header":{"parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000","uncleHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","coinbase":"0x0000000000000000000000000000000000000000","stateRoot":"0xafc7c6a8161d69dc1b082bbf799d38f88c2f251a7504b87039b2a4f682cbf323","transactionsTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","receiptTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","bloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","difficulty":"0x","number":"0x","gasLimit":"0x6691b7","gasUsed":"0x","timestamp":"0x5b607bcc","extraData":"0x","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x"},"transactions":[],"uncleHeaders":[]}
@@ -0,0 +1 @@
{"header":{"parentHash":"0x92df7e05e7e8c221851b23ef4ce61671ef7b2df3cbd1b5fb0b5b4735803484d2","uncleHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","coinbase":"0x0000000000000000000000000000000000000000","stateRoot":"0x1cf5126fea51794b0db1435d14bd933683c230379908b9899391e70c1bdfbe14","transactionsTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","receiptTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","bloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","difficulty":"0x","number":"0x01","gasLimit":"0x6691b7","gasUsed":"0x043bd6","timestamp":"0x5b607bda","extraData":"0x","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x"},"transactions":[{"nonce":"0x","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0x","value":"0x","data":"0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506102f8806100606000396000f300608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630900f01014610067578063445df0ac146100aa5780638da5cb5b146100d5578063fdacd5761461012c575b600080fd5b34801561007357600080fd5b506100a8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610159565b005b3480156100b657600080fd5b506100bf610241565b6040518082815260200191505060405180910390f35b3480156100e157600080fd5b506100ea610247565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561013857600080fd5b506101576004803603810190808035906020019092919050505061026c565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561023d578190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561022457600080fd5b505af1158015610238573d6000803e3d6000fd5b505050505b5050565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102c957806001819055505b505600a165627a7a72305820167320a3f0aefab2d9d7492779c69a7f6bbea970d8290e17d3631fbed9ad93540029","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0xd484799e4f3a24c0e83d7210ae6936700f2da07ddc3cb7191b06a5e20b10fb61"}],"uncleHeaders":[]}
@@ -0,0 +1 @@
{"header":{"parentHash":"0x3a1b9dd73229701cf992f80bc79ef5c00a9254054fa4afbcb1a619a6af48aa44","uncleHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","coinbase":"0x0000000000000000000000000000000000000000","stateRoot":"0x50b3886d0b373a1bec1077a101dfbf8cdf97373f7698dc90befabe95a62c18d0","transactionsTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","receiptTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","bloom":"0x00000000000000000020000000000000000080000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000","difficulty":"0x","number":"0x0a","gasLimit":"0x6691b7","gasUsed":"0x027c77","timestamp":"0x5b607e67","extraData":"0x","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x"},"transactions":[{"nonce":"0x","gasPrice":"0x01","gasLimit":"0x44aa20","to":"0x08cb6176addcca2e1d1ffe21bee464b72ee4cd8d","value":"0x","data":"0x351de6000000000000000000000000007340e006f4135ba6970d43bf43d88dcad4e7a8ca00000000000000000000000007fa9ef6609ca7921112231f8f195138ebba2977000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000","v":"0x1c","r":"0x","s":"0x","from":"0x64d922894153be9eef7b7218dc565d1d0ce2a092","hash":"0x6b155a55fd77b751195deeebf7abfd8691ca01ee588817a920f19d5b27f65191"}],"uncleHeaders":[]}
@@ -0,0 +1 @@
{"header":{"parentHash":"0x7e8df460b9fe6f779d308571d81629f57e66648907f6c97ba7712d15a553087a","uncleHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","coinbase":"0x0000000000000000000000000000000000000000","stateRoot":"0x3ad54ef88f031c776dcc858e4339ee689f634fb929d7ac5d9ceec36c15b2779e","transactionsTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","receiptTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","bloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","difficulty":"0x","number":"0x02","gasLimit":"0x6691b7","gasUsed":"0xa418","timestamp":"0x5b607bda","extraData":"0x","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x"},"transactions":[{"nonce":"0x01","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0xfc0ba85028256ef48f5ba64dd65dc258988955f6","value":"0x","data":"0xfdacd5760000000000000000000000000000000000000000000000000000000000000001","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0xc0bdfdb15c288d6a7b0af865d953677c4818c6655d26631bd7b840e9cfb2d668"}],"uncleHeaders":[]}
@@ -0,0 +1 @@
{"header":{"parentHash":"0xa991182133d4d762d84b3213e93f29caf30a8c68552f95830a934b886560762a","uncleHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","coinbase":"0x0000000000000000000000000000000000000000","stateRoot":"0x3ec08de1b6fc2f56324ce3a496f6945898622e7b8e875feb74d0578b18f6730c","transactionsTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","receiptTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","bloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","difficulty":"0x","number":"0x03","gasLimit":"0x6691b7","gasUsed":"0x010cba","timestamp":"0x5b607bdb","extraData":"0x","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x"},"transactions":[{"nonce":"0x02","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0x","value":"0x","data":"0x6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00a165627a7a72305820562865e6c1f558e8a54735c0ff54b7f6a1fbc65c540a84c894f17a5fec64110d0029","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0x9430a6e3c1665c19dfe6e55eba73ae209d256b17d8f2ea63acb9bdf23144f0a9"}],"uncleHeaders":[]}
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"header":{"parentHash":"0x82ddc58a8608bdac6cf29a962dabd34e0f3e1b8c76bf14459f8a1c9bdb1a9789","uncleHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","coinbase":"0x0000000000000000000000000000000000000000","stateRoot":"0x2755f446d0c4053242e02044d205ff5f10f34d7eada2b8170e32dbe7ce649b54","transactionsTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","receiptTrie":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","bloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","difficulty":"0x","number":"0x05","gasLimit":"0x6691b7","gasUsed":"0x6980","timestamp":"0x5b607bdb","extraData":"0x","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x"},"transactions":[{"nonce":"0x04","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0xfc0ba85028256ef48f5ba64dd65dc258988955f6","value":"0x","data":"0xfdacd5760000000000000000000000000000000000000000000000000000000000000002","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0x2194da14a0d4be36fb809efd3f9f426bf60842dbf244788d0a84b894b3e6bd49"}],"uncleHeaders":[]}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
11
@@ -0,0 +1 @@
{"transactionHash":"0x082845bda230c63db3069f3568ef138653aed0beaf8791ca1644b0d2e62b4b62","transactionIndex":"0x0","blockHash":"0x3a1b9dd73229701cf992f80bc79ef5c00a9254054fa4afbcb1a619a6af48aa44","blockNumber":"0x9","gasUsed":"0x1e6e49","cumulativeGasUsed":"0x1e6e49","contractAddress":"0x08cb6176addcca2e1d1ffe21bee464b72ee4cd8d","logs":[],"status":"0x1","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}
@@ -0,0 +1 @@
{"transactionHash":"0x194d05ed98adbaab385bf58f5a2b6aa2d53e5a083e156ab4115940687baf2d48","transactionIndex":"0x0","blockHash":"0xea660033df6296bce69b24ca2e91556f1d9c5f6c6e9c4ee5ea9877426b6fc893","blockNumber":"0x6","gasUsed":"0xbabc2","cumulativeGasUsed":"0xbabc2","contractAddress":"0xff3f2400f1600f3f493a9a92704a29b96795af1a","logs":[],"status":"0x1","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}
@@ -0,0 +1 @@
{"transactionHash":"0x2194da14a0d4be36fb809efd3f9f426bf60842dbf244788d0a84b894b3e6bd49","transactionIndex":"0x0","blockHash":"0xe3f5f15620f4599a82eba709537542c5db00c2f03f1863646bc2633f80b1a549","blockNumber":"0x5","gasUsed":"0x6980","cumulativeGasUsed":"0x6980","contractAddress":null,"logs":[],"status":"0x1","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}
@@ -0,0 +1 @@
{"transactionHash":"0x319b41551e19a365e1819fc312f1cd52e315c575d505c9fa90a748b7dab11eb9","transactionIndex":"0x0","blockHash":"0x4e22a16f36c4579b10db23891796b93ec0452791bf24426836837fc420bec9b7","blockNumber":"0x7","gasUsed":"0xfc1e5","cumulativeGasUsed":"0xfc1e5","contractAddress":"0x76189df410263ad1d9fe2f4af2eab3d24f1b6f41","logs":[],"status":"0x1","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}
@@ -0,0 +1 @@
{"transactionHash":"0x6b155a55fd77b751195deeebf7abfd8691ca01ee588817a920f19d5b27f65191","transactionIndex":"0x0","blockHash":"0x59d43865d29b1ddf0baff73a78e06849c015249fd1884bd5a93e83d5be9c05dd","blockNumber":"0xa","gasUsed":"0x27c77","cumulativeGasUsed":"0x27c77","contractAddress":null,"logs":[{"logIndex":"0x0","transactionIndex":"0x0","transactionHash":"0x6b155a55fd77b751195deeebf7abfd8691ca01ee588817a920f19d5b27f65191","blockHash":"0x59d43865d29b1ddf0baff73a78e06849c015249fd1884bd5a93e83d5be9c05dd","blockNumber":"0xa","address":"0x08cb6176addcca2e1d1ffe21bee464b72ee4cd8d","data":"0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000008cb6176addcca2e1d1ffe21bee464b72ee4cd8d00000000000000000000000038219779a699d67d7e7740b8c8f43d3e2dae218266616b6520696c6b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064d922894153be9eef7b7218dc565d1d0ce2a09200000000000000000000000007fa9ef6609ca7921112231f8f195138ebba2977000000000000000000000000000000000000000000000000000000005b69b8e7000000000000000000000000000000000000000000000000000000005b607e670000000000000000000000007340e006f4135ba6970d43bf43d88dcad4e7a8ca0000000000000000000000000000000000000000000000000000000000000032","topics":["0xc2d733c352a325d6ecf23d1cf0a189dbcc236b0636388b8c5e6953c061d7f0b3"],"type":"mined"}],"status":"0x1","logsBloom":"0x00000000000000000020000000000000000080000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000"}
@@ -0,0 +1 @@
{"transactionHash":"0x7ba6513b8f9e12e3a82075c61b3c2848ebed77919cf0c158292cf32fafc55172","transactionIndex":"0x0","blockHash":"0x82ddc58a8608bdac6cf29a962dabd34e0f3e1b8c76bf14459f8a1c9bdb1a9789","blockNumber":"0x4","gasUsed":"0x18b018","cumulativeGasUsed":"0x18b018","contractAddress":"0x38219779a699d67d7e7740b8c8f43d3e2dae2182","logs":[],"status":"0x1","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}
@@ -0,0 +1 @@
{"transactionHash":"0x9430a6e3c1665c19dfe6e55eba73ae209d256b17d8f2ea63acb9bdf23144f0a9","transactionIndex":"0x0","blockHash":"0x2c3b96f821a6abe12061036d3f90e3a04f72eb3b06952a1b0d8916bff0103406","blockNumber":"0x3","gasUsed":"0x10cba","cumulativeGasUsed":"0x10cba","contractAddress":"0xa970ed54e41d9db6d91db5e7ff7a9451dad98993","logs":[],"status":"0x1","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}
@@ -0,0 +1 @@
{"transactionHash":"0xc0bdfdb15c288d6a7b0af865d953677c4818c6655d26631bd7b840e9cfb2d668","transactionIndex":"0x0","blockHash":"0xa991182133d4d762d84b3213e93f29caf30a8c68552f95830a934b886560762a","blockNumber":"0x2","gasUsed":"0xa418","cumulativeGasUsed":"0xa418","contractAddress":null,"logs":[],"status":"0x1","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}
@@ -0,0 +1 @@
{"transactionHash":"0xceba2ca8e63611b307f222e9b97e1cbec800f6701ef4d8f6080edf0faa6b9732","transactionIndex":"0x0","blockHash":"0x76443e96ab64087485c83dcaf3ed15ad5303b23393957f075901dab7cdefdef8","blockNumber":"0x8","gasUsed":"0xe03c1","cumulativeGasUsed":"0xe03c1","contractAddress":"0x7dbda851034713f899a122f95860eaf707b9f833","logs":[],"status":"0x1","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}
@@ -0,0 +1 @@
{"transactionHash":"0xd484799e4f3a24c0e83d7210ae6936700f2da07ddc3cb7191b06a5e20b10fb61","transactionIndex":"0x0","blockHash":"0x7e8df460b9fe6f779d308571d81629f57e66648907f6c97ba7712d15a553087a","blockNumber":"0x1","gasUsed":"0x43bd6","cumulativeGasUsed":"0x43bd6","contractAddress":"0xfc0ba85028256ef48f5ba64dd65dc258988955f6","logs":[],"status":"0x1","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}
@@ -0,0 +1 @@
{"nonce":"0x04","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0xfc0ba85028256ef48f5ba64dd65dc258988955f6","value":"0x","data":"0xfdacd5760000000000000000000000000000000000000000000000000000000000000002","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0x2194da14a0d4be36fb809efd3f9f426bf60842dbf244788d0a84b894b3e6bd49"}
@@ -0,0 +1 @@
{"nonce":"0x","gasPrice":"0x01","gasLimit":"0x44aa20","to":"0x08cb6176addcca2e1d1ffe21bee464b72ee4cd8d","value":"0x","data":"0x351de6000000000000000000000000007340e006f4135ba6970d43bf43d88dcad4e7a8ca00000000000000000000000007fa9ef6609ca7921112231f8f195138ebba2977000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000","v":"0x1c","r":"0x","s":"0x","from":"0x64d922894153be9eef7b7218dc565d1d0ce2a092","hash":"0x6b155a55fd77b751195deeebf7abfd8691ca01ee588817a920f19d5b27f65191"}
@@ -0,0 +1 @@
{"nonce":"0x02","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0x","value":"0x","data":"0x6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00a165627a7a72305820562865e6c1f558e8a54735c0ff54b7f6a1fbc65c540a84c894f17a5fec64110d0029","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0x9430a6e3c1665c19dfe6e55eba73ae209d256b17d8f2ea63acb9bdf23144f0a9"}
@@ -0,0 +1 @@
{"nonce":"0x01","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0xfc0ba85028256ef48f5ba64dd65dc258988955f6","value":"0x","data":"0xfdacd5760000000000000000000000000000000000000000000000000000000000000001","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0xc0bdfdb15c288d6a7b0af865d953677c4818c6655d26631bd7b840e9cfb2d668"}
@@ -0,0 +1 @@
{"nonce":"0x","gasPrice":"0x174876e800","gasLimit":"0x6691b7","to":"0x","value":"0x","data":"0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506102f8806100606000396000f300608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630900f01014610067578063445df0ac146100aa5780638da5cb5b146100d5578063fdacd5761461012c575b600080fd5b34801561007357600080fd5b506100a8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610159565b005b3480156100b657600080fd5b506100bf610241565b6040518082815260200191505060405180910390f35b3480156100e157600080fd5b506100ea610247565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561013857600080fd5b506101576004803603810190808035906020019092919050505061026c565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561023d578190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561022457600080fd5b505af1158015610238573d6000803e3d6000fd5b505050505b5050565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102c957806001819055505b505600a165627a7a72305820167320a3f0aefab2d9d7492779c69a7f6bbea970d8290e17d3631fbed9ad93540029","v":"0x1c","r":"0x","s":"0x","from":"0x8e84a1e068d77059cbe263c43ad0cdc130863313","hash":"0xd484799e4f3a24c0e83d7210ae6936700f2da07ddc3cb7191b06a5e20b10fb61"}
@@ -0,0 +1 @@
"0xf90131a02b90ac735ccaf20d1204ce987c10f24fa0ecf777dbe99525c0321a58f237aa2380a01b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a2a09d284defeed07bc2b2d65d7d4ba14066c71072010c352566ceb6af2105001fa38080a074952353b0991411841541f86d37934e0d826eb7411a2420ea362466d8d60e03a0f39ba3ac12d2744dd608f89cb539b72a387a2e605dba7ad9a4e935486657e80ca0fdcb675a2fb7395ce85312eeaf38d612251395b4277a958c4a78cea448e07cc1a025fc93ab219268b7e46014c8ac580adba1ce1051d8cb8bcb1cd238f4187e577ba0b9b76c57e2bde1c38c34e662ada45402840f239a67bc577357a9dafce809946a80808080a0c03c348f717530216ab354ac3ef0e19e46c28ce0f78640f445e41e4e9b02d5ca80"
@@ -0,0 +1 @@
"0xf8f1a0422861bc32af762face51a81dfb4e3f2d563beb99ee972cf1fa30b944e6b85f580a01b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a2808080a074952353b0991411841541f86d37934e0d826eb7411a2420ea362466d8d60e03a0a7e84e568d915220899cd49f84d03cadbba602e3e04546e2c18064dcb0517963a051e94f71fe2273409ef0acbc4986df7bb808426470a9871d1f6d3324b780c194a025fc93ab219268b7e46014c8ac580adba1ce1051d8cb8bcb1cd238f4187e577ba063a1b8e271db0ec0a1816192da83ae3bec40470b66f31d047ef4911d0106dde2808080808080"
@@ -0,0 +1 @@
"0xf90131a080b4053526aa3f9eeead723f413de9449aa4066e6d54c701ac5bd5a05db08bf980a01b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a2a09d284defeed07bc2b2d65d7d4ba14066c71072010c352566ceb6af2105001fa38080a074952353b0991411841541f86d37934e0d826eb7411a2420ea362466d8d60e03a0f39ba3ac12d2744dd608f89cb539b72a387a2e605dba7ad9a4e935486657e80ca0b8a4ccd79e4c55573c4c1909205f8a64815b241b68749290e126968a01a55296a025fc93ab219268b7e46014c8ac580adba1ce1051d8cb8bcb1cd238f4187e577ba0b9b76c57e2bde1c38c34e662ada45402840f239a67bc577357a9dafce809946a80808080a0b07a87e464ce02c066bb930db0ad6af18367210d9660609b5ecf4a6acb1e0ab380"
@@ -0,0 +1 @@
"0xf85120b84ef84c80887d705cb8966c4000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
@@ -0,0 +1 @@
"0xf866943e84a1e068d77059cbe263c43ad0cdc130863313b84ff84d05890568f5064263e60000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
@@ -0,0 +1 @@
"0xf851a0d8592c6f97b855e192b45cbc3a21093b529abc9cca3c368066d44aa31c9f0a57a034d4377e4f0dee74f4a49f6c09d66f6d4ff253d260d052e8d5ffe022965d6ffc808080808080808080808080808080"
@@ -0,0 +1 @@
"0xf90131a0e471b75d1693dfa4458588ca431b54af9320eca119ece050d55e1b05a94bad2480a01b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a2a09d284defeed07bc2b2d65d7d4ba14066c71072010c352566ceb6af2105001fa38080a074952353b0991411841541f86d37934e0d826eb7411a2420ea362466d8d60e03a0d35dc35858f8b26ca6aca1a7801c782bb905b339c40e2f4d7fa9bbb6e60f2919a0ab6df9bdf417e2156e3d5b8fe119c9f9366e0fb63b6e79c6840068695a6d3b47a025fc93ab219268b7e46014c8ac580adba1ce1051d8cb8bcb1cd238f4187e577ba0b9b76c57e2bde1c38c34e662ada45402840f239a67bc577357a9dafce809946a80808080a0b07a87e464ce02c066bb930db0ad6af18367210d9660609b5ecf4a6acb1e0ab380"
@@ -0,0 +1 @@
"0xf842a01000000000000000000000000000000000000000000000000000000000000000a066c5d0a6016165e537ac63b121df2d074c649a16b50ca7a2839abc5eb3894a9a"
@@ -0,0 +1 @@
"0xf90111a08202796f16ed68ec4c55687dd91c9eaf8eb1506c93c66179b72255e15104f292a05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554aa05911f24d96912350de50f297c2d34d5d10e136757bf4cfff5fa41bfca219554a808080808080808080"
@@ -0,0 +1 @@
"0xf59310000000000000000000000000000000000000a0fb53e64824f62daa3a1598b6864c077c8b3feafa8d6f93bb5185dcd52a55f4b5"
@@ -0,0 +1 @@
"0xf85fd720959438219779a699d67d7e7740b8c8f43d3e2dae2182a0bd71221ec6a606a213189d3d27d5da39a39474894d83029f1397c838c9ac428bcb2089880e92596fd6290000cc208a89093a80000000002a3080808080808080808080808080"
@@ -0,0 +1 @@
"0xf866943e84a1e068d77059cbe263c43ad0cdc130863313b84ff84d0189056b64cb27c8321000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
@@ -0,0 +1 @@
"0xf866943463dbb283c08844ebc2aa38c225e3ebc6a0c4e4b84ff84d8089056bc75e2d63100000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
@@ -0,0 +1 @@
"0xf59310000000000000000000000000000000000000a03692ebfcca6c72d823f2edef1158597c3c964404792d86cbd9b4027f828a022f"
@@ -0,0 +1 @@
"0xf866943e84a1e068d77059cbe263c43ad0cdc130863313b84ff84d078905667668ad058ca800a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
@@ -0,0 +1 @@
"0xf90111a01e566933d70b71a726f5cc492316cd71fe8ee35d224575d33e29280c409c3c8d80a01b9a0ca00da4bf0c31264a2bf0a2352c41b0012d157942fcabc59e64f08ec8a2808080a074952353b0991411841541f86d37934e0d826eb7411a2420ea362466d8d60e03a0f39ba3ac12d2744dd608f89cb539b72a387a2e605dba7ad9a4e935486657e80ca01ae66f56e80b6ce3f6dd2c657d165248c788005cbee34e61ff0a5459edae1722a025fc93ab219268b7e46014c8ac580adba1ce1051d8cb8bcb1cd238f4187e577ba063a1b8e271db0ec0a1816192da83ae3bec40470b66f31d047ef4911d0106dde280808080a04e8bf0d45a3147eac8fc230cd9711ccec2dae78beadfdcf290c11b5ad5f0702a80"
@@ -0,0 +1 @@
"0x608060405260043610610062576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630900f01014610067578063445df0ac146100aa5780638da5cb5b146100d5578063fdacd5761461012c575b600080fd5b34801561007357600080fd5b506100a8600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610159565b005b3480156100b657600080fd5b506100bf610241565b6040518082815260200191505060405180910390f35b3480156100e157600080fd5b506100ea610247565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561013857600080fd5b506101576004803603810190808035906020019092919050505061026c565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561023d578190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b15801561022457600080fd5b505af1158015610238573d6000803e3d6000fd5b505050505b5050565b60015481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156102c957806001819055505b505600a165627a7a72305820167320a3f0aefab2d9d7492779c69a7f6bbea970d8290e17d3631fbed9ad93540029"

Some files were not shown because too many files have changed in this diff Show More