func (cs *CoinSet) removeElement(e *list.Element) Coin {
	c := e.Value.(Coin)
	cs.coinList.Remove(e)
	cs.totalValue -= c.Value()
	cs.totalValueAge -= c.ValueAge()
	return c
}
removeElement updates the cached value amounts in the CoinSet,
removes the element from the list, then returns the Coin that
was removed to the caller.
package coinset
import (
	"container/list"
	"errors"
	"sort"
	"github.com/soteria-dag/soterd/chaincfg/chainhash"
	"github.com/soteria-dag/soterd/wire"
	"github.com/soteria-dag/soterd/soterutil"
)
type Coin interface {
	Hash() *chainhash.Hash
	Index() uint32
	Value() soterutil.Amount
	PkScript() []byte
	NumConfs() int64
	ValueAge() int64
}
type Coins interface {
	Coins() []Coin
}
type CoinSet struct {
	coinList      *list.List
	totalValue    soterutil.Amount
	totalValueAge int64
}
var _ Coins = NewCoinSet(nil)
func NewCoinSet(coins []Coin) *CoinSet {
	newCoinSet := &CoinSet{
		coinList:      list.New(),
		totalValue:    0,
		totalValueAge: 0,
	}
	for _, coin := range coins {
		newCoinSet.PushCoin(coin)
	}
	return newCoinSet
}
func (cs *CoinSet) Coins() []Coin {
	coins := make([]Coin, cs.coinList.Len())
	for i, e := 0, cs.coinList.Front(); e != nil; i, e = i+1, e.Next() {
		coins[i] = e.Value.(Coin)
	}
	return coins
}
func (cs *CoinSet) TotalValue() (value soterutil.Amount) {
	return cs.totalValue
}
func (cs *CoinSet) TotalValueAge() (valueAge int64) {
	return cs.totalValueAge
}
func (cs *CoinSet) Num() int {
	return cs.coinList.Len()
}
func (cs *CoinSet) PushCoin(c Coin) {
	cs.coinList.PushBack(c)
	cs.totalValue += c.Value()
	cs.totalValueAge += c.ValueAge()
}
func (cs *CoinSet) PopCoin() Coin {
	back := cs.coinList.Back()
	if back == nil {
		return nil
	}
	return cs.removeElement(back)
}
func (cs *CoinSet) ShiftCoin() Coin {
	front := cs.coinList.Front()
	if front == nil {
		return nil
	}
	return cs.removeElement(front)
}