-
Notifications
You must be signed in to change notification settings - Fork 649
/
state.go
99 lines (79 loc) · 2.71 KB
/
state.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package interval
import (
"errors"
"github.com/ava-labs/avalanchego/database"
)
const (
intervalPrefixByte byte = iota
blockPrefixByte
prefixLen = 1
)
var (
intervalPrefix = []byte{intervalPrefixByte}
blockPrefix = []byte{blockPrefixByte}
errInvalidKeyLength = errors.New("invalid key length")
)
func GetIntervals(db database.Iteratee) ([]*Interval, error) {
it := db.NewIteratorWithPrefix(intervalPrefix)
defer it.Release()
var intervals []*Interval
for it.Next() {
dbKey := it.Key()
if len(dbKey) < prefixLen {
return nil, errInvalidKeyLength
}
intervalKey := dbKey[prefixLen:]
upperBound, err := database.ParseUInt64(intervalKey)
if err != nil {
return nil, err
}
value := it.Value()
lowerBound, err := database.ParseUInt64(value)
if err != nil {
return nil, err
}
intervals = append(intervals, &Interval{
LowerBound: lowerBound,
UpperBound: upperBound,
})
}
return intervals, it.Error()
}
func PutInterval(db database.KeyValueWriter, upperBound uint64, lowerBound uint64) error {
return database.PutUInt64(db, makeIntervalKey(upperBound), lowerBound)
}
func DeleteInterval(db database.KeyValueDeleter, upperBound uint64) error {
return db.Delete(makeIntervalKey(upperBound))
}
// makeIntervalKey uses the upperBound rather than the lowerBound because blocks
// are fetched from tip towards genesis. This means that it is more common for
// the lowerBound to change than the upperBound. Modifying the lowerBound only
// requires a single write rather than a write and a delete when modifying the
// upperBound.
func makeIntervalKey(upperBound uint64) []byte {
intervalKey := database.PackUInt64(upperBound)
return append(intervalPrefix, intervalKey...)
}
// GetBlockIterator returns a block iterator that will produce values
// corresponding to persisted blocks in order of increasing height.
func GetBlockIterator(db database.Iteratee) database.Iterator {
return db.NewIteratorWithPrefix(blockPrefix)
}
func GetBlock(db database.KeyValueReader, height uint64) ([]byte, error) {
return db.Get(makeBlockKey(height))
}
func PutBlock(db database.KeyValueWriter, height uint64, bytes []byte) error {
return db.Put(makeBlockKey(height), bytes)
}
func DeleteBlock(db database.KeyValueDeleter, height uint64) error {
return db.Delete(makeBlockKey(height))
}
// makeBlockKey ensures that the returned key maintains the same sorted order as
// the height. This ensures that database iteration of block keys will iterate
// from lower height to higher height.
func makeBlockKey(height uint64) []byte {
blockKey := database.PackUInt64(height)
return append(blockPrefix, blockKey...)
}