consensus

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jan 19, 2015 License: MIT Imports: 10 Imported by: 0

Documentation

Index

Constants

View Source
const DEBUG = false

Variables

View Source
var (
	BlockKnownErr    = errors.New("block exists in block map.")
	FutureBlockErr   = errors.New("timestamp too far in future, will try again later.")
	KnownOrphanErr   = errors.New("block is a known orphan")
	UnknownOrphanErr = errors.New("block is an unknown orphan")
)

Exported Errors

View Source
var (
	BlockSizeLimit  = 1024 * 1024 * 1024     // Blocks cannot be more than 1MB.
	BlockFrequency  = Timestamp(10)          // In seconds.
	TargetWindow    = BlockHeight(80)        // Number of blocks to use when calculating the target.
	FutureThreshold = Timestamp(3 * 60 * 60) // Seconds into the future block timestamps are valid.
	RootTarget      = Target{0, 0, 8}
	RootDepth       = Target{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}

	MaxAdjustmentUp   = big.NewRat(103, 100)
	MaxAdjustmentDown = big.NewRat(97, 100)

	InitialCoinbase = Currency(300000)
	MinimumCoinbase = Currency(30000)

	GenesisAddress   = CoinAddress{}         // TODO: NEED TO CREATE A HARDCODED ADDRESS.
	GenesisTimestamp = Timestamp(1417070299) // Approx. 1:47pm EST Nov. 13th, 2014
)

Though these are variables, they should never be changed during runtime. They get altered during testing.

View Source
var (
	ConflictingTransactionErr = errors.New("conflicting transaction exists in transaction pool")
	InvalidSignatureErr       = errors.New("invalid signature in transaction")
)

Exported errors

View Source
var SurpassThreshold = big.NewRat(5, 100)

TODO: Find a better place for this. SurpassThreshold isn't really a consensus rule, it can be modified. That tells me it should be in siad but deciding when to fork is pretty fundamental to the AcceptBlock code.

Functions

func CreateGenesisState

func CreateGenesisState() (s *State, diffs []OutputDiff)

CreateGenesisState will create the state that contains the genesis block and nothing else.

Types

type Block

type Block struct {
	ParentBlockID BlockID
	Timestamp     Timestamp
	Nonce         uint64
	MinerAddress  CoinAddress
	MerkleRoot    hash.Hash
	Transactions  []Transaction
}

Eventually, the Block and the block header will be two separate structs. This will be put into practice when we implement merged mining.

func (Block) CheckTarget

func (b Block) CheckTarget(target Target) bool

CheckTarget() returns true if the block id is lower than the target.

func (Block) ID

func (b Block) ID() BlockID

Block.ID() returns a hash of the block, which is used as the block identifier. Transactions are not included in the hash.

func (Block) SubsidyID

func (b Block) SubsidyID() OutputID

SubisdyID() returns the id of the output created by the block subsidy.

func (Block) TransactionMerkleRoot

func (b Block) TransactionMerkleRoot() hash.Hash

ExpectedTransactionMerkleRoot() returns the expected transaction merkle root of the block.

type BlockDiff

type BlockDiff struct {
	CatalystBlock    BlockID // Which block was used to derive the diffs.
	TransactionDiffs []TransactionDiff
	BlockChanges     TransactionDiff // Changes specific to the block being in place - subsidies and contract maintenance.
}

A BlockDiff contains the list of changes that happened to the state when changing from one block to another. A diff is bi-directional, and deterministically applied.

type BlockHeight

type BlockHeight uint64

type BlockID

type BlockID hash.Hash

type BlockNode

type BlockNode struct {
	Block    *Block
	Children []*BlockNode

	Height           BlockHeight
	Depth            Target        // What the target would need to be to have a weight equal to all blocks up to this block.
	Target           Target        // Target for next block.
	RecentTimestamps [11]Timestamp // The 11 recent timestamps.

	BlockDiff            BlockDiff       // Soon to replace the other 3 entirely
	ContractTerminations []*OpenContract // Contracts that terminated this block.
	MissedStorageProofs  []MissedStorageProof
	SuccessfulWindows    []ContractID
}

A BlockNode contains a block and the list of children to the block. Also contains some consensus information like which contracts have terminated and where there were missed storage proofs.

type BlockWeight

type BlockWeight *big.Rat

type CoinAddress

type CoinAddress hash.Hash // The hash of the spend conditions of an output.

type ConsensusChange

type ConsensusChange struct {
	InvertedBlocks []BlockDiff
	AppliedBlocks  []BlockDiff
}

A ConsensusChange is a list of block diffs that have been applied to the state. The ConsensusChange is sent to everyone who has subscribed to the state.

type ContractDiff

type ContractDiff struct {
	Contract   FileContract
	ContractID ContractID

	New        bool // Whether a new OpenContract should be inserted.
	Terminated bool // Whether the existing OpenContract should be deleted.

	// Either of these will be empty depending on the value of New and
	// Terminated.
	PreviousOpenContract OpenContract
	NewOpenContract      OpenContract
}

type ContractID

type ContractID hash.Hash

type CoveredFields

type CoveredFields struct {
	WholeTransaction bool
	MinerFees        []uint64 // each element indicates an index which is signed.
	Inputs           []uint64
	Outputs          []uint64
	Contracts        []uint64
	StorageProofs    []uint64
	ArbitraryData    []uint64
	Signatures       []uint64
}

type Currency

type Currency uint64

func CalculateCoinbase

func CalculateCoinbase(height BlockHeight) Currency

CalculateCoinbase takes a height and from that derives the coinbase.

type FileContract

type FileContract struct {
	ContractFund       Currency
	FileMerkleRoot     hash.Hash
	FileSize           uint64 // probably in bytes, which means the last element in the merkle tree may not be exactly 64 bytes.
	Start, End         BlockHeight
	ChallengeWindow    BlockHeight // size of window, one window at a time
	Tolerance          uint64      // number of missed proofs before triggering unsuccessful termination
	ValidProofPayout   Currency
	ValidProofAddress  CoinAddress
	MissedProofPayout  Currency
	MissedProofAddress CoinAddress
}

A FileContract contains the information necessary to enforce that a host stores a file.

func (*FileContract) StorageProofOutputID

func (fc *FileContract) StorageProofOutputID(fcID ContractID, height BlockHeight, proofValid bool) (outputID OutputID, err error)

StorageProofOutput() returns the OutputID of the output created during the window index that was active at height 'height'.

func (*FileContract) WindowIndex

func (fc *FileContract) WindowIndex(height BlockHeight) (windowIndex BlockHeight, err error)

WindowIndex returns the index of the challenge window that is open during block height 'height'.

type Input

type Input struct {
	OutputID        OutputID // the source of coins for the input
	SpendConditions SpendConditions
}

An Input contains the ID of the output it's trying to spend, and the spend conditions that unlock the output.

type InputSignatures

type InputSignatures struct {
	RemainingSignatures uint64
	PossibleKeys        []crypto.PublicKey
	UsedKeys            map[uint64]struct{}
	Index               int
}

Each input has a list of public keys and a required number of signatures. InputSignatures keeps track of which public keys have been used and how many more signatures are needed.

type MissedStorageProof

type MissedStorageProof struct {
	OutputID   OutputID
	ContractID ContractID
}

A missed storage proof indicates which contract missed the proof, and which output resulted from the missed proof. This is necessary because missed proofs are passive - they happen in the absense of a transaction, not in the presense of one. They must be stored in the block nodes so that a block can be correctly rewound without needing to scroll through the past 'ChallengeWindow' blocks to figure out if a proof was missed or not.

type OpenContract

type OpenContract struct {
	FileContract    FileContract
	ContractID      ContractID
	FundsRemaining  Currency
	Failures        uint64
	WindowSatisfied bool
}

An open contract contains all information necessary to properly enforce a contract with no knowledge of the history of the contract.

type Output

type Output struct {
	Value     Currency // how many coins are in the output
	SpendHash CoinAddress
}

An Output contains a volume of currency and a 'CoinAddress', which is just a hash of the spend conditions which unlock the output.

type OutputDiff

type OutputDiff struct {
	New    bool
	ID     OutputID
	Output Output
}

An OutputDiff indicates an output that has either been added to or removed from the unspent outputs set. New=true means that the output was added when the block was applied, and new=false means that the output was deleted when the block was applied.

type OutputID

type OutputID hash.Hash

func ContractTerminationOutputID

func ContractTerminationOutputID(fcID ContractID, successfulTermination bool) OutputID

ContractTerminationOutputID() returns the ID of a contract termination output, given the id of the contract and the status of the termination.

type SpendConditions

type SpendConditions struct {
	TimeLock      BlockHeight
	NumSignatures uint64
	PublicKeys    []crypto.PublicKey
}

SpendConditions is a timelock and a set of public keys that are used to unlock ouptuts.

func (*SpendConditions) CoinAddress

func (sc *SpendConditions) CoinAddress() CoinAddress

SpendConditions.CoinAddress() calculates the root hash of a merkle tree of the SpendConditions object, using the timelock, number of signatures required, and each public key as leaves.

type State

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

The state struct contains a list of all known blocks, sorted into a tree according to the shape of the network. It also contains the 'ConsensusState', which represents the state of consensus on the current longest fork.

The state has a RWMutex. Any time you read from or write to the State struct, you need to either have a read lock or a write lock on the state. Internally, the state has no concurrency, so the mutex is never used within the consensus package.

TODO: The mutexing in the consensus package breaks convention.

TODO: When applying blocks and transactions, make the state changes in real time (?) and then if DEBUG, remove and reapply the diffs and make sure that the resulting state is identical to the one that was created when applying in real time.

func (*State) AcceptBlock

func (s *State) AcceptBlock(b Block) (rewoundBlocks []Block, appliedBlocks []Block, outputDiffs []OutputDiff, err error)

State.AcceptBlock() will add blocks to the state, forking the blockchain if they are on a fork that is heavier than the current fork.

func (*State) AcceptTransaction

func (s *State) AcceptTransaction(t Transaction) (err error)

State.AcceptTransaction() checks for a conflict of the transaction with the transaction pool, then checks that the transaction is valid given the current state, then adds the transaction to the transaction pool. AcceptTransaction() is thread safe, and can be called concurrently.

func (*State) BlockAtHeight

func (s *State) BlockAtHeight(height BlockHeight) (b Block, err error)

BlockAtHeight() returns the block from the current history at the input height.

func (*State) BlockFromID

func (s *State) BlockFromID(bid BlockID) (b Block, err error)

BlockFromID returns the block associated with a given id. This function isn't actually used anywhere right now but it seems like it might be useful so I'm keeping it around.

func (*State) ConsensusSubscribe

func (s *State) ConsensusSubscribe() (alert chan ConsensusChange)

ConsensusSubscribe returns a channel that will receive a ConsensusChange notification each time that the consensus changes (from incoming blocks or invalidated blocks, etc.).

func (*State) CurrentBlock

func (s *State) CurrentBlock() Block

CurrentBlock returns the most recent block in the longest fork.

func (*State) CurrentBlockWeight

func (s *State) CurrentBlockWeight() BlockWeight

CurrentBlockWeight() returns the weight of the current block in the heaviest fork.

func (*State) CurrentPathCheck

func (s *State) CurrentPathCheck()

CurrentPathCheck looks at every block listed in CurrentPath and verifies that every block from current to genesis matches the block listed in CurrentPath.

func (*State) CurrentTarget

func (s *State) CurrentTarget() Target

CurrentTarget returns the target of the next block that needs to be submitted to the state.

func (*State) Depth

func (s *State) Depth() Target

State.Depth() returns the depth of the current block of the state.

func (*State) EarliestLegalTimestamp

func (s *State) EarliestLegalTimestamp() Timestamp

EarliestLegalTimestamp returns the earliest legal timestamp of the next block - earlier timestamps will render the block invalid.

func (*State) Height

func (s *State) Height() BlockHeight

State.Height() returns the height of the longest fork.

func (*State) HeightOfBlock

func (s *State) HeightOfBlock(bid BlockID) (height BlockHeight, err error)

HeightOfBlock returns the height of a block given the id.

func (*State) Output

func (s *State) Output(id OutputID) (output Output, err error)

State.Output returns the Output associated with the id provided for input, but only if the output is a part of the utxo set.

func (*State) SortedUtxoSet

func (s *State) SortedUtxoSet() (sortedOutputs []Output)

Sorted UtxoSet returns all of the unspent transaction outputs sorted according to the numerical value of their id.

func (*State) StateHash

func (s *State) StateHash() hash.Hash

StateHash returns the markle root of the current state of consensus.

func (*State) StorageProofSegmentIndex

func (s *State) StorageProofSegmentIndex(contractID ContractID, windowIndex BlockHeight) (index uint64, err error)

StorageProofSegmentIndex takes a contractID and a windowIndex and calculates the index of the segment that should be proven on when doing a proof of storage.

func (*State) TransactionList

func (s *State) TransactionList() (txns []Transaction)

func (*State) TransactionPoolDump

func (s *State) TransactionPoolDump() (transactions []Transaction)

TransactionPoolDump() returns the list of transactions that are valid but haven't yet appeared in a block. It performs a safety/sanity check to verify that no bad transactions have snuck in.

func (*State) ValidTransaction

func (s *State) ValidTransaction(t Transaction) (err error)

ValidTransaction returns err = nil if the transaction is valid, otherwise returns an error explaining what wasn't valid.

type StorageProof

type StorageProof struct {
	ContractID  ContractID
	WindowIndex BlockHeight
	Segment     [hash.SegmentSize]byte
	HashSet     []hash.Hash
}

A StorageProof contains the fields needed for a host to prove that they are still storing a file. Though WindowIndex is of type BlockHeight, it refers to the index of the window, and not the height at which the window starts.

type Target

type Target hash.Hash

func IntToTarget

func IntToTarget(i *big.Int) (t Target)

IntToTarget converts a big.Int to a Target.

func RatToTarget

func RatToTarget(r *big.Rat) Target

RatToTarget converts a big.Rat to a Target.

func (Target) Int

func (t Target) Int() *big.Int

Int returns a Target as a big.Int.

func (Target) Inverse

func (t Target) Inverse() *big.Rat

Inv returns the inverse of a Target as a big.Rat

func (Target) Rat

func (t Target) Rat() *big.Rat

Rat returns a Target as a big.Rat.

type Timestamp

type Timestamp int64

type Transaction

type Transaction struct {
	Inputs        []Input
	MinerFees     []Currency
	Outputs       []Output
	FileContracts []FileContract
	StorageProofs []StorageProof
	ArbitraryData []string
	Signatures    []TransactionSignature
}

A Transaction is an update to the state of the network, can move money around, make contracts, etc.

func (Transaction) FileContractID

func (t Transaction) FileContractID(index int) ContractID

Transaction.fileContractID returns the id of a file contract given the index of the contract.

func (Transaction) OutputID

func (t Transaction) OutputID(index int) OutputID

Transaction.OuptutID() takes the index of the output and returns the output's ID.

func (*Transaction) SigHash

func (t *Transaction) SigHash(i int) hash.Hash

SigHash returns the hash of a transaction for a specific index. The index determines which TransactionSignature is included in the hash.

type TransactionDiff

type TransactionDiff struct {
	OutputDiffs   []OutputDiff
	ContractDiffs []ContractDiff
}

A TransactionDiff is the diff that gets applied to the state in the presense of a transaction.

type TransactionID

type TransactionID hash.Hash

type TransactionSignature

type TransactionSignature struct {
	InputID        OutputID // the OutputID of the Input that this signature is addressing. Using the index has also been considered.
	TimeLock       BlockHeight
	CoveredFields  CoveredFields
	PublicKeyIndex uint64
	Signature      crypto.Signature
}

A TransactionSignature signs a single input to a transaction to help fulfill the unlock conditions of the transaction. It points to an input, a particular public key, has a timelock, and also indicates which parts of the transaction have been signed.

Jump to

Keyboard shortcuts

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