func TestCreateSpendsWithBurn(t *testing.T) { now := tNow() amt := wallet.Balance{10e6, 100} uxs := makeUxBalances([]wallet.Balance{ wallet.Balance{1e6, 50}, wallet.Balance{8e6, 40}, wallet.Balance{2e6, 60}, }, now) // Force them to get sorted uxs[2].Head.BkSeq = uint64(0) uxs[1].Head.BkSeq = uint64(1) uxs[0].Head.BkSeq = uint64(2) cuxs := append(coin.UxArray{}, uxs...) // Should spend 8e6,2e6 for the exact amount, but have to add 1e6 to // obtain +50 for a 50% fee spends, err := createSpends(now, uxs, amt, 0, 2) assert.Nil(t, err) assert.Equal(t, len(spends), 3) assert.Equal(t, spends, coin.UxArray{cuxs[2], cuxs[1], cuxs[0]}) have := wallet.Balance{0, 0} for _, ux := range spends { have = have.Add(wallet.NewBalanceFromUxOut(now, &ux)) } burn, change, err := calculateBurnAndChange(have.Hours, amt.Hours, 0, 2) assert.Equal(t, burn, uint64(50)) assert.Equal(t, change, uint64(0)) assert.Nil(t, err) }
//delete this function func createSpends(headTime uint64, uxa coin.UxArray, amt wallet.Balance) (coin.UxArray, error) { if amt.Coins == 0 { return nil, errors.New("Zero spend amount") } if amt.Coins%1e6 != 0 { return nil, errors.New("Coins must be multiple of 1e6") } uxs := OldestUxOut(uxa) sort.Sort(uxs) have := wallet.Balance{0, 0} spending := make(coin.UxArray, 0) for i := range uxs { b := wallet.NewBalanceFromUxOut(headTime, &uxs[i]) //this is bullshit if b.Coins == 0 || b.Coins%1e6 != 0 { logger.Error("UxOut coins are 0 or 1e6, can't spend") continue } have = have.Add(b) spending = append(spending, uxs[i]) } if amt.Coins > have.Coins { return nil, errors.New("Not enough coins") } return spending, nil }
func createSpends(headTime uint64, uxa coin.UxArray, amt wallet.Balance, fee, burnFactor uint64) (coin.UxArray, error) { if amt.Coins == 0 { return nil, errors.New("Zero spend amount") } if amt.Coins%1e6 != 0 { return nil, errors.New("Coins must be multiple of 1e6") } uxs := OldestUxOut(uxa) sort.Sort(uxs) have := wallet.Balance{0, 0} spending := make(coin.UxArray, 0) for i, _ := range uxs { burn, _, err := calculateBurnAndChange(have.Hours, amt.Hours, fee, burnFactor) if err == nil { trueHours := amt.Hours + fee + burn // Adjust hours as a moving target as outputs change if have.Coins > amt.Coins && have.Hours >= trueHours { break } // If we have the exact amount of both, we don't need any extra coins // for change if have.Coins == amt.Coins && have.Hours == trueHours { break } } b := wallet.NewBalanceFromUxOut(headTime, &uxs[i]) if b.Coins == 0 || b.Coins%1e6 != 0 { logger.Error("UxOut coins are 0 or 1e6, can't spend") continue } have = have.Add(b) spending = append(spending, uxs[i]) } if amt.Coins > have.Coins { return nil, errors.New("Not enough coins") } if amt.Hours+fee > have.Hours { return nil, errors.New("Not enough hours") } if _, _, err := calculateBurnAndChange(have.Hours, amt.Hours, fee, burnFactor); err != nil { return nil, errors.New("Not enough hours to burn") } return spending, nil }
func TestCreateSpends(t *testing.T) { now := tNow() amt := wallet.Balance{12e6, 125} uxs := makeUxBalances([]wallet.Balance{ wallet.Balance{1e6, 50}, wallet.Balance{8e6, 10}, // 3 wallet.Balance{2e6, 80}, // 2 wallet.Balance{5e6, 15}, // 4 wallet.Balance{7e6, 20}, // 1 }, now) uxs[4].Head.BkSeq = uint64(1) uxs[3].Head.BkSeq = uint64(4) uxs[2].Head.BkSeq = uint64(2) uxs[1].Head.BkSeq = uint64(3) uxs[0].Head.BkSeq = uint64(5) if sort.IsSorted(OldestUxOut(uxs)) { uxs[0], uxs[1] = uxs[1], uxs[0] } assert.False(t, sort.IsSorted(OldestUxOut(uxs))) expectedSorting := coin.UxArray{uxs[4], uxs[2], uxs[1], uxs[3], uxs[0]} cuxs := append(coin.UxArray{}, uxs...) sort.Sort(OldestUxOut(cuxs)) assert.Equal(t, expectedSorting, cuxs) assert.True(t, sort.IsSorted(OldestUxOut(cuxs))) assert.False(t, sort.IsSorted(OldestUxOut(uxs))) ouxs := append(coin.UxArray{}, uxs...) spends, err := createSpends(now, uxs, amt, 0, 0) assert.True(t, sort.IsSorted(OldestUxOut(uxs))) assert.Nil(t, err) assert.Equal(t, spends, cuxs[:len(spends)]) assert.Equal(t, len(spends), 4) assert.Equal(t, spends, coin.UxArray{ouxs[4], ouxs[2], ouxs[1], ouxs[3]}) // Recalculate what it should be b := wallet.Balance{0, 0} ouxs = make(coin.UxArray, 0, len(spends)) for _, ux := range cuxs { if b.Coins > amt.Coins && b.Hours >= amt.Hours { break } b = b.Add(wallet.NewBalanceFromUxOut(now, &ux)) ouxs = append(ouxs, ux) } assert.Equal(t, len(ouxs), len(spends)) assert.Equal(t, ouxs, spends) }