github.com/avahowell/sia@v0.5.1-beta.0.20160524050156-83dcc3d37c94/modules/wallet/money.go (about)

     1  package wallet
     2  
     3  import (
     4  	"github.com/NebulousLabs/Sia/build"
     5  	"github.com/NebulousLabs/Sia/types"
     6  )
     7  
     8  // sortedOutputs is a struct containing a slice of siacoin outputs and their
     9  // corresponding ids. sortedOutputs can be sorted using the sort package.
    10  type sortedOutputs struct {
    11  	ids     []types.SiacoinOutputID
    12  	outputs []types.SiacoinOutput
    13  }
    14  
    15  // ConfirmedBalance returns the balance of the wallet according to all of the
    16  // confirmed transactions.
    17  func (w *Wallet) ConfirmedBalance() (siacoinBalance types.Currency, siafundBalance types.Currency, siafundClaimBalance types.Currency) {
    18  	w.mu.Lock()
    19  	defer w.mu.Unlock()
    20  
    21  	for _, sco := range w.siacoinOutputs {
    22  		siacoinBalance = siacoinBalance.Add(sco.Value)
    23  	}
    24  	for _, sfo := range w.siafundOutputs {
    25  		siafundBalance = siafundBalance.Add(sfo.Value)
    26  		siafundClaimBalance = siafundClaimBalance.Add(w.siafundPool.Sub(sfo.ClaimStart).Mul(sfo.Value).Div(types.SiafundCount))
    27  	}
    28  	return
    29  }
    30  
    31  // UnconfirmedBalance returns the number of outgoing and incoming siacoins in
    32  // the unconfirmed transaction set. Refund outputs are included in this
    33  // reporting.
    34  func (w *Wallet) UnconfirmedBalance() (outgoingSiacoins types.Currency, incomingSiacoins types.Currency) {
    35  	w.mu.Lock()
    36  	defer w.mu.Unlock()
    37  
    38  	for _, upt := range w.unconfirmedProcessedTransactions {
    39  		for _, input := range upt.Inputs {
    40  			if input.FundType == types.SpecifierSiacoinInput && input.WalletAddress {
    41  				outgoingSiacoins = outgoingSiacoins.Add(input.Value)
    42  			}
    43  		}
    44  		for _, output := range upt.Outputs {
    45  			if output.FundType == types.SpecifierSiacoinOutput && output.WalletAddress {
    46  				incomingSiacoins = incomingSiacoins.Add(output.Value)
    47  			}
    48  		}
    49  	}
    50  	return
    51  }
    52  
    53  // SendSiacoins creates a transaction sending 'amount' to 'dest'. The transaction
    54  // is submitted to the transaction pool and is also returned.
    55  func (w *Wallet) SendSiacoins(amount types.Currency, dest types.UnlockHash) ([]types.Transaction, error) {
    56  	tpoolFee := types.SiacoinPrecision.Mul64(10) // TODO: better fee algo.
    57  	output := types.SiacoinOutput{
    58  		Value:      amount,
    59  		UnlockHash: dest,
    60  	}
    61  
    62  	txnBuilder := w.StartTransaction()
    63  	err := txnBuilder.FundSiacoins(amount.Add(tpoolFee))
    64  	if err != nil {
    65  		return nil, err
    66  	}
    67  	txnBuilder.AddMinerFee(tpoolFee)
    68  	txnBuilder.AddSiacoinOutput(output)
    69  	txnSet, err := txnBuilder.Sign(true)
    70  	if err != nil {
    71  		return nil, err
    72  	}
    73  	err = w.tpool.AcceptTransactionSet(txnSet)
    74  	if err != nil {
    75  		return nil, err
    76  	}
    77  	return txnSet, nil
    78  }
    79  
    80  // SendSiafunds creates a transaction sending 'amount' to 'dest'. The transaction
    81  // is submitted to the transaction pool and is also returned.
    82  func (w *Wallet) SendSiafunds(amount types.Currency, dest types.UnlockHash) ([]types.Transaction, error) {
    83  	tpoolFee := types.SiacoinPrecision.Mul64(10) // TODO: better fee algo.
    84  	output := types.SiafundOutput{
    85  		Value:      amount,
    86  		UnlockHash: dest,
    87  	}
    88  
    89  	txnBuilder := w.StartTransaction()
    90  	err := txnBuilder.FundSiacoins(tpoolFee)
    91  	if err != nil {
    92  		return nil, err
    93  	}
    94  	err = txnBuilder.FundSiafunds(amount)
    95  	if err != nil {
    96  		return nil, err
    97  	}
    98  	txnBuilder.AddMinerFee(tpoolFee)
    99  	txnBuilder.AddSiafundOutput(output)
   100  	txnSet, err := txnBuilder.Sign(true)
   101  	if err != nil {
   102  		return nil, err
   103  	}
   104  	err = w.tpool.AcceptTransactionSet(txnSet)
   105  	if err != nil {
   106  		return nil, err
   107  	}
   108  	return txnSet, nil
   109  }
   110  
   111  // Len returns the number of elements in the sortedOutputs struct.
   112  func (so sortedOutputs) Len() int {
   113  	if build.DEBUG && len(so.ids) != len(so.outputs) {
   114  		panic("sortedOutputs object is corrupt")
   115  	}
   116  	return len(so.ids)
   117  }
   118  
   119  // Less returns whether element 'i' is less than element 'j'. The currency
   120  // value of each output is used for comparison.
   121  func (so sortedOutputs) Less(i, j int) bool {
   122  	return so.outputs[i].Value.Cmp(so.outputs[j].Value) < 0
   123  }
   124  
   125  // Swap swaps two elements in the sortedOutputs set.
   126  func (so sortedOutputs) Swap(i, j int) {
   127  	so.ids[i], so.ids[j] = so.ids[j], so.ids[i]
   128  	so.outputs[i], so.outputs[j] = so.outputs[j], so.outputs[i]
   129  }