mirror of
https://github.com/colinear-labs/chain.git
synced 2026-03-05 22:34:25 -08:00
WIP memdb system
This commit is contained in:
18
x/cosmostest/memdb/README.md
Normal file
18
x/cosmostest/memdb/README.md
Normal file
@@ -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)]
|
||||
```
|
||||
126
x/cosmostest/memdb/biddb.go
Normal file
126
x/cosmostest/memdb/biddb.go
Normal file
@@ -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
|
||||
}
|
||||
31
x/cosmostest/memdb/biddb_test.go
Normal file
31
x/cosmostest/memdb/biddb_test.go
Normal file
@@ -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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user