OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / btcsuite / btcd / database / interface.go
1 // Copyright (c) 2015-2016 The btcsuite developers
2 // Use of this source code is governed by an ISC
3 // license that can be found in the LICENSE file.
4
5 // Parts of this interface were inspired heavily by the excellent boltdb project
6 // at https://github.com/boltdb/bolt by Ben B. Johnson.
7
8 package database
9
10 import (
11         "github.com/btcsuite/btcd/chaincfg/chainhash"
12         "github.com/btcsuite/btcutil"
13 )
14
15 // Cursor represents a cursor over key/value pairs and nested buckets of a
16 // bucket.
17 //
18 // Note that open cursors are not tracked on bucket changes and any
19 // modifications to the bucket, with the exception of Cursor.Delete, invalidates
20 // the cursor.  After invalidation, the cursor must be repositioned, or the keys
21 // and values returned may be unpredictable.
22 type Cursor interface {
23         // Bucket returns the bucket the cursor was created for.
24         Bucket() Bucket
25
26         // Delete removes the current key/value pair the cursor is at without
27         // invalidating the cursor.
28         //
29         // The interface contract guarantees at least the following errors will
30         // be returned (other implementation-specific errors are possible):
31         //   - ErrIncompatibleValue if attempted when the cursor points to a
32         //     nested bucket
33         //   - ErrTxNotWritable if attempted against a read-only transaction
34         //   - ErrTxClosed if the transaction has already been closed
35         Delete() error
36
37         // First positions the cursor at the first key/value pair and returns
38         // whether or not the pair exists.
39         First() bool
40
41         // Last positions the cursor at the last key/value pair and returns
42         // whether or not the pair exists.
43         Last() bool
44
45         // Next moves the cursor one key/value pair forward and returns whether
46         // or not the pair exists.
47         Next() bool
48
49         // Prev moves the cursor one key/value pair backward and returns whether
50         // or not the pair exists.
51         Prev() bool
52
53         // Seek positions the cursor at the first key/value pair that is greater
54         // than or equal to the passed seek key.  Returns whether or not the
55         // pair exists.
56         Seek(seek []byte) bool
57
58         // Key returns the current key the cursor is pointing to.
59         Key() []byte
60
61         // Value returns the current value the cursor is pointing to.  This will
62         // be nil for nested buckets.
63         Value() []byte
64 }
65
66 // Bucket represents a collection of key/value pairs.
67 type Bucket interface {
68         // Bucket retrieves a nested bucket with the given key.  Returns nil if
69         // the bucket does not exist.
70         Bucket(key []byte) Bucket
71
72         // CreateBucket creates and returns a new nested bucket with the given
73         // key.
74         //
75         // The interface contract guarantees at least the following errors will
76         // be returned (other implementation-specific errors are possible):
77         //   - ErrBucketExists if the bucket already exists
78         //   - ErrBucketNameRequired if the key is empty
79         //   - ErrIncompatibleValue if the key is otherwise invalid for the
80         //     particular implementation
81         //   - ErrTxNotWritable if attempted against a read-only transaction
82         //   - ErrTxClosed if the transaction has already been closed
83         CreateBucket(key []byte) (Bucket, error)
84
85         // CreateBucketIfNotExists creates and returns a new nested bucket with
86         // the given key if it does not already exist.
87         //
88         // The interface contract guarantees at least the following errors will
89         // be returned (other implementation-specific errors are possible):
90         //   - ErrBucketNameRequired if the key is empty
91         //   - ErrIncompatibleValue if the key is otherwise invalid for the
92         //     particular implementation
93         //   - ErrTxNotWritable if attempted against a read-only transaction
94         //   - ErrTxClosed if the transaction has already been closed
95         CreateBucketIfNotExists(key []byte) (Bucket, error)
96
97         // DeleteBucket removes a nested bucket with the given key.  This also
98         // includes removing all nested buckets and keys under the bucket being
99         // deleted.
100         //
101         // The interface contract guarantees at least the following errors will
102         // be returned (other implementation-specific errors are possible):
103         //   - ErrBucketNotFound if the specified bucket does not exist
104         //   - ErrTxNotWritable if attempted against a read-only transaction
105         //   - ErrTxClosed if the transaction has already been closed
106         DeleteBucket(key []byte) error
107
108         // ForEach invokes the passed function with every key/value pair in the
109         // bucket.  This does not include nested buckets or the key/value pairs
110         // within those nested buckets.
111         //
112         // WARNING: It is not safe to mutate data while iterating with this
113         // method.  Doing so may cause the underlying cursor to be invalidated
114         // and return unexpected keys and/or values.
115         //
116         // The interface contract guarantees at least the following errors will
117         // be returned (other implementation-specific errors are possible):
118         //   - ErrTxClosed if the transaction has already been closed
119         //
120         // NOTE: The slices returned by this function are only valid during a
121         // transaction.  Attempting to access them after a transaction has ended
122         // results in undefined behavior.  Additionally, the slices must NOT
123         // be modified by the caller.  These constraints prevent additional data
124         // copies and allows support for memory-mapped database implementations.
125         ForEach(func(k, v []byte) error) error
126
127         // ForEachBucket invokes the passed function with the key of every
128         // nested bucket in the current bucket.  This does not include any
129         // nested buckets within those nested buckets.
130         //
131         // WARNING: It is not safe to mutate data while iterating with this
132         // method.  Doing so may cause the underlying cursor to be invalidated
133         // and return unexpected keys and/or values.
134         //
135         // The interface contract guarantees at least the following errors will
136         // be returned (other implementation-specific errors are possible):
137         //   - ErrTxClosed if the transaction has already been closed
138         //
139         // NOTE: The keys returned by this function are only valid during a
140         // transaction.  Attempting to access them after a transaction has ended
141         // results in undefined behavior.  This constraint prevents additional
142         // data copies and allows support for memory-mapped database
143         // implementations.
144         ForEachBucket(func(k []byte) error) error
145
146         // Cursor returns a new cursor, allowing for iteration over the bucket's
147         // key/value pairs and nested buckets in forward or backward order.
148         //
149         // You must seek to a position using the First, Last, or Seek functions
150         // before calling the Next, Prev, Key, or Value functions.  Failure to
151         // do so will result in the same return values as an exhausted cursor,
152         // which is false for the Prev and Next functions and nil for Key and
153         // Value functions.
154         Cursor() Cursor
155
156         // Writable returns whether or not the bucket is writable.
157         Writable() bool
158
159         // Put saves the specified key/value pair to the bucket.  Keys that do
160         // not already exist are added and keys that already exist are
161         // overwritten.
162         //
163         // The interface contract guarantees at least the following errors will
164         // be returned (other implementation-specific errors are possible):
165         //   - ErrKeyRequired if the key is empty
166         //   - ErrIncompatibleValue if the key is the same as an existing bucket
167         //   - ErrTxNotWritable if attempted against a read-only transaction
168         //   - ErrTxClosed if the transaction has already been closed
169         //
170         // NOTE: The slices passed to this function must NOT be modified by the
171         // caller.  This constraint prevents the requirement for additional data
172         // copies and allows support for memory-mapped database implementations.
173         Put(key, value []byte) error
174
175         // Get returns the value for the given key.  Returns nil if the key does
176         // not exist in this bucket.  An empty slice is returned for keys that
177         // exist but have no value assigned.
178         //
179         // NOTE: The value returned by this function is only valid during a
180         // transaction.  Attempting to access it after a transaction has ended
181         // results in undefined behavior.  Additionally, the value must NOT
182         // be modified by the caller.  These constraints prevent additional data
183         // copies and allows support for memory-mapped database implementations.
184         Get(key []byte) []byte
185
186         // Delete removes the specified key from the bucket.  Deleting a key
187         // that does not exist does not return an error.
188         //
189         // The interface contract guarantees at least the following errors will
190         // be returned (other implementation-specific errors are possible):
191         //   - ErrKeyRequired if the key is empty
192         //   - ErrIncompatibleValue if the key is the same as an existing bucket
193         //   - ErrTxNotWritable if attempted against a read-only transaction
194         //   - ErrTxClosed if the transaction has already been closed
195         Delete(key []byte) error
196 }
197
198 // BlockRegion specifies a particular region of a block identified by the
199 // specified hash, given an offset and length.
200 type BlockRegion struct {
201         Hash   *chainhash.Hash
202         Offset uint32
203         Len    uint32
204 }
205
206 // Tx represents a database transaction.  It can either by read-only or
207 // read-write.  The transaction provides a metadata bucket against which all
208 // read and writes occur.
209 //
210 // As would be expected with a transaction, no changes will be saved to the
211 // database until it has been committed.  The transaction will only provide a
212 // view of the database at the time it was created.  Transactions should not be
213 // long running operations.
214 type Tx interface {
215         // Metadata returns the top-most bucket for all metadata storage.
216         Metadata() Bucket
217
218         // StoreBlock stores the provided block into the database.  There are no
219         // checks to ensure the block connects to a previous block, contains
220         // double spends, or any additional functionality such as transaction
221         // indexing.  It simply stores the block in the database.
222         //
223         // The interface contract guarantees at least the following errors will
224         // be returned (other implementation-specific errors are possible):
225         //   - ErrBlockExists when the block hash already exists
226         //   - ErrTxNotWritable if attempted against a read-only transaction
227         //   - ErrTxClosed if the transaction has already been closed
228         //
229         // Other errors are possible depending on the implementation.
230         StoreBlock(block *btcutil.Block) error
231
232         // HasBlock returns whether or not a block with the given hash exists
233         // in the database.
234         //
235         // The interface contract guarantees at least the following errors will
236         // be returned (other implementation-specific errors are possible):
237         //   - ErrTxClosed if the transaction has already been closed
238         //
239         // Other errors are possible depending on the implementation.
240         HasBlock(hash *chainhash.Hash) (bool, error)
241
242         // HasBlocks returns whether or not the blocks with the provided hashes
243         // exist in the database.
244         //
245         // The interface contract guarantees at least the following errors will
246         // be returned (other implementation-specific errors are possible):
247         //   - ErrTxClosed if the transaction has already been closed
248         //
249         // Other errors are possible depending on the implementation.
250         HasBlocks(hashes []chainhash.Hash) ([]bool, error)
251
252         // FetchBlockHeader returns the raw serialized bytes for the block
253         // header identified by the given hash.  The raw bytes are in the format
254         // returned by Serialize on a wire.BlockHeader.
255         //
256         // It is highly recommended to use this function (or FetchBlockHeaders)
257         // to obtain block headers over the FetchBlockRegion(s) functions since
258         // it provides the backend drivers the freedom to perform very specific
259         // optimizations which can result in significant speed advantages when
260         // working with headers.
261         //
262         // The interface contract guarantees at least the following errors will
263         // be returned (other implementation-specific errors are possible):
264         //   - ErrBlockNotFound if the requested block hash does not exist
265         //   - ErrTxClosed if the transaction has already been closed
266         //   - ErrCorruption if the database has somehow become corrupted
267         //
268         // NOTE: The data returned by this function is only valid during a
269         // database transaction.  Attempting to access it after a transaction
270         // has ended results in undefined behavior.  This constraint prevents
271         // additional data copies and allows support for memory-mapped database
272         // implementations.
273         FetchBlockHeader(hash *chainhash.Hash) ([]byte, error)
274
275         // FetchBlockHeaders returns the raw serialized bytes for the block
276         // headers identified by the given hashes.  The raw bytes are in the
277         // format returned by Serialize on a wire.BlockHeader.
278         //
279         // It is highly recommended to use this function (or FetchBlockHeader)
280         // to obtain block headers over the FetchBlockRegion(s) functions since
281         // it provides the backend drivers the freedom to perform very specific
282         // optimizations which can result in significant speed advantages when
283         // working with headers.
284         //
285         // Furthermore, depending on the specific implementation, this function
286         // can be more efficient for bulk loading multiple block headers than
287         // loading them one-by-one with FetchBlockHeader.
288         //
289         // The interface contract guarantees at least the following errors will
290         // be returned (other implementation-specific errors are possible):
291         //   - ErrBlockNotFound if any of the request block hashes do not exist
292         //   - ErrTxClosed if the transaction has already been closed
293         //   - ErrCorruption if the database has somehow become corrupted
294         //
295         // NOTE: The data returned by this function is only valid during a
296         // database transaction.  Attempting to access it after a transaction
297         // has ended results in undefined behavior.  This constraint prevents
298         // additional data copies and allows support for memory-mapped database
299         // implementations.
300         FetchBlockHeaders(hashes []chainhash.Hash) ([][]byte, error)
301
302         // FetchBlock returns the raw serialized bytes for the block identified
303         // by the given hash.  The raw bytes are in the format returned by
304         // Serialize on a wire.MsgBlock.
305         //
306         // The interface contract guarantees at least the following errors will
307         // be returned (other implementation-specific errors are possible):
308         //   - ErrBlockNotFound if the requested block hash does not exist
309         //   - ErrTxClosed if the transaction has already been closed
310         //   - ErrCorruption if the database has somehow become corrupted
311         //
312         // NOTE: The data returned by this function is only valid during a
313         // database transaction.  Attempting to access it after a transaction
314         // has ended results in undefined behavior.  This constraint prevents
315         // additional data copies and allows support for memory-mapped database
316         // implementations.
317         FetchBlock(hash *chainhash.Hash) ([]byte, error)
318
319         // FetchBlocks returns the raw serialized bytes for the blocks
320         // identified by the given hashes.  The raw bytes are in the format
321         // returned by Serialize on a wire.MsgBlock.
322         //
323         // The interface contract guarantees at least the following errors will
324         // be returned (other implementation-specific errors are possible):
325         //   - ErrBlockNotFound if the any of the requested block hashes do not
326         //     exist
327         //   - ErrTxClosed if the transaction has already been closed
328         //   - ErrCorruption if the database has somehow become corrupted
329         //
330         // NOTE: The data returned by this function is only valid during a
331         // database transaction.  Attempting to access it after a transaction
332         // has ended results in undefined behavior.  This constraint prevents
333         // additional data copies and allows support for memory-mapped database
334         // implementations.
335         FetchBlocks(hashes []chainhash.Hash) ([][]byte, error)
336
337         // FetchBlockRegion returns the raw serialized bytes for the given
338         // block region.
339         //
340         // For example, it is possible to directly extract Bitcoin transactions
341         // and/or scripts from a block with this function.  Depending on the
342         // backend implementation, this can provide significant savings by
343         // avoiding the need to load entire blocks.
344         //
345         // The raw bytes are in the format returned by Serialize on a
346         // wire.MsgBlock and the Offset field in the provided BlockRegion is
347         // zero-based and relative to the start of the block (byte 0).
348         //
349         // The interface contract guarantees at least the following errors will
350         // be returned (other implementation-specific errors are possible):
351         //   - ErrBlockNotFound if the requested block hash does not exist
352         //   - ErrBlockRegionInvalid if the region exceeds the bounds of the
353         //     associated block
354         //   - ErrTxClosed if the transaction has already been closed
355         //   - ErrCorruption if the database has somehow become corrupted
356         //
357         // NOTE: The data returned by this function is only valid during a
358         // database transaction.  Attempting to access it after a transaction
359         // has ended results in undefined behavior.  This constraint prevents
360         // additional data copies and allows support for memory-mapped database
361         // implementations.
362         FetchBlockRegion(region *BlockRegion) ([]byte, error)
363
364         // FetchBlockRegions returns the raw serialized bytes for the given
365         // block regions.
366         //
367         // For example, it is possible to directly extract Bitcoin transactions
368         // and/or scripts from various blocks with this function.  Depending on
369         // the backend implementation, this can provide significant savings by
370         // avoiding the need to load entire blocks.
371         //
372         // The raw bytes are in the format returned by Serialize on a
373         // wire.MsgBlock and the Offset fields in the provided BlockRegions are
374         // zero-based and relative to the start of the block (byte 0).
375         //
376         // The interface contract guarantees at least the following errors will
377         // be returned (other implementation-specific errors are possible):
378         //   - ErrBlockNotFound if any of the requested block hashed do not
379         //     exist
380         //   - ErrBlockRegionInvalid if one or more region exceed the bounds of
381         //     the associated block
382         //   - ErrTxClosed if the transaction has already been closed
383         //   - ErrCorruption if the database has somehow become corrupted
384         //
385         // NOTE: The data returned by this function is only valid during a
386         // database transaction.  Attempting to access it after a transaction
387         // has ended results in undefined behavior.  This constraint prevents
388         // additional data copies and allows support for memory-mapped database
389         // implementations.
390         FetchBlockRegions(regions []BlockRegion) ([][]byte, error)
391
392         // ******************************************************************
393         // Methods related to both atomic metadata storage and block storage.
394         // ******************************************************************
395
396         // Commit commits all changes that have been made to the metadata or
397         // block storage.  Depending on the backend implementation this could be
398         // to a cache that is periodically synced to persistent storage or
399         // directly to persistent storage.  In any case, all transactions which
400         // are started after the commit finishes will include all changes made
401         // by this transaction.  Calling this function on a managed transaction
402         // will result in a panic.
403         Commit() error
404
405         // Rollback undoes all changes that have been made to the metadata or
406         // block storage.  Calling this function on a managed transaction will
407         // result in a panic.
408         Rollback() error
409 }
410
411 // DB provides a generic interface that is used to store bitcoin blocks and
412 // related metadata.  This interface is intended to be agnostic to the actual
413 // mechanism used for backend data storage.  The RegisterDriver function can be
414 // used to add a new backend data storage method.
415 //
416 // This interface is divided into two distinct categories of functionality.
417 //
418 // The first category is atomic metadata storage with bucket support.  This is
419 // accomplished through the use of database transactions.
420 //
421 // The second category is generic block storage.  This functionality is
422 // intentionally separate because the mechanism used for block storage may or
423 // may not be the same mechanism used for metadata storage.  For example, it is
424 // often more efficient to store the block data as flat files while the metadata
425 // is kept in a database.  However, this interface aims to be generic enough to
426 // support blocks in the database too, if needed by a particular backend.
427 type DB interface {
428         // Type returns the database driver type the current database instance
429         // was created with.
430         Type() string
431
432         // Begin starts a transaction which is either read-only or read-write
433         // depending on the specified flag.  Multiple read-only transactions
434         // can be started simultaneously while only a single read-write
435         // transaction can be started at a time.  The call will block when
436         // starting a read-write transaction when one is already open.
437         //
438         // NOTE: The transaction must be closed by calling Rollback or Commit on
439         // it when it is no longer needed.  Failure to do so can result in
440         // unclaimed memory and/or inablity to close the database due to locks
441         // depending on the specific database implementation.
442         Begin(writable bool) (Tx, error)
443
444         // View invokes the passed function in the context of a managed
445         // read-only transaction.  Any errors returned from the user-supplied
446         // function are returned from this function.
447         //
448         // Calling Rollback or Commit on the transaction passed to the
449         // user-supplied function will result in a panic.
450         View(fn func(tx Tx) error) error
451
452         // Update invokes the passed function in the context of a managed
453         // read-write transaction.  Any errors returned from the user-supplied
454         // function will cause the transaction to be rolled back and are
455         // returned from this function.  Otherwise, the transaction is committed
456         // when the user-supplied function returns a nil error.
457         //
458         // Calling Rollback or Commit on the transaction passed to the
459         // user-supplied function will result in a panic.
460         Update(fn func(tx Tx) error) error
461
462         // Close cleanly shuts down the database and syncs all data.  It will
463         // block until all database transactions have been finalized (rolled
464         // back or committed).
465         Close() error
466 }