Commit 62439782 authored by David Vorick's avatar David Vorick

split consensus package into types package and consensus module

parent f6c70616
......@@ -26,7 +26,7 @@ fmt:
# rebuilt. This is necessary because the go tool is not smart enough to trigger
# a rebuild when build tags have been changed.
REBUILD:
@touch consensus/build*.go
@touch types/build*.go
# install builds and installs developer binaries.
install: fmt REBUILD
......
......@@ -3,7 +3,7 @@ package api
import (
"net/http"
"github.com/NebulousLabs/Sia/consensus"
"github.com/NebulousLabs/Sia/types"
)
// consensusStatusHandler handles the API call asking for the consensus status.
......@@ -11,9 +11,9 @@ func (srv *Server) consensusStatusHandler(w http.ResponseWriter, req *http.Reque
currentBlock := srv.state.CurrentBlock().ID()
target := srv.state.CurrentTarget()
writeJSON(w, struct {
Height consensus.BlockHeight
CurrentBlock consensus.BlockID
Target consensus.Target
Height types.BlockHeight
CurrentBlock types.BlockID
Target types.Target
}{
srv.state.Height(),
currentBlock,
......
......@@ -5,12 +5,12 @@ import (
"net/http"
"time"
"github.com/NebulousLabs/Sia/consensus"
"github.com/NebulousLabs/Sia/types"
)
// SiaConstants is a struct listing all of the constants in use.
type SiaConstants struct {
GenesisTimestamp consensus.Timestamp
GenesisTimestamp types.Timestamp
BlockSizeLimit int
BlockFrequency int
TargetWindow int
......@@ -24,8 +24,8 @@ type SiaConstants struct {
MinimumCoinbase int
CoinbaseAugment *big.Int
RootTarget consensus.Target
RootDepth consensus.Target
RootTarget types.Target
RootDepth types.Target
MaxAdjustmentUp *big.Rat
MaxAdjustmentDown *big.Rat
......@@ -48,25 +48,25 @@ type ModuleDeadlockStatus struct {
// debugConstantsHandler prints a json file containing all of the constants.
func (srv *Server) debugConstantsHandler(w http.ResponseWriter, req *http.Request) {
sc := SiaConstants{
GenesisTimestamp: consensus.GenesisTimestamp,
BlockSizeLimit: consensus.BlockSizeLimit,
BlockFrequency: consensus.BlockFrequency,
TargetWindow: consensus.TargetWindow,
MedianTimestampWindow: consensus.MedianTimestampWindow,
FutureThreshold: consensus.FutureThreshold,
SiafundCount: consensus.SiafundCount,
MaturityDelay: consensus.MaturityDelay,
SiafundPortion: consensus.SiafundPortion,
GenesisTimestamp: types.GenesisTimestamp,
BlockSizeLimit: types.BlockSizeLimit,
BlockFrequency: types.BlockFrequency,
TargetWindow: types.TargetWindow,
MedianTimestampWindow: types.MedianTimestampWindow,
FutureThreshold: types.FutureThreshold,
SiafundCount: types.SiafundCount,
MaturityDelay: types.MaturityDelay,
SiafundPortion: types.SiafundPortion,
InitialCoinbase: consensus.InitialCoinbase,
MinimumCoinbase: consensus.MinimumCoinbase,
CoinbaseAugment: consensus.CoinbaseAugment,
InitialCoinbase: types.InitialCoinbase,
MinimumCoinbase: types.MinimumCoinbase,
CoinbaseAugment: types.CoinbaseAugment,
RootTarget: consensus.RootTarget,
RootDepth: consensus.RootDepth,
RootTarget: types.RootTarget,
RootDepth: types.RootDepth,
MaxAdjustmentUp: consensus.MaxAdjustmentUp,
MaxAdjustmentDown: consensus.MaxAdjustmentDown,
MaxAdjustmentUp: types.MaxAdjustmentUp,
MaxAdjustmentDown: types.MaxAdjustmentDown,
}
writeJSON(w, sc)
......@@ -85,7 +85,7 @@ func (srv *Server) mutexTestHandler(w http.ResponseWriter, req *http.Request) {
// changes. After the blocking function unlocks, set the value to true.
var mds ModuleDeadlockStatus
go func() {
srv.state.AcceptBlock(consensus.Block{})
srv.state.AcceptBlock(types.Block{})
mds.State = true
}()
go func() {
......@@ -109,7 +109,7 @@ func (srv *Server) mutexTestHandler(w http.ResponseWriter, req *http.Request) {
mds.Renter = true
}()
go func() {
srv.tpool.AcceptTransaction(consensus.Transaction{})
srv.tpool.AcceptTransaction(types.Transaction{})
mds.TransactionPool = true
}()
go func() {
......
......@@ -3,8 +3,8 @@ package api
import (
"net/http"
"github.com/NebulousLabs/Sia/consensus"
"github.com/NebulousLabs/Sia/modules"
"github.com/NebulousLabs/Sia/types"
)
const (
......@@ -26,7 +26,7 @@ type FileInfo struct {
Available bool
Nickname string
Repairing bool
TimeRemaining consensus.BlockHeight
TimeRemaining types.BlockHeight
}
// renterDownloadHandler handles the API call to download a file.
......
......@@ -5,8 +5,9 @@ import (
"github.com/stretchr/graceful"
"github.com/NebulousLabs/Sia/consensus"
"github.com/NebulousLabs/Sia/modules"
"github.com/NebulousLabs/Sia/modules/consensus"
"github.com/NebulousLabs/Sia/types"
)
// A Server is essentially a collection of modules and an API server to talk
......@@ -64,8 +65,8 @@ func (srv *Server) updateWait() {
// TODO: move this to the state module?
func (srv *Server) acceptBlock(conn modules.NetConn) error {
var b consensus.Block
err := conn.ReadObject(&b, consensus.BlockSizeLimit)
var b types.Block
err := conn.ReadObject(&b, types.BlockSizeLimit)
if err != nil {
return err
}
......@@ -81,7 +82,7 @@ func (srv *Server) acceptBlock(conn modules.NetConn) error {
// Check if b is in the current path.
height, exists := srv.state.HeightOfBlock(b.ID())
if !exists {
if consensus.DEBUG {
if types.DEBUG {
panic("could not get the height of a block that did not return an error when being accepted into the state")
}
return errors.New("state malfunction")
......@@ -97,8 +98,8 @@ func (srv *Server) acceptBlock(conn modules.NetConn) error {
// TODO: move this to the tpool module?
func (srv *Server) acceptTransaction(conn modules.NetConn) error {
var t consensus.Transaction
err := conn.ReadObject(&t, consensus.BlockSizeLimit)
var t types.Transaction
err := conn.ReadObject(&t, types.BlockSizeLimit)
if err != nil {
return err
}
......
......@@ -4,7 +4,7 @@ import (
"fmt"
"net/http"
"github.com/NebulousLabs/Sia/consensus"
"github.com/NebulousLabs/Sia/types"
)
// walletAddressHandler handles the API request for a new address.
......@@ -26,8 +26,8 @@ func (srv *Server) walletAddressHandler(w http.ResponseWriter, req *http.Request
// walletSendHandler handles the API call to send coins to another address.
func (srv *Server) walletSendHandler(w http.ResponseWriter, req *http.Request) {
// Scan the inputs.
var amount consensus.Currency
var dest consensus.UnlockHash
var amount types.Currency
var dest types.UnlockHash
_, err := fmt.Sscan(req.FormValue("amount"), &amount)
if err != nil {
writeError(w, "Malformed amount", http.StatusBadRequest)
......
package modules
import (
"github.com/NebulousLabs/Sia/types"
)
// A DiffDirection indicates the "direction" of a diff, either applied or
// reverted. A bool is used to restrict the value to these two possibilities.
type DiffDirection bool
const (
DiffApply DiffDirection = true
DiffRevert DiffDirection = false
)
// A SiacoinOutputDiff indicates the addition or removal of a SiacoinOutput in
// the consensus set.
type SiacoinOutputDiff struct {
Direction DiffDirection
ID types.SiacoinOutputID
SiacoinOutput types.SiacoinOutput
}
// A FileContractDiff indicates the addition or removal of a FileContract in
// the consensus set.
type FileContractDiff struct {
Direction DiffDirection
ID types.FileContractID
FileContract types.FileContract
}
// A SiafundOutputDiff indicates the addition or removal of a SiafundOutput in
// the consensus set.
type SiafundOutputDiff struct {
Direction DiffDirection
ID types.SiafundOutputID
SiafundOutput types.SiafundOutput
}
// A SiafundPoolDiff contains the value of the siafundPool before the block
// was applied, and after the block was applied. When applying the diff, set
// siafundPool to 'Adjusted'. When reverting the diff, set siafundPool to
// 'Previous'.
type SiafundPoolDiff struct {
Previous types.Currency
Adjusted types.Currency
}
......@@ -4,6 +4,7 @@ import (
"errors"
"github.com/NebulousLabs/Sia/encoding"
"github.com/NebulousLabs/Sia/types"
)
var (
......@@ -19,18 +20,18 @@ var (
// checkMinerPayouts verifies that the sum of all the miner payouts is equal to
// the block subsidy (which is the coinbase + miner fees).
func (s *State) checkMinerPayouts(b Block) (err error) {
func (s *State) checkMinerPayouts(b types.Block) (err error) {
// Sanity check - the block's parent needs to exist and be known.
parentNode, exists := s.blockMap[b.ParentID]
if !exists {
if DEBUG {
if types.DEBUG {
panic("misuse of checkMinerPayouts - block has no known parent")
}
return ErrOrphan
}
// Find the total subsidy for the miners: coinbase + fees.
subsidy := CalculateCoinbase(parentNode.height + 1)
subsidy := types.CalculateCoinbase(parentNode.height + 1)
for _, txn := range b.Transactions {
for _, fee := range txn.MinerFees {
subsidy = subsidy.Add(fee)
......@@ -38,9 +39,9 @@ func (s *State) checkMinerPayouts(b Block) (err error) {
}
// Find the sum of the miner payouts.
var payoutSum Currency
var payoutSum types.Currency
for _, payout := range b.MinerPayouts {
if payout.Value.Cmp(ZeroCurrency) <= 0 {
if payout.Value.Cmp(types.ZeroCurrency) <= 0 {
return errors.New("cannot have zero or negative miner payout")
}
payoutSum = payoutSum.Add(payout.Value)
......@@ -55,7 +56,7 @@ func (s *State) checkMinerPayouts(b Block) (err error) {
}
// validHeader does some early, low computation verification on the block.
func (s *State) validHeader(b Block) (err error) {
func (s *State) validHeader(b types.Block) (err error) {
// Grab the parent of the block.
parent, exists := s.blockMap[b.ParentID]
if !exists {
......@@ -70,7 +71,7 @@ func (s *State) validHeader(b Block) (err error) {
}
// Check that the block is the correct size.
if len(encoding.Marshal(b)) > BlockSizeLimit {
if len(encoding.Marshal(b)) > types.BlockSizeLimit {
return ErrLargeBlock
}
......@@ -82,7 +83,7 @@ func (s *State) validHeader(b Block) (err error) {
// Check that the block is not too far in the future. An external process
// will need to be responsible for resubmitting the block once it is no
// longer in the future.
if b.Timestamp > CurrentTimestamp()+FutureThreshold {
if b.Timestamp > types.CurrentTimestamp()+types.FutureThreshold {
return ErrFutureTimestamp
}
......@@ -99,7 +100,7 @@ func (s *State) validHeader(b Block) (err error) {
// addBlockToTree inserts a block into the blockNode tree by adding it to its
// parent's list of children. If the new blockNode is heavier than the current
// node, the blockchain is forked.
func (s *State) addBlockToTree(b Block) (err error) {
func (s *State) addBlockToTree(b types.Block) (err error) {
parentNode := s.blockMap[b.ParentID]
newNode := parentNode.newChild(b)
......@@ -118,7 +119,7 @@ func (s *State) addBlockToTree(b Block) (err error) {
// AcceptBlock will add blocks to the state, forking the blockchain if they are
// on a fork that is heavier than the current fork.
func (s *State) AcceptBlock(b Block) (err error) {
func (s *State) AcceptBlock(b types.Block) (err error) {
counter := s.mu.Lock()
defer s.mu.Unlock(counter)
......
package consensus
import (
"github.com/NebulousLabs/Sia/modules"
"github.com/NebulousLabs/Sia/types"
)
// applySiacoinInputs takes all of the siacoin inputs in a transaction and
// applies them to the state, updating the diffs in the block node.
func (s *State) applySiacoinInputs(bn *blockNode, t Transaction) {
func (s *State) applySiacoinInputs(bn *blockNode, t types.Transaction) {
// Remove all siacoin inputs from the unspent siacoin outputs list.
for _, sci := range t.SiacoinInputs {
// Sanity check - the input should exist within the blockchain.
if DEBUG {
if types.DEBUG {
_, exists := s.siacoinOutputs[sci.ParentID]
if !exists {
panic("Applying a transaction with an invalid unspent output!")
}
}
bn.siacoinOutputDiffs = append(bn.siacoinOutputDiffs, SiacoinOutputDiff{
Direction: DiffRevert,
bn.siacoinOutputDiffs = append(bn.siacoinOutputDiffs, modules.SiacoinOutputDiff{
Direction: modules.DiffRevert,
ID: sci.ParentID,
SiacoinOutput: s.siacoinOutputs[sci.ParentID],
})
......@@ -24,20 +29,20 @@ func (s *State) applySiacoinInputs(bn *blockNode, t Transaction) {
// applySiacoinOutputs takes all of the siacoin outputs in a transaction and
// applies them to the state, updating the diffs in the block node.
func (s *State) applySiacoinOutputs(bn *blockNode, t Transaction) {
func (s *State) applySiacoinOutputs(bn *blockNode, t types.Transaction) {
// Add all siacoin outputs to the unspent siacoin outputs list.
for i, sco := range t.SiacoinOutputs {
// Sanity check - the output should not exist within the state.
scoid := t.SiacoinOutputID(i)
if DEBUG {
if types.DEBUG {
_, exists := s.siacoinOutputs[scoid]
if exists {
panic("applying a siacoin output when the output already exists")
}
}
bn.siacoinOutputDiffs = append(bn.siacoinOutputDiffs, SiacoinOutputDiff{
Direction: DiffApply,
bn.siacoinOutputDiffs = append(bn.siacoinOutputDiffs, modules.SiacoinOutputDiff{
Direction: modules.DiffApply,
ID: scoid,
SiacoinOutput: sco,
})
......@@ -48,19 +53,19 @@ func (s *State) applySiacoinOutputs(bn *blockNode, t Transaction) {
// applyFileContracts iterates through all of the file contracts in a
// transaction and applies them to the state, updating the diffs in the block
// node.
func (s *State) applyFileContracts(bn *blockNode, t Transaction) {
func (s *State) applyFileContracts(bn *blockNode, t types.Transaction) {
for i, fc := range t.FileContracts {
// Sanity check - the file contract should not exists within the state.
fcid := t.FileContractID(i)
if DEBUG {
if types.DEBUG {
_, exists := s.fileContracts[fcid]
if exists {
panic("applying a file contract when the contract already exists")
}
}
bn.fileContractDiffs = append(bn.fileContractDiffs, FileContractDiff{
Direction: DiffApply,
bn.fileContractDiffs = append(bn.fileContractDiffs, modules.FileContractDiff{
Direction: modules.DiffApply,
ID: fcid,
FileContract: fc,
})
......@@ -72,20 +77,20 @@ func (s *State) applyFileContracts(bn *blockNode, t Transaction) {
// applyFileContractTerminations iterates through all of the file contract
// terminations in a transaction and applies them to the state, updating the
// diffs in the block node.
func (s *State) applyFileContractTerminations(bn *blockNode, t Transaction) {
func (s *State) applyFileContractTerminations(bn *blockNode, t types.Transaction) {
for _, fct := range t.FileContractTerminations {
// Sanity check - termination should affect an existing contract.
fc, exists := s.fileContracts[fct.ParentID]
if !exists {
if DEBUG {
if types.DEBUG {
panic("file contract termination terminates a nonexisting contract")
}
continue
}
// Add the diff for the deletion to the block node.
bn.fileContractDiffs = append(bn.fileContractDiffs, FileContractDiff{
Direction: DiffRevert,
bn.fileContractDiffs = append(bn.fileContractDiffs, modules.FileContractDiff{
Direction: modules.DiffRevert,
ID: fct.ParentID,
FileContract: fc,
})
......@@ -103,12 +108,12 @@ func (s *State) applyFileContractTerminations(bn *blockNode, t Transaction) {
// applyStorageProofs iterates through all of the storage proofs in a
// transaction and applies them to the state, updating the diffs in the block
// node.
func (s *State) applyStorageProofs(bn *blockNode, t Transaction) {
func (s *State) applyStorageProofs(bn *blockNode, t types.Transaction) {
for _, sp := range t.StorageProofs {
// Sanity check - the file contract of the storage proof should exist.
fc, exists := s.fileContracts[sp.ParentID]
if !exists {
if DEBUG {
if types.DEBUG {
panic("storage proof submitted for a file contract that doesn't exist?")
}
continue
......@@ -122,7 +127,7 @@ func (s *State) applyStorageProofs(bn *blockNode, t Transaction) {
for i, output := range fc.ValidProofOutputs {
// Sanity check - output should not already exist.
id := sp.ParentID.StorageProofOutputID(true, i)
if DEBUG {
if types.DEBUG {
_, exists := s.siacoinOutputs[id]
if exists {
panic("storage proof output already exists")
......@@ -133,8 +138,8 @@ func (s *State) applyStorageProofs(bn *blockNode, t Transaction) {
bn.delayedSiacoinOutputs[id] = output
}
bn.fileContractDiffs = append(bn.fileContractDiffs, FileContractDiff{
Direction: DiffRevert,
bn.fileContractDiffs = append(bn.fileContractDiffs, modules.FileContractDiff{
Direction: modules.DiffRevert,
ID: sp.ParentID,
FileContract: fc,
})
......@@ -145,10 +150,10 @@ func (s *State) applyStorageProofs(bn *blockNode, t Transaction) {
// applySiafundInputs takes all of the siafund inputs in a transaction and
// applies them to the state, updating the diffs in the block node.
func (s *State) applySiafundInputs(bn *blockNode, t Transaction) {
func (s *State) applySiafundInputs(bn *blockNode, t types.Transaction) {
for _, sfi := range t.SiafundInputs {
// Sanity check - the input should exist within the blockchain.
if DEBUG {
if types.DEBUG {
_, exists := s.siafundOutputs[sfi.ParentID]
if !exists {
panic("applying a transaction with an invalid unspent siafund output")
......@@ -158,10 +163,10 @@ func (s *State) applySiafundInputs(bn *blockNode, t Transaction) {
// Calculate the volume of siacoins to put in the claim output.
sfo := s.siafundOutputs[sfi.ParentID]
claimPortion := s.siafundPool.Sub(sfo.ClaimStart).Div(NewCurrency64(SiafundCount))
claimPortion := s.siafundPool.Sub(sfo.ClaimStart).Div(types.NewCurrency64(types.SiafundCount))
// Add the claim output to the delayed set of outputs.
sco := SiacoinOutput{
sco := types.SiacoinOutput{
Value: claimPortion,
UnlockHash: sfo.ClaimUnlockHash,
}
......@@ -171,8 +176,8 @@ func (s *State) applySiafundInputs(bn *blockNode, t Transaction) {
// Create the siafund output diff and remove the output from the
// consensus set.
bn.siafundOutputDiffs = append(bn.siafundOutputDiffs, SiafundOutputDiff{
Direction: DiffRevert,
bn.siafundOutputDiffs = append(bn.siafundOutputDiffs, modules.SiafundOutputDiff{
Direction: modules.DiffRevert,
ID: sfi.ParentID,
SiafundOutput: s.siafundOutputs[sfi.ParentID],
})
......@@ -182,11 +187,11 @@ func (s *State) applySiafundInputs(bn *blockNode, t Transaction) {
// applySiafundOutputs takes all of the siafund outputs in a transaction and
// applies them to the state, updating the diffs in the block node.
func (s *State) applySiafundOutputs(bn *blockNode, t Transaction) {
func (s *State) applySiafundOutputs(bn *blockNode, t types.Transaction) {
for i, sfo := range t.SiafundOutputs {
// Sanity check - the output should not exist within the blockchain.
sfoid := t.SiafundOutputID(i)
if DEBUG {
if types.DEBUG {
_, exists := s.siafundOutputs[sfoid]
if exists {
panic("siafund being added to consensus set when it is already in the consensus set")
......@@ -197,8 +202,8 @@ func (s *State) applySiafundOutputs(bn *blockNode, t Transaction) {
sfo.ClaimStart = s.siafundPool
// Create and apply the diff.
bn.siafundOutputDiffs = append(bn.siafundOutputDiffs, SiafundOutputDiff{
Direction: DiffApply,
bn.siafundOutputDiffs = append(bn.siafundOutputDiffs, modules.SiafundOutputDiff{
Direction: modules.DiffApply,
ID: sfoid,
SiafundOutput: sfo,
})
......@@ -209,9 +214,9 @@ func (s *State) applySiafundOutputs(bn *blockNode, t Transaction) {
// applyTransaction applies the contents of a transaction to the State. This
// produces a set of diffs, which are stored in the blockNode containing the
// transaction.
func (s *State) applyTransaction(bn *blockNode, t Transaction) {
func (s *State) applyTransaction(bn *blockNode, t types.Transaction) {
// Sanity check - the input transaction should be valid.
if DEBUG {
if types.DEBUG {
err := s.validTransaction(t)
if err != nil {
panic("applyTransaction called with an invalid transaction!")
......
......@@ -3,6 +3,9 @@ package consensus
import (
"math/big"
"sort"
"github.com/NebulousLabs/Sia/modules"
"github.com/NebulousLabs/Sia/types"
)
// SurpassThreshold is a percentage that dictates how much heavier a competing
......@@ -19,13 +22,13 @@ var SurpassThreshold = big.NewRat(20, 100)
// block height, depth, and target. It also contains a set of diffs that
// dictate how the consensus set is affected by the block.
type blockNode struct {
block Block
block types.Block
parent *blockNode
children []*blockNode
height BlockHeight
depth Target // Cumulative weight of all parents.
target Target // Target for next block, i.e. any child blockNodes.
height types.BlockHeight
depth types.Target // Cumulative weight of all parents.
target types.Target // Target for next block, i.e. any child blockNodes.
// Diffs are computationally expensive to generate, so a lazy approach is
// taken wherein the diffs are only generated when needed. A boolean
......@@ -35,20 +38,20 @@ type blockNode struct {
// State's currentPath; this is because diffs must be generated to apply
// the node.
diffsGenerated bool
siafundPoolDiff SiafundPoolDiff
siacoinOutputDiffs []SiacoinOutputDiff
fileContractDiffs []FileContractDiff
siafundOutputDiffs []SiafundOutputDiff
delayedSiacoinOutputs map[SiacoinOutputID]SiacoinOutput
siafundPoolDiff modules.SiafundPoolDiff
siacoinOutputDiffs []modules.SiacoinOutputDiff
fileContractDiffs []modules.FileContractDiff
siafundOutputDiffs []modules.SiafundOutputDiff
delayedSiacoinOutputs map[types.SiacoinOutputID]types.SiacoinOutput
}
// childDepth returns the depth of a blockNode's child nodes. The depth is the
// "sum" of the current depth and current target, where sum is defined as:
//
// sum(x,y) := 1/(1/x + 1/y)
func (bn *blockNode) childDepth() (depth Target) {
func (bn *blockNode) childDepth() (depth types.Target) {
cumulativeDifficulty := new(big.Rat).Add(bn.target.Inverse(), bn.depth.Inverse())
return RatToTarget(new(big.Rat).Inv(cumulativeDifficulty))
return types.RatToTarget(new(big.Rat).Inv(cumulativeDifficulty))
}
// heavierThan returns true if the blockNode is sufficiently heavier than
......@@ -64,11 +67,11 @@ func (bn *blockNode) heavierThan(cmp *blockNode) bool {
// earliestChildTimestamp returns the earliest timestamp that a child node
// can have while still being valid. See section 'Timestamp Rules' in
// Consensus.md.
func (bn *blockNode) earliestChildTimestamp() Timestamp {
func (bn *blockNode) earliestChildTimestamp() types.Timestamp {
// Get the previous MedianTimestampWindow timestamps.
windowTimes := make(TimestampSlice, MedianTimestampWindow)
windowTimes := make(types.TimestampSlice, types.MedianTimestampWindow)
traverse := bn
for i := 0; i < MedianTimestampWindow; i++ {
for i := 0; i < types.MedianTimestampWindow; i++ {
windowTimes[i] = traverse.block.Timestamp
if traverse.parent != nil {
traverse = traverse.parent
......@@ -82,9 +85,9 @@ func (bn *blockNode) earliestChildTimestamp() Timestamp {
// newChild creates a blockNode from a block and adds it to the parent's set of
// children. The new node is also returned.
func (bn *blockNode) newChild(b Block) *blockNode {
func (bn *blockNode) newChild(b types.Block) *blockNode {
// Sanity check - parent can't be nil.
if DEBUG {
if types.DEBUG {
if bn == nil {
panic("can't create blockNode with nil parent")
}
......@@ -97,35 +100,35 @@ func (bn *blockNode) newChild(b Block) *blockNode {
height: bn.height + 1,
depth: bn.childDepth(),
delayedSiacoinOutputs: make(map[SiacoinOutputID]SiacoinOutput),
delayedSiacoinOutputs: make(map[types.SiacoinOutputID]types.SiacoinOutput),
}
// Calculate the target for the new node. To calculate the target, we need
// to compare our timestamp with the timestamp of the reference node, which
// is `TargetWindow` blocks earlier, or if the height is less than
// `TargetWindow`, it's the genesis block.
var numBlocks BlockHeight
var numBlocks types.BlockHeight
windowStart := child
for numBlocks = 0; numBlocks < TargetWindow && windowStart.parent != nil; numBlocks++ {
for numBlocks = 0; numBlocks < types.TargetWindow && windowStart.parent != nil; numBlocks++ {
windowStart = windowStart.parent
}
// Calculate the amount to adjust the target by dividing the amount of time
// passed by the expected amount of time passed.
timePassed := child.block.Timestamp - windowStart.block.Timestamp
expectedTimePassed := BlockFrequency * numBlocks
expectedTimePassed := types.BlockFrequency * numBlocks
targetAdjustment := big.NewRat(int64(timePassed), int64(expectedTimePassed))
// Clamp adjustment to reasonable values.
if targetAdjustment.Cmp(MaxAdjustmentUp) > 0 {
targetAdjustment = MaxAdjustmentUp
} else if targetAdjustment.Cmp(MaxAdjustmentDown) < 0 {
targetAdjustment = MaxAdjustmentDown
if targetAdjustment.Cmp(types.MaxAdjustmentUp) > 0 {
targetAdjustment = types.MaxAdjustmentUp
} else if targetAdjustment.Cmp(types.MaxAdjustmentDown) < 0 {
targetAdjustment = types.MaxAdjustmentDown
}
// Multiply the previous target by the adjustment to get the new target.
newRatTarget := new(big.Rat).Mul(bn.target.Rat(), targetAdjustment)
child.target = RatToTarget(newRatTarget)
child.target = types.RatToTarget(newRatTarget)
// add child to parent
bn.children = append(bn.children, child)
......
......@@ -2,6 +2,9 @@ package consensus
import (
"errors"
"github.com/NebulousLabs/Sia/modules"
"github.com/NebulousLabs/Sia/types"
)
// diffs.go contains all of the functions related to diffs in the consensus
......@@ -9,53 +12,11 @@ import (
// changes are recorded as diffs for easy rewinding and reapplying. The diffs
// are created, applied, reverted, and queried in this file.
// A DiffDirection indicates the "direction" of a diff, either applied or
// reverted. A bool is used to restrict the value to these two possibilities.
type DiffDirection bool
const (
DiffApply DiffDirection = true
DiffRevert DiffDirection = false
)
// A SiacoinOutputDiff indicates the addition or removal of a SiacoinOutput in
// the consensus set.
type SiacoinOutputDiff struct {
Direction DiffDirection
ID SiacoinOutputID
SiacoinOutput SiacoinOutput
}
// A FileContractDiff indicates the addition or removal of a FileContract in
// the consensus set.
type FileContractDiff struct {
Direction DiffDirection
ID FileContractID