Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wip: add CleanOutAccount. #1419

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions errors/go.mod
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
module github.com/decred/dcrwallet/errors

go 1.12
2 changes: 2 additions & 0 deletions lru/go.mod
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
module github.com/decred/dcrwallet/lru

go 1.12
18 changes: 18 additions & 0 deletions rpc/api.proto
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ service WalletService {
rpc ValidateAddress (ValidateAddressRequest) returns (ValidateAddressResponse);
rpc CommittedTickets (CommittedTicketsRequest) returns (CommittedTicketsResponse);
rpc SweepAccount (SweepAccountRequest) returns (SweepAccountResponse);
rpc CleanOutAccount (CleanOutAccountRequest) returns (CleanOutAccountResponse);
}

service WalletLoaderService {
Expand Down Expand Up @@ -1071,3 +1072,20 @@ message SweepAccountResponse {
int64 total_output_amount = 3;
uint32 estimated_signed_size = 4;
}

message CleanOutAccountRequest {
string source_account = 1;
string destination_address = 2;
uint32 required_confirmations = 3;
double fee_per_kb = 4;
}

message CleanOutAccountResponse {
message CleanOutAccountTransaction {
bytes unsigned_transaction = 1;
int64 total_previous_output_amount = 2;
int64 total_output_amount = 3;
uint32 estimated_signed_size = 4;
}
repeated CleanOutAccountTransaction transactions = 1;
}
41 changes: 36 additions & 5 deletions rpc/documentation/api.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# RPC API Specification

Version: 5.8.x
Version: 5.9.x

**Note:** This document assumes the reader is familiar with gRPC concepts.
Refer to the [gRPC Concepts documentation](http://www.grpc.io/docs/guides/concepts.html)
Expand Down Expand Up @@ -578,6 +578,7 @@ The service provides the following methods:
- [`CommittedTickets`](#committedtickets)
- [`BestBlock`](#bestblock)
- [`SweepAccount`](#sweepaccount)
- [`CleanOutAccount`](#cleanoutaccount)

#### `Ping`

Expand Down Expand Up @@ -1982,13 +1983,43 @@ an account per the request parameters.
- `double fee_per_kb`: The minimum relay fee policy (optional).

**Response:** `SweepAccountResponse`
- `bytes unsigned_transaction`: The unsigned transaction bytes.
- `bytes unsigned_transaction`: The unsigned transaction bytes.

- `int64 total_previous_output_amount`: The total transaction input amount.
- `int64 total_previous_output_amount`: The total transaction input amount.

- `int64 total_output_amount`: The total transaction output amount.
- `int64 total_output_amount`: The total transaction output amount.

- `uint32 estimated_signed_size`: The estimated size of the transaction when signed.
- `uint32 estimated_signed_size`: The estimated size of the transaction when signed.
___

___

#### `CleanOutAccount`

The `CleanOutAccount` method moves as much value as possible using a batch of
transactions for the provided account.

**Request:** `CleanOutAccountRequest`
- `string source_account`: The account to be cleaned out.

- `string destination_address`: The destination address to pay to.

- `uint32 required_confirmations`: The minimum utxo confirmation requirement.

- `double fee_per_kb`: The minimum relay fee policy (optional).

**Response:** `CleanOutAccountResponse`
- `repeated CleanOutAccountTransaction transactions`: A collection of transactions cleaning out the provided account.

**Nested message:** `CleanOutAccountTransaction`

- `bytes unsigned_transaction`: The unsigned transaction bytes.

- `int64 total_previous_output_amount`: The total transaction input amount.

- `int64 total_output_amount`: The total transaction output amount.

- `uint32 estimated_signed_size`: The estimated size of the transaction when signed.
___

#### `TransactionNotifications`
Expand Down
53 changes: 53 additions & 0 deletions rpc/rpcserver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,59 @@ func (s *walletServer) SweepAccount(ctx context.Context, req *pb.SweepAccountReq
return res, nil
}

func (s *walletServer) CleanOutAccount(ctx context.Context, req *pb.CleanOutAccountRequest) (*pb.CleanOutAccountResponse, error) {
feePerKb := s.wallet.RelayFee()

// Use provided fee per Kb if specified.
if req.FeePerKb < 0 {
return nil, status.Errorf(codes.InvalidArgument, "%s",
"fee per kb argument cannot be negative")
}

if req.FeePerKb > 0 {
var err error
feePerKb, err = dcrutil.NewAmount(req.FeePerKb)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "%v", err)
}
}

account, err := s.wallet.AccountNumber(req.SourceAccount)
if err != nil {
return nil, translateError(err)
}

txs, err := s.wallet.CleanOutAccount(account, req.DestinationAddress,
feePerKb, req.RequiredConfirmations)
if err != nil {
return nil, translateError(err)
}

res := &pb.CleanOutAccountResponse{}
res.Transactions =
make([]*pb.CleanOutAccountResponse_CleanOutAccountTransaction, len(txs))
var txBuf bytes.Buffer
for idx, tx := range txs {
txBuf.Grow(tx.Tx.SerializeSize())
err = tx.Tx.Serialize(&txBuf)
if err != nil {
return nil, translateError(err)
}

entry := &pb.CleanOutAccountResponse_CleanOutAccountTransaction{
UnsignedTransaction: txBuf.Bytes(),
TotalPreviousOutputAmount: int64(tx.TotalInput),
TotalOutputAmount: int64(h.SumOutputValues(tx.Tx.TxOut)),
EstimatedSignedSize: uint32(tx.EstimatedSignedSerializeSize),
}

res.Transactions[idx] = entry
txBuf.Reset()
}

return res, nil
}

func (s *walletServer) BlockInfo(ctx context.Context, req *pb.BlockInfoRequest) (*pb.BlockInfoResponse, error) {
var blockID *wallet.BlockIdentifier
switch {
Expand Down
Loading