Newer
Older
// applytransaction.go handles applying a transaction to the consensus set.
// There is an assumption that the transaction has already been verified.
"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 processed block.
func applySiacoinInputs(tx *bolt.Tx, pb *processedBlock, t types.Transaction) {
// Remove all siacoin inputs from the unspent siacoin outputs list.
for _, sci := range t.SiacoinInputs {
sco, err := getSiacoinOutput(tx, sci.ParentID)
if build.DEBUG && err != nil {
panic(err)
scod := modules.SiacoinOutputDiff{
Direction: modules.DiffRevert,
ID: sci.ParentID,
pb.SiacoinOutputDiffs = append(pb.SiacoinOutputDiffs, scod)
commitSiacoinOutputDiff(tx, scod, modules.DiffApply)
// applySiacoinOutputs takes all of the siacoin outputs in a transaction and
// applies them to the state, updating the diffs in the processed block.
func applySiacoinOutputs(tx *bolt.Tx, pb *processedBlock, t types.Transaction) {
// Add all siacoin outputs to the unspent siacoin outputs list.
for i, sco := range t.SiacoinOutputs {
scod := modules.SiacoinOutputDiff{
Direction: modules.DiffApply,
ID: scoid,
SiacoinOutput: sco,
pb.SiacoinOutputDiffs = append(pb.SiacoinOutputDiffs, scod)
commitSiacoinOutputDiff(tx, scod, modules.DiffApply)
// applyFileContracts iterates through all of the file contracts in a
// transaction and applies them to the state, updating the diffs in the proccesed
// block.
func applyFileContracts(tx *bolt.Tx, pb *processedBlock, t types.Transaction) {
for i, fc := range t.FileContracts {
fcd := modules.FileContractDiff{
Direction: modules.DiffApply,
ID: fcid,
FileContract: fc,
}
pb.FileContractDiffs = append(pb.FileContractDiffs, fcd)
commitFileContractDiff(tx, fcd, modules.DiffApply)
// Get the portion of the contract that goes into the siafund pool and
// add it to the siafund pool.
sfp := getSiafundPool(tx)
sfpd := modules.SiafundPoolDiff{
Direction: modules.DiffApply,
Adjusted: sfp.Add(types.Tax(blockHeight(tx), fc.Payout)),
pb.SiafundPoolDiffs = append(pb.SiafundPoolDiffs, sfpd)
commitSiafundPoolDiff(tx, sfpd, modules.DiffApply)
// applyTxFileContractRevisions iterates through all of the file contract
// revisions in a transaction and applies them to the state, updating the diffs
func applyFileContractRevisions(tx *bolt.Tx, pb *processedBlock, t types.Transaction) {
for _, fcr := range t.FileContractRevisions {
// Add the diff to delete the old file contract.
Direction: modules.DiffRevert,
pb.FileContractDiffs = append(pb.FileContractDiffs, fcd)
commitFileContractDiff(tx, fcd, modules.DiffApply)
// Add the diff to add the revised file contract.
FileSize: fcr.NewFileSize,
FileMerkleRoot: fcr.NewFileMerkleRoot,
WindowStart: fcr.NewWindowStart,
WindowEnd: fcr.NewWindowEnd,
Payout: fc.Payout,
ValidProofOutputs: fcr.NewValidProofOutputs,
MissedProofOutputs: fcr.NewMissedProofOutputs,
UnlockHash: fcr.NewUnlockHash,
RevisionNumber: fcr.NewRevisionNumber,
Direction: modules.DiffApply,
ID: fcr.ParentID,
pb.FileContractDiffs = append(pb.FileContractDiffs, fcd)
commitFileContractDiff(tx, fcd, modules.DiffApply)
// applyTxStorageProofs iterates through all of the storage proofs in a
// transaction and applies them to the state, updating the diffs in the processed
// block.
func applyStorageProofs(tx *bolt.Tx, pb *processedBlock, t types.Transaction) {
// Add all of the outputs in the ValidProofOutputs of the contract.
for i, vpo := range fc.ValidProofOutputs {
spoid := sp.ParentID.StorageProofOutputID(types.ProofValid, uint64(i))
dscod := modules.DelayedSiacoinOutputDiff{
Direction: modules.DiffApply,
ID: spoid,
SiacoinOutput: vpo,
MaturityHeight: pb.Height + types.MaturityDelay,
pb.DelayedSiacoinOutputDiffs = append(pb.DelayedSiacoinOutputDiffs, dscod)
commitDelayedSiacoinOutputDiff(tx, dscod, modules.DiffApply)
Direction: modules.DiffRevert,
pb.FileContractDiffs = append(pb.FileContractDiffs, fcd)
commitFileContractDiff(tx, fcd, modules.DiffApply)
// applyTxSiafundInputs takes all of the siafund inputs in a transaction and
// applies them to the state, updating the diffs in the processed block.
func applySiafundInputs(tx *bolt.Tx, pb *processedBlock, t types.Transaction) {
for _, sfi := range t.SiafundInputs {
// Calculate the volume of siacoins to put in the claim output.
sfo, err := getSiafundOutput(tx, sfi.ParentID)
claimPortion := getSiafundPool(tx).Sub(sfo.ClaimStart).Div(types.SiafundCount).Mul(sfo.Value)
// Add the claim output to the delayed set of outputs.
sco := types.SiacoinOutput{
Value: claimPortion,
UnlockHash: sfi.ClaimUnlockHash,
}
sfoid := sfi.ParentID.SiaClaimOutputID()
dscod := modules.DelayedSiacoinOutputDiff{
Direction: modules.DiffApply,
ID: sfoid,
SiacoinOutput: sco,
MaturityHeight: pb.Height + types.MaturityDelay,
pb.DelayedSiacoinOutputDiffs = append(pb.DelayedSiacoinOutputDiffs, dscod)
commitDelayedSiacoinOutputDiff(tx, dscod, modules.DiffApply)
// Create the siafund output diff and remove the output from the
// consensus set.
sfod := modules.SiafundOutputDiff{
Direction: modules.DiffRevert,
pb.SiafundOutputDiffs = append(pb.SiafundOutputDiffs, sfod)
commitSiafundOutputDiff(tx, sfod, modules.DiffApply)
// applySiafundOutput applies a siafund output to the consensus set.
func applySiafundOutputs(tx *bolt.Tx, pb *processedBlock, t types.Transaction) {
sfo.ClaimStart = getSiafundPool(tx)
sfod := modules.SiafundOutputDiff{
Direction: modules.DiffApply,
ID: sfoid,
SiafundOutput: sfo,
}
pb.SiafundOutputDiffs = append(pb.SiafundOutputDiffs, sfod)
commitSiafundOutputDiff(tx, sfod, modules.DiffApply)
// applyTransaction applies the contents of a transaction to the ConsensusSet.
// This produces a set of diffs, which are stored in the blockNode containing
// the transaction. No verification is done by this function.
func applyTransaction(tx *bolt.Tx, pb *processedBlock, t types.Transaction) {
applySiacoinInputs(tx, pb, t)
applySiacoinOutputs(tx, pb, t)
applyFileContracts(tx, pb, t)
applyFileContractRevisions(tx, pb, t)
applyStorageProofs(tx, pb, t)
applySiafundInputs(tx, pb, t)