blockchain

package
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 28, 2023 License: MIT Imports: 31 Imported by: 2

Documentation

Index

Constants

View Source
const (
	// FlushRequired is used to signal that a validator set flush must take place.
	FlushRequired flushMode = iota

	// FlushPeriodic will flush if a certain time interval has passed since the last
	// flush.
	FlushPeriodic

	// FlushNop signals to skip the flush.
	FlushNop
)
View Source
const (
	ErrDuplicateBlock = iota
	ErrInvalidProducer
	ErrDoesNotConnect
	ErrInvalidHeight
	ErrInvalidTimestamp
	ErrInvalidHeaderSignature
	ErrEmptyBlock
	ErrInvalidTxRoot
	ErrDoubleSpend
	ErrDuplicateCoinbase
	ErrBlockStakeSpend
	ErrInvalidTx
	ErrInvalidGenesis
	ErrUnknownTxEnum
	ErrBlockSort
	ErrRestakeTooEarly
	ErrInvalidCheckpoint
)
View Source
const (
	// NTBlockConnected indicates the associated block was connected to the chain.
	NTBlockConnected = iota
	NTAddValidator
	NTRemoveValidator
	NTNewEpoch
)

Constants for the type of a notification message. We only have one now maybe we'll add others later so we put the plumbing here for it.

View Source
const (
	DefaultMaxTxoRoots    = 500
	DefaultMaxNullifiers  = 100000
	DefaultSigCacheSize   = 100000
	DefaultProofCacheSize = 100000
)
View Source
const (
	PubkeyLen = 36

	CiphertextLen = 304

	AssetIDLen = 32

	MaxDocumentHashLen = 68

	MaxTransactionSize = 1000000

	MaxBlockFutureTime = time.Second * 10

	RestakePeriod = time.Hour * 24 * 7
)
View Source
const (
	ValidatorExpiration = time.Hour * 24 * 7 * 26
)

Variables

View Source
var ErrNoCheckpoint = errors.New("no accumulator checkpoint")

Functions

func BuildMerkleTreeStore

func BuildMerkleTreeStore(data []types.ID) [][]byte

BuildMerkleTreeStore creates a merkle tree from a slice of data, stores it using a linear array, and returns a slice of the backing array. A linear array was chosen as opposed to an actual tree structure since it uses about half as much memory. The following describes a merkle tree and how it is stored in a linear array.

A merkle tree is a tree in which every non-leaf node is the hash of its children nodes. A diagram depicting how this works for illium transactions where h(x) is a hash function follows:

         root = h1234 = h(h12 + h34)
        /                           \
  h12 = h(h1 + h2)            h34 = h(h3 + h4)
   /            \              /            \
h1 = h(tx1)  h2 = h(tx2)    h3 = h(tx3)  h4 = h(tx4)

The above stored as a linear array is as follows:

[h1 h2 h3 h4 h12 h34 root]

As the above shows, the merkle root is always the last element in the array.

The number of inputs is not always a power of two which results in a balanced tree structure as above. In that case, parent nodes with no children are also zero and parent nodes with only a single left node are calculated by concatenating the left node with itself before hashing. Since this function uses nodes that are pointers to the hashes, empty nodes will be nil.

func CheckTransactionSanity

func CheckTransactionSanity(t *transactions.Transaction, blockTime time.Time) error

CheckTransactionSanity performs a sanity check on the transaction. No blockchain context is considered by this function.

func ErrorIs

func ErrorIs(err error, code ErrorCode) bool

func MerkleInclusionProof

func MerkleInclusionProof(merkleTreeStore [][]byte, txid types.ID) ([][]byte, uint32)

MerkleInclusionProof returns an inclusion proof which proves that the txid in the given merkle tree store.

func NewBlockIndex

func NewBlockIndex(ds repo.Datastore) *blockIndex

NewBlockIndex returns a new blockIndex.

func NewProofValidator

func NewProofValidator(proofCache *ProofCache) *proofValidator

NewProofValidator returns a new ProofValidator. The proofCache must NOT be nil.

func NewSigValidator

func NewSigValidator(sigCache *SigCache) *sigValidator

NewSigValidator returns a new SigValidator. The sigCache must NOT be nil.

func TransactionsMerkleRoot

func TransactionsMerkleRoot(txs []*transactions.Transaction) types.ID

TransactionsMerkleRoot returns the merkle root for the transactions in a block. It is the root of two separate merkle trees - The UID tree and WID tree.

              root = h(uid_root + wid_root)
	        /                           \
	  uid_root                        wid_root

A UID is the hash of each transaction with the transaction's proof set to nil. A WID is the hash of the transactions' proof.

By committing the transaction in two separate pieces it makes it possible to build nodes that only download the transaction without the proof and validate an aggregate proof later, while still ensuring the full transaction data is committed.

func UpdateLogger

func UpdateLogger()

func ValidateTransactionProof

func ValidateTransactionProof(tx *transactions.Transaction, proofCache *ProofCache) <-chan error

ValidateTransactionProof validates the zero knowledge proof for a single transaction. proofCache must not be nil. The validator will check whether the proof already exists in the cache. If it does the proof will be assumed to be valid. If not it will validate the proof and add the proof to the cache if valid.

func ValidateTransactionSig

func ValidateTransactionSig(tx *transactions.Transaction, sigCache *SigCache) <-chan error

ValidateTransactionSig validates the signature for a single transaction. sigCache must not be nil. The validator will check whether the signature already exists in the cache. If it does the signature will be assumed to be valid. If not it will validate the signature and add the signature to the cache if valid.

Types

type Accumulator

type Accumulator struct {
	// contains filtered or unexported fields
}

Accumulator is a hashed-based cryptographic data structure similar to a markle tree. Like a merkle tree, the added elements (leafs) are hashed together to form branches an ultimately a root hash.

This accumulator, however, uses a special type of tree designed for fast appends. Another name for the accumulator is a Merkle Mountain Range. Instead of a single tree, the data structure consists of multiple trees, each one smaller than the previous.

When a new data element is added that would make the tree unbalanced, it is used to start a new tree. Consider the following balanced tree:

            peak0
       /            \
    h12              h34
  /     \          /     \
h1       h2      h3       h4

When h5 is added it will start a new tree. The follow depicts the state after h5 and h6 are added:

            peak0
       /            \
    h12              h34             peak1
  /     \          /     \         /      \
h1       h2      h3       h4      h5      h6

Notice we have two peaks. And if h7 were added that would form a third peak. The "root" of the entire data structure is the hash of all the peaks, hash(peak0 || peak1) in this case. Whenever two peaks reach the same height, the two trees are merged back together into a single tree. Thus, as elements are added, the number of peaks initially fans out before ultimately collapsing back together.

To add new elements to the tree and calculate the new root we only need to store the peaks, nothing else.

func NewAccumulator

func NewAccumulator() *Accumulator

NewAccumulator returns a new Accumulator.

func (*Accumulator) Clone

func (a *Accumulator) Clone() *Accumulator

Clone returns a copy of the accumulator. Modifications to the copy will not affect the original.

func (*Accumulator) DropProof

func (a *Accumulator) DropProof(data []byte)

DropProof ceases tracking of the inclusion proof for the given element and deletes all tree branches related to the proof.

This is NOT safe for concurrent access.

func (*Accumulator) GetProof

func (a *Accumulator) GetProof(data []byte) (*InclusionProof, error)

GetProof returns an inclusion proof, if it exists, for the provided hash.

This is NOT safe for concurrent access.

func (*Accumulator) Hashes

func (a *Accumulator) Hashes() [][]byte

func (*Accumulator) Insert

func (a *Accumulator) Insert(data []byte, protect bool)

Insert inserts a data element into the accumulator. The element is prepended with data index and hashed. This will change the accumulator root. It is not possible to go backwards and undo this operation so make sure you mean to do it.

If you wish to keep track of an InclusionProof for this data element set 'protect' true. This must be done at the time of adding as it's not possible to go back and protect previous items after the accumulator has been mutated.

func (*Accumulator) NumElements

func (a *Accumulator) NumElements() uint64

NumElements returns the current number of elements in the accumulator.

func (*Accumulator) Root

func (a *Accumulator) Root() types.ID

Root returns the root hash of the accumulator. This is not cached and a new hash is calculated each time this method is called.

type AccumulatorDB

type AccumulatorDB struct {
	// contains filtered or unexported fields
}

AccumulatorDB is responsible for persisting the accumulator on disk. It maintains a memory cache and periodically flushes to disk. This will speed up writes as we don't have to write to disk every block but rather only periodically.

func NewAccumulatorDB

func NewAccumulatorDB(ds repo.Datastore) *AccumulatorDB

NewAccumulatorDB returns a new AccumulatorDB

func (*AccumulatorDB) Accumulator

func (adb *AccumulatorDB) Accumulator() *Accumulator

Accumulator returns a clone of the current accumulator.

func (*AccumulatorDB) Commit

func (adb *AccumulatorDB) Commit(accumulator *Accumulator, chainHeight uint32, mode flushMode) error

Commit updates the accumulator in memory and flushes the change to disk using the flushMode. This commit is atomic. If there is an error flushing to the accumulator state in memory will not change.

func (*AccumulatorDB) Flush

func (adb *AccumulatorDB) Flush(mode flushMode, chainHeight uint32) error

Flush will trigger a manual flush of the accumulator DB to disk.

This is safe for concurrent access

func (*AccumulatorDB) Init

func (adb *AccumulatorDB) Init(tip *blockNode) error

Init will initialize the accumulator DB. It will load the accumulator from disk and if it is not currently at the tip of the chain it will roll the accumulator forward until it is up to the tip.

type AssertError

type AssertError string

AssertError identifies an error that indicates an internal code consistency issue and should be treated as a critical and unrecoverable error.

func (AssertError) Error

func (e AssertError) Error() string

Error returns the assertion error as a human-readable string and satisfies the error interface.

type BehaviorFlags

type BehaviorFlags uint8

BehaviorFlags is a bitmask defining tweaks to the normal behavior when performing chain processing and consensus rules checks.

const (
	// BFFastAdd may be set to indicate that several checks can be avoided
	// for the block since it is already known to fit into the chain due to
	// already proving it correct links into the chain up to a known
	// checkpoint.  This is primarily used for headers-first mode.
	BFFastAdd BehaviorFlags = 1 << iota

	// BFNoDupBlockCheck signals if the block should skip existence
	// checks.
	BFNoDupBlockCheck

	// BFNoValidation is used to signal that this block has already been
	// validated and is known to be good and does not need to be validated
	// again.
	BFNoValidation

	// BFGenesisValidation is the flag used to validate the genesis block
	// using special validation rules.
	BFGenesisValidation

	// BFNoFlush skips flushing memory caches to disk.
	BFNoFlush

	// BFNone is a convenience value to specifically indicate no flags.
	BFNone BehaviorFlags = 0
)

func (BehaviorFlags) HasFlag

func (behaviorFlags BehaviorFlags) HasFlag(flag BehaviorFlags) bool

HasFlag returns whether the BehaviorFlags has the passed flag set.

type Blockchain

type Blockchain struct {
	// contains filtered or unexported fields
}

Blockchain is a class which handles all the functionality needed for maintaining the state of the chain. This includes validating blocks, connecting blocks to the chain and saving state to the database.

func NewBlockchain

func NewBlockchain(opts ...Option) (*Blockchain, error)

NewBlockchain returns a fully initialized blockchain.

func (*Blockchain) BestBlock

func (b *Blockchain) BestBlock() (types.ID, uint32, time.Time)

BestBlock returns the ID, height, and timestamp of the block at the tip of the chain.

func (*Blockchain) CalcChainScore

func (b *Blockchain) CalcChainScore(blks []*blocks.Block) (ChainScore, error)

func (*Blockchain) CheckConnectBlock

func (b *Blockchain) CheckConnectBlock(blk *blocks.Block) error

CheckConnectBlock checks that the block is valid for the current state of the blockchain and that it can be connected to the chain. This method does not change any blockchain state. It merely reads the current state to determine the block validity.

func (*Blockchain) Close

func (b *Blockchain) Close() error

Close flushes all caches to disk and makes the node safe to shutdown.

func (*Blockchain) ConnectBlock

func (b *Blockchain) ConnectBlock(blk *blocks.Block, flags BehaviorFlags) (err error)

ConnectBlock attempts to connect the block to the chain. This method is atomic - if there is any error the state of the chain will be rolled back to the state prior to calling this method.

The behavior flags can be used to control which aspects of the block are validated. Make sure the appropriate flags are set when calling this method as otherwise an invalid block could be connected.

func (*Blockchain) CurrentSupply

func (b *Blockchain) CurrentSupply() (types.Amount, error)

CurrentSupply returns the current circulating supply of coins.

func (*Blockchain) GetAccumulatorCheckpointByHeight

func (b *Blockchain) GetAccumulatorCheckpointByHeight(height uint32) (*Accumulator, uint32, error)

GetAccumulatorCheckpointByHeight returns the accumulator checkpoint at the given height. If there is no checkpoint at that height the prior checkpoint will be returned. If there is no prior checkpoint and error will be returned.

func (*Blockchain) GetAccumulatorCheckpointByTimestamp

func (b *Blockchain) GetAccumulatorCheckpointByTimestamp(timestamp time.Time) (*Accumulator, uint32, error)

GetAccumulatorCheckpointByTimestamp returns the accumulator checkpoint at or prior to the given timestamp. If there is no prior checkpoint and error will be returned.

func (*Blockchain) GetBlockByHeight

func (b *Blockchain) GetBlockByHeight(height uint32) (*blocks.Block, error)

GetBlockByHeight returns the block at the given height. The block will be loaded from disk.

func (*Blockchain) GetBlockByID

func (b *Blockchain) GetBlockByID(blockID types.ID) (*blocks.Block, error)

GetBlockByID returns the block with the given ID. The block will be loaded from disk.

func (*Blockchain) GetBlockIDByHeight

func (b *Blockchain) GetBlockIDByHeight(height uint32) (types.ID, error)

GetBlockIDByHeight returns the ID of the block at the given height.

func (*Blockchain) GetHeaderByHeight

func (b *Blockchain) GetHeaderByHeight(height uint32) (*blocks.BlockHeader, error)

GetHeaderByHeight returns the header at the given height. The header will be loaded from disk.

func (*Blockchain) GetInclusionProof

func (b *Blockchain) GetInclusionProof(commitment types.ID) (*InclusionProof, types.ID, error)

GetInclusionProof returns an inclusion proof for the input if the blockchain scanner had the encryption key *before* the commitment was processed in a block.

func (*Blockchain) GetValidator

func (b *Blockchain) GetValidator(validatorID peer.ID) (*Validator, error)

GetValidator returns the validator for the given ID

func (*Blockchain) HasBlock

func (b *Blockchain) HasBlock(blockID types.ID) bool

HasBlock returns whether the block exists in the chain.

func (*Blockchain) IsProducerUnderLimit

func (b *Blockchain) IsProducerUnderLimit(validatorID peer.ID) (bool, error)

IsProducerUnderLimit returns whether the given validator is currently under the block production limit.

func (*Blockchain) NullifierExists

func (b *Blockchain) NullifierExists(n types.Nullifier) (bool, error)

NullifierExists returns whether a nullifier exists in the nullifier set.

func (*Blockchain) Params

func (b *Blockchain) Params() *params.NetworkParams

Params returns the current chain parameters use by the blockchain.

func (*Blockchain) ReindexChainState

func (b *Blockchain) ReindexChainState() error

ReindexChainState deletes all the state data from the database and rebuilds it by loading all blocks from genesis to the tip and re-processing them.

func (*Blockchain) Subscribe

func (b *Blockchain) Subscribe(callback NotificationCallback)

Subscribe to blockchain notifications. Registers a callback to be executed when various events take place. See the documentation on Notification and NotificationType for details on the types and contents of notifications.

func (*Blockchain) TotalStaked

func (b *Blockchain) TotalStaked() types.Amount

TotalStaked returns the total number of coins staked in the validator set.

func (*Blockchain) TreasuryBalance

func (b *Blockchain) TreasuryBalance() (types.Amount, error)

TreasuryBalance returns the current balance of the treasury.

func (*Blockchain) TxoRootExists

func (b *Blockchain) TxoRootExists(txoRoot types.ID) (bool, error)

TxoRootExists returns whether the given root exists in the txo root set.

func (*Blockchain) ValidatorSetSize

func (b *Blockchain) ValidatorSetSize() int

ValidatorSetSize returns the number of validators in the validator set.

func (*Blockchain) Validators

func (b *Blockchain) Validators() []*Validator

Validators returns the full list of validators.

func (*Blockchain) WeightedRandomValidator

func (b *Blockchain) WeightedRandomValidator() peer.ID

WeightedRandomValidator returns a validator weighted by their current stake.

type ChainScore

type ChainScore float64

type ErrorCode

type ErrorCode int

func (ErrorCode) String

func (e ErrorCode) String() string

String returns the ErrorCode as a human-readable name.

type InclusionProof

type InclusionProof struct {
	ID          types.ID
	Accumulator [][]byte
	Hashes      [][]byte
	Flags       uint64
	Index       uint64
	// contains filtered or unexported fields
}

InclusionProof is a merkle inclusion proof which proves that a given element is in the set with the given accumulator root.

type NotCurrentError

type NotCurrentError string

NotCurrentError means that the blockchain is not currently synced to the tip.

func (NotCurrentError) Error

func (e NotCurrentError) Error() string

Error returns the assertion error as a human-readable string and satisfies the error interface.

type Notification

type Notification struct {
	Type NotificationType
	Data interface{}
}

Notification defines notification that is sent to the caller via the callback function provided during the call to New and consists of a notification type as well as associated data that depends on the type as follows:

  • NTBlockConnected: *blocks.Block

type NotificationCallback

type NotificationCallback func(*Notification)

NotificationCallback is used for a caller to provide a callback for notifications about various chain events.

We use a callback rather than a channel here because we want to execute the callback with the state lock held to prevent races.

type NotificationType

type NotificationType int

NotificationType represents the type of a notification message.

func (NotificationType) String

func (n NotificationType) String() string

String returns the NotificationType in human-readable form.

type NullifierSet

type NullifierSet struct {
	// contains filtered or unexported fields
}

NullifierSet provides cached access to the nullifier set database.

func NewNullifierSet

func NewNullifierSet(ds repo.Datastore, maxEntries uint) *NullifierSet

NewNullifierSet returns a new NullifierSet. maxEntries controls how much memory is used for cache purposes.

func (*NullifierSet) AddNullifiers

func (ns *NullifierSet) AddNullifiers(dbtx datastore.Txn, nullifiers []types.Nullifier) error

AddNullifiers adds the nullifiers to the database using the provided database transaction. There is no caching of these writes as the nullifiers will never be deleted or mutated so we have to incure the write penalty at some point.

func (*NullifierSet) Clone

func (ns *NullifierSet) Clone() *NullifierSet

Clone returns a copy of the NullifierSet

func (*NullifierSet) NullifierExists

func (ns *NullifierSet) NullifierExists(nullifier types.Nullifier) (bool, error)

NullifierExists returns whether or not the nullifier exists in the nullifier set. If the entry is cached we'll return from memory, otherwise we have to check the disk.

After determining if the nullifier exists we'll update the cache with the value. This is useful, for example, if the mempool checks the existence of the nullifier, we cache it, then the blockchain doesn't need to hit the disk a second time when validating the block.

type Option

type Option func(cfg *config) error

Option is configuration option function for the blockchain

func Datastore

func Datastore(ds repo.Datastore) Option

Datastore is an implementation of the repo.Datastore interface

This option is required.

func DefaultOptions

func DefaultOptions() Option

DefaultOptions returns a blockchain configure option that fills in the default settings. You will almost certainly want to override some of the defaults, such as parameters and datastore, etc.

func Indexers

func Indexers(indexers []indexers.Indexer) Option

Indexers is a list of indexers to initialize the chain with. These indexers will be notified whenever a new block is connected.

func MaxNullifiers

func MaxNullifiers(maxNullifiers uint) Option

MaxNullifiers is the maximum amount of nullifiers to hold in memory for fast access.

func MaxTxoRoots

func MaxTxoRoots(maxTxoRoots uint) Option

MaxTxoRoots is the maximum amount of TxoRoots to hold in memory for fast access.

func Params

func Params(params *params.NetworkParams) Option

Params identifies which chain parameters the chain is associated with.

This option is required.

func SignatureCache

func SignatureCache(sigCache *SigCache) Option

SignatureCache caches signature validation so we don't need to expend extra CPU to validate signatures more than once.

If this is not provided a new instance will be used.

func SnarkProofCache

func SnarkProofCache(proofCache *ProofCache) Option

SnarkProofCache caches proof validation so we don't need to expend extra CPU to validate zk-snark proofs more than once.

If this is not provided a new instance will be used.

type OrphanBlockError

type OrphanBlockError string

OrphanBlockError means that the processed block is an orphan.

func (OrphanBlockError) Error

func (e OrphanBlockError) Error() string

Error returns the assertion error as a human-readable string and satisfies the error interface.

type ProofCache

type ProofCache struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

ProofCache is used to cache the validation of zero knowledge proofs. Transactions are typically validated twice. Once when they enter the mempool and once again when a block is connected to the chain. We cache the validated proofs here to avoid having to redo expensive computation.

func NewProofCache

func NewProofCache(maxEntries uint) *ProofCache

NewProofCache returns an instantiated ProofCache. maxEntries can be used to control memory usage.

func (*ProofCache) Add

func (p *ProofCache) Add(proofHash types.ID, proof []byte)

Add will add a new proof to the cache. If the new proof would exceed maxEntries a random proof will be evicted from the cache.

NOTE: Proofs should be validated before adding to this cache and only valid proofs should ever be added.

func (*ProofCache) Exists

func (p *ProofCache) Exists(proofHash types.ID, proof []byte) bool

Exists returns whether the proof exists in the cache.

type RuleError

type RuleError struct {
	ErrorCode   ErrorCode // Describes the kind of error
	Description string    // Human-readable description of the issue
}

RuleError identifies a rule violation. It is used to indicate that processing of a block or transaction failed due to one of the many validation rules. The caller can use type assertions to determine if a failure was specifically due to a rule violation and access the ErrorCode field to ascertain the specific reason for the rule violation.

func (RuleError) Error

func (e RuleError) Error() string

Error satisfies the error interface and prints human-readable errors.

type SigCache

type SigCache struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

SigCache is used to cache the validation of transaction signatures. Transactions are typically validated twice. Once when they enter the mempool and once again when a block is connected to the chain. We cache the validated signatures here to avoid having to redo expensive computation.

func NewSigCache

func NewSigCache(maxEntries uint) *SigCache

NewSigCache returns an instantiated SigCache. maxEntries can be used to control memory usage.

func (*SigCache) Add

func (s *SigCache) Add(sigHash types.ID, sig []byte, pubKey crypto.PubKey)

Add will add a new signature to the cache. If the new signature would exceed maxEntries a random signature will be evicted from the cache.

NOTE: Signatures should be validated before adding to this cache and only valid signatures should ever be added.

func (*SigCache) Exists

func (s *SigCache) Exists(sigHash types.ID, sig []byte, pubKey crypto.PubKey) bool

Exists returns whether the signature exists in the cache.

type Stake

type Stake struct {
	Amount     types.Amount
	Blockstamp time.Time
}

Stake represents a given staked utxo and the time at which it was added to the validator set.

type TxoRootSet

type TxoRootSet struct {
	// contains filtered or unexported fields
}

TxoRootSet holds the full set of txoRoots for the entire chain. A new root is created with each block so this set grows with each block.

In the future we could consider limiting the set to N blocks from the tip to reduce storage, however this would make transactions that were signed prior to N but not broadcasted invalid. For now we'll just store everything.

func NewTxoRootSet

func NewTxoRootSet(ds repo.Datastore, maxEntires uint) *TxoRootSet

NewTxoRootSet returns a new TxoRootSet. maxEntries can be used to control the amount of memory used by the cache.

func (*TxoRootSet) AddRoot

func (t *TxoRootSet) AddRoot(dbtx datastore.Txn, txoRoot types.ID) error

AddRoot will add a new root to the set.

NOTE: This adds the root to disk storage only as it's expected this method will be called as part of a broader database transaction. We don't update the memory cache here because we don't want it to get out of sync with the disk if there is a rollback on the database transaction.

Ideally database interface would support commit hooks for this purpose but that will require wrapping the libp2p interface and building out a new db implementation. For now we will expect the caller to use the UpdateCache method upon a successful database transaction commit.

func (*TxoRootSet) Clone

func (t *TxoRootSet) Clone() *TxoRootSet

Clone returns a copy of the TxoRootSet

func (*TxoRootSet) RootExists

func (t *TxoRootSet) RootExists(txoRoot types.ID) (bool, error)

RootExists checks whether the root exists in the set. The memory cache holds the most recent roots as those are most likely to be used in transactions. If the root is in memory we can skip going to disk.

func (*TxoRootSet) UpdateCache

func (t *TxoRootSet) UpdateCache(txoRoot types.ID)

UpdateCache will add the new txoRoot to the memory cache. If the new entry would cause the cache to exceed maxEntires, the oldest entry will be evicted.

NOTE: This should be called after successfully committing the root via the AddRoot function. It's no big deal if this functionality is not used as this will just trigger root lookups from disk, however no root should ever be added to the cache that isn't also on disk.

type Validator

type Validator struct {
	PeerID         peer.ID
	TotalStake     types.Amount
	Nullifiers     map[types.Nullifier]Stake
	UnclaimedCoins types.Amount
	EpochBlocks    uint32
	// contains filtered or unexported fields
}

Validator holds all the information about a validator in the ValidatorSet that is needed to validate blocks.

func (*Validator) Clone

func (v *Validator) Clone() *Validator

Clone returns a copy of the validator

type ValidatorSet

type ValidatorSet struct {
	EpochBlocks uint32
	// contains filtered or unexported fields
}

ValidatorSet maintains the current state of the set of validators in the network.

We maintain a memory cache and periodically flush changes to disk. This is done because a change to the set may cancel out a previous change and committing one to disk only to have to go to disk and undo the change would increase overhead.

func NewValidatorSet

func NewValidatorSet(params *params.NetworkParams, ds repo.Datastore) *ValidatorSet

NewValidatorSet returns a new, uninitialized, ValidatorSet.

func (*ValidatorSet) BlockProductionLimit

func (vs *ValidatorSet) BlockProductionLimit(validatorID peer.ID) (uint32, uint32, error)

BlockProductionLimit returns the maximum blocks that a validator can produce without losing this coinbase. This is based on the current snapshot state of the set and changes every block.

func (*ValidatorSet) CommitBlock

func (vs *ValidatorSet) CommitBlock(blk *blocks.Block, validatorReward types.Amount, flushMode flushMode) error

CommitBlock commits the changes to the validator set found in the block into the set. This function is fully atomic, if an error is returned, no changes are committed. It is expected that the block is fully validated before calling this method.

func (*ValidatorSet) Flush

func (vs *ValidatorSet) Flush(mode flushMode, chainHeight uint32) error

Flush flushes changes from the memory cache to disk.

This method is safe for concurrent access.

func (*ValidatorSet) GetValidator

func (vs *ValidatorSet) GetValidator(id peer.ID) (*Validator, error)

GetValidator returns the validator given the ID.

func (*ValidatorSet) Init

func (vs *ValidatorSet) Init(tip *blockNode) error

Init initializes the validator set. We check to make sure that the set is consistent with the tip of the blockchain. In the event of a hard shutdown or shutdown in the middle of a flush, the state could be inconsistent. If this is the case, Init will attempt to repair the validator set. Depending on the severity of the problem, repair could take a while as we may need to rebuild the set from genesis.

func (*ValidatorSet) NullifierExists

func (vs *ValidatorSet) NullifierExists(nullifier types.Nullifier) bool

NullifierExists returns whether or not a nullifier exists in the set.

func (*ValidatorSet) SubscribeEvents

func (vs *ValidatorSet) SubscribeEvents(callback NotificationCallback)

func (*ValidatorSet) TotalStaked

func (vs *ValidatorSet) TotalStaked() types.Amount

TotalStaked returns the total staked by all validators.

This method is safe for concurrent access.

func (*ValidatorSet) ValidatorExists

func (vs *ValidatorSet) ValidatorExists(id peer.ID) bool

ValidatorExists returns whether the validator exists in the set.

func (*ValidatorSet) WeightedRandomValidator

func (vs *ValidatorSet) WeightedRandomValidator() peer.ID

WeightedRandomValidator returns a validator weighted by their current stake.

NOTE: If there are no validators then "" will be returned for the peer ID.

type WeightedChooser

type WeightedChooser interface {
	WeightedRandomValidator() peer.ID
}

WeightedChooser is an interface for the Blockchain's WeightedRandomValidator method.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL