diff --git a/bus/bus.go b/bus/bus.go index fbda894d7..045b8e82a 100644 --- a/bus/bus.go +++ b/bus/bus.go @@ -606,6 +606,11 @@ func (b *bus) walletRedistributeHandler(jc jape.Context) { } var ids []types.TransactionID + if len(txns) == 0 { + jc.Encode(ids) + return + } + for i := 0; i < len(txns); i++ { err = b.w.SignTransaction(cs, &txns[i], toSign, types.CoveredFields{WholeTransaction: true}) if jc.Check("couldn't sign the transaction", err) != nil { diff --git a/internal/test/e2e/cluster_test.go b/internal/test/e2e/cluster_test.go index 4c96cc989..5ca7141d5 100644 --- a/internal/test/e2e/cluster_test.go +++ b/internal/test/e2e/cluster_test.go @@ -2382,7 +2382,7 @@ func TestMultipartUploadWrappedByPartialSlabs(t *testing.T) { uploadPacking: true, }) defer cluster.Shutdown() - defer cluster.Shutdown() + b := cluster.Bus w := cluster.Worker slabSize := test.RedundancySettings.SlabSizeNoRedundancy() @@ -2449,6 +2449,48 @@ func TestMultipartUploadWrappedByPartialSlabs(t *testing.T) { } } +func TestWalletRedistribute(t *testing.T) { + if testing.Short() { + t.SkipNow() + } + + cluster := newTestCluster(t, testClusterOptions{ + hosts: test.RedundancySettings.TotalShards, + uploadPacking: true, + }) + defer cluster.Shutdown() + + // redistribute into 5 outputs + _, err := cluster.Bus.WalletRedistribute(context.Background(), 5, types.Siacoins(10)) + if err != nil { + t.Fatal(err) + } + cluster.MineBlocks(1) + + // assert we have 5 outputs with 10 SC + outputs, err := cluster.Bus.WalletOutputs(context.Background()) + if err != nil { + t.Fatal(err) + } + + var cnt int + for _, output := range outputs { + if output.Value.Cmp(types.Siacoins(10)) == 0 { + cnt++ + } + } + if cnt != 5 { + t.Fatalf("expected 5 outputs with 10 SC, got %v", cnt) + } + + // assert redistributing into 3 outputs succeeds, used to fail because we + // were broadcasting an empty transaction set + _, err = cluster.Bus.WalletRedistribute(context.Background(), 3, types.Siacoins(10)) + if err != nil { + t.Fatal(err) + } +} + func TestHostScan(t *testing.T) { // New cluster with autopilot disabled cfg := clusterOptsDefault