Commit adb71da2 authored by David Vorick's avatar David Vorick

apply changes across consensus package

parent 7b02d454
......@@ -21,7 +21,7 @@ type blockNode struct {
siacoinOutputDiffs []SiacoinOutputDiff
fileContractDiffs []FileContractDiff
siafundOutputDiffs []SiafundOutputDiff
delayedSiacoinOutputs map[OutputID]SiacoinOutput
delayedSiacoinOutputs map[SiacoinOutputID]SiacoinOutput
}
// childDepth returns the depth that any child node would have.
......@@ -73,7 +73,7 @@ func (s *State) addBlockToTree(b Block) (err error) {
height: parentNode.height + 1,
depth: parentNode.childDepth(),
delayedSiacoinOutputs: make(map[OutputID]SiacoinOutput),
delayedSiacoinOutputs: make(map[SiacoinOutputID]SiacoinOutput),
}
newNode.setTarget()
......
......@@ -45,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.openFileContracts[sp.FileContractID]
contract, exists := s.openFileContracts[sp.ParentID]
if !exists {
return errors.New("unrecognized contract id in storage proof")
}
// Check that the storage proof itself is valid.
segmentIndex, err := s.storageProofSegment(sp.FileContractID)
segmentIndex, err := s.storageProofSegment(sp.ParentID)
if err != nil {
return err
}
......@@ -147,8 +147,8 @@ func (s *State) applyStorageProofs(bn *blockNode, t Transaction) {
}
// Get the id of the file contract and the siacoin output it creates.
fileContract := s.openFileContracts[sp.FileContractID]
outputID := sp.FileContractID.StorageProofOutputID(true)
fileContract := s.openFileContracts[sp.ParentID]
outputID := sp.ParentID.StorageProofOutputID(true)
// Sanity check - output should not already exist.
if DEBUG {
_, exists := s.unspentSiacoinOutputs[outputID]
......@@ -164,14 +164,14 @@ func (s *State) applyStorageProofs(bn *blockNode, t Transaction) {
// Create the siacoin output resulting from the storage proof.
sco := SiacoinOutput{
Value: outputPortion,
SpendHash: fileContract.ValidProofAddress,
Value: outputPortion,
UnlockHash: fileContract.ValidProofUnlockHash,
}
// Add the output to the list of delayed outputs, delete the
// contract from the state, and add the poolPortion to the siafundPool.
s.delayedSiacoinOutputs[s.height()][outputID] = sco
delete(s.openFileContracts, sp.FileContractID)
delete(s.openFileContracts, sp.ParentID)
err := s.siafundPool.Add(poolPortion)
if DEBUG {
if err != nil {
......@@ -182,7 +182,7 @@ func (s *State) applyStorageProofs(bn *blockNode, t Transaction) {
// update the block node diffs.
fcd := FileContractDiff{
New: false,
ID: sp.FileContractID,
ID: sp.ParentID,
FileContract: fileContract,
}
bn.delayedSiacoinOutputs[outputID] = sco
......@@ -200,8 +200,8 @@ func (s *State) applyMissedProof(bn *blockNode, fc FileContract, fcid FileContra
// Create the output for the missed proof.
sco := SiacoinOutput{
Value: outputPortion,
SpendHash: fc.MissedProofAddress,
Value: outputPortion,
UnlockHash: fc.MissedProofUnlockHash,
}
outputID := fcid.StorageProofOutputID(false)
......
......@@ -15,7 +15,7 @@ package consensus
// the block was applied.
type SiacoinOutputDiff struct {
New bool
ID OutputID
ID SiacoinOutputID
SiacoinOutput SiacoinOutput
}
......@@ -27,7 +27,7 @@ type FileContractDiff struct {
type SiafundOutputDiff struct {
New bool
ID OutputID
ID SiafundOutputID
SiafundOutput SiafundOutput
}
......
......@@ -122,7 +122,7 @@ func (s *State) generateAndApplyDiff(bn *blockNode) (err error) {
// Update the current block and current path.
s.currentBlockID = bn.block.ID()
s.currentPath[bn.height] = bn.block.ID()
s.delayedSiacoinOutputs[s.height()] = make(map[OutputID]SiacoinOutput)
s.delayedSiacoinOutputs[s.height()] = make(map[SiacoinOutputID]SiacoinOutput)
// Validate and apply each transaction in the block.
for _, txn := range bn.block.Transactions {
......
......@@ -49,7 +49,7 @@ 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) (sco SiacoinOutput, exists bool) {
func (s *State) output(id SiacoinOutputID) (sco SiacoinOutput, exists bool) {
sco, exists = s.unspentSiacoinOutputs[id]
return
}
......@@ -66,7 +66,7 @@ func (s *State) sortedUscoSet() (sortedOutputs []SiacoinOutput) {
// Get the outputs in order according to their sorted string form.
for _, utxoString := range unspentOutputStrings {
var outputID OutputID
var outputID SiacoinOutputID
copy(outputID[:], utxoString)
output, _ := s.output(outputID)
sortedOutputs = append(sortedOutputs, output)
......@@ -86,7 +86,7 @@ func (s *State) sortedUsfoSet() (sortedOutputs []SiafundOutput) {
// Get the outputs in order according to their sorted string form.
for _, idString := range idStrings {
var outputID OutputID
var outputID SiafundOutputID
copy(outputID[:], idString)
// Sanity check - the output should exist.
......@@ -169,7 +169,7 @@ func (s *State) stateHash() crypto.Hash {
sort.Strings(delayedStrings)
for _, delayedString := range delayedStrings {
var id OutputID
var id SiacoinOutputID
copy(id[:], delayedString)
leaves = append(leaves, crypto.HashObject(delayedOutputs[id]))
}
......@@ -276,7 +276,7 @@ func (s *State) HeightOfBlock(bid BlockID) (height BlockHeight, exists bool) {
// Output returns the output associated with an OutputID, returning an error if
// the output is not found.
func (s *State) Output(id OutputID) (output SiacoinOutput, exists bool) {
func (s *State) Output(id SiacoinOutputID) (output SiacoinOutput, exists bool) {
s.mu.RLock()
defer s.mu.RUnlock()
return s.output(id)
......
......@@ -7,12 +7,8 @@ import (
"github.com/NebulousLabs/Sia/encoding"
)
// TODO: when testing the covered fields stuff, antagonistically try to cause
// seg faults by throwing covered fields objects at the state which point to
// nonexistent objects in the transaction.
var (
MissingSignaturesErr = errors.New("transaction has inputs with missing signatures")
ErrMissingSignatures = errors.New("transaction has inputs with missing signatures")
)
// Each input has a list of public keys and a required number of signatures.
......@@ -168,7 +164,7 @@ func (s *State) validSignatures(t Transaction) (err error) {
}
// Check that the timelock has expired.
if sig.TimeLock > s.height() {
if sig.Timelock > s.height() {
return errors.New("signature used before timelock expiration")
}
......@@ -187,7 +183,7 @@ func (s *State) validSignatures(t Transaction) (err error) {
return err
}
var decodedSig crypto.Signature
err = encoding.Unmarshal(sig.Signature, &decodedSig)
err = encoding.Unmarshal([]byte(sig.Signature), &decodedSig)
if err != nil {
return err
}
......@@ -210,7 +206,7 @@ func (s *State) validSignatures(t Transaction) (err error) {
// Check that all inputs have been sufficiently signed.
for _, reqSigs := range sigMap {
if reqSigs.RemainingSignatures != 0 {
return MissingSignaturesErr
return ErrMissingSignatures
}
}
......
......@@ -6,7 +6,7 @@ import (
)
var (
ZeroAddress = CoinAddress{0}
ZeroAddress = UnlockHash{0}
ZeroCurrency = NewCurrency64(0)
)
......@@ -40,10 +40,10 @@ type State struct {
// currentPath) will have an identical consensus set. Anything else is a
// software bug.
siafundPool Currency
unspentSiacoinOutputs map[OutputID]SiacoinOutput
unspentSiacoinOutputs map[SiacoinOutputID]SiacoinOutput
openFileContracts map[FileContractID]FileContract
unspentSiafundOutputs map[OutputID]SiafundOutput
delayedSiacoinOutputs map[BlockHeight]map[OutputID]SiacoinOutput
unspentSiafundOutputs map[SiafundOutputID]SiafundOutput
delayedSiacoinOutputs map[BlockHeight]map[SiacoinOutputID]SiacoinOutput
// Per convention, all exported functions in the consensus package can be
// called concurrently. The state mutex helps to orchestrate thread safety.
......@@ -63,10 +63,10 @@ func CreateGenesisState(genesisTime Timestamp) (s *State) {
badBlocks: make(map[BlockID]struct{}),
blockMap: make(map[BlockID]*blockNode),
currentPath: make(map[BlockHeight]BlockID),
unspentSiacoinOutputs: make(map[OutputID]SiacoinOutput),
unspentSiacoinOutputs: make(map[SiacoinOutputID]SiacoinOutput),
openFileContracts: make(map[FileContractID]FileContract),
unspentSiafundOutputs: make(map[OutputID]SiafundOutput),
delayedSiacoinOutputs: make(map[BlockHeight]map[OutputID]SiacoinOutput),
unspentSiafundOutputs: make(map[SiafundOutputID]SiafundOutput),
delayedSiacoinOutputs: make(map[BlockHeight]map[SiacoinOutputID]SiacoinOutput),
}
// Create the genesis block and add it as the BlockRoot.
......@@ -84,13 +84,13 @@ func CreateGenesisState(genesisTime Timestamp) (s *State) {
s.currentBlockID = genesisBlock.ID()
s.currentPath[BlockHeight(0)] = genesisBlock.ID()
s.unspentSiacoinOutputs[genesisBlock.MinerPayoutID(0)] = SiacoinOutput{
Value: CalculateCoinbase(0),
SpendHash: ZeroAddress, // TODO: change to Nebulous Genesis Siacoin SpendHash Address
Value: CalculateCoinbase(0),
UnlockHash: ZeroAddress, // TODO: change to Nebulous Genesis Siacoin SpendHash Address
}
s.unspentSiafundOutputs[OutputID{0}] = SiafundOutput{
Value: NewCurrency64(SiafundCount),
SpendHash: ZeroAddress, // TODO: change to Nebulous Genesis Siafund SpendHash Address
ClaimDestination: ZeroAddress, // TODO: change to Nebulous Genesis ClaimDestination Address
s.unspentSiafundOutputs[SiafundOutputID{0}] = SiafundOutput{
Value: NewCurrency64(SiafundCount),
UnlockHash: ZeroAddress, // TODO: change to Nebulous Genesis Siafund SpendHash Address
ClaimUnlockHash: ZeroAddress, // TODO: change to Nebulous Genesis ClaimDestination Address
}
return
......
......@@ -5,7 +5,9 @@ import (
)
var (
MissingOutputErr = errors.New("transaction spends a nonexisting output")
ErrMissingSiacoinOutput = errors.New("transaction spends a nonexisting siacoin output")
ErrMissingSiafundOutput = errors.New("transaction spends a nonexisting siafund output")
ErrMissingFileContract = errors.New("transaction terminates a nonexisting file contract")
)
// followsStorageProofRule checks that a transaction follows the limitations
......@@ -35,20 +37,20 @@ func (t Transaction) followsStorageProofRules() bool {
// consensus state. If not, an error is returned.
func (s *State) validSiacoinInput(sci SiacoinInput) (sco SiacoinOutput, err error) {
// Check the input spends an existing and valid output.
sco, exists := s.unspentSiacoinOutputs[sci.OutputID]
sco, exists := s.unspentSiacoinOutputs[sci.ParentID]
if !exists {
err = MissingOutputErr
err = ErrMissingSiacoinOutput
return
}
// Check that the spend conditions match the hash listed in the output.
if sci.SpendConditions.CoinAddress() != s.unspentSiacoinOutputs[sci.OutputID].SpendHash {
if sci.UnlockConditions.UnlockHash() != sco.UnlockHash {
err = errors.New("spend conditions do not match hash")
return
}
// Check the timelock on the spend conditions is expired.
if sci.SpendConditions.TimeLock > s.height() {
if sci.UnlockConditions.Timelock > s.height() {
err = errors.New("output spent before timelock expiry.")
return
}
......@@ -60,20 +62,20 @@ func (s *State) validSiacoinInput(sci SiacoinInput) (sco SiacoinOutput, err erro
// consensus state. If not, an error is returned.
func (s *State) validSiafundInput(sfi SiafundInput) (sfo SiafundOutput, err error) {
// Check the input spends an existing and valid output.
sfo, exists := s.unspentSiafundOutputs[sfi.OutputID]
sfo, exists := s.unspentSiafundOutputs[sfi.ParentID]
if !exists {
err = MissingOutputErr
err = ErrMissingSiafundOutput
return
}
// Check that the spend conditions match the hash listed in the output.
if sfi.SpendConditions.CoinAddress() != s.unspentSiafundOutputs[sfi.OutputID].SpendHash {
if sfi.UnlockConditions.UnlockHash() != sfo.UnlockHash {
err = errors.New("spend conditions do not match hash")
return
}
// Check the timelock on the spend conditions is expired.
if sfi.SpendConditions.TimeLock > s.height() {
if sfi.UnlockConditions.Timelock > s.height() {
err = errors.New("output spent before timelock expiry.")
return
}
......@@ -199,7 +201,7 @@ func (s *State) applySiacoinInputs(bn *blockNode, t Transaction) {
for _, sci := range t.SiacoinInputs {
// Sanity check - the input should exist within the blockchain.
if DEBUG {
_, exists := s.unspentSiacoinOutputs[sci.OutputID]
_, exists := s.unspentSiacoinOutputs[sci.ParentID]
if !exists {
panic("Applying a transaction with an invalid unspent output!")
}
......@@ -207,11 +209,11 @@ func (s *State) applySiacoinInputs(bn *blockNode, t Transaction) {
scod := SiacoinOutputDiff{
New: false,
ID: sci.OutputID,
SiacoinOutput: s.unspentSiacoinOutputs[sci.OutputID],
ID: sci.ParentID,
SiacoinOutput: s.unspentSiacoinOutputs[sci.ParentID],
}
bn.siacoinOutputDiffs = append(bn.siacoinOutputDiffs, scod)
delete(s.unspentSiacoinOutputs, sci.OutputID)
delete(s.unspentSiacoinOutputs, sci.ParentID)
}
}
......@@ -244,7 +246,7 @@ func (s *State) applySiafundInputs(bn *blockNode, t Transaction) {
for _, sfi := range t.SiafundInputs {
// Sanity check - the input should exist within the blockchain.
if DEBUG {
_, exists := s.unspentSiafundOutputs[sfi.OutputID]
_, exists := s.unspentSiafundOutputs[sfi.ParentID]
if !exists {
panic("applying a transaction with an invalid unspent siafund output")
}
......@@ -252,7 +254,7 @@ func (s *State) applySiafundInputs(bn *blockNode, t Transaction) {
// Calculate the volume of siacoins to put in the claim output.
claimPortion := s.siafundPool
sfo := s.unspentSiafundOutputs[sfi.OutputID]
sfo := s.unspentSiafundOutputs[sfi.ParentID]
err := claimPortion.Sub(sfo.ClaimStart)
if err != nil {
if DEBUG {
......@@ -272,10 +274,10 @@ func (s *State) applySiafundInputs(bn *blockNode, t Transaction) {
// Add the claim output to the delayed set of outputs.
sco := SiacoinOutput{
Value: claimPortion,
SpendHash: sfo.ClaimDestination,
Value: claimPortion,
UnlockHash: sfo.ClaimUnlockHash,
}
scoid := sfi.OutputID.SiaClaimOutputID()
scoid := sfi.ParentID.SiaClaimOutputID()
s.delayedSiacoinOutputs[s.height()][scoid] = sco
bn.delayedSiacoinOutputs[scoid] = sco
......@@ -283,11 +285,11 @@ func (s *State) applySiafundInputs(bn *blockNode, t Transaction) {
// consensus set.
sfod := SiafundOutputDiff{
New: false,
ID: sfi.OutputID,
SiafundOutput: s.unspentSiafundOutputs[sfi.OutputID],
ID: sfi.ParentID,
SiafundOutput: s.unspentSiafundOutputs[sfi.ParentID],
}
bn.siafundOutputDiffs = append(bn.siafundOutputDiffs, sfod)
delete(s.unspentSiafundOutputs, sfi.OutputID)
delete(s.unspentSiafundOutputs, sfi.ParentID)
}
}
......
......@@ -316,13 +316,13 @@ func CalculateCoinbase(height BlockHeight) (c Currency) {
// number of signatures.
func (uc UnlockConditions) UnlockHash() UnlockHash {
leaves := []crypto.Hash{
crypto.HashObject(sc.Timelock),
crypto.HashObject(uc.Timelock),
}
for i := range sc.PublicKeys {
leaves = append(leaves, crypto.HashObject(sc.PublicKeys[i]))
for i := range uc.PublicKeys {
leaves = append(leaves, crypto.HashObject(uc.PublicKeys[i]))
}
leaves = append(leaves, crypto.HashObject(sc.NumSignatures))
return CoinAddress(crypto.MerkleRoot(leaves))
leaves = append(leaves, crypto.HashObject(uc.NumSignatures))
return UnlockHash(crypto.MerkleRoot(leaves))
}
// ID returns the id of a block, which is calculated by concatenating the
......@@ -355,8 +355,8 @@ func (b Block) MerkleRoot() crypto.Hash {
// MinerPayoutID returns the ID of the miner payout at the given index, which
// is derived by appending the index of the miner payout to the id of the
// block.
func (b Block) MinerPayoutID(i int) OutputID {
return OutputID(crypto.HashAll(
func (b Block) MinerPayoutID(i int) SiacoinOutputID {
return SiacoinOutputID(crypto.HashAll(
b.ID(),
i,
))
......@@ -366,8 +366,8 @@ func (b Block) MinerPayoutID(i int) OutputID {
// output. The id is derived by taking SpecifierSiacoinOutput, appending all of
// the fields in the transaction except the signatures, and then appending the
// index of the SiacoinOutput in the transaction and taking the hash.
func (t Transaction) SiacoinOutputID(i int) OutputID {
return OutputID(crypto.HashAll(
func (t Transaction) SiacoinOutputID(i int) SiacoinOutputID {
return SiacoinOutputID(crypto.HashAll(
SpecifierSiacoinOutput,
t.SiacoinInputs,
t.SiacoinOutputs,
......@@ -407,8 +407,8 @@ func (t Transaction) FileContractID(i int) FileContractID {
// is derived by taking SpecifierFileContractTerminationPayout, appending the
// id of the file contract that is being terminated, and then appending the
// index of the payout in the termination and taking the hash.
func (fcid FileContractID) FileContractTerminationPayoutID(i int) FileContractID {
return FileContractID(crypto.HashAll(
func (fcid FileContractID) FileContractTerminationPayoutID(i int) SiacoinOutputID {
return SiacoinOutputID(crypto.HashAll(
SpecifierFileContractTerminationPayout,
fcid,
i,
......@@ -420,22 +420,21 @@ func (fcid FileContractID) FileContractTerminationPayoutID(i int) FileContractID
// SpecifierStorageProofOutput, appending the id of the file contract that the
// proof is for, and then appending a bool indicating whether the proof was
// valid or missed (true is valid, false is missed), then taking the hash.
func (fcid FileContractID) StorageProofOutputID(proofValid bool) (outputID OutputID) {
outputID = OutputID(crypto.HashAll(
func (fcid FileContractID) StorageProofOutputID(proofValid bool) SiacoinOutputID {
return SiacoinOutputID(crypto.HashAll(
SpecifierStorageProofOutput,
fcid,
proofValid,
))
return
}
// SiafundOutputID returns the id of a SiafundOutput given the index of the
// output. The id is derived by taking SpecifierSiafundOutput, appending all of
// the fields in the transaction except the signatures, and then appending the
// index of the SiafundOutput in the transaction and taking the hash.
func (t Transaction) SiafundOutputID(i int) OutputID {
return OutputID(crypto.HashAll(
SiafundOutputSpecifier,
func (t Transaction) SiafundOutputID(i int) SiafundOutputID {
return SiafundOutputID(crypto.HashAll(
SpecifierSiafundOutput,
t.SiacoinInputs,
t.SiacoinOutputs,
t.FileContracts,
......@@ -452,8 +451,8 @@ func (t Transaction) SiafundOutputID(i int) OutputID {
// SiaClaimOutputID returns the id of the SiacoinOutput that is created when
// the siafund output gets spent. The id is calculated by taking the hash of
// the id of the SiafundOutput.
func (id SiafundOutputID) SiaClaimOutputID() OutputID {
return OutputID(crypto.HashAll(
func (id SiafundOutputID) SiaClaimOutputID() SiacoinOutputID {
return SiacoinOutputID(crypto.HashAll(
id,
))
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment