ipfs blockservice based validator

This commit is contained in:
Ian Norden
2020-07-12 23:16:16 -05:00
parent cad3bb3fb6
commit 4f089a7a1a
9 changed files with 797 additions and 40 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
// VulcanizeDB
// Copyright © 2019 Vulcanize
// Copyright © 2020 Vulcanize
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
+29
View File
@@ -17,9 +17,14 @@
package validator
import (
"context"
"github.com/ipfs/go-blockservice"
"github.com/ipfs/go-cid"
"github.com/ipfs/go-ipfs-blockstore"
"github.com/ipfs/go-ipfs-ds-help"
"github.com/ipfs/go-ipfs/core"
"github.com/ipfs/go-ipfs/repo/fsrepo"
"github.com/jmoiron/sqlx"
)
@@ -49,3 +54,27 @@ func RawdataToCid(codec uint64, rawdata []byte, multiHash uint64) (cid.Cid, erro
}
return c, nil
}
// InitIPFSBlockService is used to configure and return a BlockService using an ipfs repo path (e.g. ~/.ipfs)
func InitIPFSBlockService(ipfsPath string) (blockservice.BlockService, error) {
r, openErr := fsrepo.Open(ipfsPath)
if openErr != nil {
return nil, openErr
}
ctx := context.Background()
cfg := &core.BuildCfg{
Online: false,
Repo: r,
}
ipfsNode, newNodeErr := core.NewNode(ctx, cfg)
if newNodeErr != nil {
return nil, newNodeErr
}
return ipfsNode.Blocks, nil
}
// ResetTestDB drops all rows in the test db public.blocks table
func ResetTestDB(db *sqlx.DB) error {
_, err := db.Exec("DELETE FROM public.blocks")
return err
}
+26 -4
View File
@@ -24,9 +24,11 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/trie"
"github.com/ipfs/go-blockservice"
"github.com/jmoiron/sqlx"
pgipfsethdb "github.com/vulcanize/pg-ipfs-ethdb/postgres"
"github.com/vulcanize/ipfs-ethdb"
"github.com/vulcanize/ipfs-ethdb/postgres"
)
// Validator is used for validating Ethereum state and storage tries on PG-IPFS
@@ -36,12 +38,32 @@ type Validator struct {
stateDatabase state.Database
}
// NewPGIPFSValidator returns a new trie validator ontop of a connection pool for an IPFS backing Postgres database
func NewPGIPFSValidator(db *sqlx.DB) *Validator {
kvs := pgipfsethdb.NewKeyValueStore(db)
database := pgipfsethdb.NewDatabase(db)
return &Validator{
kvs: kvs,
trieDB: trie.NewDatabase(kvs),
stateDatabase: state.NewDatabase(database),
}
}
// NewIPFSValidator returns a new trie validator ontop of an IPFS blockservice
func NewIPFSValidator(bs blockservice.BlockService) *Validator {
kvs := ipfsethdb.NewKeyValueStore(bs)
database := ipfsethdb.NewDatabase(bs)
return &Validator{
kvs: kvs,
trieDB: trie.NewDatabase(kvs),
stateDatabase: state.NewDatabase(database),
}
}
// NewValidator returns a new trie validator
// Validating the completeness of a modified merkle patricia tries requires traversing the entire trie and verifying that
// every node is present, this is an expensive operation
func NewValidator(db *sqlx.DB) *Validator {
kvs := pgipfsethdb.NewKeyValueStore(db)
database := pgipfsethdb.NewDatabase(db)
func NewValidator(kvs ethdb.KeyValueStore, database ethdb.Database) *Validator {
return &Validator{
kvs: kvs,
trieDB: trie.NewDatabase(kvs),
+15 -8
View File
@@ -30,7 +30,7 @@ import (
. "github.com/onsi/gomega"
"github.com/vulcanize/eth-ipfs-state-validator/pkg"
"github.com/vulcanize/pg-ipfs-ethdb/postgres"
"github.com/vulcanize/ipfs-ethdb/postgres"
)
var (
@@ -192,18 +192,17 @@ var (
err error
)
var _ = Describe("Validator", func() {
var _ = Describe("PG-IPFS Validator", func() {
BeforeEach(func() {
db, err = pgipfsethdb.TestDB()
Expect(err).ToNot(HaveOccurred())
v = validator.NewValidator(db)
v = validator.NewPGIPFSValidator(db)
})
AfterEach(func() {
err = pgipfsethdb.ResetTestDB(db)
Expect(err).ToNot(HaveOccurred())
})
Describe("ValidateTrie", func() {
AfterEach(func() {
err = validator.ResetTestDB(db)
Expect(err).ToNot(HaveOccurred())
})
It("Returns an error the state root node is missing", func() {
loadTrie(missingRootStateNodes, trieStorageNodes)
err = v.ValidateTrie(stateRoot)
@@ -236,6 +235,10 @@ var _ = Describe("Validator", func() {
})
Describe("ValidateStateTrie", func() {
AfterEach(func() {
err = validator.ResetTestDB(db)
Expect(err).ToNot(HaveOccurred())
})
It("Returns an error the state root node is missing", func() {
loadTrie(missingRootStateNodes, nil)
err = v.ValidateStateTrie(stateRoot)
@@ -256,6 +259,10 @@ var _ = Describe("Validator", func() {
})
Describe("ValidateStorageTrie", func() {
AfterEach(func() {
err = validator.ResetTestDB(db)
Expect(err).ToNot(HaveOccurred())
})
It("Returns an error the storage root node is missing", func() {
loadTrie(nil, missingRootStorageNodes)
err = v.ValidateStorageTrie(contractAddr, storageRoot)