forked from cerc-io/ipld-eth-server
Update BlockChain to record NodeInfo (#95)
This commit is contained in:
parent
18163f970e
commit
921bde1089
62
Gopkg.lock
generated
62
Gopkg.lock
generated
@ -13,23 +13,29 @@
|
|||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "4748e29d5718c2df4028a6543edf86fd8cc0f881"
|
revision = "4748e29d5718c2df4028a6543edf86fd8cc0f881"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/aristanetworks/goarista"
|
||||||
|
packages = ["monotime"]
|
||||||
|
revision = "8d0e8f607a4080e7df3532e645440ed0900c64a4"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/btcsuite/btcd"
|
name = "github.com/btcsuite/btcd"
|
||||||
packages = ["btcec"]
|
packages = ["btcec"]
|
||||||
revision = "c7588cbf7690cd9f047a28efa2dcd8f2435a4e5e"
|
revision = "2e60448ffcc6bf78332d1fe590260095f554dd78"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/ethereum/go-ethereum"
|
name = "github.com/ethereum/go-ethereum"
|
||||||
packages = [".","accounts/abi","common","common/hexutil","common/math","core/types","crypto","crypto/secp256k1","crypto/sha3","ethclient","log","params","rlp","rpc","trie"]
|
packages = [".","accounts/abi","common","common/hexutil","common/math","common/mclock","core/types","crypto","crypto/ecies","crypto/secp256k1","crypto/sha3","ethclient","event","log","metrics","p2p","p2p/discover","p2p/discv5","p2p/nat","p2p/netutil","params","rlp","rpc","trie"]
|
||||||
revision = "1db4ecdc0b9e828ff65777fb466fc7c1d04e0de9"
|
revision = "4bb3c89d44e372e6a9ab85a8be0c9345265c763a"
|
||||||
version = "v1.7.2"
|
version = "v1.7.3"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/go-stack/stack"
|
name = "github.com/go-stack/stack"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "817915b46b97fd7bb80e8ab6b69f01a53ac3eebf"
|
revision = "259ab82a6cad3992b4e21ff5cac294ccb06474bc"
|
||||||
version = "v1.6.0"
|
version = "v1.7.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
@ -37,23 +43,41 @@
|
|||||||
packages = ["proto"]
|
packages = ["proto"]
|
||||||
revision = "1e59b77b52bf8e4b449a57e6f79f21226d571845"
|
revision = "1e59b77b52bf8e4b449a57e6f79f21226d571845"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/golang/snappy"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "553a641470496b2327abcac10b36396bd98e45c9"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/howeyc/gopass"
|
name = "github.com/howeyc/gopass"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "bf9dde6d0d2c004a008c27aaee91170c786f6db8"
|
revision = "bf9dde6d0d2c004a008c27aaee91170c786f6db8"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/huin/goupnp"
|
||||||
|
packages = [".","dcps/internetgateway1","dcps/internetgateway2","httpu","scpd","soap","ssdp"]
|
||||||
|
revision = "dceda08e705b2acee36aab47d765ed801f64cfc7"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/jackpal/go-nat-pmp"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "c9cfead9f2a36ddf3daa40ba269aa7f4bbba6b62"
|
||||||
|
version = "v1.0.1"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/jmoiron/sqlx"
|
name = "github.com/jmoiron/sqlx"
|
||||||
packages = [".","reflectx"]
|
packages = [".","reflectx"]
|
||||||
revision = "3379e5993990b1f927fc8db926485e6f6becf2d2"
|
revision = "99f3ad6d85ae53d0fecf788ab62d0e9734b3c117"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/lib/pq"
|
name = "github.com/lib/pq"
|
||||||
packages = [".","oid"]
|
packages = [".","oid"]
|
||||||
revision = "b609790bd85edf8e9ab7e0f8912750a786177bcf"
|
revision = "83612a56d3dd153a94a629cd64925371c9adad78"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/mattn/go-colorable"
|
name = "github.com/mattn/go-colorable"
|
||||||
@ -112,8 +136,8 @@
|
|||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/rcrowley/go-metrics"
|
name = "github.com/rcrowley/go-metrics"
|
||||||
packages = ["."]
|
packages = [".","exp"]
|
||||||
revision = "1f30fe9094a513ce4c700b9a54458bbb0c96996c"
|
revision = "e181e095bae94582363434144c61a9653aff6e50"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/rs/cors"
|
name = "github.com/rs/cors"
|
||||||
@ -121,29 +145,35 @@
|
|||||||
revision = "7af7a1e09ba336d2ea14b1ce73bf693c6837dbf6"
|
revision = "7af7a1e09ba336d2ea14b1ce73bf693c6837dbf6"
|
||||||
version = "v1.2"
|
version = "v1.2"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/syndtr/goleveldb"
|
||||||
|
packages = ["leveldb","leveldb/cache","leveldb/comparer","leveldb/errors","leveldb/filter","leveldb/iterator","leveldb/journal","leveldb/memdb","leveldb/opt","leveldb/storage","leveldb/table","leveldb/util"]
|
||||||
|
revision = "adf24ef3f94bd13ec4163060b21a5678f22b429b"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "golang.org/x/crypto"
|
name = "golang.org/x/crypto"
|
||||||
packages = ["ssh/terminal"]
|
packages = ["ssh/terminal"]
|
||||||
revision = "bd6f299fb381e4c3393d1c4b1f0b94f5e77650c8"
|
revision = "94eea52f7b742c7cbe0b03b22f0c4c8631ece122"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "golang.org/x/net"
|
name = "golang.org/x/net"
|
||||||
packages = ["context","html","html/atom","html/charset","websocket"]
|
packages = ["context","html","html/atom","html/charset","websocket"]
|
||||||
revision = "1087133bc4af3073e18add999345c6ae75918503"
|
revision = "faacc1b5e36e3ff02cbec9661c69ac63dd5a83ad"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "golang.org/x/sys"
|
name = "golang.org/x/sys"
|
||||||
packages = ["unix","windows"]
|
packages = ["unix","windows"]
|
||||||
revision = "8dbc5d05d6edcc104950cc299a1ce6641235bc86"
|
revision = "a0f4589a76f1f83070cb9e5613809e1d07b97c13"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "golang.org/x/text"
|
name = "golang.org/x/text"
|
||||||
packages = ["encoding","encoding/charmap","encoding/htmlindex","encoding/internal","encoding/internal/identifier","encoding/japanese","encoding/korean","encoding/simplifiedchinese","encoding/traditionalchinese","encoding/unicode","internal/gen","internal/tag","internal/utf8internal","language","runes","transform","unicode/cldr"]
|
packages = ["encoding","encoding/charmap","encoding/htmlindex","encoding/internal","encoding/internal/identifier","encoding/japanese","encoding/korean","encoding/simplifiedchinese","encoding/traditionalchinese","encoding/unicode","internal/gen","internal/tag","internal/utf8internal","language","runes","transform","unicode/cldr"]
|
||||||
revision = "c01e4764d870b77f8abe5096ee19ad20d80e8075"
|
revision = "be25de41fadfae372d6470bda81ca6beb55ef551"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "gopkg.in/fatih/set.v0"
|
name = "gopkg.in/fatih/set.v0"
|
||||||
@ -173,11 +203,11 @@
|
|||||||
branch = "v2"
|
branch = "v2"
|
||||||
name = "gopkg.in/yaml.v2"
|
name = "gopkg.in/yaml.v2"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "eb3733d160e74a9c7e442f435eb3bea458e1d19f"
|
revision = "287cf08546ab5e7e37d55a84f7ed3fd1db036de5"
|
||||||
|
|
||||||
[solve-meta]
|
[solve-meta]
|
||||||
analyzer-name = "dep"
|
analyzer-name = "dep"
|
||||||
analyzer-version = 1
|
analyzer-version = 1
|
||||||
inputs-digest = "90af18ee127c0b2099f47adc5d33fb6ce9b98630278ec66648ef3e1c5ad9063f"
|
inputs-digest = "9b993b03db46de97fde5cfe8022a60d1654172dcb7d63c2c4b876308ffd1f73e"
|
||||||
solver-name = "gps-cdcl"
|
solver-name = "gps-cdcl"
|
||||||
solver-version = 1
|
solver-version = 1
|
||||||
|
@ -16,7 +16,7 @@ func main() {
|
|||||||
flag.Parse()
|
flag.Parse()
|
||||||
config := cmd.LoadConfig(*environment)
|
config := cmd.LoadConfig(*environment)
|
||||||
blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
||||||
repository := cmd.LoadPostgres(config.Database)
|
repository := cmd.LoadPostgres(config.Database, blockchain.Node())
|
||||||
numberOfBlocksCreated := history.PopulateBlocks(blockchain, repository, int64(*startingBlockNumber))
|
numberOfBlocksCreated := history.PopulateBlocks(blockchain, repository, int64(*startingBlockNumber))
|
||||||
fmt.Printf("Populated %d blocks", numberOfBlocksCreated)
|
fmt.Printf("Populated %d blocks", numberOfBlocksCreated)
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,11 @@ func main() {
|
|||||||
environment := flag.String("environment", "", "Environment name")
|
environment := flag.String("environment", "", "Environment name")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
config := cmd.LoadConfig(*environment)
|
config := cmd.LoadConfig(*environment)
|
||||||
repository := cmd.LoadPostgres(config.Database)
|
|
||||||
fmt.Printf("Creating Geth Blockchain to: %s\n", config.Client.IPCPath)
|
fmt.Printf("Creating Geth Blockchain to: %s\n", config.Client.IPCPath)
|
||||||
|
blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
||||||
|
repository := cmd.LoadPostgres(config.Database, blockchain.Node())
|
||||||
listener := blockchain_listener.NewBlockchainListener(
|
listener := blockchain_listener.NewBlockchainListener(
|
||||||
geth.NewGethBlockchain(config.Client.IPCPath),
|
blockchain,
|
||||||
[]core.BlockchainObserver{
|
[]core.BlockchainObserver{
|
||||||
observers.BlockchainLoggingObserver{},
|
observers.BlockchainLoggingObserver{},
|
||||||
observers.NewBlockchainDbObserver(repository),
|
observers.NewBlockchainDbObserver(repository),
|
||||||
|
@ -21,7 +21,7 @@ func main() {
|
|||||||
flag.Parse()
|
flag.Parse()
|
||||||
config := cmd.LoadConfig(*environment)
|
config := cmd.LoadConfig(*environment)
|
||||||
blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
||||||
repository := cmd.LoadPostgres(config.Database)
|
repository := cmd.LoadPostgres(config.Database, blockchain.Node())
|
||||||
blockNumber := requestedBlockNumber(_blockNumber)
|
blockNumber := requestedBlockNumber(_blockNumber)
|
||||||
|
|
||||||
contractSummary, err := contract_summary.NewSummary(blockchain, repository, *contractHash, blockNumber)
|
contractSummary, err := contract_summary.NewSummary(blockchain, repository, *contractHash, blockNumber)
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"github.com/8thlight/vulcanizedb/cmd"
|
"github.com/8thlight/vulcanizedb/cmd"
|
||||||
"github.com/8thlight/vulcanizedb/pkg/core"
|
"github.com/8thlight/vulcanizedb/pkg/core"
|
||||||
|
"github.com/8thlight/vulcanizedb/pkg/geth"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -15,7 +16,8 @@ func main() {
|
|||||||
|
|
||||||
contractAbiString := cmd.GetAbi(*abiFilepath, *contractHash)
|
contractAbiString := cmd.GetAbi(*abiFilepath, *contractHash)
|
||||||
config := cmd.LoadConfig(*environment)
|
config := cmd.LoadConfig(*environment)
|
||||||
repository := cmd.LoadPostgres(config.Database)
|
blockchain := geth.NewGethBlockchain(config.Client.IPCPath)
|
||||||
|
repository := cmd.LoadPostgres(config.Database, blockchain.Node())
|
||||||
watchedContract := core.Contract{
|
watchedContract := core.Contract{
|
||||||
Abi: contractAbiString,
|
Abi: contractAbiString,
|
||||||
Hash: *contractHash,
|
Hash: *contractHash,
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/8thlight/vulcanizedb/pkg/config"
|
"github.com/8thlight/vulcanizedb/pkg/config"
|
||||||
|
"github.com/8thlight/vulcanizedb/pkg/core"
|
||||||
"github.com/8thlight/vulcanizedb/pkg/geth"
|
"github.com/8thlight/vulcanizedb/pkg/geth"
|
||||||
"github.com/8thlight/vulcanizedb/pkg/repositories"
|
"github.com/8thlight/vulcanizedb/pkg/repositories"
|
||||||
)
|
)
|
||||||
@ -20,8 +21,8 @@ func LoadConfig(environment string) config.Config {
|
|||||||
return cfg
|
return cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadPostgres(database config.Database) repositories.Postgres {
|
func LoadPostgres(database config.Database, node core.Node) repositories.Postgres {
|
||||||
repository, err := repositories.NewPostgres(database)
|
repository, err := repositories.NewPostgres(database, node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error loading postgres\n%v", err)
|
log.Fatalf("Error loading postgres\n%v", err)
|
||||||
}
|
}
|
||||||
|
1
db/migrations/1512504078_add_nodes_table.down.sql
Normal file
1
db/migrations/1512504078_add_nodes_table.down.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
DROP TABLE nodes;
|
6
db/migrations/1512504078_add_nodes_table.up.sql
Normal file
6
db/migrations/1512504078_add_nodes_table.up.sql
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
CREATE TABLE nodes (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
genesis_block VARCHAR(66),
|
||||||
|
network_id NUMERIC,
|
||||||
|
CONSTRAINT node_uc UNIQUE (genesis_block, network_id)
|
||||||
|
);
|
2
db/migrations/1512507280_add_node_fk_to_blocks.down.sql
Normal file
2
db/migrations/1512507280_add_node_fk_to_blocks.down.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE blocks
|
||||||
|
DROP COLUMN node_id;
|
5
db/migrations/1512507280_add_node_fk_to_blocks.up.sql
Normal file
5
db/migrations/1512507280_add_node_fk_to_blocks.up.sql
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
ALTER TABLE blocks
|
||||||
|
ADD COLUMN node_id INTEGER NOT NULL,
|
||||||
|
ADD CONSTRAINT node_fk
|
||||||
|
FOREIGN KEY (node_id)
|
||||||
|
REFERENCES nodes (id);
|
@ -49,7 +49,8 @@ CREATE TABLE blocks (
|
|||||||
block_nonce character varying(20),
|
block_nonce character varying(20),
|
||||||
block_parenthash character varying(66),
|
block_parenthash character varying(66),
|
||||||
block_size bigint,
|
block_size bigint,
|
||||||
uncle_hash character varying(66)
|
uncle_hash character varying(66),
|
||||||
|
node_id integer NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -72,6 +73,36 @@ CREATE SEQUENCE blocks_id_seq
|
|||||||
ALTER SEQUENCE blocks_id_seq OWNED BY blocks.id;
|
ALTER SEQUENCE blocks_id_seq OWNED BY blocks.id;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: nodes; Type: TABLE; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE nodes (
|
||||||
|
id integer NOT NULL,
|
||||||
|
genesis_block character varying(66),
|
||||||
|
network_id numeric
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: nodes_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE SEQUENCE nodes_id_seq
|
||||||
|
START WITH 1
|
||||||
|
INCREMENT BY 1
|
||||||
|
NO MINVALUE
|
||||||
|
NO MAXVALUE
|
||||||
|
CACHE 1;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: nodes_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER SEQUENCE nodes_id_seq OWNED BY nodes.id;
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: schema_migrations; Type: TABLE; Schema: public; Owner: -
|
-- Name: schema_migrations; Type: TABLE; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
@ -155,6 +186,13 @@ ALTER SEQUENCE watched_contracts_contract_id_seq OWNED BY watched_contracts.cont
|
|||||||
ALTER TABLE ONLY blocks ALTER COLUMN id SET DEFAULT nextval('blocks_id_seq'::regclass);
|
ALTER TABLE ONLY blocks ALTER COLUMN id SET DEFAULT nextval('blocks_id_seq'::regclass);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: nodes id; Type: DEFAULT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY nodes ALTER COLUMN id SET DEFAULT nextval('nodes_id_seq'::regclass);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: transactions id; Type: DEFAULT; Schema: public; Owner: -
|
-- Name: transactions id; Type: DEFAULT; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
@ -185,6 +223,22 @@ ALTER TABLE ONLY watched_contracts
|
|||||||
ADD CONSTRAINT contract_hash_uc UNIQUE (contract_hash);
|
ADD CONSTRAINT contract_hash_uc UNIQUE (contract_hash);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: nodes node_uc; Type: CONSTRAINT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY nodes
|
||||||
|
ADD CONSTRAINT node_uc UNIQUE (genesis_block, network_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: nodes nodes_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY nodes
|
||||||
|
ADD CONSTRAINT nodes_pkey PRIMARY KEY (id);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: schema_migrations schema_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
-- Name: schema_migrations schema_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
@ -224,6 +278,14 @@ ALTER TABLE ONLY transactions
|
|||||||
ADD CONSTRAINT fk_test FOREIGN KEY (block_id) REFERENCES blocks(id);
|
ADD CONSTRAINT fk_test FOREIGN KEY (block_id) REFERENCES blocks(id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: blocks node_fk; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY blocks
|
||||||
|
ADD CONSTRAINT node_fk FOREIGN KEY (node_id) REFERENCES nodes(id);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- PostgreSQL database dump complete
|
-- PostgreSQL database dump complete
|
||||||
--
|
--
|
||||||
|
@ -54,4 +54,15 @@ var _ = Describe("Reading from the Geth blockchain", func() {
|
|||||||
close(done)
|
close(done)
|
||||||
}, 15)
|
}, 15)
|
||||||
|
|
||||||
|
It("retrieves the node info", func(done Done) {
|
||||||
|
node := blockchain.Node()
|
||||||
|
devNetworkGenesisBlock := "0xe5be92145a301820111f91866566e3e99ee344d155569e4556a39bc71238f3bc"
|
||||||
|
devNetworkNodeId := float64(1)
|
||||||
|
|
||||||
|
Expect(node.GenesisBlock).To(Equal(devNetworkGenesisBlock))
|
||||||
|
Expect(node.NetworkId).To(Equal(devNetworkNodeId))
|
||||||
|
|
||||||
|
close(done)
|
||||||
|
}, 15)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
@ -4,6 +4,7 @@ import "math/big"
|
|||||||
|
|
||||||
type Blockchain interface {
|
type Blockchain interface {
|
||||||
GetBlockByNumber(blockNumber int64) Block
|
GetBlockByNumber(blockNumber int64) Block
|
||||||
|
Node() Node
|
||||||
SubscribeToBlocks(blocks chan Block)
|
SubscribeToBlocks(blocks chan Block)
|
||||||
StartListening()
|
StartListening()
|
||||||
StopListening()
|
StopListening()
|
||||||
|
6
pkg/core/node_info.go
Normal file
6
pkg/core/node_info.go
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package core
|
||||||
|
|
||||||
|
type Node struct {
|
||||||
|
GenesisBlock string
|
||||||
|
NetworkId float64
|
||||||
|
}
|
@ -13,6 +13,11 @@ type Blockchain struct {
|
|||||||
contractAttributes map[string]map[string]string
|
contractAttributes map[string]map[string]string
|
||||||
blocksChannel chan core.Block
|
blocksChannel chan core.Block
|
||||||
WasToldToStop bool
|
WasToldToStop bool
|
||||||
|
node core.Node
|
||||||
|
}
|
||||||
|
|
||||||
|
func (blockchain *Blockchain) Node() core.Node {
|
||||||
|
return blockchain.node
|
||||||
}
|
}
|
||||||
|
|
||||||
func (blockchain *Blockchain) GetAttribute(contract core.Contract, attributeName string, blockNumber *big.Int) (interface{}, error) {
|
func (blockchain *Blockchain) GetAttribute(contract core.Contract, attributeName string, blockNumber *big.Int) (interface{}, error) {
|
||||||
@ -29,6 +34,7 @@ func NewBlockchain() *Blockchain {
|
|||||||
return &Blockchain{
|
return &Blockchain{
|
||||||
blocks: make(map[int64]core.Block),
|
blocks: make(map[int64]core.Block),
|
||||||
contractAttributes: make(map[string]map[string]string),
|
contractAttributes: make(map[string]map[string]string),
|
||||||
|
node: core.Node{GenesisBlock: "GENESIS"},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,9 +6,11 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/8thlight/vulcanizedb/pkg/core"
|
"github.com/8thlight/vulcanizedb/pkg/core"
|
||||||
|
"github.com/8thlight/vulcanizedb/pkg/geth/node"
|
||||||
"github.com/ethereum/go-ethereum"
|
"github.com/ethereum/go-ethereum"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethclient"
|
"github.com/ethereum/go-ethereum/ethclient"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -17,6 +19,11 @@ type GethBlockchain struct {
|
|||||||
readGethHeaders chan *types.Header
|
readGethHeaders chan *types.Header
|
||||||
outputBlocks chan core.Block
|
outputBlocks chan core.Block
|
||||||
newHeadSubscription ethereum.Subscription
|
newHeadSubscription ethereum.Subscription
|
||||||
|
node core.Node
|
||||||
|
}
|
||||||
|
|
||||||
|
func (blockchain *GethBlockchain) Node() core.Node {
|
||||||
|
return blockchain.node
|
||||||
}
|
}
|
||||||
|
|
||||||
func (blockchain *GethBlockchain) GetBlockByNumber(blockNumber int64) core.Block {
|
func (blockchain *GethBlockchain) GetBlockByNumber(blockNumber int64) core.Block {
|
||||||
@ -26,7 +33,9 @@ func (blockchain *GethBlockchain) GetBlockByNumber(blockNumber int64) core.Block
|
|||||||
|
|
||||||
func NewGethBlockchain(ipcPath string) *GethBlockchain {
|
func NewGethBlockchain(ipcPath string) *GethBlockchain {
|
||||||
blockchain := GethBlockchain{}
|
blockchain := GethBlockchain{}
|
||||||
client, _ := ethclient.Dial(ipcPath)
|
rpcClient, _ := rpc.Dial(ipcPath)
|
||||||
|
client := ethclient.NewClient(rpcClient)
|
||||||
|
blockchain.node = node.Retrieve(rpcClient)
|
||||||
blockchain.client = client
|
blockchain.client = client
|
||||||
return &blockchain
|
return &blockchain
|
||||||
}
|
}
|
||||||
|
32
pkg/geth/node/node.go
Normal file
32
pkg/geth/node/node.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package node
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/8thlight/vulcanizedb/pkg/core"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Retrieve(client *rpc.Client) core.Node {
|
||||||
|
var info p2p.NodeInfo
|
||||||
|
node := core.Node{}
|
||||||
|
client.CallContext(context.Background(), &info, "admin_nodeInfo")
|
||||||
|
for protocolName, protocol := range info.Protocols {
|
||||||
|
if protocolName == "eth" {
|
||||||
|
protocolMap, _ := protocol.(map[string]interface{})
|
||||||
|
node.GenesisBlock = getAttribute(protocolMap, "genesis").(string)
|
||||||
|
node.NetworkId = getAttribute(protocolMap, "network").(float64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAttribute(protocolMap map[string]interface{}, protocol string) interface{} {
|
||||||
|
for key, val := range protocolMap {
|
||||||
|
if key == protocol {
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package repositories_test
|
package repositories_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/8thlight/vulcanizedb/pkg/core"
|
||||||
"github.com/8thlight/vulcanizedb/pkg/repositories"
|
"github.com/8thlight/vulcanizedb/pkg/repositories"
|
||||||
"github.com/8thlight/vulcanizedb/pkg/repositories/testing"
|
"github.com/8thlight/vulcanizedb/pkg/repositories/testing"
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
@ -9,7 +10,7 @@ import (
|
|||||||
|
|
||||||
var _ = Describe("In memory repository", func() {
|
var _ = Describe("In memory repository", func() {
|
||||||
|
|
||||||
testing.AssertRepositoryBehavior(func() repositories.Repository {
|
testing.AssertRepositoryBehavior(func(core.Node) repositories.Repository {
|
||||||
return repositories.NewInMemory()
|
return repositories.NewInMemory()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -14,21 +14,46 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Postgres struct {
|
type Postgres struct {
|
||||||
Db *sqlx.DB
|
Db *sqlx.DB
|
||||||
|
node core.Node
|
||||||
|
nodeId int64
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrDBInsertFailed = errors.New("postgres: insert failed")
|
ErrDBInsertFailed = errors.New("postgres: insert failed")
|
||||||
ErrDBConnectionFailed = errors.New("postgres: db connection failed")
|
ErrDBConnectionFailed = errors.New("postgres: db connection failed")
|
||||||
|
ErrUnableToSetNode = errors.New("postgres: unable to set node")
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewPostgres(databaseConfig config.Database) (Postgres, error) {
|
func NewPostgres(databaseConfig config.Database, node core.Node) (Postgres, error) {
|
||||||
connectString := config.DbConnectionString(databaseConfig)
|
connectString := config.DbConnectionString(databaseConfig)
|
||||||
db, err := sqlx.Connect("postgres", connectString)
|
db, err := sqlx.Connect("postgres", connectString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Postgres{}, ErrDBConnectionFailed
|
return Postgres{}, ErrDBConnectionFailed
|
||||||
}
|
}
|
||||||
return Postgres{Db: db}, nil
|
pg := Postgres{Db: db, node: node}
|
||||||
|
err = pg.CreateNode(&node)
|
||||||
|
if err != nil {
|
||||||
|
return Postgres{}, ErrUnableToSetNode
|
||||||
|
}
|
||||||
|
return pg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repository *Postgres) CreateNode(node *core.Node) error {
|
||||||
|
var nodeId int64
|
||||||
|
err := repository.Db.QueryRow(
|
||||||
|
`INSERT INTO nodes (genesis_block, network_id)
|
||||||
|
VALUES ($1, $2)
|
||||||
|
ON CONFLICT (genesis_block, network_id)
|
||||||
|
DO UPDATE
|
||||||
|
SET genesis_block = $1, network_id = $2
|
||||||
|
RETURNING id`,
|
||||||
|
node.GenesisBlock, node.NetworkId).Scan(&nodeId)
|
||||||
|
if err != nil {
|
||||||
|
return ErrUnableToSetNode
|
||||||
|
}
|
||||||
|
repository.nodeId = nodeId
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repository Postgres) CreateContract(contract core.Contract) error {
|
func (repository Postgres) CreateContract(contract core.Contract) error {
|
||||||
@ -53,7 +78,8 @@ func (repository Postgres) CreateContract(contract core.Contract) error {
|
|||||||
func (repository Postgres) ContractExists(contractHash string) bool {
|
func (repository Postgres) ContractExists(contractHash string) bool {
|
||||||
var exists bool
|
var exists bool
|
||||||
repository.Db.QueryRow(
|
repository.Db.QueryRow(
|
||||||
`SELECT exists(SELECT 1 FROM watched_contracts WHERE contract_hash=$1) FROM watched_contracts`, contractHash).Scan(&exists)
|
`SELECT exists(SELECT 1 FROM watched_contracts WHERE contract_hash=$1)
|
||||||
|
FROM watched_contracts`, contractHash).Scan(&exists)
|
||||||
return exists
|
return exists
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +118,9 @@ func (repository Postgres) MissingBlockNumbers(startingBlockNumber int64, highes
|
|||||||
|
|
||||||
func (repository Postgres) FindBlockByNumber(blockNumber int64) *core.Block {
|
func (repository Postgres) FindBlockByNumber(blockNumber int64) *core.Block {
|
||||||
blockRows, _ := repository.Db.Query(
|
blockRows, _ := repository.Db.Query(
|
||||||
`SELECT id, block_number, block_gaslimit, block_gasused, block_time, block_difficulty, block_hash, block_nonce, block_parenthash, block_size, uncle_hash FROM blocks`)
|
`SELECT id, block_number, block_gaslimit, block_gasused, block_time, block_difficulty, block_hash, block_nonce, block_parenthash, block_size, uncle_hash
|
||||||
|
FROM blocks
|
||||||
|
WHERE node_id = $1`, repository.nodeId)
|
||||||
var savedBlocks []core.Block
|
var savedBlocks []core.Block
|
||||||
for blockRows.Next() {
|
for blockRows.Next() {
|
||||||
savedBlock := repository.loadBlock(blockRows)
|
savedBlock := repository.loadBlock(blockRows)
|
||||||
@ -116,10 +144,10 @@ func (repository Postgres) CreateBlock(block core.Block) error {
|
|||||||
var blockId int64
|
var blockId int64
|
||||||
err := tx.QueryRow(
|
err := tx.QueryRow(
|
||||||
`INSERT INTO blocks
|
`INSERT INTO blocks
|
||||||
(block_number, block_gaslimit, block_gasused, block_time, block_difficulty, block_hash, block_nonce, block_parenthash, block_size, uncle_hash)
|
(node_id, block_number, block_gaslimit, block_gasused, block_time, block_difficulty, block_hash, block_nonce, block_parenthash, block_size, uncle_hash)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
||||||
RETURNING id `,
|
RETURNING id `,
|
||||||
block.Number, block.GasLimit, block.GasUsed, block.Time, block.Difficulty, block.Hash, block.Nonce, block.ParentHash, block.Size, block.UncleHash).
|
repository.nodeId, block.Number, block.GasLimit, block.GasUsed, block.Time, block.Difficulty, block.Hash, block.Nonce, block.ParentHash, block.Size, block.UncleHash).
|
||||||
Scan(&blockId)
|
Scan(&blockId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tx.Rollback()
|
tx.Rollback()
|
||||||
@ -138,8 +166,8 @@ func (repository Postgres) createTransactions(tx *sql.Tx, blockId int64, transac
|
|||||||
for _, transaction := range transactions {
|
for _, transaction := range transactions {
|
||||||
_, err := tx.Exec(
|
_, err := tx.Exec(
|
||||||
`INSERT INTO transactions
|
`INSERT INTO transactions
|
||||||
(block_id, tx_hash, tx_nonce, tx_to, tx_from, tx_gaslimit, tx_gasprice, tx_value)
|
(block_id, tx_hash, tx_nonce, tx_to, tx_from, tx_gaslimit, tx_gasprice, tx_value)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`,
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`,
|
||||||
blockId, transaction.Hash, transaction.Nonce, transaction.To, transaction.From, transaction.GasLimit, transaction.GasPrice, transaction.Value)
|
blockId, transaction.Hash, transaction.Nonce, transaction.To, transaction.From, transaction.GasLimit, transaction.GasPrice, transaction.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -204,7 +232,7 @@ func (repository Postgres) loadTransactions(transactionRows *sql.Rows) []core.Tr
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (repository Postgres) addTransactions(contract core.Contract) core.Contract {
|
func (repository Postgres) addTransactions(contract core.Contract) core.Contract {
|
||||||
transactionRows, _ := repository.Db.Query(`SELECT tx_hash, tx_nonce, tx_to, tx_from, tx_gaslimit, tx_gasprice, tx_value FROM transactions WHERE tx_to = $1 ORDER BY block_id desc`, contract.Hash)
|
transactionRows, _ := repository.Db.Query(`SELECT tx_hash, tx_nonce, tx_to, tx_from, tx_gaslimit, tx_gasprice, tx_value FROM transactions WHERE tx_to = $1 ORDER BY block_id DESC`, contract.Hash)
|
||||||
transactions := repository.loadTransactions(transactionRows)
|
transactions := repository.loadTransactions(transactionRows)
|
||||||
savedContract := core.Contract{Hash: contract.Hash, Transactions: transactions, Abi: contract.Abi}
|
savedContract := core.Contract{Hash: contract.Hash, Transactions: transactions, Abi: contract.Abi}
|
||||||
return savedContract
|
return savedContract
|
||||||
|
@ -24,9 +24,9 @@ var _ = Describe("Postgres repository", func() {
|
|||||||
Expect(db).ShouldNot(BeNil())
|
Expect(db).ShouldNot(BeNil())
|
||||||
})
|
})
|
||||||
|
|
||||||
testing.AssertRepositoryBehavior(func() repositories.Repository {
|
testing.AssertRepositoryBehavior(func(node core.Node) repositories.Repository {
|
||||||
cfg, _ := config.NewConfig("private")
|
cfg, _ := config.NewConfig("private")
|
||||||
repository, _ := repositories.NewPostgres(cfg.Database)
|
repository, _ := repositories.NewPostgres(cfg.Database, node)
|
||||||
testing.ClearData(repository)
|
testing.ClearData(repository)
|
||||||
return repository
|
return repository
|
||||||
})
|
})
|
||||||
@ -40,7 +40,8 @@ var _ = Describe("Postgres repository", func() {
|
|||||||
Transactions: []core.Transaction{},
|
Transactions: []core.Transaction{},
|
||||||
}
|
}
|
||||||
cfg, _ := config.NewConfig("private")
|
cfg, _ := config.NewConfig("private")
|
||||||
repository, _ := repositories.NewPostgres(cfg.Database)
|
node := core.Node{GenesisBlock: "GENESIS", NetworkId: 1}
|
||||||
|
repository, _ := repositories.NewPostgres(cfg.Database, node)
|
||||||
|
|
||||||
err := repository.CreateBlock(badBlock)
|
err := repository.CreateBlock(badBlock)
|
||||||
savedBlock := repository.FindBlockByNumber(123)
|
savedBlock := repository.FindBlockByNumber(123)
|
||||||
@ -51,10 +52,19 @@ var _ = Describe("Postgres repository", func() {
|
|||||||
|
|
||||||
It("throws error when can't connect to the database", func() {
|
It("throws error when can't connect to the database", func() {
|
||||||
invalidDatabase := config.Database{}
|
invalidDatabase := config.Database{}
|
||||||
_, err := repositories.NewPostgres(invalidDatabase)
|
node := core.Node{GenesisBlock: "GENESIS", NetworkId: 1}
|
||||||
|
_, err := repositories.NewPostgres(invalidDatabase, node)
|
||||||
Expect(err).To(Equal(repositories.ErrDBConnectionFailed))
|
Expect(err).To(Equal(repositories.ErrDBConnectionFailed))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("throws error when can't create node", func() {
|
||||||
|
cfg, _ := config.NewConfig("private")
|
||||||
|
badHash := fmt.Sprintf("x %s", strings.Repeat("1", 100))
|
||||||
|
node := core.Node{GenesisBlock: badHash, NetworkId: 1}
|
||||||
|
_, err := repositories.NewPostgres(cfg.Database, node)
|
||||||
|
Expect(err).To(Equal(repositories.ErrUnableToSetNode))
|
||||||
|
})
|
||||||
|
|
||||||
It("does not commit block or transactions if transaction is invalid", func() {
|
It("does not commit block or transactions if transaction is invalid", func() {
|
||||||
//badHash violates db To field length
|
//badHash violates db To field length
|
||||||
badHash := fmt.Sprintf("x %s", strings.Repeat("1", 100))
|
badHash := fmt.Sprintf("x %s", strings.Repeat("1", 100))
|
||||||
@ -64,7 +74,8 @@ var _ = Describe("Postgres repository", func() {
|
|||||||
Transactions: []core.Transaction{badTransaction},
|
Transactions: []core.Transaction{badTransaction},
|
||||||
}
|
}
|
||||||
cfg, _ := config.NewConfig("private")
|
cfg, _ := config.NewConfig("private")
|
||||||
repository, _ := repositories.NewPostgres(cfg.Database)
|
node := core.Node{GenesisBlock: "GENESIS", NetworkId: 1}
|
||||||
|
repository, _ := repositories.NewPostgres(cfg.Database, node)
|
||||||
|
|
||||||
err := repository.CreateBlock(block)
|
err := repository.CreateBlock(block)
|
||||||
savedBlock := repository.FindBlockByNumber(123)
|
savedBlock := repository.FindBlockByNumber(123)
|
||||||
|
@ -13,11 +13,12 @@ func ClearData(postgres repositories.Postgres) {
|
|||||||
postgres.Db.MustExec("DELETE FROM blocks")
|
postgres.Db.MustExec("DELETE FROM blocks")
|
||||||
}
|
}
|
||||||
|
|
||||||
func AssertRepositoryBehavior(buildRepository func() repositories.Repository) {
|
func AssertRepositoryBehavior(buildRepository func(node core.Node) repositories.Repository) {
|
||||||
var repository repositories.Repository
|
var repository repositories.Repository
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
repository = buildRepository()
|
node := core.Node{GenesisBlock: "GENESIS", NetworkId: 1}
|
||||||
|
repository = buildRepository(node)
|
||||||
})
|
})
|
||||||
|
|
||||||
Describe("Saving blocks", func() {
|
Describe("Saving blocks", func() {
|
||||||
@ -34,6 +35,21 @@ func AssertRepositoryBehavior(buildRepository func() repositories.Repository) {
|
|||||||
Expect(repository.BlockCount()).To(Equal(1))
|
Expect(repository.BlockCount()).To(Equal(1))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("associates blocks to a node", func() {
|
||||||
|
block := core.Block{
|
||||||
|
Number: 123,
|
||||||
|
}
|
||||||
|
repository.CreateBlock(block)
|
||||||
|
nodeTwo := core.Node{
|
||||||
|
GenesisBlock: "0x456",
|
||||||
|
NetworkId: 1,
|
||||||
|
}
|
||||||
|
repositoryTwo := buildRepository(nodeTwo)
|
||||||
|
|
||||||
|
foundBlock := repositoryTwo.FindBlockByNumber(123)
|
||||||
|
Expect(foundBlock).To(BeNil())
|
||||||
|
})
|
||||||
|
|
||||||
It("saves the attributes of the block", func() {
|
It("saves the attributes of the block", func() {
|
||||||
blockNumber := int64(123)
|
blockNumber := int64(123)
|
||||||
gasLimit := int64(1000000)
|
gasLimit := int64(1000000)
|
||||||
|
Loading…
Reference in New Issue
Block a user