mirror of https://github.com/poanetwork/gecko.git
ava state prefixdb
This commit is contained in:
parent
60668c3a91
commit
198accdea7
|
@ -80,11 +80,6 @@ func (s *prefixedState) Funds(id ids.ID) ([]ids.ID, error) {
|
|||
return s.state.IDs(uniqueID(id, fundsID, s.funds))
|
||||
}
|
||||
|
||||
// SetFunds saves the mapping from address to utxo IDs to storage.
|
||||
func (s *prefixedState) SetFunds(id ids.ID, idSlice []ids.ID) error {
|
||||
return s.state.SetIDs(uniqueID(id, fundsID, s.funds), idSlice)
|
||||
}
|
||||
|
||||
// SpendUTXO consumes the provided utxo.
|
||||
func (s *prefixedState) SpendUTXO(utxoID ids.ID) error {
|
||||
utxo, err := s.UTXO(utxoID)
|
||||
|
@ -106,11 +101,7 @@ func (s *prefixedState) SpendUTXO(utxoID ids.ID) error {
|
|||
func (s *prefixedState) removeUTXO(addrs [][]byte, utxoID ids.ID) error {
|
||||
for _, addr := range addrs {
|
||||
addrID := ids.NewID(hashing.ComputeHash256Array(addr))
|
||||
utxos := ids.Set{}
|
||||
funds, _ := s.Funds(addrID)
|
||||
utxos.Add(funds...)
|
||||
utxos.Remove(utxoID)
|
||||
if err := s.SetFunds(addrID, utxos.List()); err != nil {
|
||||
if err := s.state.RemoveID(addrID, utxoID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -135,11 +126,7 @@ func (s *prefixedState) FundUTXO(utxo *ava.UTXO) error {
|
|||
func (s *prefixedState) addUTXO(addrs [][]byte, utxoID ids.ID) error {
|
||||
for _, addr := range addrs {
|
||||
addrID := ids.NewID(hashing.ComputeHash256Array(addr))
|
||||
utxos := ids.Set{}
|
||||
funds, _ := s.Funds(addrID)
|
||||
utxos.Add(funds...)
|
||||
utxos.Add(utxoID)
|
||||
if err := s.SetFunds(addrID, utxos.List()); err != nil {
|
||||
if err := s.state.AddID(addrID, utxoID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,13 +27,15 @@ func TestStateIDs(t *testing.T) {
|
|||
id1 := ids.NewID([32]byte{0xff, 0})
|
||||
id2 := ids.NewID([32]byte{0xff, 0})
|
||||
|
||||
if _, err := state.IDs(ids.Empty); err == nil {
|
||||
t.Fatalf("Should have errored when reading ids")
|
||||
if _, err := state.IDs(ids.Empty); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
expected := []ids.ID{id0, id1}
|
||||
if err := state.SetIDs(ids.Empty, expected); err != nil {
|
||||
t.Fatal(err)
|
||||
for _, id := range expected {
|
||||
if err := state.AddID(ids.Empty, id); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
result, err := state.IDs(ids.Empty)
|
||||
|
@ -53,8 +55,10 @@ func TestStateIDs(t *testing.T) {
|
|||
}
|
||||
|
||||
expected = []ids.ID{id1, id2}
|
||||
if err := state.SetIDs(ids.Empty, expected); err != nil {
|
||||
t.Fatal(err)
|
||||
for _, id := range expected {
|
||||
if err := state.AddID(ids.Empty, id); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
result, err = state.IDs(ids.Empty)
|
||||
|
@ -115,14 +119,10 @@ func TestStateIDs(t *testing.T) {
|
|||
t.Fatalf("Should have returned the %s status", choices.Accepted)
|
||||
}
|
||||
|
||||
if err := state.SetIDs(ids.Empty, []ids.ID{ids.ID{}}); err == nil {
|
||||
if err := state.AddID(ids.Empty, ids.ID{}); err == nil {
|
||||
t.Fatalf("Should have errored during serialization")
|
||||
}
|
||||
|
||||
if err := state.SetIDs(ids.Empty, []ids.ID{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := state.IDs(ids.Empty); err == nil {
|
||||
t.Fatalf("Should have errored when reading ids")
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ func TestStateStatuses(t *testing.T) {
|
|||
t.Fatalf("Should have returned the %s status", choices.Accepted)
|
||||
}
|
||||
|
||||
if err := state.SetIDs(ids.Empty, []ids.ID{ids.Empty}); err != nil {
|
||||
if err := state.AddID(ids.Empty, ids.Empty); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := state.Status(ids.Empty); err == nil {
|
||||
|
|
|
@ -97,11 +97,7 @@ func (s *chainState) setStatus(id ids.ID, status choices.Status) error {
|
|||
func (s *chainState) removeUTXO(addrs [][]byte, utxoID ids.ID) error {
|
||||
for _, addr := range addrs {
|
||||
addrID := ids.NewID(hashing.ComputeHash256Array(addr))
|
||||
utxos := ids.Set{}
|
||||
funds, _ := s.Funds(addrID)
|
||||
utxos.Add(funds...)
|
||||
utxos.Remove(utxoID)
|
||||
if err := s.setFunds(addrID, utxos.List()); err != nil {
|
||||
if err := s.RemoveID(addrID, utxoID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -111,21 +107,13 @@ func (s *chainState) removeUTXO(addrs [][]byte, utxoID ids.ID) error {
|
|||
func (s *chainState) addUTXO(addrs [][]byte, utxoID ids.ID) error {
|
||||
for _, addr := range addrs {
|
||||
addrID := ids.NewID(hashing.ComputeHash256Array(addr))
|
||||
utxos := ids.Set{}
|
||||
funds, _ := s.Funds(addrID)
|
||||
utxos.Add(funds...)
|
||||
utxos.Add(utxoID)
|
||||
if err := s.setFunds(addrID, utxos.List()); err != nil {
|
||||
if err := s.AddID(addrID, utxoID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *chainState) setFunds(id ids.ID, idSlice []ids.ID) error {
|
||||
return s.SetIDs(UniqueID(id, s.fundsIDPrefix, s.fundsID), idSlice)
|
||||
}
|
||||
|
||||
// PrefixedState wraps a state object. By prefixing the state, there will
|
||||
// be no collisions between different types of objects that have the same hash.
|
||||
type PrefixedState struct {
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
"github.com/ava-labs/gecko/cache"
|
||||
"github.com/ava-labs/gecko/database"
|
||||
"github.com/ava-labs/gecko/database/prefixdb"
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/snow/choices"
|
||||
"github.com/ava-labs/gecko/vms/components/codec"
|
||||
|
@ -116,39 +117,29 @@ func (s *State) SetStatus(id ids.ID, status choices.Status) error {
|
|||
|
||||
// IDs returns a slice of IDs from storage
|
||||
func (s *State) IDs(id ids.ID) ([]ids.ID, error) {
|
||||
if idsIntf, found := s.Cache.Get(id); found {
|
||||
if idSlice, ok := idsIntf.([]ids.ID); ok {
|
||||
return idSlice, nil
|
||||
}
|
||||
return nil, errCacheTypeMismatch
|
||||
}
|
||||
|
||||
bytes, err := s.DB.Get(id.Bytes())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
idSlice := []ids.ID(nil)
|
||||
if err := s.Codec.Unmarshal(bytes, &idSlice); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iter := prefixdb.New(id.Bytes(), s.DB).NewIterator()
|
||||
defer iter.Release()
|
||||
|
||||
s.Cache.Put(id, idSlice)
|
||||
for iter.Next() {
|
||||
keyID, err := ids.ToID(iter.Key())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
idSlice = append(idSlice, keyID)
|
||||
}
|
||||
return idSlice, nil
|
||||
}
|
||||
|
||||
// SetIDs saves a slice of IDs to the database.
|
||||
func (s *State) SetIDs(id ids.ID, idSlice []ids.ID) error {
|
||||
if len(idSlice) == 0 {
|
||||
s.Cache.Evict(id)
|
||||
return s.DB.Delete(id.Bytes())
|
||||
}
|
||||
|
||||
bytes, err := s.Codec.Marshal(idSlice)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.Cache.Put(id, idSlice)
|
||||
return s.DB.Put(id.Bytes(), bytes)
|
||||
// AddID saves an ID to the prefixed database
|
||||
func (s *State) AddID(id ids.ID, key ids.ID) error {
|
||||
db := prefixdb.New(id.Bytes(), s.DB)
|
||||
return db.Put(key.Bytes(), nil)
|
||||
}
|
||||
|
||||
// RemoveID removes an ID from the prefixed database
|
||||
func (s *State) RemoveID(id ids.ID, key ids.ID) error {
|
||||
db := prefixdb.New(id.Bytes(), s.DB)
|
||||
return db.Delete(key.Bytes())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue