misc: export more functions, make save/load to db default.
This commit is contained in:
parent
372cd7a72f
commit
feebb96caa
7 changed files with 132 additions and 110 deletions
|
@ -47,7 +47,8 @@ func (c *Claim) expireAt() Height {
|
|||
return c.Accepted + paramOriginalClaimExpirationTime
|
||||
}
|
||||
|
||||
func isActiveAt(c *Claim, ht Height) bool {
|
||||
// IsActiveAt ...
|
||||
func IsActiveAt(c *Claim, ht Height) bool {
|
||||
return c != nil && c.ActiveAt <= ht && c.expireAt() > ht
|
||||
}
|
||||
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
package claim
|
||||
|
||||
type list []*Claim
|
||||
type List []*Claim
|
||||
|
||||
type comparator func(c *Claim) bool
|
||||
type Comparator func(c *Claim) bool
|
||||
|
||||
func byOP(op OutPoint) comparator {
|
||||
func ByOP(op OutPoint) Comparator {
|
||||
return func(c *Claim) bool {
|
||||
return c.OutPoint == op
|
||||
}
|
||||
}
|
||||
|
||||
func byID(id ID) comparator {
|
||||
func ByID(id ID) Comparator {
|
||||
return func(c *Claim) bool {
|
||||
return c.ID == id
|
||||
}
|
||||
}
|
||||
|
||||
func remove(l list, cmp comparator) (list, *Claim) {
|
||||
func Remove(l List, cmp Comparator) (List, *Claim) {
|
||||
last := len(l) - 1
|
||||
for i, v := range l {
|
||||
if !cmp(v) {
|
||||
|
@ -30,7 +30,7 @@ func remove(l list, cmp comparator) (list, *Claim) {
|
|||
return l, nil
|
||||
}
|
||||
|
||||
func find(cmp comparator, lists ...list) *Claim {
|
||||
func Find(cmp Comparator, lists ...List) *Claim {
|
||||
for _, l := range lists {
|
||||
for _, v := range l {
|
||||
if cmp(v) {
|
||||
|
|
|
@ -16,11 +16,11 @@ type Node struct {
|
|||
best *Claim
|
||||
tookover Height
|
||||
|
||||
claims list
|
||||
supports list
|
||||
claims List
|
||||
supports List
|
||||
|
||||
// refer to updateClaim.
|
||||
removed list
|
||||
removed List
|
||||
}
|
||||
|
||||
// NewNode returns a new Node.
|
||||
|
@ -28,6 +28,11 @@ func NewNode(name string) *Node {
|
|||
return &Node{name: name}
|
||||
}
|
||||
|
||||
// Name returns the Name where the Node blongs.
|
||||
func (n *Node) Name() string {
|
||||
return n.name
|
||||
}
|
||||
|
||||
// Height returns the current height.
|
||||
func (n *Node) Height() Height {
|
||||
return n.height
|
||||
|
@ -38,15 +43,30 @@ func (n *Node) BestClaim() *Claim {
|
|||
return n.best
|
||||
}
|
||||
|
||||
// Tookover returns the the height at when the current BestClaim tookover.
|
||||
func (n *Node) Tookover() Height {
|
||||
return n.tookover
|
||||
}
|
||||
|
||||
// Claims returns the claims at the current height.
|
||||
func (n *Node) Claims() List {
|
||||
return n.claims
|
||||
}
|
||||
|
||||
// Supports returns the supports at the current height.
|
||||
func (n *Node) Supports() List {
|
||||
return n.supports
|
||||
}
|
||||
|
||||
// AddClaim adds a Claim to the Node.
|
||||
func (n *Node) AddClaim(op OutPoint, amt Amount) error {
|
||||
if find(byOP(op), n.claims, n.supports) != nil {
|
||||
func (n *Node) AddClaim(op OutPoint, amt Amount, val []byte) error {
|
||||
if Find(ByOP(op), n.claims, n.supports) != nil {
|
||||
return ErrDuplicate
|
||||
}
|
||||
accepted := n.height + 1
|
||||
c := New(op, amt).setID(NewID(op)).setAccepted(accepted)
|
||||
c := New(op, amt).setID(NewID(op)).setAccepted(accepted).setValue(val)
|
||||
c.setActiveAt(accepted + calDelay(accepted, n.tookover))
|
||||
if !isActiveAt(n.best, accepted) {
|
||||
if !IsActiveAt(n.best, accepted) {
|
||||
c.setActiveAt(accepted)
|
||||
n.best, n.tookover = c, accepted
|
||||
}
|
||||
|
@ -57,7 +77,7 @@ func (n *Node) AddClaim(op OutPoint, amt Amount) error {
|
|||
// SpendClaim spends a Claim in the Node.
|
||||
func (n *Node) SpendClaim(op OutPoint) error {
|
||||
var c *Claim
|
||||
if n.claims, c = remove(n.claims, byOP(op)); c == nil {
|
||||
if n.claims, c = Remove(n.claims, ByOP(op)); c == nil {
|
||||
return ErrNotFound
|
||||
}
|
||||
n.removed = append(n.removed, c)
|
||||
|
@ -74,17 +94,17 @@ func (n *Node) SpendClaim(op OutPoint) error {
|
|||
//
|
||||
// For each block, all the spent claims are kept in n.removed until committed.
|
||||
// The paired (spend, update) commands has to happen in the same trasaction.
|
||||
func (n *Node) UpdateClaim(op OutPoint, amt Amount, id ID) error {
|
||||
if find(byOP(op), n.claims, n.supports) != nil {
|
||||
func (n *Node) UpdateClaim(op OutPoint, amt Amount, id ID, val []byte) error {
|
||||
if Find(ByOP(op), n.claims, n.supports) != nil {
|
||||
return ErrDuplicate
|
||||
}
|
||||
var c *Claim
|
||||
if n.removed, c = remove(n.removed, byID(id)); c == nil {
|
||||
if n.removed, c = Remove(n.removed, ByID(id)); c == nil {
|
||||
return errors.Wrapf(ErrNotFound, "remove(n.removed, byID(%s)", id)
|
||||
}
|
||||
|
||||
accepted := n.height + 1
|
||||
c.setOutPoint(op).setAmt(amt).setAccepted(accepted)
|
||||
c.setOutPoint(op).setAmt(amt).setAccepted(accepted).setValue(val)
|
||||
c.setActiveAt(accepted + calDelay(accepted, n.tookover))
|
||||
if n.best != nil && n.best.ID == id {
|
||||
c.setActiveAt(n.tookover)
|
||||
|
@ -95,12 +115,12 @@ func (n *Node) UpdateClaim(op OutPoint, amt Amount, id ID) error {
|
|||
|
||||
// AddSupport adds a Support to the Node.
|
||||
func (n *Node) AddSupport(op OutPoint, amt Amount, id ID) error {
|
||||
if find(byOP(op), n.claims, n.supports) != nil {
|
||||
if Find(ByOP(op), n.claims, n.supports) != nil {
|
||||
return ErrDuplicate
|
||||
}
|
||||
// Accepted by rules. No effects on bidding result though.
|
||||
// It may be spent later.
|
||||
if find(byID(id), n.claims, n.removed) == nil {
|
||||
if Find(ByID(id), n.claims, n.removed) == nil {
|
||||
// fmt.Printf("INFO: can't find suooported claim ID: %s for %s\n", id, n.name)
|
||||
}
|
||||
|
||||
|
@ -117,7 +137,7 @@ func (n *Node) AddSupport(op OutPoint, amt Amount, id ID) error {
|
|||
// SpendSupport spends a support in the Node.
|
||||
func (n *Node) SpendSupport(op OutPoint) error {
|
||||
var s *Claim
|
||||
if n.supports, s = remove(n.supports, byOP(op)); s != nil {
|
||||
if n.supports, s = Remove(n.supports, ByOP(op)); s != nil {
|
||||
return nil
|
||||
}
|
||||
return ErrNotFound
|
||||
|
@ -147,7 +167,7 @@ func (n *Node) AdjustTo(ht Height) *Node {
|
|||
// When no pending updates exist, current height is returned.
|
||||
func (n *Node) NextUpdate() Height {
|
||||
next := Height(math.MaxInt32)
|
||||
min := func(l list) Height {
|
||||
min := func(l List) Height {
|
||||
for _, v := range l {
|
||||
exp := v.expireAt()
|
||||
if n.height >= exp {
|
||||
|
@ -187,15 +207,15 @@ func (n *Node) bid() {
|
|||
n.removed = nil
|
||||
}
|
||||
|
||||
func updateEffectiveAmounts(ht Height, claims, supports list) {
|
||||
func updateEffectiveAmounts(ht Height, claims, supports List) {
|
||||
for _, c := range claims {
|
||||
c.EffAmt = 0
|
||||
if !isActiveAt(c, ht) {
|
||||
if !IsActiveAt(c, ht) {
|
||||
continue
|
||||
}
|
||||
c.EffAmt = c.Amt
|
||||
for _, s := range supports {
|
||||
if !isActiveAt(s, ht) || s.ID != c.ID {
|
||||
if !IsActiveAt(s, ht) || s.ID != c.ID {
|
||||
continue
|
||||
}
|
||||
c.EffAmt += s.Amt
|
||||
|
@ -203,7 +223,7 @@ func updateEffectiveAmounts(ht Height, claims, supports list) {
|
|||
}
|
||||
}
|
||||
|
||||
func updateActiveHeights(n *Node, lists ...list) {
|
||||
func updateActiveHeights(n *Node, lists ...List) {
|
||||
for _, l := range lists {
|
||||
for _, v := range l {
|
||||
v.ActiveAt = v.Accepted + calDelay(n.height, n.tookover)
|
||||
|
@ -211,11 +231,11 @@ func updateActiveHeights(n *Node, lists ...list) {
|
|||
}
|
||||
}
|
||||
|
||||
func findCandiadte(ht Height, claims list) *Claim {
|
||||
func findCandiadte(ht Height, claims List) *Claim {
|
||||
var c *Claim
|
||||
for _, v := range claims {
|
||||
switch {
|
||||
case !isActiveAt(v, ht):
|
||||
case !IsActiveAt(v, ht):
|
||||
continue
|
||||
case c == nil:
|
||||
c = v
|
||||
|
|
|
@ -17,8 +17,8 @@ func export(n *Node) interface{} {
|
|||
Tookover Height
|
||||
NextUpdate Height
|
||||
BestClaim *Claim
|
||||
Claims list
|
||||
Supports list
|
||||
Claims List
|
||||
Supports List
|
||||
}{
|
||||
Height: n.height,
|
||||
Hash: hash,
|
||||
|
|
83
claimtrie.go
83
claimtrie.go
|
@ -3,6 +3,7 @@ package claimtrie
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/lbryio/claimtrie/cfg"
|
||||
"github.com/lbryio/claimtrie/change"
|
||||
"github.com/lbryio/claimtrie/claim"
|
||||
"github.com/lbryio/claimtrie/nodemgr"
|
||||
|
@ -18,41 +19,71 @@ type ClaimTrie struct {
|
|||
cm *CommitMgr
|
||||
nm *nodemgr.NodeMgr
|
||||
tr *trie.Trie
|
||||
|
||||
cleanup func() error
|
||||
}
|
||||
|
||||
// New returns a ClaimTrie.
|
||||
func New(dbCommit, dbTrie, dbNodeMgr *leveldb.DB) *ClaimTrie {
|
||||
nm := nodemgr.New(dbNodeMgr)
|
||||
cm := NewCommitMgr(dbCommit)
|
||||
func New() (*ClaimTrie, error) {
|
||||
path := cfg.DefaultConfig(cfg.TrieDB)
|
||||
dbTrie, err := leveldb.OpenFile(path, nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "can't open %s", path)
|
||||
}
|
||||
|
||||
return &ClaimTrie{
|
||||
path = cfg.DefaultConfig(cfg.NodeDB)
|
||||
dbNodeMgr, err := leveldb.OpenFile(path, nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "can't open %s", path)
|
||||
}
|
||||
|
||||
path = cfg.DefaultConfig(cfg.CommitDB)
|
||||
dbCommit, err := leveldb.OpenFile(path, nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "can't open %s", path)
|
||||
}
|
||||
|
||||
cm := NewCommitMgr(dbCommit)
|
||||
if err := cm.Load(); err != nil {
|
||||
return nil, errors.Wrapf(err, "cm.Load()")
|
||||
}
|
||||
fmt.Printf("%d of commits loaded. Head: %d\n", len(cm.commits), cm.head.Meta.Height)
|
||||
|
||||
nm := nodemgr.New(dbNodeMgr)
|
||||
nm.Load(cm.head.Meta.Height)
|
||||
fmt.Printf("%d of nodes loaded.\n", nm.Size())
|
||||
|
||||
tr := trie.New(nm, dbTrie)
|
||||
tr.SetRoot(cm.Head().MerkleRoot)
|
||||
fmt.Printf("ClaimTrie Root: %s.\n", tr.MerkleHash())
|
||||
|
||||
ct := &ClaimTrie{
|
||||
cm: cm,
|
||||
nm: nm,
|
||||
tr: trie.New(nm, dbTrie),
|
||||
tr: tr,
|
||||
|
||||
cleanup: func() error {
|
||||
if err := cm.Save(); err != nil {
|
||||
return errors.Wrapf(err, "cm.Save()")
|
||||
}
|
||||
if err := dbTrie.Close(); err != nil {
|
||||
return errors.Wrapf(err, "dbTrie.Close()")
|
||||
}
|
||||
if err := dbNodeMgr.Close(); err != nil {
|
||||
return errors.Wrapf(err, "dbNodeMgr.Close()")
|
||||
}
|
||||
if err := dbCommit.Close(); err != nil {
|
||||
return errors.Wrapf(err, "dbCommit.Close()")
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
return ct, nil
|
||||
}
|
||||
|
||||
// Load loads ClaimTrie, NodeManager, Trie from databases.
|
||||
func (ct *ClaimTrie) Load() error {
|
||||
if err := ct.cm.Load(); err != nil {
|
||||
return errors.Wrapf(err, "cm.Load()")
|
||||
}
|
||||
fmt.Printf("%d of commits loaded. Head: %d\n", len(ct.cm.commits), ct.cm.head.Meta.Height)
|
||||
|
||||
ct.nm.Load(ct.Height())
|
||||
fmt.Printf("%d of nodes loaded.\n", ct.nm.Size())
|
||||
|
||||
ct.tr.SetRoot(ct.cm.Head().MerkleRoot)
|
||||
fmt.Printf("Trie root: %s.\n", ct.MerkleHash())
|
||||
return nil
|
||||
}
|
||||
|
||||
// Save saves ClaimTrie state to database.
|
||||
func (ct *ClaimTrie) Save() error {
|
||||
if err := ct.cm.Save(); err != nil {
|
||||
return errors.Wrapf(err, "cm.Save()")
|
||||
}
|
||||
return nil
|
||||
// Close saves ClaimTrie state to database.
|
||||
func (ct *ClaimTrie) Close() error {
|
||||
return ct.cleanup()
|
||||
}
|
||||
|
||||
// Height returns the highest height of blocks commited to the ClaimTrie.
|
||||
|
|
|
@ -149,22 +149,6 @@ func main() {
|
|||
Action: cmdImport,
|
||||
Flags: []cli.Flag{flagHeight, flagCheck, flagVerbose},
|
||||
},
|
||||
{
|
||||
Name: "load",
|
||||
Aliases: []string{"ld"},
|
||||
Usage: "Load nodes from datbase.",
|
||||
Before: parseArgs,
|
||||
Action: cmdLoad,
|
||||
Flags: []cli.Flag{},
|
||||
},
|
||||
{
|
||||
Name: "save",
|
||||
Aliases: []string{"sv"},
|
||||
Usage: "Save nodes to datbase.",
|
||||
Before: parseArgs,
|
||||
Action: cmdSave,
|
||||
Flags: []cli.Flag{},
|
||||
},
|
||||
{
|
||||
Name: "erase",
|
||||
Usage: "Erase datbase",
|
||||
|
@ -181,28 +165,10 @@ func main() {
|
|||
},
|
||||
}
|
||||
|
||||
path := cfg.DefaultConfig(cfg.TrieDB)
|
||||
dbTrie, err := leveldb.OpenFile(path, nil)
|
||||
if err != nil {
|
||||
log.Fatalf("can't open %s, err: %s\n", path, err)
|
||||
var err error
|
||||
if ct, err = claimtrie.New(); err != nil {
|
||||
log.Fatalf("can'y create ClaimTrie, err: %s", err)
|
||||
}
|
||||
fmt.Printf("opened %q\n", path)
|
||||
|
||||
path = cfg.DefaultConfig(cfg.NodeDB)
|
||||
dbNodeMgr, err := leveldb.OpenFile(path, nil)
|
||||
if err != nil {
|
||||
log.Fatalf("can't open %s, err: %s\n", path, err)
|
||||
}
|
||||
fmt.Printf("opened %q\n", path)
|
||||
|
||||
path = cfg.DefaultConfig(cfg.CommitDB)
|
||||
dbCommit, err := leveldb.OpenFile(path, nil)
|
||||
if err != nil {
|
||||
log.Fatalf("can't open %s, err: %s\n", path, err)
|
||||
}
|
||||
fmt.Printf("opened %q\n", path)
|
||||
|
||||
ct = claimtrie.New(dbCommit, dbTrie, dbNodeMgr)
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
fmt.Printf("error: %s\n", err)
|
||||
}
|
||||
|
@ -283,14 +249,6 @@ func cmdImport(c *cli.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func cmdLoad(c *cli.Context) error {
|
||||
return ct.Load()
|
||||
}
|
||||
|
||||
func cmdSave(c *cli.Context) error {
|
||||
return ct.Save()
|
||||
}
|
||||
|
||||
func cmdErase(c *cli.Context) error {
|
||||
if err := os.RemoveAll(cfg.DefaultConfig(cfg.CommitDB)); err != nil {
|
||||
return err
|
||||
|
@ -329,8 +287,8 @@ func cmdShell(app *cli.App) {
|
|||
continue
|
||||
}
|
||||
if text == "quit" || text == "q" {
|
||||
if err = ct.Save(); err != nil {
|
||||
fmt.Printf("ct.Save() failed, err: %s\n", err)
|
||||
if err = ct.Close(); err != nil {
|
||||
fmt.Printf("ct.Close() failed, err: %s\n", err)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ func (nm *NodeMgr) Load(ht claim.Height) {
|
|||
|
||||
// Get returns the latest node with name specified by key.
|
||||
func (nm *NodeMgr) Get(key []byte) trie.Value {
|
||||
return nm.nodeAt(string(key), nm.height)
|
||||
return nm.NodeAt(string(key), nm.height)
|
||||
}
|
||||
|
||||
// Reset resets all nodes to specified height.
|
||||
|
@ -66,8 +66,8 @@ func (nm *NodeMgr) load(name string, ht claim.Height) *claim.Node {
|
|||
return NewFromChanges(name, c, ht)
|
||||
}
|
||||
|
||||
// nodeAt returns the node adjusted to specified height.
|
||||
func (nm *NodeMgr) nodeAt(name string, ht claim.Height) *claim.Node {
|
||||
// NodeAt returns the node adjusted to specified height.
|
||||
func (nm *NodeMgr) NodeAt(name string, ht claim.Height) *claim.Node {
|
||||
n, ok := nm.cache[name]
|
||||
if !ok {
|
||||
n = claim.NewNode(name)
|
||||
|
@ -84,7 +84,7 @@ func (nm *NodeMgr) nodeAt(name string, ht claim.Height) *claim.Node {
|
|||
// ModifyNode returns the node adjusted to specified height.
|
||||
func (nm *NodeMgr) ModifyNode(name string, chg *change.Change) error {
|
||||
ht := nm.height
|
||||
n := nm.nodeAt(name, ht)
|
||||
n := nm.NodeAt(name, ht)
|
||||
n.AdjustTo(ht)
|
||||
if err := execute(n, chg); err != nil {
|
||||
return errors.Wrapf(err, "claim.execute(n,chg)")
|
||||
|
@ -100,12 +100,24 @@ func (nm *NodeMgr) CatchUp(ht claim.Height, notifier func(key []byte)) {
|
|||
nm.height = ht
|
||||
for name := range nm.nextUpdates[ht] {
|
||||
notifier([]byte(name))
|
||||
if next := nm.nodeAt(name, ht).NextUpdate(); next > ht {
|
||||
if next := nm.NodeAt(name, ht).NextUpdate(); next > ht {
|
||||
nm.nextUpdates.set(name, next)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// VisitFunc ...
|
||||
type VisitFunc func(n *claim.Node) (stop bool)
|
||||
|
||||
// Visit visits every node in the cache with VisiFunc.
|
||||
func (nm *NodeMgr) Visit(v VisitFunc) {
|
||||
for _, n := range nm.cache {
|
||||
if v(n) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Show is a conevenient function for debugging and velopment purpose.
|
||||
// The proper way to handle user request would be a query function with filters specified.
|
||||
func (nm *NodeMgr) Show(name string, ht claim.Height, dump bool) error {
|
||||
|
@ -119,7 +131,7 @@ func (nm *NodeMgr) Show(name string, ht claim.Height, dump bool) error {
|
|||
}
|
||||
sort.Strings(names)
|
||||
for _, name := range names {
|
||||
n := nm.nodeAt(name, ht)
|
||||
n := nm.NodeAt(name, ht)
|
||||
if n.BestClaim() == nil {
|
||||
continue
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue