NewChain returns a new Chain using store as the underlying storage.
(ctx context.Context, initialBlockHash bc.Hash, store Store, heights <-chan uint64)
| 109 | |
| 110 | // NewChain returns a new Chain using store as the underlying storage. |
| 111 | func NewChain(ctx context.Context, initialBlockHash bc.Hash, store Store, heights <-chan uint64) (*Chain, error) { |
| 112 | c := &Chain{ |
| 113 | InitialBlockHash: initialBlockHash, |
| 114 | store: store, |
| 115 | pendingSnapshots: make(chan pendingSnapshot, 1), |
| 116 | prevalidated: prevalidatedTxsCache{ |
| 117 | lru: lru.New(maxCachedValidatedTxs), |
| 118 | }, |
| 119 | } |
| 120 | c.state.cond.L = new(sync.Mutex) |
| 121 | |
| 122 | var err error |
| 123 | c.state.height, err = store.Height(ctx) |
| 124 | if err != nil { |
| 125 | return nil, errors.Wrap(err, "looking up blockchain height") |
| 126 | } |
| 127 | |
| 128 | // Note that c.height.n may still be zero here. |
| 129 | if heights != nil { |
| 130 | go func() { |
| 131 | for h := range heights { |
| 132 | c.setHeight(h) |
| 133 | } |
| 134 | }() |
| 135 | } |
| 136 | |
| 137 | go func() { |
| 138 | for { |
| 139 | select { |
| 140 | case <-ctx.Done(): |
| 141 | return |
| 142 | case ps := <-c.pendingSnapshots: |
| 143 | err = store.SaveSnapshot(ctx, ps.height, ps.snapshot) |
| 144 | if err != nil { |
| 145 | log.Error(ctx, err, "at", "saving snapshot") |
| 146 | } |
| 147 | } |
| 148 | } |
| 149 | }() |
| 150 | |
| 151 | return c, nil |
| 152 | } |
| 153 | |
| 154 | // Height returns the current height of the blockchain. |
| 155 | func (c *Chain) Height() uint64 { |