mirror of
https://github.com/luxfi/platformvm.git
synced 2026-10-30 15:22:12 +00:00
- Drop atomic_block.go + legacy *_block_test.go (consolidated) - Add block/v0/ subdir + lift_v0.go for old version handling - Copyright header: 'Lux Industries, Inc.' → 'Lux Industries Inc' (no comma) - block_adapter.go: new adapter layer
143 lines
3.5 KiB
Go
143 lines
3.5 KiB
Go
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package state
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/luxfi/database"
|
|
"github.com/luxfi/database/linkeddb"
|
|
"github.com/luxfi/database/prefixdb"
|
|
"github.com/luxfi/ids"
|
|
lux "github.com/luxfi/utxo"
|
|
"github.com/luxfi/node/vms/platformvm/status"
|
|
"github.com/luxfi/node/vms/platformvm/txs"
|
|
)
|
|
|
|
func (s *state) GetTx(txID ids.ID) (*txs.Tx, status.Status, error) {
|
|
if tx, exists := s.addedTxs[txID]; exists {
|
|
return tx.tx, tx.status, nil
|
|
}
|
|
if tx, cached := s.txCache.Get(txID); cached {
|
|
if tx == nil {
|
|
return nil, status.Unknown, database.ErrNotFound
|
|
}
|
|
return tx.tx, tx.status, nil
|
|
}
|
|
|
|
txBytes, err := s.txDB.Get(txID[:])
|
|
if err == database.ErrNotFound {
|
|
s.txCache.Put(txID, nil)
|
|
return nil, status.Unknown, database.ErrNotFound
|
|
}
|
|
if err != nil {
|
|
return nil, status.Unknown, err
|
|
}
|
|
|
|
stx := txBytesAndStatus{}
|
|
if _, err := txs.GenesisCodec.Unmarshal(txBytes, &stx); err != nil {
|
|
return nil, status.Unknown, err
|
|
}
|
|
|
|
tx, err := txs.Parse(txs.GenesisCodec, stx.Tx)
|
|
if err != nil {
|
|
return nil, status.Unknown, err
|
|
}
|
|
|
|
ptx := &txAndStatus{
|
|
tx: tx,
|
|
status: stx.Status,
|
|
}
|
|
|
|
s.txCache.Put(txID, ptx)
|
|
return ptx.tx, ptx.status, nil
|
|
}
|
|
|
|
func (s *state) AddTx(tx *txs.Tx, status status.Status) {
|
|
s.addedTxs[tx.ID()] = &txAndStatus{
|
|
tx: tx,
|
|
status: status,
|
|
}
|
|
}
|
|
|
|
func (s *state) GetRewardUTXOs(txID ids.ID) ([]*lux.UTXO, error) {
|
|
if utxos, exists := s.addedRewardUTXOs[txID]; exists {
|
|
return utxos, nil
|
|
}
|
|
if utxos, cached := s.rewardUTXOsCache.Get(txID); cached {
|
|
return utxos, nil
|
|
}
|
|
|
|
rawTxDB := prefixdb.New(txID[:], s.rewardUTXODB)
|
|
txDB := linkeddb.NewDefault(rawTxDB)
|
|
it := txDB.NewIterator()
|
|
defer it.Release()
|
|
|
|
utxos := []*lux.UTXO(nil)
|
|
for it.Next() {
|
|
utxo := &lux.UTXO{}
|
|
if _, err := txs.GenesisCodec.Unmarshal(it.Value(), utxo); err != nil {
|
|
return nil, err
|
|
}
|
|
utxos = append(utxos, utxo)
|
|
}
|
|
if err := it.Error(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
s.rewardUTXOsCache.Put(txID, utxos)
|
|
return utxos, nil
|
|
}
|
|
|
|
func (s *state) AddRewardUTXO(txID ids.ID, utxo *lux.UTXO) {
|
|
s.addedRewardUTXOs[txID] = append(s.addedRewardUTXOs[txID], utxo)
|
|
}
|
|
|
|
func (s *state) writeTXs() error {
|
|
for txID, txStatus := range s.addedTxs {
|
|
stx := txBytesAndStatus{
|
|
Tx: txStatus.tx.Bytes(),
|
|
Status: txStatus.status,
|
|
}
|
|
|
|
// Note that we're serializing a [txBytesAndStatus] here, not a
|
|
// *txs.Tx, so we don't use [txs.Codec].
|
|
txBytes, err := txs.GenesisCodec.Marshal(txs.CodecVersion, &stx)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to serialize tx: %w", err)
|
|
}
|
|
|
|
delete(s.addedTxs, txID)
|
|
// Note: Evict is used rather than Put here because stx may end up
|
|
// referencing additional data (because of shared byte slices) that
|
|
// would not be properly accounted for in the cache sizing.
|
|
s.txCache.Evict(txID)
|
|
if err := s.txDB.Put(txID[:], txBytes); err != nil {
|
|
return fmt.Errorf("failed to add tx: %w", err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *state) writeRewardUTXOs() error {
|
|
for txID, utxos := range s.addedRewardUTXOs {
|
|
delete(s.addedRewardUTXOs, txID)
|
|
s.rewardUTXOsCache.Put(txID, utxos)
|
|
rawTxDB := prefixdb.New(txID[:], s.rewardUTXODB)
|
|
txDB := linkeddb.NewDefault(rawTxDB)
|
|
|
|
for _, utxo := range utxos {
|
|
utxoBytes, err := txs.GenesisCodec.Marshal(txs.CodecVersion, utxo)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to serialize reward UTXO: %w", err)
|
|
}
|
|
utxoID := utxo.InputID()
|
|
if err := txDB.Put(utxoID[:], utxoBytes); err != nil {
|
|
return fmt.Errorf("failed to add reward UTXO: %w", err)
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|