chaindata

package
v0.3.14 Latest Latest
Warning

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

Go to latest
Published: Sep 18, 2021 License: ISC Imports: 28 Imported by: 7

README

blockchain

Build Status ISC License GoDoc

Package blockchain implements bitcoin block handling and chain selection rules. The test coverage is currently only around 60%, but will be increasing over time. See test_coverage.txt for the gocov coverage report. Alternatively, if you are running a POSIX OS, you can run the cov_report.sh script for a real-time report. Package blockchain is licensed under the liberal ISC license.

There is an associated blog post about the release of this package here.

This package has intentionally been designed so it can be used as a standalone package for any projects needing to handle processing of blocks into the bitcoin block chain.

Installation and Updating

$ go get -u gitlab.com/jaxnet/jaxnetd/shards/blockchain

Bitcoin Chain Processing Overview

Before a block is allowed into the block chain, it must go through an intensive series of validation rules. The following list serves as a general outline of those rules to provide some intuition into what is going on under the hood, but is by no means exhaustive:

  • Reject duplicate blocks
  • Perform a series of sanity checks on the block and its transactions such as verifying proof of work, timestamps, number and character of transactions, transaction amounts, script complexity, and merkle root calculations
  • Compare the block against predetermined checkpoints for expected timestamps and difficulty based on elapsed time since the checkpoint
  • Save the most recent orphan blocks for a limited time in case their parent blocks become available
  • Stop processing if the block is an orphan as the rest of the processing depends on the block's position within the block chain
  • Perform a series of more thorough checks that depend on the block's position within the block chain such as verifying block difficulties adhere to difficulty retarget rules, timestamps are after the median of the last several blocks, all transactions are finalized, checkpoint blocks match, and block versions are in line with the previous blocks
  • Determine how the block fits into the chain and perform different actions accordingly in order to ensure any side chains which have higher difficulty than the main chain become the new main chain
  • When a block is being connected to the main chain (either through reorganization of a side chain to the main chain or just extending the main chain), perform further checks on the block's transactions such as verifying transaction duplicates, script complexity for the combination of connected scripts, coinbase maturity, double spends, and connected transaction values
  • Run the transaction scripts to verify the spender is allowed to spend the coins
  • Insert the block into the block database

Examples

  • ProcessBlock Example
    Demonstrates how to create a new chain instance and use ProcessBlock to attempt to add a block to the chain. This example intentionally attempts to insert a duplicate genesis block to illustrate how an invalid block is handled.

  • CompactToBig Example
    Demonstrates how to convert the compact "bits" in a block header which represent the target difficulty to a big integer and display it using the typical hex notation.

  • BigToCompact Example
    Demonstrates how to convert a target difficulty into the compact "bits" in a block header which represent that target difficulty.

GPG Verification Key

All official release tags are signed by Conformal so users can ensure the code has not been tampered with and is coming from the btcsuite developers. To verify the signature perform the following:

  • Download the public key from the Conformal website at https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt

  • Import the public key into your GPG keyring:

    gpg --import GIT-GPG-KEY-conformal.txt
    
  • Verify the release tag with the following command where TAG_NAME is a placeholder for the specific tag:

    git tag -v TAG_NAME
    

License

Package blockchain is licensed under the copyfree ISC License.

Documentation

Overview

Package chaindata: Functions related to Block Serial ID feature.

BlockLastSerialID is the name of the db bucket used to house the block last serial id.

BlockHashSerialID is the name of the db bucket used to house the mapping of block hash to serial id. BlockSerialIDHashPrevSerialID is the name of the db bucket used to house the mapping of block serial id to hash and previous serial id.

| bucket                         | Key        | Value           |
| ------------------------------ | ---------- | --------------- |
| BlockSerialIDHashPrevSerialID  | serialID   | {hash; prev_id} |
| BlockHashSerialID              | block_hash | serialID        |
| BlockLastSerialID              | BlockLastSerialID | lastSerialID |

Copyright (c) 2020 The JaxNetwork developers Use of this source code is governed by an ISC license that can be found in the LICENSE file.

Copyright (c) 2020 The JaxNetwork developers Use of this source code is governed by an ISC license that can be found in the LICENSE file.

Index

Constants

View Source
const (

	// LatestUtxoSetBucketVersion is the current version of the utxo set
	// bucket that is used to track all unspent outputs.
	LatestUtxoSetBucketVersion = 2

	// LatestSpendJournalBucketVersion is the current version of the spend
	// journal bucket that is used to track all spent transactions for use
	// in reorgs.
	LatestSpendJournalBucketVersion = 1
)
View Source
const (
	// CoinbaseWitnessDataLen is the required length of the only element within
	// the coinbase's witness data if the coinbase transaction contains a
	// witness commitment.
	CoinbaseWitnessDataLen = 32

	// CoinbaseWitnessPkScriptLength is the length of the public key script
	// containing an OP_RETURN, the WitnessMagicBytes, and the witness
	// commitment itself. In order to be a valid candidate for the output
	// containing the witness commitment
	CoinbaseWitnessPkScriptLength = 38
)
View Source
const (
	// MaxTimeOffsetSeconds is the maximum number of seconds a block time
	// is allowed to be ahead of the current time.  This is currently 2
	// hours.
	MaxTimeOffsetSeconds = 2 * 60 * 60

	// MinCoinbaseScriptLen is the minimum length a coinbase script can be.
	MinCoinbaseScriptLen = 2

	// MaxCoinbaseScriptLen is the maximum length a coinbase script can be.
	MaxCoinbaseScriptLen = 100
)
View Source
const (
	// todo(mike): check this value
	// MaxBlockWeight defines the maximum block weight, where "block
	// weight" is interpreted as defined in BIP0141. A block's weight is
	// calculated as the sum of the of bytes in the existing transactions
	// and header, plus the weight of each byte within a transaction. The
	// weight of a "base" byte is 4, while the weight of a witness byte is
	// 1. As a result, for a block to be valid, the BlockWeight MUST be
	// less than, or equal to MaxBlockWeight.
	MaxBlockWeight = 4000000

	// MaxBlockBaseSize is the maximum number of bytes within a block
	// which can be allocated to non-witness data.
	MaxBlockBaseSize = 1000000

	// MaxBlockSigOpsCost is the maximum number of signature operations
	// allowed for a block. It is calculated via a weighted algorithm which
	// weights segregated witness sig ops lower than regular sig ops.
	MaxBlockSigOpsCost = 80000

	// WitnessScaleFactor determines the level of "discount" witness data
	// receives compared to "base" data. A scale factor of 4, denotes that
	// witness data is 1/4 as cheap as regular non-witness data.
	WitnessScaleFactor = 4

	// MinTxOutputWeight is the minimum possible weight for a transaction
	// output.
	MinTxOutputWeight = WitnessScaleFactor * wire.MinTxOutPayload

	// MaxOutputsPerBlock is the maximum number of transaction outputs there
	// can be in a block of max weight size.
	MaxOutputsPerBlock = MaxBlockWeight / MinTxOutputWeight
)

Variables

View Source
var (
	// BlockIndexBucketName is the name of the db bucket used to house to the
	// block headers and contextual information.
	BlockIndexBucketName = []byte("blockheaderidx")

	// HashIndexBucketName is the name of the db bucket used to house to the
	// block Hash -> block height index.
	HashIndexBucketName = []byte("hashidx")

	// HeightIndexBucketName is the name of the db bucket used to house to
	// the block height -> block Hash index.
	HeightIndexBucketName = []byte("heightidx")

	// ChainStateKeyName is the name of the db key used to store the best
	// chain state.
	ChainStateKeyName = []byte("chainstate")

	// SpendJournalVersionKeyName is the name of the db key used to store
	// the version of the spend journal currently in the database.
	SpendJournalVersionKeyName = []byte("spendjournalversion")

	// SpendJournalBucketName is the name of the db bucket used to house
	// transactions outputs that are spent in each block.
	SpendJournalBucketName = []byte("spendjournal")

	// UtxoSetVersionKeyName is the name of the db key used to store the
	// version of the utxo set currently in the database.
	UtxoSetVersionKeyName = []byte("utxosetversion")

	// UtxoSetBucketName is the name of the db bucket used to house the
	// unspent transaction output set.
	UtxoSetBucketName = []byte("utxosetv2")

	// ShardsMMRBucketName is the name of the db bucket used to house the
	// MerkleMountainRange for Merged Mining Tree.
	ShardsMMRBucketName = []byte("shardsmmr")

	// EADAddressesBucketNameV1 is the name of the db bucket used to house the
	// net addresses of Exchange Agents.
	EADAddressesBucketNameV1 = []byte("ead_addresses")

	// EADAddressesBucketNameV2 is the name of the db bucket used to house the
	// net addresses of Exchange Agents.
	EADAddressesBucketNameV2 = []byte("ead_addresses_v2")

	// BlockLastSerialID is the name of the db bucket used to house the
	// block last serial id.
	BlockLastSerialID = []byte("block_last_serial_id")

	// BlockHashSerialID is the name of the db bucket used to house the mapping of
	// block hash to serial id.
	BlockHashSerialID = []byte("block_hash_serial_id")

	// BlockSerialIDHashPrevSerialID is the name of the db bucket used to house the mapping of
	// block serial id to hash and previous serial id.
	BlockSerialIDHashPrevSerialID = []byte("block_serial_id_hash_prev_serial_id")
)
View Source
var (
	// WitnessMagicBytes is the prefix marker within the public key script
	// of a coinbase output to indicate that this output holds the witness
	// commitment for a block.
	WitnessMagicBytes = []byte{
		txscript.OP_RETURN,
		txscript.OP_DATA_36,
		0xaa,
		0x21,
		0xa9,
		0xed,
	}
)

Functions

func BuildMerkleTreeStore

func BuildMerkleTreeStore(transactions []*jaxutil.Tx, witness bool) []*chainhash.Hash

BuildMerkleTreeStore creates a merkle tree from a slice of transactions, 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 bitcoin transactions where h(x) is a double sha256 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.

The additional bool parameter indicates if we are generating the merkle tree using witness transaction id's rather than regular transaction id's. This also presents an additional case wherein the wtxid of the coinbase transaction is the zeroHash.

func CalcBlockSubsidy

func CalcBlockSubsidy(height int32, chainParams *chaincfg.Params) int64

CalcBlockSubsidy returns the subsidy amount a block at the provided height should have. This is mainly used for determining how much the coinbase for newly generated blocks awards as well as validating the coinbase for blocks has the expected value.

The subsidy is halved every SubsidyReductionInterval blocks. Mathematically this is: baseSubsidy / 2^(height/SubsidyReductionInterval)

At the target block generation rate for the main network, this is approximately every 4 years.

func CheckBlockSanity

func CheckBlockSanity(block *jaxutil.Block, powLimit *big.Int, timeSource MedianTimeSource) error

CheckBlockSanity performs some preliminary checks on a block to ensure it is sane before continuing with block processing. These checks are context free.

func CheckBlockSanityWF

func CheckBlockSanityWF(block *jaxutil.Block, powLimit *big.Int, timeSource MedianTimeSource, flags BehaviorFlags) error

CheckBlockSanityWF performs some preliminary checks on a block to ensure it is sane before continuing with block processing. These checks are context free.

The flags do not modify the behavior of this function directly, however they are needed to pass along to checkBlockHeaderSanity.

func CheckBlockScripts

func CheckBlockScripts(block *jaxutil.Block, utxoView *UtxoViewpoint,
	scriptFlags txscript.ScriptFlags, sigCache *txscript.SigCache,
	hashCache *txscript.HashCache) error

CheckBlockScripts executes and validates the scripts for all transactions in the passed block using multiple goroutines.

func CheckProofOfWork

func CheckProofOfWork(block *jaxutil.Block, powLimit *big.Int) error

CheckProofOfWork ensures the block header bits which indicate the target difficulty is in min/max range and that the block Hash is less than the target difficulty as claimed.

func CheckSerializedHeight

func CheckSerializedHeight(coinbaseTx *jaxutil.Tx, wantHeight int32) error

CheckSerializedHeight checks if the signature script in the passed transaction starts with the serialized block height of wantHeight.

func CheckTransactionInputs

func CheckTransactionInputs(tx *jaxutil.Tx, txHeight int32, utxoView *UtxoViewpoint, chainParams *chaincfg.Params) (int64, error)

CheckTransactionInputs performs a series of checks on the inputs to a transaction to ensure they are valid. An example of some of the checks include verifying all inputs exist, ensuring the coinbase seasoning requirements are met, detecting double spends, validating all values and fees are in the legal range and the total output amount doesn't exceed the input amount, and verifying the signatures to prove the spender was the owner of the bitcoins and therefore allowed to spend them. As it checks the inputs, it also calculates the total fees for the transaction and returns that value.

NOTE: The transaction MUST have already been sanity checked with the CheckTransactionSanity function prior to calling this function.

func CheckTransactionSanity

func CheckTransactionSanity(tx *jaxutil.Tx) error

CheckTransactionSanity performs some preliminary checks on a transaction to ensure it is sane. These checks are context free.

func CountP2SHSigOps

func CountP2SHSigOps(tx *jaxutil.Tx, isCoinBaseTx bool, utxoView *UtxoViewpoint) (int, error)

CountP2SHSigOps returns the number of signature operations for all input transactions which are of the pay-to-script-Hash type. This uses the precise, signature operation counting mechanism from the script engine which requires access to the input transaction scripts.

func CountSigOps

func CountSigOps(tx *jaxutil.Tx) int

CountSigOps returns the number of signature operations for all transaction input and output scripts in the provided transaction. This uses the quicker, but imprecise, signature operation counting mechanism from txscript.

func CountSpentOutputs

func CountSpentOutputs(block *jaxutil.Block) int

CountSpentOutputs returns the number of utxos the passed block spends.

func DBFetchAllEADAddresses

func DBFetchAllEADAddresses(dbTx database.Tx) (map[string]*wire.EADAddresses, error)

DBFetchAllEADAddresses ...

func DBFetchBlockByNode

func DBFetchBlockByNode(chain chain.IChainCtx, dbTx database.Tx, node blocknode.IBlockNode) (*jaxutil.Block, error)

DBFetchBlockByNode uses an existing database transaction to retrieve the raw block for the provided node, deserialize it, and return a jaxutil.Block with the height set.

func DBFetchBlockHashBySerialID

func DBFetchBlockHashBySerialID(dbTx database.Tx, serialID int64) (*chainhash.Hash, int64, error)

func DBFetchBlockSerialID

func DBFetchBlockSerialID(dbTx database.Tx, hash *chainhash.Hash) (int64, int64, error)

func DBFetchEADAddresses

func DBFetchEADAddresses(dbTx database.Tx, ownerPK string) (*wire.EADAddresses, error)

DBFetchEADAddresses ...

func DBFetchHeightByHash

func DBFetchHeightByHash(dbTx database.Tx, hash *chainhash.Hash) (int32, error)

DBFetchHeightByHash uses an existing database transaction to retrieve the height for the provided Hash from the index.

func DBFetchLastSerialID

func DBFetchLastSerialID(dbTx database.Tx) (int64, error)

func DBFetchOrCreateVersion

func DBFetchOrCreateVersion(dbTx database.Tx, key []byte, defaultVersion uint32) (uint32, error)

DBFetchOrCreateVersion uses an existing database transaction to attempt to fetch the provided key from the metadata bucket as a version and in the case it doesn't exist, it adds the entry with the provided default version and returns that. This is useful during upgrades to automatically handle loading and adding version keys as necessary.

func DBFetchUtxoEntries

func DBFetchUtxoEntries(dbTx database.Tx, limit int) (map[wire.OutPoint]*UtxoEntry, error)

func DBPutBestState

func DBPutBestState(dbTx database.Tx, snapshot *BestState, workSum *big.Int) error

DBPutBestState uses an existing database transaction to update the best chain state with the given parameters.

func DBPutBlockHashSerialID

func DBPutBlockHashSerialID(dbTx database.Tx, hash *chainhash.Hash, serialID int64) error

func DBPutBlockIndex

func DBPutBlockIndex(dbTx database.Tx, hash *chainhash.Hash, height int32) error

DBPutBlockIndex uses an existing database transaction to update or add the block index entries for the Hash to height and height to Hash mappings for the provided values.

func DBPutBlockSerialIDHash

func DBPutBlockSerialIDHash(dbTx database.Tx, hash *chainhash.Hash, serialID int64) error

func DBPutBlockSerialIDHashPrevSerialID

func DBPutBlockSerialIDHashPrevSerialID(dbTx database.Tx, hash *chainhash.Hash, serialID, lastSerialID int64) error

func DBPutEADAddresses

func DBPutEADAddresses(dbTx database.Tx, updateSet map[string]*wire.EADAddresses) error

DBPutEADAddresses ...

func DBPutLastSerialID

func DBPutLastSerialID(dbTx database.Tx, lastSerialID int64) error

func DBPutSpendJournalEntry

func DBPutSpendJournalEntry(dbTx database.Tx, blockHash *chainhash.Hash, stxos []SpentTxOut) error

DBPutSpendJournalEntry uses an existing database transaction to update the spend journal entry for the given block Hash using the provided slice of spent txouts. The spent txouts slice must contain an entry for every txout the transactions in the block spend in the order they are spent.

func DBPutUtxoView

func DBPutUtxoView(dbTx database.Tx, view *UtxoViewpoint) error

DBPutUtxoView uses an existing database transaction to update the utxo set in the database based on the provided utxo view contents and state. In particular, only the entries that have been marked as modified are written to the database.

func DBPutVersion

func DBPutVersion(dbTx database.Tx, key []byte, version uint32) error

DBPutVersion uses an existing database transaction to update the provided key in the metadata bucket to the given version. It is primarily used to track versions on entities such as buckets.

func DBRemoveBlockIndex

func DBRemoveBlockIndex(dbTx database.Tx, hash *chainhash.Hash, height int32) error

DBRemoveBlockIndex uses an existing database transaction remove block index entries from the Hash to height and height to Hash mappings for the provided values.

func DBRemoveSpendJournalEntry

func DBRemoveSpendJournalEntry(dbTx database.Tx, blockHash *chainhash.Hash) error

DBRemoveSpendJournalEntry uses an existing database transaction to remove the spend journal entry for the passed block Hash.

func DBStoreBlock

func DBStoreBlock(dbTx database.Tx, block *jaxutil.Block) error

DBStoreBlock stores the provided block in the database if it is not already there. The full block data is written to ffldb.

func DBStoreBlockNode

func DBStoreBlockNode(chain chain.IChainCtx, dbTx database.Tx, node blocknode.IBlockNode) error

DBStoreBlockNode stores the block header and validation status to the block index bucket. This overwrites the current entry if there exists one.

func DecodeEADAddressV1 added in v0.3.9

func DecodeEADAddressV1(r io.Reader, pver uint32) (wire.EADAddress, error)

func DecodeEADAddressesV1 added in v0.3.9

func DecodeEADAddressesV1(r io.Reader, pver uint32) (wire.EADAddresses, error)

func DeserializeBlockRow

func DeserializeBlockRow(ch chain.IChainCtx, blockRow []byte) (wire.BlockHeader, blocknode.BlockStatus, error)

DeserializeBlockRow parses a value in the block index bucket into a block header and block status bitfield.

func DisableLog

func DisableLog()

DisableLog disables all library log output. Logging output is disabled by default until UseLogger is called.

func ExtractCoinbaseHeight

func ExtractCoinbaseHeight(coinbaseTx *jaxutil.Tx) (int32, error)

ExtractCoinbaseHeight attempts to extract the height of the block from the scriptSig of a coinbase transaction. Coinbase heights are only present in blocks of version 2 or later. This was added as part of BIP0034.

func ExtractWitnessCommitment

func ExtractWitnessCommitment(tx *jaxutil.Tx) ([]byte, bool)

ExtractWitnessCommitment attempts to locate, and return the witness commitment for a block. The witness commitment is of the form: SHA256(witness root || witness nonce). The function additionally returns a boolean indicating if the witness root was located within any of the txOut's in the passed transaction. The witness commitment is stored as the data push for an OP_RETURN with special magic bytes to aide in location.

func GetBlockWeight

func GetBlockWeight(blk *jaxutil.Block) int64

GetBlockWeight computes the value of the weight metric for a given block. Currently the weight metric is simply the sum of the block's serialized size without any witness data scaled proportionally by the WitnessScaleFactor, and the block's serialized size including any witness data.

func GetSigOpCost

func GetSigOpCost(tx *jaxutil.Tx, isCoinBaseTx bool, utxoView *UtxoViewpoint, bip16, segWit bool) (int, error)

GetSigOpCost returns the unified sig op cost for the passed transaction respecting current active soft-forks which modified sig op cost counting. The unified sig op cost for a transaction is computed as the sum of: the legacy sig op count scaled according to the WitnessScaleFactor, the sig op count for all p2sh inputs scaled by the WitnessScaleFactor, and finally the unscaled sig op count for any inputs spending witness programs.

func GetTransactionWeight

func GetTransactionWeight(tx *jaxutil.Tx) int64

GetTransactionWeight computes the value of the weight metric for a given transaction. Currently the weight metric is simply the sum of the transactions's serialized size without any witness data scaled proportionally by the WitnessScaleFactor, and the transaction's serialized size including any witness data.

func IsBIP0030Node

func IsBIP0030Node(node blocknode.IBlockNode) bool

isBIP0030Node returns whether or not the passed node represents one of the two blocks that violate the BIP0030 rule which prevents transactions from overwriting old ones.

func IsCoinBase

func IsCoinBase(tx *jaxutil.Tx) bool

IsCoinBase determines whether or not a transaction is a coinbase. A coinbase is a special transaction created by miners that has no inputs. This is represented in the block chain by a transaction with a single input that has a previous output transaction index set to the maximum value along with a zero Hash.

This function only differs from IsCoinBaseTx in that it works with a higher level util transaction as opposed to a raw wire transaction.

func IsCoinBaseTx

func IsCoinBaseTx(msgTx *wire.MsgTx) bool

IsCoinBaseTx determines whether or not a transaction is a coinbase. A coinbase is a special transaction created by miners that has no inputs. This is represented in the block chain by a transaction with a single input that has a previous output transaction index set to the maximum value along with a zero Hash.

This function only differs from IsCoinBase in that it works with a raw wire transaction as opposed to a higher level util transaction.

func IsDeserializeErr

func IsDeserializeErr(err error) bool

IsDeserializeErr returns whether or not the passed error is an ErrDeserialize error.

func IsFinalizedTransaction

func IsFinalizedTransaction(tx *jaxutil.Tx, blockHeight int32, blockTime time.Time) bool

IsFinalizedTransaction determines whether or not a transaction is finalized.

func IsNotInMainChainErr

func IsNotInMainChainErr(err error) bool

IsNotInMainChainErr returns whether or not the passed error is an ErrNotInMainChain error.

func MigrateBlockIndex

func MigrateBlockIndex(db database.DB) error

MigrateBlockIndex migrates all block entries from the v1 block index bucket to the v2 bucket. The v1 bucket stores all block entries keyed by block Hash, whereas the v2 bucket stores the exact same values, but keyed instead by block height + Hash.

func MigrateEADAddresses added in v0.3.9

func MigrateEADAddresses(dbTx database.Tx) error

func SequenceLockActive

func SequenceLockActive(sequenceLock *SequenceLock, blockHeight int32,
	medianTimePast time.Time) bool

SequenceLockActive determines if a transaction's sequence locks have been met, meaning that all the inputs of a given transaction have reached a height or time sufficient for their relative lock-time maturity.

func ShouldHaveSerializedBlockHeight

func ShouldHaveSerializedBlockHeight(header wire.BlockHeader) bool

ShouldHaveSerializedBlockHeight determines if a block should have a serialized block height embedded within the scriptSig of its coinbase transaction. Judgement is based on the block version in the block header. Blocks with version 2 and above satisfy this criteria. See BIP0034 for further information.

func UpgradeUtxoSetToV2

func UpgradeUtxoSetToV2(db database.DB, interrupt <-chan struct{}) error

UpgradeUtxoSetToV2 migrates the utxo set entries from version 1 to 2 in batches. It is guaranteed to updated if this returns without failure.

func UseLogger

func UseLogger(logger zerolog.Logger)

UseLogger uses a specified Logger to output package logging info.

func ValidMoneyBackAfterExpiration

func ValidMoneyBackAfterExpiration(tx *jaxutil.Tx, view *UtxoViewpoint) bool

func ValidateSwapTxStructure

func ValidateSwapTxStructure(tx *wire.MsgTx, missedUTXO int) error

ValidateSwapTxStructure validates formats of the cross shard swap tx. wire.TxMarkShardSwap transaction is a special tx for atomic swap between chains. It can contain only TWO or FOUR inputs and TWO or FOUR outputs. TxIn and TxOut are strictly associated with each other by index. One pair corresponds to the current chain. The second is for another, unknown chain.

| # | --- []TxIn ----- | --- | --- []TxOut ----- | # | | - | ---------------- | --- | ----------------- | - | | 0 | TxIn_0 ∈ Shard_X | --> | TxOut_0 ∈ Shard_X | 0 | | 1 | TxIn_1 ∈ Shard_X | --> | TxOut_1 ∈ Shard_X | 1 | | 2 | TxIn_2 ∈ Shard_Y | --> | TxOut_2 ∈ Shard_Y | 2 | | 3 | TxIn_3 ∈ Shard_Y | --> | TxOut_3 ∈ Shard_Y | 3 |

The order is not deterministic.

func ValidateTransactionScripts

func ValidateTransactionScripts(tx *jaxutil.Tx, utxoView *UtxoViewpoint,
	flags txscript.ScriptFlags, sigCache *txscript.SigCache,
	hashCache *txscript.HashCache) error

ValidateTransactionScripts validates the scripts for the passed transaction using multiple goroutines.

func ValidateWitnessCommitment

func ValidateWitnessCommitment(blk *jaxutil.Block) error

ValidateWitnessCommitment validates the witness commitment (if any) found within the coinbase transaction of the passed block.

Types

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 uint32

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

	// BFNoPoWCheck may be set to indicate the proof of work check which
	// ensures a block hashes to a value less than the required target will
	// not be performed.
	BFNoPoWCheck

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

type BestChainState

type BestChainState struct {
	Hash chainhash.Hash

	TotalTxns uint64
	// contains filtered or unexported fields
}

BestChainState represents the data to be stored the database for the current best chain state.

func DeserializeBestChainState

func DeserializeBestChainState(serializedData []byte) (BestChainState, error)

DeserializeBestChainState deserializes the passed serialized best chain state. This is data stored in the chain state bucket and is updated after every block is connected or disconnected form the main chain. block.

type BestState

type BestState struct {
	Hash        chainhash.Hash // The hash of the block.
	Height      int32          // The height of the block.
	Bits        uint32         // The difficulty bits of the block.
	K           uint32         // The K coefficient.
	BlockSize   uint64         // The size of the block.
	BlockWeight uint64         // The weight of the block.
	NumTxns     uint64         // The number of txns in the block.
	TotalTxns   uint64         // The total number of txns in the chain.
	MedianTime  time.Time      // Median time as per CalcPastMedianTime.
}

BestState houses information about the current best block and other info related to the state of the main chain as it exists from the point of view of the current best block.

The BestSnapshot method can be used to obtain access to this information in a concurrent safe manner and the data will not be changed out from under the caller when chain state changes occur as the function name implies. However, the returned snapshot must be treated as immutable since it is shared by all callers.

func NewBestState

func NewBestState(node blocknode.IBlockNode, blockSize, blockWeight, numTxns,
	totalTxns uint64, medianTime time.Time) *BestState

NewBestState returns a new best stats instance for the given parameters.

type DeploymentError

type DeploymentError uint32

DeploymentError identifies an error that indicates a deployment ID was specified that does not exist.

func (DeploymentError) Error

func (e DeploymentError) Error() string

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

type ErrDeserialize

type ErrDeserialize string

ErrDeserialize signifies that a problem was encountered when deserializing data.

func (ErrDeserialize) Error

func (e ErrDeserialize) Error() string

Error implements the error interface.

type ErrNotInMainChain

type ErrNotInMainChain string

ErrNotInMainChain signifies that a block Hash or height that is not in the main chain was requested.

func (ErrNotInMainChain) Error

func (e ErrNotInMainChain) Error() string

Error implements the error interface.

type ErrorCode

type ErrorCode int

ErrorCode identifies a kind of error.

const (
	// ErrDuplicateBlock indicates a block with the same Hash already
	// exists.
	ErrDuplicateBlock ErrorCode = iota

	// ErrBlockTooBig indicates the serialized block size exceeds the
	// maximum allowed size.
	ErrBlockTooBig

	// ErrBlockWeightTooHigh indicates that the block's computed weight
	// metric exceeds the maximum allowed value.
	ErrBlockWeightTooHigh

	// ErrBlockVersionTooOld indicates the block version is too old and is
	// no longer accepted since the majority of the network has upgraded
	// to a newer version.
	ErrBlockVersionTooOld

	// ErrInvalidTime indicates the time in the passed block has a precision
	// that is more than one second.  The chain consensus rules require
	// timestamps to have a maximum precision of one second.
	ErrInvalidTime

	// ErrTimeTooOld indicates the time is either before the median time of
	// the last several blocks per the chain consensus rules or prior to the
	// most recent checkpoint.
	ErrTimeTooOld

	// ErrTimeTooNew indicates the time is too far in the future as compared
	// the current time.
	ErrTimeTooNew

	// ErrDifficultyTooLow indicates the difficulty for the block is lower
	// than the difficulty required by the most recent checkpoint.
	ErrDifficultyTooLow

	// ErrUnexpectedDifficulty indicates specified bits do not align with
	// the expected value either because it doesn't match the calculated
	// valued based on difficulty regarted rules or it is out of the valid
	// range.
	ErrUnexpectedDifficulty

	// ErrHighHash indicates the block does not Hash to a value which is
	// lower than the required target difficultly.
	ErrHighHash

	// ErrBadMerkleRoot indicates the calculated merkle root does not match
	// the expected value.
	ErrBadMerkleRoot

	// ErrBadCheckpoint indicates a block that is expected to be at a
	// checkpoint height does not match the expected one.
	ErrBadCheckpoint

	// ErrForkTooOld indicates a block is attempting to fork the block chain
	// before the most recent checkpoint.
	ErrForkTooOld

	// ErrCheckpointTimeTooOld indicates a block has a timestamp before the
	// most recent checkpoint.
	ErrCheckpointTimeTooOld

	// ErrNoTransactions indicates the block does not have a least one
	// transaction.  A valid block must have at least the coinbase
	// transaction.
	ErrNoTransactions

	// ErrNoTxInputs indicates a transaction does not have any inputs.  A
	// valid transaction must have at least one input.
	ErrNoTxInputs

	// ErrNoTxOutputs indicates a transaction does not have any outputs.  A
	// valid transaction must have at least one output.
	ErrNoTxOutputs

	// ErrTxTooBig indicates a transaction exceeds the maximum allowed size
	// when serialized.
	ErrTxTooBig

	// ErrBadTxOutValue indicates an output value for a transaction is
	// invalid in some way such as being out of range.
	ErrBadTxOutValue

	// ErrDuplicateTxInputs indicates a transaction references the same
	// input more than once.
	ErrDuplicateTxInputs

	// ErrBadTxInput indicates a transaction input is invalid in some way
	// such as referencing a previous transaction outpoint which is out of
	// range or not referencing one at all.
	ErrBadTxInput

	// ErrMissingTxOut indicates a transaction output referenced by an input
	// either does not exist or has already been spent.
	ErrMissingTxOut

	// ErrUnfinalizedTx indicates a transaction has not been finalized.
	// A valid block may only contain finalized transactions.
	ErrUnfinalizedTx

	// ErrDuplicateTx indicates a block contains an identical transaction
	// (or at least two transactions which Hash to the same value).  A
	// valid block may only contain unique transactions.
	ErrDuplicateTx

	// ErrOverwriteTx indicates a block contains a transaction that has
	// the same Hash as a previous transaction which has not been fully
	// spent.
	ErrOverwriteTx

	// ErrImmatureSpend indicates a transaction is attempting to spend a
	// coinbase that has not yet reached the required maturity.
	ErrImmatureSpend

	// ErrSpendTooHigh indicates a transaction is attempting to spend more
	// value than the sum of all of its inputs.
	ErrSpendTooHigh

	// ErrBadFees indicates the total fees for a block are invalid due to
	// exceeding the maximum possible value.
	ErrBadFees

	// ErrTooManySigOps indicates the total number of signature operations
	// for a transaction or block exceed the maximum allowed limits.
	ErrTooManySigOps

	// ErrFirstTxNotCoinbase indicates the first transaction in a block
	// is not a coinbase transaction.
	ErrFirstTxNotCoinbase

	// ErrMultipleCoinbases indicates a block contains more than one
	// coinbase transaction.
	ErrMultipleCoinbases

	// ErrBadCoinbaseScriptLen indicates the length of the signature script
	// for a coinbase transaction is not within the valid range.
	ErrBadCoinbaseScriptLen

	// ErrBadCoinbaseValue indicates the amount of a coinbase value does
	// not match the expected value of the subsidy plus the sum of all fees.
	ErrBadCoinbaseValue

	// ErrMissingCoinbaseHeight indicates the coinbase transaction for a
	// block does not start with the serialized block block height as
	// required for version 2 and higher blocks.
	ErrMissingCoinbaseHeight

	// ErrBadCoinbaseHeight indicates the serialized block height in the
	// coinbase transaction for version 2 and higher blocks does not match
	// the expected value.
	ErrBadCoinbaseHeight

	// ErrScriptMalformed indicates a transaction script is malformed in
	// some way.  For example, it might be longer than the maximum allowed
	// length or fail to parse.
	ErrScriptMalformed

	// ErrScriptValidation indicates the result of executing transaction
	// script failed.  The error covers any failure when executing scripts
	// such signature verification failures and execution past the end of
	// the stack.
	ErrScriptValidation

	// ErrUnexpectedWitness indicates that a block includes transactions
	// with witness data, but doesn't also have a witness commitment within
	// the coinbase transaction.
	ErrUnexpectedWitness

	// ErrInvalidWitnessCommitment indicates that a block's witness
	// commitment is not well formed.
	ErrInvalidWitnessCommitment

	// ErrWitnessCommitmentMismatch indicates that the witness commitment
	// included in the block's coinbase transaction doesn't match the
	// manually computed witness commitment.
	ErrWitnessCommitmentMismatch

	// ErrPreviousBlockUnknown indicates that the previous block is not known.
	ErrPreviousBlockUnknown

	// ErrInvalidAncestorBlock indicates that an ancestor of this block has
	// already failed validation.
	ErrInvalidAncestorBlock

	// ErrPrevBlockNotBest indicates that the block's previous block is not the
	// current chain tip. This is not a block validation rule, but is required
	// for block proposals submitted via getblocktemplate RPC.
	ErrPrevBlockNotBest

	// ErrInvalidShardSwapInOuts indicates that tx content not match
	// with ShardsSwapTx requirements.
	ErrInvalidShardSwapInOuts
)

These constants are used to identify a specific RuleError.

func (ErrorCode) String

func (e ErrorCode) String() string

String returns the ErrorCode as a human-readable name.

type MedianTimeSource

type MedianTimeSource interface {
	// AdjustedTime returns the current time adjusted by the median time
	// offset as calculated from the time samples added by AddTimeSample.
	AdjustedTime() time.Time

	// AddTimeSample adds a time sample that is used when determining the
	// median time of the added samples.
	AddTimeSample(id string, timeVal time.Time)

	// Offset returns the number of seconds to adjust the local clock based
	// upon the median of the time samples added by AddTimeData.
	Offset() time.Duration
}

MedianTimeSource provides a mechanism to add several time samples which are used to determine a median time which is then used as an offset to the local clock.

func NewMedianTime

func NewMedianTime() MedianTimeSource

NewMedianTime returns a new instance of concurrency-safe implementation of the MedianTimeSource interface. The returned implementation contains the rules necessary for proper time handling in the chain consensus rules and expects the time samples to be added from the timestamp field of the version message received from remote peers that successfully connect and negotiate.

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 NewRuleError

func NewRuleError(c ErrorCode, desc string) RuleError

NewRuleError creates an RuleError given a set of arguments.

func (RuleError) Error

func (e RuleError) Error() string

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

type SequenceLock

type SequenceLock struct {
	Seconds     int64
	BlockHeight int32
}

SequenceLock represents the converted relative lock-time in seconds, and absolute block-height for a transaction input's relative lock-times. According to SequenceLock, after the referenced input has been confirmed within a block, a transaction spending that input can be included into a block either after 'seconds' (according to past median time), or once the 'BlockHeight' has been reached.

type SerialValue

type SerialValue struct {
	Hash   *chainhash.Hash `json:"hash"`
	PrevID int64           `json:"prev_id"`
}

type SpentTxOut

type SpentTxOut struct {
	// Amount is the amount of the output.
	Amount int64

	// PkScipt is the the public key script for the output.
	PkScript []byte

	// Height is the height of the the block containing the creating tx.
	Height int32

	// Denotes if the creating tx is a coinbase.
	IsCoinBase bool
}

SpentTxOut contains a spent transaction output and potentially additional contextual information such as whether or not it was contained in a coinbase transaction, the version of the transaction it was contained in, and which block height the containing transaction was included in. As described in the comments above, the additional contextual information will only be valid when this spent txout is spending the last unspent output of the containing transaction.

func DBFetchSpendJournalEntry

func DBFetchSpendJournalEntry(dbTx database.Tx, block *jaxutil.Block) ([]SpentTxOut, error)

DBFetchSpendJournalEntry fetches the spend journal entry for the passed block and deserializes it into a slice of spent txout entries.

NOTE: Legacy entries will not have the coinbase flag or height set unless it was the final output spend in the containing transaction. It is up to the caller to handle this properly by looking the information up in the utxo set.

type UtxoEntry

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

UtxoEntry houses details about an individual transaction output in a utxo view such as whether or not it was contained in a coinbase tx, the height of the block that contains the tx, whether or not it is spent, its public key script, and how much it pays.

func DBFetchUtxoEntry

func DBFetchUtxoEntry(dbTx database.Tx, outpoint wire.OutPoint) (*UtxoEntry, error)

DBFetchUtxoEntry uses an existing database transaction to fetch the specified transaction output from the utxo set.

When there is no entry for the provided output, nil will be returned for both the entry and the error.

func (*UtxoEntry) Amount

func (entry *UtxoEntry) Amount() int64

Amount returns the amount of the output.

func (*UtxoEntry) BlockHeight

func (entry *UtxoEntry) BlockHeight() int32

BlockHeight returns the height of the block containing the output.

func (*UtxoEntry) Clone

func (entry *UtxoEntry) Clone() *UtxoEntry

Clone returns a shallow copy of the utxo entry.

func (*UtxoEntry) IsCoinBase

func (entry *UtxoEntry) IsCoinBase() bool

IsCoinBase returns whether or not the output was contained in a coinbase transaction.

func (*UtxoEntry) IsSpent

func (entry *UtxoEntry) IsSpent() bool

IsSpent returns whether or not the output has been spent based upon the current state of the unspent transaction output view it was obtained from.

func (*UtxoEntry) PkScript

func (entry *UtxoEntry) PkScript() []byte

PkScript returns the public key script for the output.

func (*UtxoEntry) Spend

func (entry *UtxoEntry) Spend()

Spend marks the output as spent. Spending an output that is already spent has no effect.

type UtxoViewpoint

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

UtxoViewpoint represents a view into the set of unspent transaction outputs from a specific point of view in the chain. For example, it could be for the end of the main chain, some point in the history of the main chain, or down a side chain.

The unspent outputs are needed by other transactions for things such as script validation and double spend prevention.

func NewUtxoViewpoint

func NewUtxoViewpoint(beacon bool) *UtxoViewpoint

NewUtxoViewpoint returns a new empty unspent transaction output view.

func (*UtxoViewpoint) AddTxOut

func (view *UtxoViewpoint) AddTxOut(tx *jaxutil.Tx, txOutIdx uint32, blockHeight int32)

AddTxOut adds the specified output of the passed transaction to the view if it exists and is not provably unspendable. When the view already has an entry for the output, it will be marked unspent. All fields will be updated for existing entries since it's possible it has changed during a reorg.

func (*UtxoViewpoint) AddTxOuts

func (view *UtxoViewpoint) AddTxOuts(tx *jaxutil.Tx, blockHeight int32)

AddTxOuts adds all outputs in the passed transaction which are not provably unspendable to the view. When the view already has entries for any of the outputs, they are simply marked unspent. All fields will be updated for existing entries since it's possible it has changed during a reorg.

func (*UtxoViewpoint) BestHash

func (view *UtxoViewpoint) BestHash() *chainhash.Hash

BestHash returns the Hash of the best block in the chain the view currently respresents.

func (*UtxoViewpoint) Commit

func (view *UtxoViewpoint) Commit()

Commit prunes all entries marked modified that are now fully spent and marks all entries as unmodified.

func (*UtxoViewpoint) ConnectTransaction

func (view *UtxoViewpoint) ConnectTransaction(tx *jaxutil.Tx, blockHeight int32, stxos *[]SpentTxOut) error

ConnectTransaction updates the view by adding all new utxos created by the passed transaction and marking all utxos that the transactions spend as spent. In addition, when the 'stxos' argument is not nil, it will be updated to append an entry for each spent txout. An error will be returned if the view does not contain the required utxos.

func (*UtxoViewpoint) ConnectTransactions

func (view *UtxoViewpoint) ConnectTransactions(block *jaxutil.Block, stxos *[]SpentTxOut) error

ConnectTransactions updates the view by adding all new utxos created by all of the transactions in the passed block, marking all utxos the transactions spend as spent, and setting the best Hash for the view to the passed block. In addition, when the 'stxos' argument is not nil, it will be updated to append an entry for each spent txout.

func (*UtxoViewpoint) DisconnectTransactions

func (view *UtxoViewpoint) DisconnectTransactions(db database.DB, block *jaxutil.Block, stxos []SpentTxOut) error

DisconnectTransactions updates the view by removing all of the transactions created by the passed block, restoring all utxos the transactions spent by using the provided spent txo information, and setting the best Hash for the view to the block before the passed block.

func (*UtxoViewpoint) EADAddressesSet

func (view *UtxoViewpoint) EADAddressesSet() map[string]*wire.EADAddresses

func (*UtxoViewpoint) Entries

func (view *UtxoViewpoint) Entries() map[wire.OutPoint]*UtxoEntry

Entries returns the underlying map that stores of all the utxo entries.

func (*UtxoViewpoint) FetchInputUtxos

func (view *UtxoViewpoint) FetchInputUtxos(db database.DB, block *jaxutil.Block) error

FetchInputUtxos loads the unspent transaction outputs for the inputs referenced by the transactions in the given block into the view from the database as needed. In particular, referenced entries that are earlier in the block are added to the view and entries that are already in the view are not modified.

func (*UtxoViewpoint) FetchUtxos

func (view *UtxoViewpoint) FetchUtxos(db database.DB, outpoints map[wire.OutPoint]struct{}) error

FetchUtxos loads the unspent transaction outputs for the provided set of outputs into the view from the database as needed unless they already exist in the view in which case they are ignored.

func (*UtxoViewpoint) FetchUtxosMain

func (view *UtxoViewpoint) FetchUtxosMain(db database.DB, outpoints map[wire.OutPoint]struct{}) error

FetchUtxosMain fetches unspent transaction output data about the provided set of outpoints from the point of view of the end of the main chain at the time of the call.

Upon completion of this function, the view will contain an entry for each requested outpoint. Spent outputs, or those which otherwise don't exist, will result in a nil entry in the view.

func (*UtxoViewpoint) LookupEntry

func (view *UtxoViewpoint) LookupEntry(outpoint wire.OutPoint) *UtxoEntry

LookupEntry returns information about a given transaction output according to the current state of the view. It will return nil if the passed output does not exist in the view or is otherwise not available such as when it has been disconnected during a reorg.

func (*UtxoViewpoint) RemoveEntry

func (view *UtxoViewpoint) RemoveEntry(outpoint wire.OutPoint)

RemoveEntry removes the given transaction output from the current state of the view. It will have no effect if the passed output does not exist in the view.

func (*UtxoViewpoint) SetBestHash

func (view *UtxoViewpoint) SetBestHash(hash *chainhash.Hash)

SetBestHash sets the Hash of the best block in the chain the view currently respresents.

Jump to

Keyboard shortcuts

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