forked from cerc-io/ipfs-ethdb
blockservice ethdb tests
This commit is contained in:
parent
09277325ef
commit
8daba4f4fa
13
batch.go
13
batch.go
@ -19,10 +19,12 @@ package ipfsethdb
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/hashicorp/golang-lru"
|
"github.com/hashicorp/golang-lru"
|
||||||
"github.com/ipfs/go-block-format"
|
"github.com/ipfs/go-block-format"
|
||||||
"github.com/ipfs/go-blockservice"
|
"github.com/ipfs/go-blockservice"
|
||||||
|
"github.com/ipfs/go-cid/_rsrch/cidiface"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -64,7 +66,8 @@ func NewBatch(bs blockservice.BlockService, capacity int) (ethdb.Batch, error) {
|
|||||||
// but this adds additional overhead to every Put/Delete
|
// but this adds additional overhead to every Put/Delete
|
||||||
func (b *Batch) Put(key []byte, value []byte) (err error) {
|
func (b *Batch) Put(key []byte, value []byte) (err error) {
|
||||||
b.valueSize += len(value)
|
b.valueSize += len(value)
|
||||||
if b.putCache.Add(key, value) {
|
strKey := common.Bytes2Hex(key)
|
||||||
|
if b.putCache.Add(strKey, value) {
|
||||||
return EvictionWarningErr
|
return EvictionWarningErr
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -73,7 +76,8 @@ func (b *Batch) Put(key []byte, value []byte) (err error) {
|
|||||||
// Delete satisfies the ethdb.Batch interface
|
// Delete satisfies the ethdb.Batch interface
|
||||||
// Delete removes the key from the key-value data store
|
// Delete removes the key from the key-value data store
|
||||||
func (b *Batch) Delete(key []byte) (err error) {
|
func (b *Batch) Delete(key []byte) (err error) {
|
||||||
if b.deleteCache.Add(key, true) {
|
strKey := common.Bytes2Hex(key)
|
||||||
|
if b.deleteCache.Add(strKey, true) {
|
||||||
return EvictionWarningErr
|
return EvictionWarningErr
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -92,7 +96,7 @@ func (b *Batch) Write() error {
|
|||||||
puts := make([]blocks.Block, b.putCache.Len())
|
puts := make([]blocks.Block, b.putCache.Len())
|
||||||
for i, key := range b.putCache.Keys() {
|
for i, key := range b.putCache.Keys() {
|
||||||
val, _ := b.putCache.Get(key) // don't need to check "ok"s, the key is known and val is always []byte
|
val, _ := b.putCache.Get(key) // don't need to check "ok"s, the key is known and val is always []byte
|
||||||
b, err := NewBlock(key.([]byte), val.([]byte))
|
b, err := NewBlock(common.Hex2Bytes(key.(string)), val.([]byte))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -102,7 +106,8 @@ func (b *Batch) Write() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, key := range b.deleteCache.Keys() {
|
for _, key := range b.deleteCache.Keys() {
|
||||||
c, err := Keccak256ToCid(key.([]byte))
|
// we are using state codec because we don't know the codec and at this level the codec doesn't matter, the datastore key is multihash-only derived
|
||||||
|
c, err := Keccak256ToCid(common.Hex2Bytes(key.(string)), cid.EthStateTrie)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
114
batch_test.go
Normal file
114
batch_test.go
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
// VulcanizeDB
|
||||||
|
// Copyright © 2019 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
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package ipfsethdb_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
|
ipfsethdb "github.com/vulcanize/ipfs-ethdb"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
batch ethdb.Batch
|
||||||
|
testHeader2 = types.Header{Number: big.NewInt(2)}
|
||||||
|
testValue2, _ = rlp.EncodeToBytes(testHeader2)
|
||||||
|
testEthKey2 = testHeader2.Hash().Bytes()
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Batch", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
blockService = ipfsethdb.NewMockBlockservice()
|
||||||
|
batch, err = ipfsethdb.NewBatch(blockService, 1024)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
database = ipfsethdb.NewDatabase(blockService)
|
||||||
|
})
|
||||||
|
|
||||||
|
Describe("Put/Write", func() {
|
||||||
|
It("adds the key-value pair to the batch", func() {
|
||||||
|
_, err = database.Get(testEthKey)
|
||||||
|
Expect(err).To(HaveOccurred())
|
||||||
|
Expect(err.Error()).To(ContainSubstring("block not found"))
|
||||||
|
_, err = database.Get(testEthKey2)
|
||||||
|
Expect(err).To(HaveOccurred())
|
||||||
|
Expect(err.Error()).To(ContainSubstring("block not found"))
|
||||||
|
|
||||||
|
err = batch.Put(testEthKey, testValue)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
err = batch.Put(testEthKey2, testValue2)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
err = batch.Write()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
val, err := database.Get(testEthKey)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(val).To(Equal(testValue))
|
||||||
|
val2, err := database.Get(testEthKey2)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(val2).To(Equal(testValue2))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Describe("Delete/Reset/Write", func() {
|
||||||
|
It("deletes the key-value pair in the batch", func() {
|
||||||
|
err = batch.Put(testEthKey, testValue)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
err = batch.Put(testEthKey2, testValue2)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
err = batch.Write()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
batch.Reset()
|
||||||
|
err = batch.Delete(testEthKey)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
err = batch.Delete(testEthKey2)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
err = batch.Write()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
_, err = database.Get(testEthKey)
|
||||||
|
Expect(err).To(HaveOccurred())
|
||||||
|
Expect(err.Error()).To(ContainSubstring("block not found"))
|
||||||
|
_, err = database.Get(testEthKey2)
|
||||||
|
Expect(err).To(HaveOccurred())
|
||||||
|
Expect(err.Error()).To(ContainSubstring("block not found"))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Describe("ValueSize/Reset", func() {
|
||||||
|
It("returns the size of data in the batch queued for write", func() {
|
||||||
|
err = batch.Put(testEthKey, testValue)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
err = batch.Put(testEthKey2, testValue2)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
err = batch.Write()
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
size := batch.ValueSize()
|
||||||
|
Expect(size).To(Equal(len(testValue) + len(testValue2)))
|
||||||
|
|
||||||
|
batch.Reset()
|
||||||
|
size = batch.ValueSize()
|
||||||
|
Expect(size).To(Equal(0))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
@ -20,6 +20,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/ipfs/go-cid/_rsrch/cidiface"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -57,7 +58,8 @@ func NewDatabase(bs blockservice.BlockService) ethdb.Database {
|
|||||||
// Has retrieves if a key is present in the key-value data store
|
// Has retrieves if a key is present in the key-value data store
|
||||||
// This only operates on the local blockstore not through the exchange
|
// This only operates on the local blockstore not through the exchange
|
||||||
func (d *Database) Has(key []byte) (bool, error) {
|
func (d *Database) Has(key []byte) (bool, error) {
|
||||||
c, err := Keccak256ToCid(key) // we are using cidv0 because we don't know the codec and codec doesn't matter, the datastore key is multihash-only derived
|
// we are using state codec because we don't know the codec and at this level the codec doesn't matter, the datastore key is multihash-only derived
|
||||||
|
c, err := Keccak256ToCid(key, cid.EthStateTrie)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@ -67,12 +69,16 @@ func (d *Database) Has(key []byte) (bool, error) {
|
|||||||
// Get satisfies the ethdb.KeyValueReader interface
|
// Get satisfies the ethdb.KeyValueReader interface
|
||||||
// Get retrieves the given key if it's present in the key-value data store
|
// Get retrieves the given key if it's present in the key-value data store
|
||||||
func (d *Database) Get(key []byte) ([]byte, error) {
|
func (d *Database) Get(key []byte) ([]byte, error) {
|
||||||
c, err := Keccak256ToCid(key)
|
// we are using state codec because we don't know the codec and at this level the codec doesn't matter, the datastore key is multihash-only derived
|
||||||
|
c, err := Keccak256ToCid(key, cid.EthStateTrie)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
block, err := d.blockService.GetBlock(context.Background(), c)
|
block, err := d.blockService.GetBlock(context.Background(), c)
|
||||||
return block.RawData(), err
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return block.RawData(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put satisfies the ethdb.KeyValueWriter interface
|
// Put satisfies the ethdb.KeyValueWriter interface
|
||||||
@ -89,7 +95,8 @@ func (d *Database) Put(key []byte, value []byte) error {
|
|||||||
// Delete satisfies the ethdb.KeyValueWriter interface
|
// Delete satisfies the ethdb.KeyValueWriter interface
|
||||||
// Delete removes the key from the key-value data store
|
// Delete removes the key from the key-value data store
|
||||||
func (d *Database) Delete(key []byte) error {
|
func (d *Database) Delete(key []byte) error {
|
||||||
c, err := Keccak256ToCid(key)
|
// we are using state codec because we don't know the codec and at this level the codec doesn't matter, the datastore key is multihash-only derived
|
||||||
|
c, err := Keccak256ToCid(key, cid.EthStateTrie)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
106
database_test.go
Normal file
106
database_test.go
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
// VulcanizeDB
|
||||||
|
// Copyright © 2019 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
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package ipfsethdb_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
"github.com/ipfs/go-blockservice"
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
|
ipfsethdb "github.com/vulcanize/ipfs-ethdb"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
database ethdb.Database
|
||||||
|
blockService blockservice.BlockService
|
||||||
|
err error
|
||||||
|
testHeader = types.Header{Number: big.NewInt(1337)}
|
||||||
|
testValue, _ = rlp.EncodeToBytes(testHeader)
|
||||||
|
testEthKey = testHeader.Hash().Bytes()
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("Database", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
blockService = ipfsethdb.NewMockBlockservice()
|
||||||
|
database = ipfsethdb.NewDatabase(blockService)
|
||||||
|
})
|
||||||
|
|
||||||
|
Describe("Has", func() {
|
||||||
|
It("returns false if a key-pair doesn't exist in the db", func() {
|
||||||
|
has, err := database.Has(testEthKey)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(has).ToNot(BeTrue())
|
||||||
|
})
|
||||||
|
It("returns true if a key-pair exists in the db", func() {
|
||||||
|
err := database.Put(testEthKey, testValue)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
has, err := database.Has(testEthKey)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(has).To(BeTrue())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Describe("Get", func() {
|
||||||
|
It("throws an err if the key-pair doesn't exist in the db", func() {
|
||||||
|
_, err = database.Get(testEthKey)
|
||||||
|
Expect(err).To(HaveOccurred())
|
||||||
|
Expect(err.Error()).To(ContainSubstring("block not found"))
|
||||||
|
})
|
||||||
|
It("returns the value associated with the key, if the pair exists", func() {
|
||||||
|
err := database.Put(testEthKey, testValue)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
val, err := database.Get(testEthKey)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(val).To(Equal(testValue))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Describe("Put", func() {
|
||||||
|
It("persists the key-value pair in the database", func() {
|
||||||
|
_, err = database.Get(testEthKey)
|
||||||
|
Expect(err).To(HaveOccurred())
|
||||||
|
Expect(err.Error()).To(ContainSubstring("block not found"))
|
||||||
|
|
||||||
|
err = database.Put(testEthKey, testValue)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
val, err := database.Get(testEthKey)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(val).To(Equal(testValue))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Describe("Delete", func() {
|
||||||
|
It("removes the key-value pair from the database", func() {
|
||||||
|
err = database.Put(testEthKey, testValue)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
val, err := database.Get(testEthKey)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
Expect(val).To(Equal(testValue))
|
||||||
|
|
||||||
|
err = database.Delete(testEthKey)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
_, err = database.Get(testEthKey)
|
||||||
|
Expect(err).To(HaveOccurred())
|
||||||
|
Expect(err.Error()).To(ContainSubstring("block not found"))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
3
go.mod
3
go.mod
@ -1,4 +1,4 @@
|
|||||||
module github.com/vulcanize/pg-ipfs-ethdb
|
module github.com/vulcanize/ipfs-ethdb
|
||||||
|
|
||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
@ -10,6 +10,7 @@ require (
|
|||||||
github.com/ipfs/go-cid v0.0.5
|
github.com/ipfs/go-cid v0.0.5
|
||||||
github.com/ipfs/go-ipfs-blockstore v1.0.0
|
github.com/ipfs/go-ipfs-blockstore v1.0.0
|
||||||
github.com/ipfs/go-ipfs-ds-help v1.0.0
|
github.com/ipfs/go-ipfs-ds-help v1.0.0
|
||||||
|
github.com/ipfs/go-ipfs-exchange-interface v0.0.1
|
||||||
github.com/jmoiron/sqlx v1.2.0
|
github.com/jmoiron/sqlx v1.2.0
|
||||||
github.com/lib/pq v1.0.0
|
github.com/lib/pq v1.0.0
|
||||||
github.com/multiformats/go-multihash v0.0.13
|
github.com/multiformats/go-multihash v0.0.13
|
||||||
|
6
go.sum
6
go.sum
@ -117,7 +117,6 @@ github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67Fexh
|
|||||||
github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE=
|
github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE=
|
||||||
github.com/ipfs/go-datastore v0.0.5/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE=
|
github.com/ipfs/go-datastore v0.0.5/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE=
|
||||||
github.com/ipfs/go-datastore v0.1.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw=
|
github.com/ipfs/go-datastore v0.1.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw=
|
||||||
github.com/ipfs/go-datastore v0.4.1 h1:W4ZfzyhNi3xmuU5dQhjfuRn/wFuqEE1KnOmmQiOevEY=
|
|
||||||
github.com/ipfs/go-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA=
|
github.com/ipfs/go-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA=
|
||||||
github.com/ipfs/go-datastore v0.4.4 h1:rjvQ9+muFaJ+QZ7dN5B1MSDNQ0JVZKkkES/rMZmA8X8=
|
github.com/ipfs/go-datastore v0.4.4 h1:rjvQ9+muFaJ+QZ7dN5B1MSDNQ0JVZKkkES/rMZmA8X8=
|
||||||
github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA=
|
github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA=
|
||||||
@ -155,7 +154,6 @@ github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH
|
|||||||
github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs=
|
github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs=
|
||||||
github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA=
|
github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA=
|
||||||
github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs=
|
github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs=
|
||||||
github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8 h1:bspPhN+oKYFk5fcGNuQzp6IGzYQSenLEgH3s6jkXrWw=
|
|
||||||
github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY=
|
github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY=
|
||||||
github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10=
|
github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10=
|
||||||
github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4=
|
github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4=
|
||||||
@ -222,14 +220,12 @@ github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw
|
|||||||
github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow=
|
github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow=
|
||||||
github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow=
|
github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow=
|
||||||
github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
|
|
||||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||||
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
|
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
|
||||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
|
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
|
||||||
github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
|
github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
|
||||||
github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw=
|
|
||||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
|
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
|
||||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
@ -275,11 +271,9 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn
|
|||||||
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||||
github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
|
||||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
|
github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
|
||||||
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
|
|
||||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
|
github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
|
||||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
|
@ -18,6 +18,7 @@ package ipfsethdb
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/ipfs/go-cid/_rsrch/cidiface"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ipfs/go-blockservice"
|
"github.com/ipfs/go-blockservice"
|
||||||
@ -72,7 +73,8 @@ func (i *Iterator) Key() []byte {
|
|||||||
// The caller should not modify the contents of the returned slice
|
// The caller should not modify the contents of the returned slice
|
||||||
// and its contents may change on the next call to Next
|
// and its contents may change on the next call to Next
|
||||||
func (i *Iterator) Value() []byte {
|
func (i *Iterator) Value() []byte {
|
||||||
c, err := Keccak256ToCid(i.currentKey)
|
// we are using state codec because we don't know the codec and at this level the codec doesn't matter, the datastore key is multihash-only derived
|
||||||
|
c, err := Keccak256ToCid(i.currentKey, cid.EthStateTrie)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
i.err = err
|
i.err = err
|
||||||
return nil
|
return nil
|
||||||
|
@ -19,8 +19,6 @@ package pgipfsethdb
|
|||||||
import (
|
import (
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
|
|
||||||
"github.com/vulcanize/pg-ipfs-ethdb"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Batch is the type that satisfies the ethdb.Batch interface for PG-IPFS Ethereum data using a direct Postgres connection
|
// Batch is the type that satisfies the ethdb.Batch interface for PG-IPFS Ethereum data using a direct Postgres connection
|
||||||
@ -31,20 +29,23 @@ type Batch struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewBatch returns a ethdb.Batch interface for PG-IPFS
|
// NewBatch returns a ethdb.Batch interface for PG-IPFS
|
||||||
func NewBatch(db *sqlx.DB) ethdb.Batch {
|
//
|
||||||
return &Batch{
|
func NewBatch(db *sqlx.DB, tx *sqlx.Tx) ethdb.Batch {
|
||||||
|
b := &Batch{
|
||||||
db: db,
|
db: db,
|
||||||
|
tx: tx,
|
||||||
}
|
}
|
||||||
|
if tx == nil {
|
||||||
|
b.Reset()
|
||||||
|
}
|
||||||
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put satisfies the ethdb.Batch interface
|
// Put satisfies the ethdb.Batch interface
|
||||||
// Put inserts the given value into the key-value data store
|
// Put inserts the given value into the key-value data store
|
||||||
// Key is expected to be the keccak256 hash of value
|
// Key is expected to be the keccak256 hash of value
|
||||||
func (b *Batch) Put(key []byte, value []byte) (err error) {
|
func (b *Batch) Put(key []byte, value []byte) (err error) {
|
||||||
if b.tx == nil {
|
mhKey, err := MultihashKeyFromKeccak256(key)
|
||||||
b.Reset()
|
|
||||||
}
|
|
||||||
mhKey, err := ipfsethdb.MultihashKeyFromKeccak256(key)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -58,10 +59,7 @@ func (b *Batch) Put(key []byte, value []byte) (err error) {
|
|||||||
// Delete satisfies the ethdb.Batch interface
|
// Delete satisfies the ethdb.Batch interface
|
||||||
// Delete removes the key from the key-value data store
|
// Delete removes the key from the key-value data store
|
||||||
func (b *Batch) Delete(key []byte) (err error) {
|
func (b *Batch) Delete(key []byte) (err error) {
|
||||||
if b.tx == nil {
|
mhKey, err := MultihashKeyFromKeccak256(key)
|
||||||
b.Reset()
|
|
||||||
}
|
|
||||||
mhKey, err := ipfsethdb.MultihashKeyFromKeccak256(key)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,7 @@ import (
|
|||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/vulcanize/pg-ipfs-ethdb"
|
pgipfsethdb "github.com/vulcanize/ipfs-ethdb/postgres"
|
||||||
"github.com/vulcanize/pg-ipfs-ethdb/postgres"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -38,13 +37,13 @@ var (
|
|||||||
|
|
||||||
var _ = Describe("Batch", func() {
|
var _ = Describe("Batch", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
db, err = ipfsethdb.TestDB()
|
db, err = pgipfsethdb.TestDB()
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
database = pgipfsethdb.NewDatabase(db)
|
database = pgipfsethdb.NewDatabase(db)
|
||||||
batch = database.NewBatch()
|
batch = database.NewBatch()
|
||||||
})
|
})
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
err = ipfsethdb.ResetTestDB(db)
|
err = pgipfsethdb.ResetTestDB(db)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -75,7 +74,6 @@ var _ = Describe("Batch", func() {
|
|||||||
|
|
||||||
Describe("Delete/Reset/Write", func() {
|
Describe("Delete/Reset/Write", func() {
|
||||||
It("deletes the key-value pair in the batch", func() {
|
It("deletes the key-value pair in the batch", func() {
|
||||||
_, err = db.Exec("INSERT into public.blocks (key, data) VALUES ($1, $2)", testMhKey, testValue)
|
|
||||||
err = batch.Put(testEthKey, testValue)
|
err = batch.Put(testEthKey, testValue)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
err = batch.Put(testEthKey2, testValue2)
|
err = batch.Put(testEthKey2, testValue2)
|
||||||
|
@ -23,8 +23,6 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
|
|
||||||
"github.com/vulcanize/pg-ipfs-ethdb"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var errNotSupported = errors.New("this operation is not supported")
|
var errNotSupported = errors.New("this operation is not supported")
|
||||||
@ -59,7 +57,7 @@ func NewDatabase(db *sqlx.DB) ethdb.Database {
|
|||||||
// Has satisfies the ethdb.KeyValueReader interface
|
// Has satisfies the ethdb.KeyValueReader interface
|
||||||
// Has retrieves if a key is present in the key-value data store
|
// Has retrieves if a key is present in the key-value data store
|
||||||
func (d *Database) Has(key []byte) (bool, error) {
|
func (d *Database) Has(key []byte) (bool, error) {
|
||||||
mhKey, err := ipfsethdb.MultihashKeyFromKeccak256(key)
|
mhKey, err := MultihashKeyFromKeccak256(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@ -70,7 +68,7 @@ func (d *Database) Has(key []byte) (bool, error) {
|
|||||||
// Get satisfies the ethdb.KeyValueReader interface
|
// Get satisfies the ethdb.KeyValueReader interface
|
||||||
// Get retrieves the given key if it's present in the key-value data store
|
// Get retrieves the given key if it's present in the key-value data store
|
||||||
func (d *Database) Get(key []byte) ([]byte, error) {
|
func (d *Database) Get(key []byte) ([]byte, error) {
|
||||||
mhKey, err := ipfsethdb.MultihashKeyFromKeccak256(key)
|
mhKey, err := MultihashKeyFromKeccak256(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -82,7 +80,7 @@ func (d *Database) Get(key []byte) ([]byte, error) {
|
|||||||
// Put inserts the given value into the key-value data store
|
// Put inserts the given value into the key-value data store
|
||||||
// Key is expected to be the keccak256 hash of value
|
// Key is expected to be the keccak256 hash of value
|
||||||
func (d *Database) Put(key []byte, value []byte) error {
|
func (d *Database) Put(key []byte, value []byte) error {
|
||||||
mhKey, err := ipfsethdb.MultihashKeyFromKeccak256(key)
|
mhKey, err := MultihashKeyFromKeccak256(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -93,7 +91,7 @@ func (d *Database) Put(key []byte, value []byte) error {
|
|||||||
// Delete satisfies the ethdb.KeyValueWriter interface
|
// Delete satisfies the ethdb.KeyValueWriter interface
|
||||||
// Delete removes the key from the key-value data store
|
// Delete removes the key from the key-value data store
|
||||||
func (d *Database) Delete(key []byte) error {
|
func (d *Database) Delete(key []byte) error {
|
||||||
mhKey, err := ipfsethdb.MultihashKeyFromKeccak256(key)
|
mhKey, err := MultihashKeyFromKeccak256(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -26,8 +26,7 @@ import (
|
|||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
|
||||||
"github.com/vulcanize/pg-ipfs-ethdb"
|
pgipfsethdb "github.com/vulcanize/ipfs-ethdb/postgres"
|
||||||
"github.com/vulcanize/pg-ipfs-ethdb/postgres"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -37,17 +36,17 @@ var (
|
|||||||
testHeader = types.Header{Number: big.NewInt(1337)}
|
testHeader = types.Header{Number: big.NewInt(1337)}
|
||||||
testValue, _ = rlp.EncodeToBytes(testHeader)
|
testValue, _ = rlp.EncodeToBytes(testHeader)
|
||||||
testEthKey = testHeader.Hash().Bytes()
|
testEthKey = testHeader.Hash().Bytes()
|
||||||
testMhKey, _ = ipfsethdb.MultihashKeyFromKeccak256(testEthKey)
|
testMhKey, _ = pgipfsethdb.MultihashKeyFromKeccak256(testEthKey)
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("Database", func() {
|
var _ = Describe("Database", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
db, err = ipfsethdb.TestDB()
|
db, err = pgipfsethdb.TestDB()
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
database = pgipfsethdb.NewDatabase(db)
|
database = pgipfsethdb.NewDatabase(db)
|
||||||
})
|
})
|
||||||
AfterEach(func() {
|
AfterEach(func() {
|
||||||
err = ipfsethdb.ResetTestDB(db)
|
err = pgipfsethdb.ResetTestDB(db)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -19,8 +19,6 @@ package pgipfsethdb
|
|||||||
import (
|
import (
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
|
|
||||||
"github.com/vulcanize/pg-ipfs-ethdb"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Iterator is the type that satisfies the ethdb.Iterator interface for PG-IPFS Ethereum data using a direct Postgres connection
|
// Iterator is the type that satisfies the ethdb.Iterator interface for PG-IPFS Ethereum data using a direct Postgres connection
|
||||||
@ -72,7 +70,7 @@ func (i *Iterator) Key() []byte {
|
|||||||
// The caller should not modify the contents of the returned slice
|
// The caller should not modify the contents of the returned slice
|
||||||
// and its contents may change on the next call to Next
|
// and its contents may change on the next call to Next
|
||||||
func (i *Iterator) Value() []byte {
|
func (i *Iterator) Value() []byte {
|
||||||
mhKey, err := ipfsethdb.MultihashKeyFromKeccak256(i.currentKey)
|
mhKey, err := MultihashKeyFromKeccak256(i.currentKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
i.err = err
|
i.err = err
|
||||||
return nil
|
return nil
|
||||||
|
49
postgres/util.go
Normal file
49
postgres/util.go
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// VulcanizeDB
|
||||||
|
// Copyright © 2019 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
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package pgipfsethdb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ipfs/go-ipfs-blockstore"
|
||||||
|
"github.com/ipfs/go-ipfs-ds-help"
|
||||||
|
"github.com/jmoiron/sqlx"
|
||||||
|
_ "github.com/lib/pq" //postgres driver
|
||||||
|
"github.com/multiformats/go-multihash"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MultihashKeyFromKeccak256 converts keccak256 hash bytes into a blockstore-prefixed multihash db key string
|
||||||
|
func MultihashKeyFromKeccak256(h []byte) (string, error) {
|
||||||
|
mh, err := multihash.Encode(h, multihash.KECCAK_256)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
dbKey := dshelp.MultihashToDsKey(mh)
|
||||||
|
return blockstore.BlockPrefix.String() + dbKey.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestDB connect to the testing database
|
||||||
|
// it assumes the database has the IPFS public.blocks table present
|
||||||
|
// DO NOT use a production db for the test db, as it will remove all contents of the public.blocks table
|
||||||
|
func TestDB() (*sqlx.DB, error) {
|
||||||
|
connectStr := "postgresql://localhost:5432/vulcanize_testing?sslmode=disable"
|
||||||
|
return sqlx.Connect("postgres", connectStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetTestDB drops all rows in the test db public.blocks table
|
||||||
|
func ResetTestDB(db *sqlx.DB) error {
|
||||||
|
_, err := db.Exec("TRUNCATE public.blocks")
|
||||||
|
return err
|
||||||
|
}
|
29
suite_test.go
Normal file
29
suite_test.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// VulcanizeDB
|
||||||
|
// 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
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package ipfsethdb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestIPFSETHDB(t *testing.T) {
|
||||||
|
RegisterFailHandler(Fail)
|
||||||
|
RunSpecs(t, "IPFS ethdb test")
|
||||||
|
}
|
36
util.go
36
util.go
@ -19,49 +19,23 @@ package ipfsethdb
|
|||||||
import (
|
import (
|
||||||
"github.com/ipfs/go-block-format"
|
"github.com/ipfs/go-block-format"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/ipfs/go-ipfs-blockstore"
|
|
||||||
"github.com/ipfs/go-ipfs-ds-help"
|
|
||||||
"github.com/jmoiron/sqlx"
|
|
||||||
_ "github.com/lib/pq" //postgres driver
|
_ "github.com/lib/pq" //postgres driver
|
||||||
"github.com/multiformats/go-multihash"
|
"github.com/multiformats/go-multihash"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MultihashKeyFromKeccak256 converts keccak256 hash bytes into a blockstore-prefixed multihash db key string
|
// Keccak256ToCid takes a keccak256 hash and returns its cid v1 using the provided codec.
|
||||||
func MultihashKeyFromKeccak256(h []byte) (string, error) {
|
func Keccak256ToCid(h []byte, codec uint64) (cid.Cid, error) {
|
||||||
mh, err := multihash.Encode(h, multihash.KECCAK_256)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
dbKey := dshelp.MultihashToDsKey(mh)
|
|
||||||
return blockstore.BlockPrefix.String() + dbKey.String(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestDB connect to the testing database
|
|
||||||
// it assumes the database has the IPFS public.blocks table present
|
|
||||||
// DO NOT use a production db for the test db, as it will remove all contents of the public.blocks table
|
|
||||||
func TestDB() (*sqlx.DB, error) {
|
|
||||||
connectStr := "postgresql://localhost:5432/vulcanize_testing?sslmode=disable"
|
|
||||||
return sqlx.Connect("postgres", connectStr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResetTestDB drops all rows in the test db public.blocks table
|
|
||||||
func ResetTestDB(db *sqlx.DB) error {
|
|
||||||
_, err := db.Exec("TRUNCATE public.blocks")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keccak256ToCid takes a keccak256 hash and returns its cid v0 using the provided codec.
|
|
||||||
func Keccak256ToCid(h []byte) (cid.Cid, error) {
|
|
||||||
buf, err := multihash.Encode(h, multihash.KECCAK_256)
|
buf, err := multihash.Encode(h, multihash.KECCAK_256)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cid.Cid{}, err
|
return cid.Cid{}, err
|
||||||
}
|
}
|
||||||
return cid.NewCidV0(multihash.Multihash(buf)), nil
|
return cid.NewCidV1(codec ,multihash.Multihash(buf)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBlock takes a keccak256 hash key and the rlp []byte value it was derived from and creates an ipfs block object
|
// NewBlock takes a keccak256 hash key and the rlp []byte value it was derived from and creates an ipfs block object
|
||||||
func NewBlock(key, value []byte) (blocks.Block, error) {
|
func NewBlock(key, value []byte) (blocks.Block, error) {
|
||||||
c, err := Keccak256ToCid(key) // we are using cidv0 because we don't know the codec and codec doesn't matter, the datastore key is multihash-only derived
|
// we are using state codec because we don't know the codec and at this level the codec doesn't matter, the datastore key is multihash-only derived
|
||||||
|
c, err := Keccak256ToCid(key, cid.EthStateTrie)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user