diff --git a/README.md b/README.md index 952c22c..fcce144 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Ancient interfaces are used for Ancient/frozen data operations (e.g. rawdb/table Outside of these primarily auxiliary capabilities, this package satisfies the interfaces required for many state operations using Ethereum data on IPFS. e.g. - + go-ethereum trie.NodeIterator and state.NodeIterator can be constructed from the ethdb.KeyValueStore and ethdb.Database interfaces, respectively: ```go @@ -42,7 +42,7 @@ package main import ( "context" - + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/trie" @@ -50,7 +50,7 @@ import ( "github.com/ipfs/go-ipfs/core" "github.com/ipfs/go-ipfs/repo/fsrepo" "github.com/jmoiron/sqlx" - "github.com/vulcanize/ipfs-ethdb" + "github.com/vulcanize/ipfs-ethdb/v4" ) func main() { diff --git a/batch_test.go b/batch_test.go index 259fc46..7f296dc 100644 --- a/batch_test.go +++ b/batch_test.go @@ -25,7 +25,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - ipfsethdb "github.com/vulcanize/ipfs-ethdb/v3" + ipfsethdb "github.com/vulcanize/ipfs-ethdb/v4" ) var ( diff --git a/database_test.go b/database_test.go index b3b8518..28c340f 100644 --- a/database_test.go +++ b/database_test.go @@ -26,7 +26,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - ipfsethdb "github.com/vulcanize/ipfs-ethdb/v3" + ipfsethdb "github.com/vulcanize/ipfs-ethdb/v4" ) var ( diff --git a/go.mod b/go.mod index 00843b0..1b97146 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/vulcanize/ipfs-ethdb/v3 +module github.com/vulcanize/ipfs-ethdb/v4 go 1.15 diff --git a/postgres/batch.go b/postgres/batch.go index 1ceeaf8..0099567 100644 --- a/postgres/batch.go +++ b/postgres/batch.go @@ -17,6 +17,8 @@ package pgipfsethdb import ( + "math/big" + "github.com/ethereum/go-ethereum/ethdb" "github.com/jmoiron/sqlx" ) @@ -28,13 +30,16 @@ type Batch struct { db *sqlx.DB tx *sqlx.Tx valueSize int + + blockNumber *big.Int } // NewBatch returns a ethdb.Batch interface for PG-IPFS -func NewBatch(db *sqlx.DB, tx *sqlx.Tx) ethdb.Batch { +func NewBatch(db *sqlx.DB, tx *sqlx.Tx, blockNumber *big.Int) ethdb.Batch { b := &Batch{ - db: db, - tx: tx, + db: db, + tx: tx, + blockNumber: blockNumber, } if tx == nil { b.Reset() @@ -50,7 +55,7 @@ func (b *Batch) Put(key []byte, value []byte) (err error) { if err != nil { return err } - if _, err = b.tx.Exec(putPgStr, mhKey, value); err != nil { + if _, err = b.tx.Exec(putPgStr, mhKey, value, b.blockNumber.Uint64()); err != nil { return err } b.valueSize += len(value) diff --git a/postgres/batch_test.go b/postgres/batch_test.go index 199a183..e5ede9e 100644 --- a/postgres/batch_test.go +++ b/postgres/batch_test.go @@ -27,7 +27,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - pgipfsethdb "github.com/vulcanize/ipfs-ethdb/v3/postgres" + pgipfsethdb "github.com/vulcanize/ipfs-ethdb/v4/postgres" ) var ( @@ -49,6 +49,11 @@ var _ = Describe("Batch", func() { } database = pgipfsethdb.NewDatabase(db, cacheConfig) + + databaseWithBlock, ok := database.(*pgipfsethdb.Database) + Expect(ok).To(BeTrue()) + (*databaseWithBlock).BlockNumber = testBlockNumber + batch = database.NewBatch() }) AfterEach(func() { diff --git a/postgres/database.go b/postgres/database.go index a064961..321337f 100644 --- a/postgres/database.go +++ b/postgres/database.go @@ -20,6 +20,7 @@ import ( "context" "errors" "fmt" + "math/big" "strconv" "strings" "time" @@ -32,9 +33,9 @@ import ( var errNotSupported = errors.New("this operation is not supported") var ( - hasPgStr = "SELECT exists(select 1 from public.blocks WHERE key = $1)" - getPgStr = "SELECT data FROM public.blocks WHERE key = $1" - putPgStr = "INSERT INTO public.blocks (key, data) VALUES ($1, $2) ON CONFLICT (key) DO NOTHING" + hasPgStr = "SELECT exists(select 1 from public.blocks WHERE key = $1 LIMIT 1)" + getPgStr = "SELECT data FROM public.blocks WHERE key = $1 LIMIT 1" + putPgStr = "INSERT INTO public.blocks (key, data, block_number) VALUES ($1, $2, $3) ON CONFLICT DO NOTHING" deletePgStr = "DELETE FROM public.blocks WHERE key = $1" dbSizePgStr = "SELECT pg_database_size(current_database())" ) @@ -45,6 +46,8 @@ var _ ethdb.Database = &Database{} type Database struct { db *sqlx.DB cache *groupcache.Group + + BlockNumber *big.Int } func (d *Database) ModifyAncients(f func(ethdb.AncientWriteOp) error) (int64, error) { @@ -136,7 +139,7 @@ func (d *Database) Put(key []byte, value []byte) error { if err != nil { return err } - _, err = d.db.Exec(putPgStr, mhKey, value) + _, err = d.db.Exec(putPgStr, mhKey, value, d.BlockNumber.Uint64()) return err } @@ -245,13 +248,13 @@ func (d *Database) Compact(start []byte, limit []byte) error { // NewBatch creates a write-only database that buffers changes to its host db // until a final write is called func (d *Database) NewBatch() ethdb.Batch { - return NewBatch(d.db, nil) + return NewBatch(d.db, nil, d.BlockNumber) } // NewBatchWithSize satisfies the ethdb.Batcher interface. // NewBatchWithSize creates a write-only database batch with pre-allocated buffer. func (d *Database) NewBatchWithSize(size int) ethdb.Batch { - return NewBatch(d.db, nil) + return NewBatch(d.db, nil, d.BlockNumber) } // NewIterator satisfies the ethdb.Iteratee interface diff --git a/postgres/database_test.go b/postgres/database_test.go index 3ce5072..a1d9b2b 100644 --- a/postgres/database_test.go +++ b/postgres/database_test.go @@ -28,17 +28,18 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - pgipfsethdb "github.com/vulcanize/ipfs-ethdb/v3/postgres" + pgipfsethdb "github.com/vulcanize/ipfs-ethdb/v4/postgres" ) var ( - database ethdb.Database - db *sqlx.DB - err error - testHeader = types.Header{Number: big.NewInt(1337)} - testValue, _ = rlp.EncodeToBytes(testHeader) - testEthKey = testHeader.Hash().Bytes() - testMhKey, _ = pgipfsethdb.MultihashKeyFromKeccak256(testEthKey) + database ethdb.Database + db *sqlx.DB + err error + testBlockNumber = big.NewInt(1337) + testHeader = types.Header{Number: testBlockNumber} + testValue, _ = rlp.EncodeToBytes(testHeader) + testEthKey = testHeader.Hash().Bytes() + testMhKey, _ = pgipfsethdb.MultihashKeyFromKeccak256(testEthKey) ) var _ = Describe("Database", func() { @@ -53,6 +54,10 @@ var _ = Describe("Database", func() { } database = pgipfsethdb.NewDatabase(db, cacheConfig) + + databaseWithBlock, ok := database.(*pgipfsethdb.Database) + Expect(ok).To(BeTrue()) + (*databaseWithBlock).BlockNumber = testBlockNumber }) AfterEach(func() { groupcache.DeregisterGroup("db") @@ -67,7 +72,7 @@ var _ = Describe("Database", func() { Expect(has).ToNot(BeTrue()) }) It("returns true if a key-pair exists in the db", func() { - _, err = db.Exec("INSERT into public.blocks (key, data) VALUES ($1, $2)", testMhKey, testValue) + _, err = db.Exec("INSERT into public.blocks (key, data, block_number) VALUES ($1, $2, $3)", testMhKey, testValue, testBlockNumber.Uint64()) Expect(err).ToNot(HaveOccurred()) has, err := database.Has(testEthKey) Expect(err).ToNot(HaveOccurred()) @@ -82,7 +87,7 @@ var _ = Describe("Database", func() { Expect(err.Error()).To(ContainSubstring("sql: no rows in result set")) }) It("returns the value associated with the key, if the pair exists", func() { - _, err = db.Exec("INSERT into public.blocks (key, data) VALUES ($1, $2)", testMhKey, testValue) + _, err = db.Exec("INSERT into public.blocks (key, data, block_number) VALUES ($1, $2, $3)", testMhKey, testValue, testBlockNumber.Uint64()) Expect(err).ToNot(HaveOccurred()) val, err := database.Get(testEthKey) Expect(err).ToNot(HaveOccurred()) diff --git a/postgres/doc.md b/postgres/doc.md index cf68683..a9c6d9d 100644 --- a/postgres/doc.md +++ b/postgres/doc.md @@ -18,7 +18,7 @@ import ( "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/trie" "github.com/jmoiron/sqlx" - "github.com/vulcanize/ipfs-ethdb/v3/postgres" + "github.com/vulcanize/ipfs-ethdb/v4/postgres" ) func main() {