func (m *RadixMap) walk(f WalkFunc, key data.Hash256, depth uint8, fill bool) error { if key.IsZero() { return nil } var node *RadixNode if fill { var err error node = &RadixNode{ Depth: depth, } node.Node, err = m.db.Get(key) if err != nil { return err } m.nodes[key] = node } else { var ok bool node, ok = m.nodes[key] if !ok { return fmt.Errorf("Missing hash: %s", key.String()) } if err := f(key, node); err != nil { return err } } inner, ok := node.Node.(*data.InnerNode) if !ok { return nil } return inner.Each(func(pos int, child data.Hash256) error { return m.walk(f, child, depth+1, fill) }) }
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 }