Commit b2b49fd8 authored by David Vorick's avatar David Vorick

rename critical fields

parent d1d86941
......@@ -16,9 +16,12 @@ type blockNode struct {
depth Target // Cumulative weight of all parents.
target Target // Target for next block.
diffsGenerated bool
outputDiffs []OutputDiff
contractDiffs []ContractDiff
diffsGenerated bool
siafundPoolDiff SiafundPoolDiff
siacoinOutputDiffs []SiacoinOutputDiff
fileContractDiffs []FileContractDiff
siafundOutputDiffs []SiafundOutputDiff
newDelayedSiacoinOutputs []SiacoinOutput
}
// childDepth returns the depth that any child node would have.
......
......@@ -28,4 +28,7 @@ var (
MaxAdjustmentUp = big.NewRat(103, 100)
MaxAdjustmentDown = big.NewRat(97, 100)
// The CoinbaseAugment should be a big.Int equal to 1 << 80.
CoinbaseAugment = new(big.Int).Mul(big.NewInt(1<<40), big.NewInt(1<<40))
)
......@@ -10,8 +10,8 @@ const (
DEBUG = true // This is a temporary setting, will stay during beta.
BlockSizeLimit = 1e6 // Blocks cannot be more than 1MB.
BlockFrequency = 6e3 // In seconds.
TargetWindow = 2e3 // Number of blocks to use when calculating the target.
BlockFrequency = 600 // In seconds.
TargetWindow = 1e3 // Number of blocks to use when calculating the target.
MedianTimestampWindow = 11 // Number of blocks that get considered when determining if a timestamp is valid - should be an odd number.
FutureThreshold = 3 * 60 * 60 // Seconds into the future block timestamps are valid.
SiafundCount = 10e3 // The total (static) number of siafunds.
......@@ -28,4 +28,7 @@ var (
MaxAdjustmentUp = big.NewRat(1001, 1000)
MaxAdjustmentDown = big.NewRat(999, 1000)
// The CoinbaseAugment should be a big.Int equal to 1 << 80.
CoinbaseAugment = new(big.Int).Mul(big.NewInt(1<<40), big.NewInt(1<<40))
)
......@@ -28,4 +28,7 @@ var (
MaxAdjustmentUp = big.NewRat(1001, 1000)
MaxAdjustmentDown = big.NewRat(999, 1000)
// The CoinbaseAugment should be a big.Int equal to 1 << 80.
CoinbaseAugment = new(big.Int).Mul(big.NewInt(1<<40), big.NewInt(1<<40))
)
......@@ -7,16 +7,13 @@ import (
"github.com/NebulousLabs/Sia/hash"
)
// storageProofSegment 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 (s *State) storageProofSegment(contractID ContractID) (index uint64, err error) {
contract, exists := s.openContracts[contractID]
func (s *State) storageProofSegment(fcid FileContractID) (index uint64, err error) {
contract, exists := s.openFileContracts[fcid]
if !exists {
err = errors.New("unrecognized contractID")
err = errors.New("unrecognized file contract id")
return
}
// Get the id of the block used as the seed.
triggerHeight := contract.Start - 1
triggerBlock, exists := s.blockAtHeight(triggerHeight)
if !exists {
......@@ -25,9 +22,7 @@ func (s *State) storageProofSegment(contractID ContractID) (index uint64, err er
}
triggerID := triggerBlock.ID()
// Combine the contractID and triggerID, convert to an int, then take the
// mod to get the segment.
seed := hash.HashBytes(append(triggerID[:], contractID[:]...))
seed := hash.HashBytes(append(triggerID[:], fcid[:]...))
numSegments := int64(hash.CalculateSegments(contract.FileSize))
seedInt := new(big.Int).SetBytes(seed[:])
index = seedInt.Mod(seedInt, big.NewInt(numSegments)).Uint64()
......@@ -50,13 +45,13 @@ func (s *State) validContract(fc FileContract) error {
// validProof returns err = nil if the storage proof provided is valid given
// the state context, otherwise returning an error to indicate what is invalid.
func (s *State) validProof(sp StorageProof) error {
contract, exists := s.openContracts[sp.ContractID]
contract, exists := s.openFileContracts[sp.FileContractID]
if !exists {
return errors.New("unrecognized contract id in storage proof")
}
// Check that the storage proof itself is valid.
segmentIndex, err := s.storageProofSegment(sp.ContractID)
segmentIndex, err := s.storageProofSegment(sp.FileContractID)
if err != nil {
return err
}
......@@ -76,78 +71,79 @@ func (s *State) validProof(sp StorageProof) error {
// addContract takes a FileContract and its corresponding ContractID and adds
// it to the state.
func (s *State) applyContract(contract FileContract, id ContractID) (cd ContractDiff) {
s.openContracts[id] = contract
cd = ContractDiff{
New: true,
ID: id,
Contract: contract,
func (s *State) applyContract(fc FileContract, fcid FileContractID) (fcd FileContractDiff) {
s.openFileContracts[fcid] = fc
fcd = FileContractDiff{
New: true,
ID: fcid,
FileContract: fc,
}
return
}
// applyStorageProof takes a storage proof and adds any outputs created by it
// to the consensus state.
func (s *State) applyStorageProof(sp StorageProof) (od OutputDiff, cd ContractDiff) {
func (s *State) applyStorageProof(sp StorageProof) (scod SiacoinOutputDiff, fcd FileContractDiff) {
// Calculate the new output and its id.
contract := s.openContracts[sp.ContractID]
output := SiacoinOutput{
contract := s.openFileContracts[sp.FileContractID]
sco := SiacoinOutput{
Value: contract.Payout,
SpendHash: contract.ValidProofAddress,
}
outputID := sp.ContractID.StorageProofOutputID(true)
outputID := sp.FileContractID.StorageProofOutputID(true)
// Update the state.
s.unspentOutputs[outputID] = output
delete(s.openContracts, sp.ContractID)
s.unspentSiacoinOutputs[outputID] = sco
delete(s.openFileContracts, sp.FileContractID)
od = OutputDiff{
New: true,
ID: outputID,
Output: output,
scod = SiacoinOutputDiff{
New: true,
ID: outputID,
SiacoinOutput: sco,
}
cd = ContractDiff{
New: false,
ID: sp.ContractID,
Contract: contract,
fcd = FileContractDiff{
New: false,
ID: sp.FileContractID,
FileContract: contract,
}
return
}
// applyMissedProof adds outputs to the State to manage a missed storage proof
// on a file contract.
func (s *State) applyMissedProof(contract FileContract, id ContractID) (od OutputDiff, cd ContractDiff) {
func (s *State) applyMissedProof(fc FileContract, fcid FileContractID) (scod SiacoinOutputDiff, fcd FileContractDiff) {
// Create the output for the missed proof.
output := SiacoinOutput{
Value: contract.Payout,
SpendHash: contract.MissedProofAddress,
sco := SiacoinOutput{
Value: fc.Payout,
SpendHash: fc.MissedProofAddress,
}
outputID := id.StorageProofOutputID(false)
outputID := fcid.StorageProofOutputID(false)
// Update the state.
s.unspentOutputs[outputID] = output
delete(s.openContracts, id)
s.unspentSiacoinOutputs[outputID] = sco
delete(s.openFileContracts, fcid)
cd = ContractDiff{
New: false,
ID: id,
Contract: contract,
// Create the diffs.
fcd = FileContractDiff{
New: false,
ID: fcid,
FileContract: fc,
}
od = OutputDiff{
New: true,
ID: outputID,
Output: output,
scod = SiacoinOutputDiff{
New: true,
ID: outputID,
SiacoinOutput: sco,
}
return
}
func (s *State) applyContractMaintenance() (outputDiffs []OutputDiff, contractDiffs []ContractDiff) {
func (s *State) applyContractMaintenance() (scods []SiacoinOutputDiff, fcds []FileContractDiff) {
// Iterate through all contracts and figure out which ones have expired.
// Expiring a contract deletes it from the map we are iterating through, so
// we need to store it and deleted once we're done iterating through the
// map.
var expiredContracts []ContractID
for id, contract := range s.openContracts {
var expiredContracts []FileContractID
for id, contract := range s.openFileContracts {
if s.height() == contract.End {
expiredContracts = append(expiredContracts, id)
}
......@@ -155,10 +151,10 @@ func (s *State) applyContractMaintenance() (outputDiffs []OutputDiff, contractDi
// Delete all of the contracts that terminated.
for _, id := range expiredContracts {
contract := s.openContracts[id]
outputDiff, contractDiff := s.applyMissedProof(contract, id)
outputDiffs = append(outputDiffs, outputDiff)
contractDiffs = append(contractDiffs, contractDiff)
contract := s.openFileContracts[id]
scod, fcd := s.applyMissedProof(contract, id)
scods = append(scods, scod)
fcds = append(fcds, fcd)
}
return
......@@ -167,10 +163,10 @@ func (s *State) applyContractMaintenance() (outputDiffs []OutputDiff, contractDi
// 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 (s *State) StorageProofSegment(id ContractID) (index uint64, err error) {
func (s *State) StorageProofSegment(fcid FileContractID) (index uint64, err error) {
s.mu.RLock()
defer s.mu.RUnlock()
return s.storageProofSegment(id)
return s.storageProofSegment(fcid)
}
func (s *State) ValidContract(fc FileContract) error {
......
......@@ -17,22 +17,33 @@ import (
// 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 OutputDiff struct {
New bool
ID OutputID
Output SiacoinOutput
type SiacoinOutputDiff struct {
New bool
ID OutputID
SiacoinOutput SiacoinOutput
}
type ContractDiff struct {
New bool
ID ContractID
Contract FileContract
type FileContractDiff struct {
New bool
ID FileContractID
FileContract FileContract
}
type SiafundOutputDiff struct {
New bool
ID OutputID
SiafundOutput SiafundOutput
}
type SiafundPoolDiff struct {
Previous Currency
Adjusted Currency
}
// commitOutputDiff takes an output diff and applies it to the state. Forward
// indicates the direction of the blockchain.
func (s *State) commitOutputDiff(od OutputDiff, forward bool) {
add := od.New
func (s *State) commitSiacoinOutputDiff(scod SiacoinOutputDiff, forward bool) {
add := scod.New
if !forward {
add = !add
}
......@@ -40,30 +51,30 @@ func (s *State) commitOutputDiff(od OutputDiff, forward bool) {
if add {
// Sanity check - output should not already exist.
if DEBUG {
_, exists := s.unspentOutputs[od.ID]
_, exists := s.unspentSiacoinOutputs[scod.ID]
if exists {
panic("rogue new output in applyOutputDiff")
}
}
s.unspentOutputs[od.ID] = od.Output
s.unspentSiacoinOutputs[scod.ID] = scod.SiacoinOutput
} else {
// Sanity check - output should exist.
if DEBUG {
_, exists := s.unspentOutputs[od.ID]
_, exists := s.unspentSiacoinOutputs[scod.ID]
if !exists {
panic("rogue non-new output in applyOutputDiff")
}
}
delete(s.unspentOutputs, od.ID)
delete(s.unspentSiacoinOutputs, scod.ID)
}
}
// commitContractDiff takes a contract diff and applies it to the state. Forward
// indicates the direction of the blockchain.
func (s *State) commitContractDiff(cd ContractDiff, forward bool) {
add := cd.New
func (s *State) commitFileContractDiff(fcd FileContractDiff, forward bool) {
add := fcd.New
if !forward {
add = !add
}
......@@ -71,27 +82,27 @@ func (s *State) commitContractDiff(cd ContractDiff, forward bool) {
if add {
// Sanity check - contract should not already exist.
if DEBUG {
_, exists := s.openContracts[cd.ID]
_, exists := s.openFileContracts[fcd.ID]
if exists {
panic("rogue new contract in applyContractDiff")
}
}
s.openContracts[cd.ID] = cd.Contract
s.openFileContracts[fcd.ID] = fcd.FileContract
} else {
// Sanity check - contract should exist.
if DEBUG {
_, exists := s.openContracts[cd.ID]
_, exists := s.openFileContracts[fcd.ID]
if !exists {
panic("rogue non-new contract in applyContractDiff")
}
}
delete(s.openContracts, cd.ID)
delete(s.openFileContracts, fcd.ID)
}
}
func (s *State) BlockOutputDiffs(id BlockID) (diffs []OutputDiff, err error) {
func (s *State) BlockOutputDiffs(id BlockID) (scods []SiacoinOutputDiff, err error) {
node, exists := s.blockMap[id]
if !exists {
err = errors.New("requested an unknown block")
......@@ -101,6 +112,6 @@ func (s *State) BlockOutputDiffs(id BlockID) (diffs []OutputDiff, err error) {
err = errors.New("diffs have not been generated for the requested block.")
return
}
diffs = node.outputDiffs
scods = node.siacoinOutputDiffs
return
}
......@@ -66,12 +66,19 @@ func (s *State) invertRecentBlock() {
// Invert all of the diffs.
direction := false // blockchain is inverting, set direction flag to false.
for _, diff := range bn.outputDiffs {
s.commitOutputDiff(diff, direction)
for _, scod := range bn.siacoinOutputDiffs {
s.commitSiacoinOutputDiff(scod, direction)
}
for _, diff := range bn.contractDiffs {
s.commitContractDiff(diff, direction)
for _, fcd := range bn.fileContractDiffs {
s.commitFileContractDiff(fcd, direction)
}
for _, sfod := range bn.siafundOutputDiffs {
s.commitSiafundOutputDiff(sfod, direction)
}
s.commitSiafundPoolDuff(bn.siafundPoolDiff, direction)
// Delete the delated outputs created by the node.
delete(s.delayedSiacoinOutputs, bn.height)
// Update the current path and currentBlockID
delete(s.currentPath, bn.height)
......@@ -98,15 +105,15 @@ func (s *State) rewindToNode(bn *blockNode) (rewoundNodes []*blockNode) {
// applyMinerSubsidy adds all of the outputs recorded in the MinerPayouts to
// the state, and returns the corresponding set of diffs.
func (s *State) applyMinerSubsidy(bn *blockNode) (diffs []OutputDiff) {
func (s *State) applyMinerSubsidy(bn *blockNode) (scods []SiacoinOutputDiff) {
for i, payout := range bn.block.MinerPayouts {
diff := OutputDiff{
New: true,
ID: bn.block.MinerPayoutID(i),
Output: payout,
scod := SiacoinOutputDiff{
New: true,
ID: bn.block.MinerPayoutID(i),
SiacoinOutput: payout,
}
s.unspentOutputs[diff.ID] = payout
diffs = append(diffs, diff)
s.unspentSiacoinOutputs[scod.ID] = payout
scods = append(scods, scod)
}
return
}
......@@ -115,14 +122,11 @@ func (s *State) applyMinerSubsidy(bn *blockNode) (diffs []OutputDiff) {
// consensus state.
func (s *State) generateAndApplyDiff(bn *blockNode) (err error) {
// Sanity check - generate should only be called if the diffs have not yet
// been generated.
// been generated - current node must be the input node's parent.
if DEBUG {
if bn.diffsGenerated {
panic("misuse of generateAndApplyDiff")
}
}
// Sanity check - current node must be the input node's parent.
if DEBUG {
if bn.parent.block.ID() != s.currentBlockID {
panic("applying a block node when it's not a valid successor")
}
......@@ -140,19 +144,19 @@ func (s *State) generateAndApplyDiff(bn *blockNode) (err error) {
return
}
outputDiffs, contractDiffs := s.applyTransaction(txn)
bn.outputDiffs = append(bn.outputDiffs, outputDiffs...)
bn.contractDiffs = append(bn.contractDiffs, contractDiffs...)
siacoinOutputDiffs, fileContractDiffs := s.applyTransaction(txn)
bn.siacoinOutputDiffs = append(bn.siacoinOutputDiffs, siacoinOutputDiffs...)
bn.fileContractDiffs = append(bn.fileContractDiffs, fileContractDiffs...)
}
// Perform maintanence on all open contracts.
outputDiffs, contractDiffs := s.applyContractMaintenance()
bn.outputDiffs = append(bn.outputDiffs, outputDiffs...)
bn.contractDiffs = append(bn.contractDiffs, contractDiffs...)
siacoinOutputDiffs, fileContractDiffs := s.applyContractMaintenance()
bn.siacoinOutputDiffs = append(bn.siacoinOutputDiffs, siacoinOutputDiffs...)
bn.fileContractDiffs = append(bn.fileContractDiffs, fileContractDiffs...)
// Add the miner payouts.
subsidyDiffs := s.applyMinerSubsidy(bn)
bn.outputDiffs = append(bn.outputDiffs, subsidyDiffs...)
bn.siacoinOutputDiffs = append(bn.siacoinOutputDiffs, subsidyDiffs...)
bn.diffsGenerated = true
return
......@@ -183,11 +187,11 @@ func (s *State) applyBlockNode(bn *blockNode) {
// Apply all of the diffs.
direction := true // blockchain is going forward, set direction flag to true.
for _, od := range bn.outputDiffs {
s.commitOutputDiff(od, direction)
for _, scod := range bn.siacoinOutputDiffs {
s.commitSiacoinOutputDiff(scod, direction)
}
for _, cd := range bn.contractDiffs {
s.commitContractDiff(cd, direction)
for _, fcd := range bn.fileContractDiffs {
s.commitFileContractDiff(fcd, direction)
}
}
......
......@@ -48,8 +48,8 @@ func (s *State) height() BlockHeight {
// 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 (s *State) output(id OutputID) (output SiacoinOutput, exists bool) {
output, exists = s.unspentOutputs[id]
func (s *State) output(id OutputID) (sco SiacoinOutput, exists bool) {
sco, exists = s.unspentSiacoinOutputs[id]
return
}
......@@ -58,7 +58,7 @@ func (s *State) output(id OutputID) (output SiacoinOutput, exists bool) {
func (s *State) sortedUtxoSet() (sortedOutputs []SiacoinOutput) {
// Get all of the outputs in string form and sort the strings.
var unspentOutputStrings []string
for outputID := range s.unspentOutputs {
for outputID := range s.unspentSiacoinOutputs {
unspentOutputStrings = append(unspentOutputStrings, string(outputID[:]))
}
sort.Strings(unspentOutputStrings)
......@@ -111,16 +111,16 @@ func (s *State) stateHash() hash.Hash {
// Sort the open contracts by the string value of their ID.
var openContractStrings []string
for contractID := range s.openContracts {
for contractID := range s.openFileContracts {
openContractStrings = append(openContractStrings, string(contractID[:]))
}
sort.Strings(openContractStrings)
// Add the open contracts in sorted order.
for _, stringContractID := range openContractStrings {
var contractID ContractID
var contractID FileContractID
copy(contractID[:], stringContractID)
leaves = append(leaves, hash.HashObject(s.openContracts[contractID]))
leaves = append(leaves, hash.HashObject(s.openFileContracts[contractID]))
}
return hash.MerkleRoot(leaves)
......@@ -154,11 +154,11 @@ func (s *State) BlockAtHeight(height BlockHeight) (b Block, exists bool) {
// Contract returns a the contract associated with the input id, and whether
// the contract exists.
func (s *State) Contract(id ContractID) (fc FileContract, exists bool) {
func (s *State) Contract(id FileContractID) (fc FileContract, exists bool) {
s.mu.RLock()
defer s.mu.RUnlock()
fc, exists = s.openContracts[id]
fc, exists = s.openFileContracts[id]
if !exists {
return
}
......
......@@ -160,7 +160,11 @@ func (s *State) validSignatures(t Transaction) (err error) {
// statement.
publicKey := sigMap[sig.InputID].PossibleKeys[sig.PublicKeyIndex]
switch publicKey.Algorithm {
case ED25519Identifier:
case SignatureEntropy:
if len(publicKey.Key) != 32 {
return InvalidSignatureErr
}
case SignatureED25519:
// Decode the public key and signature.
var decodedPK crypto.PublicKey
err := encoding.Unmarshal(publicKey.Key, &decodedPK)
......
......@@ -33,10 +33,10 @@ type State struct {
// the same path will have the same exact consensus variables, anything
// else is a software bug.
siafundPool Currency
unspentSiacoinOutputs map[OutputID]SiacoinOutput
openFileContracts map[FileContractID]FileContract
unspentSiafundOutputs map[OutputID]SiafundOutput
unspentOutputs map[OutputID]SiacoinOutput
delayedOutputs map[BlockHeight]SiacoinOutput
openContracts map[ContractID]FileContract
delayedSiacoinOutputs map[BlockHeight][]SiacoinOutput
// Per convention, all exported functions in the consensus package can be
// called concurrently. The state mutex helps to orchestrate thread safety.
......@@ -56,8 +56,8 @@ func CreateGenesisState(genesisTime Timestamp) (s *State) {
badBlocks: make(map[BlockID]struct{}),
blockMap: make(map[BlockID]*blockNode),
currentPath: make(map[BlockHeight]BlockID),
openContracts: make(map[ContractID]FileContract),
unspentOutputs: make(map[OutputID]SiacoinOutput),
openFileContracts: make(map[FileContractID]FileContract),
unspentSiacoinOutputs: make(map[OutputID]SiacoinOutput),
unspentSiafundOutputs: make(map[OutputID]SiafundOutput),
}
......@@ -75,7 +75,7 @@ func CreateGenesisState(genesisTime Timestamp) (s *State) {
// Fill out the consensus informaiton for the genesis block.
s.currentBlockID = genesisBlock.ID()
s.currentPath[BlockHeight(0)] = genesisBlock.ID()
s.unspentOutputs[genesisBlock.MinerPayoutID(0)] = SiacoinOutput{
s.unspentSiacoinOutputs[genesisBlock.MinerPayoutID(0)] = SiacoinOutput{
Value: CalculateCoinbase(0),
SpendHash: ZeroAddress, // TODO: change to Nebulous Genesis Siacoin SpendHash Address
}
......
......@@ -32,14 +32,14 @@ func (t Transaction) validStorageProofs() bool {
// otherwise returns an error explaining what wasn't valid.
func (s *State) validInput(input SiacoinInput) (err error) {
// Check the input spends an existing and valid output.
_, exists := s.unspentOutputs[input.OutputID]
_, exists := s.unspentSiacoinOutputs[input.OutputID]
if !exists {
err = MissingOutputErr
return
}
// Check that the spend conditions match the hash listed in the output.
if input.SpendConditions.CoinAddress() != s.unspentOutputs[input.OutputID].SpendHash {
if input.SpendConditions.CoinAddress() != s.unspentSiacoinOutputs[input.OutputID].SpendHash {
err = errors.New("spend conditions do not match hash")
return
}
......@@ -71,7 +71,7 @@ func (s *State) validTransaction(t Transaction) (err error) {
}
// Add this input's value
err = inputSum.Add(s.unspentOutputs[input.OutputID].Value)
err = inputSum.Add(s.unspentSiacoinOutputs[input.OutputID].Value)
if err != nil {
return
}
......@@ -115,25 +115,25 @@ func (s *State) validTransaction(t Transaction) (err error) {
// applyTransaction() takes a transaction and adds it to the
// ConsensusState, updating the list of contracts, outputs, etc.
func (s *State) applyTransaction(t Transaction) (outputDiffs []OutputDiff, contractDiffs []ContractDiff) {
func (s *State) applyTransaction(t Transaction) (scods []SiacoinOutputDiff, fcds []FileContractDiff) {
// Remove all inputs from the unspent outputs list.
for _, input := range t.SiacoinInputs {
// Sanity check - the input must exist within the blockchain, should
// have already been verified.
if DEBUG {
_, exists := s.unspentOutputs[input.OutputID]
_, exists := s.unspentSiacoinOutputs[input.OutputID]
if !exists {
panic("Applying a transaction with an invalid unspent output!")
}
}
outputDiff := OutputDiff{
New: false,
ID: input.OutputID,
Output: s.unspentOutputs[input.OutputID],
scod := SiacoinOutputDiff{
New: false,
ID: input.OutputID,
SiacoinOutput: s.unspentSiacoinOutputs[input.OutputID],
}
outputDiffs = append(outputDiffs, outputDiff)
delete(s.unspentOutputs, input.OutputID)
scods = append(scods, scod)
delete(s.unspentSiacoinOutputs, input.OutputID)
}
// Add all finanacial outputs to the unspent outputs list.
......@@ -141,32 +141,32 @@ func (s *State) applyTransaction(t Transaction) (outputDiffs []OutputDiff, contr
// Sanity check - the output must not exist within the state, should
// have already been verified.
if DEBUG {
_, exists := s.unspentOutputs[t.SiacoinOutputID(i)]
_, exists := s.unspentSiacoinOutputs[t.SiacoinOutputID(i)]
if exists {
panic("applying a transaction with an invalid new output")
}
}
diff := OutputDiff{
New: true,
ID: t.SiacoinOutputID(i),
Output: output,
scod := SiacoinOutputDiff{
New: true,
ID: t.SiacoinOutputID(i),
SiacoinOutput: output,
}
s.unspentOutputs[t.SiacoinOutputID(i)] = output
outputDiffs = append(outputDiffs, diff)
s.unspentSiacoinOutputs[t.SiacoinOutputID(i)] = output
scods = append(scods, scod)
}
// Add all outputs created by storage proofs.
for _, sp := range t.StorageProofs {
outputDiff, contractDiff := s.applyStorageProof(sp)
outputDiffs = append(outputDiffs, outputDiff)
contractDiffs = append(contractDiffs, contractDiff)
scod, fcd := s.applyStorageProof(sp)
scods = append(scods, scod)
fcds = append(fcds, fcd)
}
// Add all new contracts to the OpenContracts list.
for i, contract := range t.FileContracts {
contractDiff := s.applyContract(contract, t.FileContractID(i))
contractDiffs = append(contractDiffs, contractDiff)
fcd := s.applyContract(contract, t.FileContractID(i))
fcds = append(fcds, fcd)
}
return
}
......
package consensus
// TODO: Swtich to 128 bit Currency, which is overflow-safe. Then update
// CalculateCoinbase.
// TODO: Enforce the 100 block spending hold on certain types of outputs: Miner
// payouts, storage proof outputs, siafund claims.
// TODO: Enforce siafund rules in consensus.
// TODO: Switch to typed public keys, with typed verification.
// TODO: Complete non-adversarial test coverage, partial adversarial test
// coverage.
......@@ -28,11 +23,11 @@ type (
Identifier [16]byte
Signature []byte
BlockID hash.Hash
OutputID hash.Hash
ContractID hash.Hash
CoinAddress hash.Hash
Target hash.Hash
BlockID hash.Hash
OutputID hash.Hash
FileContractID hash.Hash
CoinAddress hash.Hash
Target hash.Hash
)
// A Currency is a 128-bit unsigned integer. Currency operations are performed
......@@ -55,7 +50,12 @@ var FileContractIdentifier = Identifier{'f', 'i', 'l', 'e', ' ', 'c', 'o', 'n',
var SiacoinOutputIdentifier = Identifier{'s', 'i', 'a', 'c', 'o', 'i', 'n', ' ', 'o', 'u', 't', 'p', 'u', 't'}
var SiafundOutputIdentifier = Identifier{'s', 'i', 'a', 'f', 'u', 'n', 'd', ' ', 'o', 'u', 't', 'p', 'u', 't'}
var ED25519Identifier = Identifier{'e', 'd', '2', '5', '5', '1', '9'}