From 2ef71da720c1f29869b79980b114c857f0d5dd21 Mon Sep 17 00:00:00 2001 From: turtlebasket Date: Mon, 29 Aug 2022 00:42:43 +0000 Subject: [PATCH] WIP memdb system --- go.mod | 5 +- go.sum | 9 ++- x/cosmostest/memdb/README.md | 18 +++++ x/cosmostest/memdb/biddb.go | 126 +++++++++++++++++++++++++++++++ x/cosmostest/memdb/biddb_test.go | 31 ++++++++ 5 files changed, 187 insertions(+), 2 deletions(-) create mode 100644 x/cosmostest/memdb/README.md create mode 100644 x/cosmostest/memdb/biddb.go create mode 100644 x/cosmostest/memdb/biddb_test.go diff --git a/go.mod b/go.mod index 2fc1a6f..a14e2a3 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.18 require ( github.com/cosmos/cosmos-sdk v0.45.5 github.com/cosmos/ibc-go/v3 v3.0.1 + github.com/dgraph-io/badger/v3 v3.2103.2 github.com/gogo/protobuf v1.3.3 github.com/golang/protobuf v1.5.2 github.com/gorilla/mux v1.8.0 @@ -54,7 +55,7 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/dgraph-io/badger/v2 v2.2007.2 // indirect - github.com/dgraph-io/ristretto v0.0.3 // indirect + github.com/dgraph-io/ristretto v0.1.0 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/docker/docker v20.10.7+incompatible // indirect github.com/docker/go-units v0.4.0 // indirect @@ -75,9 +76,11 @@ require ( github.com/goccy/go-yaml v1.9.4 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gogo/gateway v1.1.0 // indirect + github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/snappy v0.0.3 // indirect github.com/google/btree v1.0.0 // indirect + github.com/google/flatbuffers v1.12.1 // indirect github.com/google/orderedcode v0.0.1 // indirect github.com/gookit/color v1.5.0 // indirect github.com/gorilla/handlers v1.5.1 // indirect diff --git a/go.sum b/go.sum index 91a334c..e8dc1a2 100644 --- a/go.sum +++ b/go.sum @@ -423,9 +423,12 @@ github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= github.com/dgraph-io/badger/v2 v2.2007.2 h1:EjjK0KqwaFMlPin1ajhP943VPENHJdEz1KLIegjaI3k= github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= +github.com/dgraph-io/badger/v3 v3.2103.2 h1:dpyM5eCJAtQCBcMCZcT4UBZchuTJgCywerHHgmxfxM8= +github.com/dgraph-io/badger/v3 v3.2103.2/go.mod h1:RHo4/GmYcKKh5Lxu63wLEMHJ70Pac2JqZRYGhlyAo2M= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgraph-io/ristretto v0.0.3 h1:jh22xisGBjrEVnRZ1DVTpBVQm0Xndu8sMl0CWDzSIBI= github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= +github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= @@ -599,6 +602,7 @@ github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzw github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188/go.mod h1:vXjM/+wXQnTPR4KqTKDgJukSZ6amVRtWMPEjE6sQoK8= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -643,6 +647,8 @@ github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= +github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -863,6 +869,7 @@ github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= diff --git a/x/cosmostest/memdb/README.md b/x/cosmostest/memdb/README.md new file mode 100644 index 0000000..365ee0d --- /dev/null +++ b/x/cosmostest/memdb/README.md @@ -0,0 +1,18 @@ +# MemDB + +## Bidding Flow + +```mermaid +flowchart + +s[Submit Bid] --> rdb{{Read MemBids}} --> h{Is Highest Bid?} + +h -- Yes --> m{{Add to MemBids}} +h -- No --> re1[[Error]] + +m -- Every Block --> ae{Auction expired?} +ae -- Yes --> fh{{Find Highest Bid}} +ae -- No --> ca{{Check again}} -- Next block --> ae + +fh -- Settle --> scs[(Chain State)] +``` diff --git a/x/cosmostest/memdb/biddb.go b/x/cosmostest/memdb/biddb.go new file mode 100644 index 0000000..ba482b7 --- /dev/null +++ b/x/cosmostest/memdb/biddb.go @@ -0,0 +1,126 @@ +package memdb + +import ( + "bytes" + "cosmos-test/x/cosmostest/types" + "encoding/gob" + "log" + "math/big" + + "github.com/dgraph-io/badger/v3" +) + +type bidDB struct { + db *badger.DB +} + +var BidDB bidDB + +// Mount Db & initialize encoder/decoder +func (b *bidDB) Mount() { + db, err := badger.Open(badger.DefaultOptions("").WithInMemory(true)) + if err != nil { + // must force crash here, since db is absolutely required + log.Fatalf("Failed to mount in-memory db: %s", err) + } + b.db = db + + // initialize encode/decode stuff + gob.Register([]types.Bid{}) +} + +// Add a bid to the bid list under specified auction key. +func (b *bidDB) AddBid(auctionId string, bid *types.Bid) error { + buf := bytes.NewBuffer([]byte{}) + enc := gob.NewEncoder(buf) + dec := gob.NewDecoder(buf) + k := []byte(auctionId) + + err := b.db.Update(func(txn *badger.Txn) error { + var bids []*types.Bid + bidsOld, err := txn.Get(k) + if err == badger.ErrKeyNotFound { + // key not found -> just create a new Bid array + bids = []*types.Bid{} + } else { + if err != nil { + return err + } + // key found -> decode contents to bids + bidsOld.Value(func(val []byte) error { + buf.Reset() + if _, err := buf.Read(val); err != nil { + return err + } + if err := dec.Decode(&bids); err != nil { + return err + } + return nil + }) + } + + // append bid + bids = append(bids, bid) + // encode new list + buf.Reset() + if err := enc.Encode(&bids); err != nil { + return err + } + // set under auction key in db + if err := txn.Set(k, buf.Bytes()); err != nil { + return err + } + + return nil + }) + + return err +} + +// Get the highest bid in the list under specified auction key. +func (b *bidDB) GetHighestBid(auctionId string) (*types.Bid, error) { + k := []byte(auctionId) + buf := bytes.NewBuffer([]byte{}) + dec := gob.NewDecoder(buf) + + var bid *types.Bid + + err := b.db.View(func(txn *badger.Txn) error { + bidData, err := txn.Get(k) + if err != nil { + return err + } + + err = bidData.Value(func(val []byte) error { + buf.Reset() + if _, err := buf.Read(val); err != nil { + return err + } + // panic(len(val)) + + var bids []*types.Bid + if err := dec.Decode(&bids); err != nil { + return err + } + + amt := big.NewInt(0) + rAmt := big.NewInt(0) + for _, rBid := range bids { + if bid == nil { + bid = rBid + amt.SetString(rBid.Amount, 10) + } else { + rAmt.SetString(rBid.Amount, 10) + if rAmt.Cmp(amt) == 1 { + bid = rBid + } + } + } + return nil + }) + + return err + }) + + return bid, err +} diff --git a/x/cosmostest/memdb/biddb_test.go b/x/cosmostest/memdb/biddb_test.go new file mode 100644 index 0000000..7cc9aae --- /dev/null +++ b/x/cosmostest/memdb/biddb_test.go @@ -0,0 +1,31 @@ +package memdb + +import ( + "cosmos-test/x/cosmostest/types" + "testing" +) + +func TestBasicFlow(t *testing.T) { + // this should panic if there's a problem + BidDB.Mount() + + // add a bid + testBid := &types.Bid{ + Owner: "cosmos123", + Amount: "100", + } + if err := BidDB.AddBid("0", testBid); err != nil { + panic(err) + } + + // // add a duplicate bid (won't check amount) + // if err := BidDB.AddBid("0", testBid); err != nil { + // panic(err) + // } + + if bid, err := BidDB.GetHighestBid("0"); err != nil { + panic(err) + } else { + panic(bid) + } +}