Documentation ¶
Index ¶
- Constants
- Variables
- func BuildMerkleTreeStore(data []types.ID) [][]byte
- func CheckTransactionSanity(t *transactions.Transaction, blockTime time.Time) error
- func ErrorIs(err error, code ErrorCode) bool
- func MerkleInclusionProof(merkleTreeStore [][]byte, txid types.ID) ([][]byte, uint32)
- func NewBlockIndex(ds repo.Datastore) *blockIndex
- func NewProofValidator(proofCache *ProofCache) *proofValidator
- func NewSigValidator(sigCache *SigCache) *sigValidator
- func TransactionsMerkleRoot(txs []*transactions.Transaction) types.ID
- func UpdateLogger()
- func ValidateTransactionProof(tx *transactions.Transaction, proofCache *ProofCache) <-chan error
- func ValidateTransactionSig(tx *transactions.Transaction, sigCache *SigCache) <-chan error
- type Accumulator
- func (a *Accumulator) Clone() *Accumulator
- func (a *Accumulator) DropProof(data []byte)
- func (a *Accumulator) GetProof(data []byte) (*InclusionProof, error)
- func (a *Accumulator) Hashes() [][]byte
- func (a *Accumulator) Insert(data []byte, protect bool)
- func (a *Accumulator) NumElements() uint64
- func (a *Accumulator) Root() types.ID
- type AccumulatorDB
- type AssertError
- type BehaviorFlags
- type Blockchain
- func (b *Blockchain) BestBlock() (types.ID, uint32, time.Time)
- func (b *Blockchain) CalcChainScore(blks []*blocks.Block) (ChainScore, error)
- func (b *Blockchain) CheckConnectBlock(blk *blocks.Block) error
- func (b *Blockchain) Close() error
- func (b *Blockchain) ConnectBlock(blk *blocks.Block, flags BehaviorFlags) (err error)
- func (b *Blockchain) CurrentSupply() (types.Amount, error)
- func (b *Blockchain) GetAccumulatorCheckpointByHeight(height uint32) (*Accumulator, uint32, error)
- func (b *Blockchain) GetAccumulatorCheckpointByTimestamp(timestamp time.Time) (*Accumulator, uint32, error)
- func (b *Blockchain) GetBlockByHeight(height uint32) (*blocks.Block, error)
- func (b *Blockchain) GetBlockByID(blockID types.ID) (*blocks.Block, error)
- func (b *Blockchain) GetBlockIDByHeight(height uint32) (types.ID, error)
- func (b *Blockchain) GetHeaderByHeight(height uint32) (*blocks.BlockHeader, error)
- func (b *Blockchain) GetInclusionProof(commitment types.ID) (*InclusionProof, types.ID, error)
- func (b *Blockchain) GetValidator(validatorID peer.ID) (*Validator, error)
- func (b *Blockchain) HasBlock(blockID types.ID) bool
- func (b *Blockchain) IsProducerUnderLimit(validatorID peer.ID) (bool, error)
- func (b *Blockchain) NullifierExists(n types.Nullifier) (bool, error)
- func (b *Blockchain) Params() *params.NetworkParams
- func (b *Blockchain) ReindexChainState() error
- func (b *Blockchain) Subscribe(callback NotificationCallback)
- func (b *Blockchain) TotalStaked() types.Amount
- func (b *Blockchain) TreasuryBalance() (types.Amount, error)
- func (b *Blockchain) TxoRootExists(txoRoot types.ID) (bool, error)
- func (b *Blockchain) ValidatorSetSize() int
- func (b *Blockchain) Validators() []*Validator
- func (b *Blockchain) WeightedRandomValidator() peer.ID
- type ChainScore
- type ErrorCode
- type InclusionProof
- type NotCurrentError
- type Notification
- type NotificationCallback
- type NotificationType
- type NullifierSet
- type Option
- func Datastore(ds repo.Datastore) Option
- func DefaultOptions() Option
- func Indexers(indexers []indexers.Indexer) Option
- func MaxNullifiers(maxNullifiers uint) Option
- func MaxTxoRoots(maxTxoRoots uint) Option
- func Params(params *params.NetworkParams) Option
- func SignatureCache(sigCache *SigCache) Option
- func SnarkProofCache(proofCache *ProofCache) Option
- type OrphanBlockError
- type ProofCache
- type RuleError
- type SigCache
- type Stake
- type TxoRootSet
- type Validator
- type ValidatorSet
- func (vs *ValidatorSet) BlockProductionLimit(validatorID peer.ID) (uint32, uint32, error)
- func (vs *ValidatorSet) CommitBlock(blk *blocks.Block, validatorReward types.Amount, flushMode flushMode) error
- func (vs *ValidatorSet) Flush(mode flushMode, chainHeight uint32) error
- func (vs *ValidatorSet) GetValidator(id peer.ID) (*Validator, error)
- func (vs *ValidatorSet) Init(tip *blockNode) error
- func (vs *ValidatorSet) NullifierExists(nullifier types.Nullifier) bool
- func (vs *ValidatorSet) SubscribeEvents(callback NotificationCallback)
- func (vs *ValidatorSet) TotalStaked() types.Amount
- func (vs *ValidatorSet) ValidatorExists(id peer.ID) bool
- func (vs *ValidatorSet) WeightedRandomValidator() peer.ID
- type WeightedChooser
Constants ¶
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 )
const ( ErrDuplicateBlock = iota ErrInvalidProducer ErrDoesNotConnect ErrInvalidHeight ErrInvalidTimestamp ErrInvalidHeaderSignature ErrEmptyBlock ErrInvalidTxRoot ErrDoubleSpend ErrDuplicateCoinbase ErrBlockStakeSpend ErrInvalidTx ErrInvalidGenesis ErrUnknownTxEnum ErrBlockSort ErrRestakeTooEarly ErrInvalidCheckpoint )
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.
const ( DefaultMaxTxoRoots = 500 DefaultMaxNullifiers = 100000 DefaultSigCacheSize = 100000 DefaultProofCacheSize = 100000 )
const ( PubkeyLen = 36 CiphertextLen = 304 AssetIDLen = 32 MaxDocumentHashLen = 68 MaxTransactionSize = 1000000 MaxBlockFutureTime = time.Second * 10 RestakePeriod = time.Hour * 24 * 7 )
const (
ValidatorExpiration = time.Hour * 24 * 7 * 26
)
Variables ¶
var ErrNoCheckpoint = errors.New("no accumulator checkpoint")
Functions ¶
func BuildMerkleTreeStore ¶
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 MerkleInclusionProof ¶
MerkleInclusionProof returns an inclusion proof which proves that the txid in the given merkle tree store.
func NewBlockIndex ¶
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 (*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 ¶
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 ¶
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 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 ¶
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 ¶
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 ¶
Indexers is a list of indexers to initialize the chain with. These indexers will be notified whenever a new block is connected.
func MaxNullifiers ¶
MaxNullifiers is the maximum amount of nullifiers to hold in memory for fast access.
func MaxTxoRoots ¶
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 ¶
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 ¶
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.
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.
type SigCache ¶
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 ¶
NewSigCache returns an instantiated SigCache. maxEntries can be used to control memory usage.
type Stake ¶
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.
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 ¶
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 ¶
WeightedChooser is an interface for the Blockchain's WeightedRandomValidator method.