func visitChildren(node data.Storer, db storage.DB, ops *RadixOperations, depth uint8, action RadixAction) error { inner, ok := node.(*data.InnerNode) if !ok { return nil } return inner.Each(func(pos int, h data.Hash256) error { child, err := db.Get(h) if err != nil { return nil } ops.Add(child, action, depth) return visitChildren(child, db, ops, depth+1, action) }) }
func NewLedgerStateFromDB(hash data.Hash256, db storage.DB) (*LedgerState, error) { node, err := db.Get(hash) if err != nil { return nil, err } ledger, ok := node.(*data.Ledger) if !ok { return nil, fmt.Errorf("NewLedgerStateFromDB: not a ledger:%s", hash.String()) } return &LedgerState{ Ledger: ledger, AccountState: NewRadixMap(ledger.StateHash, db), Transactions: NewRadixMap(ledger.TransactionHash, db), Books: make(map[CurrencyPair]Offers), }, nil }
func diff(left, right data.Hash256, db storage.DB, ops *RadixOperations, depth uint8) error { var l, r data.Storer var err error switch { case left.IsZero() && right.IsZero(): return nil case left.IsZero(): r, err = db.Get(left) if err != nil { return err } ops.Add(r, Deletion, depth) return visitChildren(r, db, ops, depth+1, Deletion) case right.IsZero(): l, err = db.Get(left) if err != nil { return err } ops.Add(l, Addition, depth) return visitChildren(l, db, ops, depth+1, Addition) } l, err = db.Get(left) if err != nil { return err } r, err = db.Get(right) if err != nil { return err } ops.Add(r, Deletion, depth) ops.Add(l, Addition, depth) leftInner, leftOk := l.(*data.InnerNode) rightInner, rightOk := r.(*data.InnerNode) switch { case !leftOk && !rightOk: return nil case !leftOk: return visitChildren(r, db, ops, depth+1, Deletion) case !rightOk: return visitChildren(l, db, ops, depth+1, Addition) default: for i := 0; i < 16; i++ { leftChild, rightChild := leftInner.Children[i], rightInner.Children[i] switch { case leftChild == rightChild: continue case leftChild.IsZero(): child, err := db.Get(rightChild) if err != nil { return err } if err := visitChildren(child, db, ops, depth+1, Deletion); err != nil { return err } case rightChild.IsZero(): child, err := db.Get(leftChild) if err != nil { return err } if err := visitChildren(child, db, ops, depth+1, Addition); err != nil { return err } default: if err := diff(leftChild, rightChild, db, ops, depth+1); err != nil { return err } } } } return nil }