github.com/ZuluSpl0it/Sia@v1.3.7/modules/consensus.go (about)

     1  package modules
     2  
     3  import (
     4  	"errors"
     5  
     6  	"github.com/NebulousLabs/Sia/crypto"
     7  	"github.com/NebulousLabs/Sia/types"
     8  )
     9  
    10  const (
    11  	// ConsensusDir is the name of the directory used for all of the consensus
    12  	// persistence files.
    13  	ConsensusDir = "consensus"
    14  
    15  	// DiffApply indicates that a diff is being applied to the consensus set.
    16  	DiffApply DiffDirection = true
    17  
    18  	// DiffRevert indicates that a diff is being reverted from the consensus
    19  	// set.
    20  	DiffRevert DiffDirection = false
    21  )
    22  
    23  var (
    24  	// ConsensusChangeBeginning is a special consensus change id that tells the
    25  	// consensus set to provide all consensus changes starting from the very
    26  	// first diff, which includes the genesis block diff.
    27  	ConsensusChangeBeginning = ConsensusChangeID{}
    28  
    29  	// ConsensusChangeRecent is a special consensus change id that tells the
    30  	// consensus set to provide the most recent consensus change, instead of
    31  	// starting from a specific value (which may not be known to the caller).
    32  	ConsensusChangeRecent = ConsensusChangeID{1}
    33  
    34  	// ErrBlockKnown is an error indicating that a block is already in the
    35  	// database.
    36  	ErrBlockKnown = errors.New("block already present in database")
    37  
    38  	// ErrBlockUnsolved indicates that a block did not meet the required POW
    39  	// target.
    40  	ErrBlockUnsolved = errors.New("block does not meet target")
    41  
    42  	// ErrInvalidConsensusChangeID indicates that ConsensusSetPersistSubscribe
    43  	// was called with a consensus change id that is not recognized. Most
    44  	// commonly, this means that the consensus set was deleted or replaced and
    45  	// now the module attempting the subscription has desynchronized. This error
    46  	// should be handled by the module, and not reported to the user.
    47  	ErrInvalidConsensusChangeID = errors.New("consensus subscription has invalid id - files are inconsistent")
    48  
    49  	// ErrNonExtendingBlock indicates that a block is valid but does not result
    50  	// in a fork that is the heaviest known fork - the consensus set has not
    51  	// changed as a result of seeing the block.
    52  	ErrNonExtendingBlock = errors.New("block does not extend the longest fork")
    53  )
    54  
    55  type (
    56  	// ConsensusChangeID is the id of a consensus change.
    57  	ConsensusChangeID crypto.Hash
    58  
    59  	// A DiffDirection indicates the "direction" of a diff, either applied or
    60  	// reverted. A bool is used to restrict the value to these two possibilities.
    61  	DiffDirection bool
    62  
    63  	// A ConsensusSetSubscriber is an object that receives updates to the consensus
    64  	// set every time there is a change in consensus.
    65  	ConsensusSetSubscriber interface {
    66  		// ProcessConsensusChange sends a consensus update to a module through
    67  		// a function call. Updates will always be sent in the correct order.
    68  		// There may not be any reverted blocks, but there will always be
    69  		// applied blocks.
    70  		ProcessConsensusChange(ConsensusChange)
    71  	}
    72  
    73  	// A ConsensusChange enumerates a set of changes that occurred to the consensus set.
    74  	ConsensusChange struct {
    75  		// ID is a unique id for the consensus change derived from the reverted
    76  		// and applied blocks.
    77  		ID ConsensusChangeID
    78  
    79  		// RevertedBlocks is the list of blocks that were reverted by the change.
    80  		// The reverted blocks were always all reverted before the applied blocks
    81  		// were applied. The revered blocks are presented in the order that they
    82  		// were reverted.
    83  		RevertedBlocks []types.Block
    84  
    85  		// AppliedBlocks is the list of blocks that were applied by the change. The
    86  		// applied blocks are always all applied after all the reverted blocks were
    87  		// reverted. The applied blocks are presented in the order that they were
    88  		// applied.
    89  		AppliedBlocks []types.Block
    90  
    91  		// SiacoinOutputDiffs contains the set of siacoin diffs that were applied
    92  		// to the consensus set in the recent change. The direction for the set of
    93  		// diffs is 'DiffApply'.
    94  		SiacoinOutputDiffs []SiacoinOutputDiff
    95  
    96  		// FileContractDiffs contains the set of file contract diffs that were
    97  		// applied to the consensus set in the recent change. The direction for the
    98  		// set of diffs is 'DiffApply'.
    99  		FileContractDiffs []FileContractDiff
   100  
   101  		// SiafundOutputDiffs contains the set of siafund diffs that were applied
   102  		// to the consensus set in the recent change. The direction for the set of
   103  		// diffs is 'DiffApply'.
   104  		SiafundOutputDiffs []SiafundOutputDiff
   105  
   106  		// DelayedSiacoinOutputDiffs contains the set of delayed siacoin output
   107  		// diffs that were applied to the consensus set in the recent change.
   108  		DelayedSiacoinOutputDiffs []DelayedSiacoinOutputDiff
   109  
   110  		// SiafundPoolDiffs are the siafund pool diffs that were applied to the
   111  		// consensus set in the recent change.
   112  		SiafundPoolDiffs []SiafundPoolDiff
   113  
   114  		// ChildTarget defines the target of any block that would be the child
   115  		// of the block most recently appended to the consensus set.
   116  		ChildTarget types.Target
   117  
   118  		// MinimumValidChildTimestamp defines the minimum allowed timestamp for
   119  		// any block that is the child of the block most recently appended to
   120  		// the consensus set.
   121  		MinimumValidChildTimestamp types.Timestamp
   122  
   123  		// Synced indicates whether or not the ConsensusSet is synced with its
   124  		// peers.
   125  		Synced bool
   126  
   127  		// TryTransactionSet is an unlocked version of
   128  		// ConsensusSet.TryTransactionSet. This allows the TryTransactionSet
   129  		// function to be called by a subscriber during
   130  		// ProcessConsensusChange.
   131  		TryTransactionSet func([]types.Transaction) (ConsensusChange, error)
   132  	}
   133  
   134  	// A SiacoinOutputDiff indicates the addition or removal of a SiacoinOutput in
   135  	// the consensus set.
   136  	SiacoinOutputDiff struct {
   137  		Direction     DiffDirection
   138  		ID            types.SiacoinOutputID
   139  		SiacoinOutput types.SiacoinOutput
   140  	}
   141  
   142  	// A FileContractDiff indicates the addition or removal of a FileContract in
   143  	// the consensus set.
   144  	FileContractDiff struct {
   145  		Direction    DiffDirection
   146  		ID           types.FileContractID
   147  		FileContract types.FileContract
   148  	}
   149  
   150  	// A SiafundOutputDiff indicates the addition or removal of a SiafundOutput in
   151  	// the consensus set.
   152  	SiafundOutputDiff struct {
   153  		Direction     DiffDirection
   154  		ID            types.SiafundOutputID
   155  		SiafundOutput types.SiafundOutput
   156  	}
   157  
   158  	// A DelayedSiacoinOutputDiff indicates the introduction of a siacoin output
   159  	// that cannot be spent until after maturing for 144 blocks. When the output
   160  	// has matured, a SiacoinOutputDiff will be provided.
   161  	DelayedSiacoinOutputDiff struct {
   162  		Direction      DiffDirection
   163  		ID             types.SiacoinOutputID
   164  		SiacoinOutput  types.SiacoinOutput
   165  		MaturityHeight types.BlockHeight
   166  	}
   167  
   168  	// A SiafundPoolDiff contains the value of the siafundPool before the block
   169  	// was applied, and after the block was applied. When applying the diff, set
   170  	// siafundPool to 'Adjusted'. When reverting the diff, set siafundPool to
   171  	// 'Previous'.
   172  	SiafundPoolDiff struct {
   173  		Direction DiffDirection
   174  		Previous  types.Currency
   175  		Adjusted  types.Currency
   176  	}
   177  
   178  	// A ConsensusSet accepts blocks and builds an understanding of network
   179  	// consensus.
   180  	ConsensusSet interface {
   181  		// AcceptBlock adds a block to consensus. An error will be returned if the
   182  		// block is invalid, has been seen before, is an orphan, or doesn't
   183  		// contribute to the heaviest fork known to the consensus set. If the block
   184  		// does not become the head of the heaviest known fork but is otherwise
   185  		// valid, it will be remembered by the consensus set but an error will
   186  		// still be returned.
   187  		AcceptBlock(types.Block) error
   188  
   189  		// BlockAtHeight returns the block found at the input height, with a
   190  		// bool to indicate whether that block exists.
   191  		BlockAtHeight(types.BlockHeight) (types.Block, bool)
   192  
   193  		// BlocksByID returns a block found for a given ID and its height, with
   194  		// a bool to indicate whether that block exists.
   195  		BlockByID(types.BlockID) (types.Block, types.BlockHeight, bool)
   196  
   197  		// ChildTarget returns the target required to extend the current heaviest
   198  		// fork. This function is typically used by miners looking to extend the
   199  		// heaviest fork.
   200  		ChildTarget(types.BlockID) (types.Target, bool)
   201  
   202  		// Close will shut down the consensus set, giving the module enough time to
   203  		// run any required closing routines.
   204  		Close() error
   205  
   206  		// ConsensusSetSubscribe adds a subscriber to the list of subscribers
   207  		// and gives them every consensus change that has occurred since the
   208  		// change with the provided id. There are a few special cases,
   209  		// described by the ConsensusChangeX variables in this package.
   210  		// A channel can be provided to abort the subscription process.
   211  		ConsensusSetSubscribe(ConsensusSetSubscriber, ConsensusChangeID, <-chan struct{}) error
   212  
   213  		// CurrentBlock returns the latest block in the heaviest known
   214  		// blockchain.
   215  		CurrentBlock() types.Block
   216  
   217  		// Flush will cause the consensus set to finish all in-progress
   218  		// routines.
   219  		Flush() error
   220  
   221  		// Height returns the current height of consensus.
   222  		Height() types.BlockHeight
   223  
   224  		// Synced returns true if the consensus set is synced with the network.
   225  		Synced() bool
   226  
   227  		// InCurrentPath returns true if the block id presented is found in the
   228  		// current path, false otherwise.
   229  		InCurrentPath(types.BlockID) bool
   230  
   231  		// MinimumValidChildTimestamp returns the earliest timestamp that is
   232  		// valid on the current longest fork according to the consensus set. This is
   233  		// a required piece of information for the miner, who could otherwise be at
   234  		// risk of mining invalid blocks.
   235  		MinimumValidChildTimestamp(types.BlockID) (types.Timestamp, bool)
   236  
   237  		// StorageProofSegment returns the segment to be used in the storage proof for
   238  		// a given file contract.
   239  		StorageProofSegment(types.FileContractID) (uint64, error)
   240  
   241  		// TryTransactionSet checks whether the transaction set would be valid if
   242  		// it were added in the next block. A consensus change is returned
   243  		// detailing the diffs that would result from the application of the
   244  		// transaction.
   245  		TryTransactionSet([]types.Transaction) (ConsensusChange, error)
   246  
   247  		// Unsubscribe removes a subscriber from the list of subscribers,
   248  		// allowing for garbage collection and rescanning. If the subscriber is
   249  		// not found in the subscriber database, no action is taken.
   250  		Unsubscribe(ConsensusSetSubscriber)
   251  	}
   252  )
   253  
   254  // Append takes to ConsensusChange objects and adds all of their diffs together.
   255  //
   256  // NOTE: It is possible for diffs to overlap or be inconsistent. This function
   257  // should only be used with consecutive or disjoint consensus change objects.
   258  func (cc ConsensusChange) Append(cc2 ConsensusChange) ConsensusChange {
   259  	return ConsensusChange{
   260  		RevertedBlocks:            append(cc.RevertedBlocks, cc2.RevertedBlocks...),
   261  		AppliedBlocks:             append(cc.AppliedBlocks, cc2.AppliedBlocks...),
   262  		SiacoinOutputDiffs:        append(cc.SiacoinOutputDiffs, cc2.SiacoinOutputDiffs...),
   263  		FileContractDiffs:         append(cc.FileContractDiffs, cc2.FileContractDiffs...),
   264  		SiafundOutputDiffs:        append(cc.SiafundOutputDiffs, cc2.SiafundOutputDiffs...),
   265  		DelayedSiacoinOutputDiffs: append(cc.DelayedSiacoinOutputDiffs, cc2.DelayedSiacoinOutputDiffs...),
   266  	}
   267  }