mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-08-01 12:31:23 +00:00
Save value of inputs when completing transactions and persist it to the wallet protobuf. Determine the fee of a transaction in case we have all the values.
This commit is contained in:
committed by
Mike Hearn
parent
03e8934576
commit
780be05260
@@ -1,4 +1,5 @@
|
||||
/** Copyright 2013 Google Inc.
|
||||
* Copyright 2014 Andreas Schildbach
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -14,7 +15,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors: Jim Burton, Miron Cuperman
|
||||
* Authors: Jim Burton, Miron Cuperman, Andreas Schildbach
|
||||
*/
|
||||
|
||||
/* Notes:
|
||||
@@ -94,6 +95,8 @@ message TransactionInput {
|
||||
required bytes script_bytes = 3;
|
||||
// Sequence number. Currently unused, but intended for contracts in future.
|
||||
optional uint32 sequence = 4;
|
||||
// Value of connected output, if known
|
||||
optional int64 value = 5;
|
||||
}
|
||||
|
||||
message TransactionOutput {
|
||||
|
@@ -1,5 +1,6 @@
|
||||
/**
|
||||
* Copyright 2011 Google Inc.
|
||||
* Copyright 2014 Andreas Schildbach
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -375,6 +376,25 @@ public class Transaction extends ChildMessage implements Serializable {
|
||||
return getValueSentToMe(wallet).subtract(getValueSentFromMe(wallet));
|
||||
}
|
||||
|
||||
/**
|
||||
* The transaction fee is the difference of the value of all inputs and the value of all outputs. Currently, the fee
|
||||
* can only be determined for transactions created by us.
|
||||
*
|
||||
* @return fee, or null if it cannot be determined
|
||||
*/
|
||||
public BigInteger getFee() {
|
||||
BigInteger fee = BigInteger.ZERO;
|
||||
for (TransactionInput input : inputs) {
|
||||
if (input.getValue() == null)
|
||||
return null;
|
||||
fee = fee.add(input.getValue());
|
||||
}
|
||||
for (TransactionOutput output : outputs) {
|
||||
fee = fee.subtract(output.getValue());
|
||||
}
|
||||
return fee;
|
||||
}
|
||||
|
||||
boolean disconnectInputs() {
|
||||
boolean disconnected = false;
|
||||
maybeParse();
|
||||
@@ -635,6 +655,8 @@ public class Transaction extends ChildMessage implements Serializable {
|
||||
try {
|
||||
Script scriptSig = in.getScriptSig();
|
||||
s.append(scriptSig);
|
||||
if (in.getValue() != null)
|
||||
s.append(" ").append(bitcoinValueToFriendlyString(in.getValue())).append(" BTC");
|
||||
s.append("\n ");
|
||||
s.append("outpoint:");
|
||||
final TransactionOutPoint outpoint = in.getOutpoint();
|
||||
|
@@ -1,5 +1,6 @@
|
||||
/**
|
||||
* Copyright 2011 Google Inc.
|
||||
* Copyright 2014 Andreas Schildbach
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,6 +25,7 @@ import java.io.ObjectOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -54,28 +56,32 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
||||
// The Script object obtained from parsing scriptBytes. Only filled in on demand and if the transaction is not
|
||||
// coinbase.
|
||||
transient private WeakReference<Script> scriptSig;
|
||||
/** Value of the output connected to the input, if known. This field does not participate in equals()/hashCode(). */
|
||||
@Nullable
|
||||
private final BigInteger value;
|
||||
// A pointer to the transaction that owns this input.
|
||||
private Transaction parentTransaction;
|
||||
private final Transaction parentTransaction;
|
||||
|
||||
/**
|
||||
* Creates an input that connects to nothing - used only in creation of coinbase transactions.
|
||||
*/
|
||||
public TransactionInput(NetworkParameters params, Transaction parentTransaction, byte[] scriptBytes) {
|
||||
super(params);
|
||||
this.scriptBytes = scriptBytes;
|
||||
this.outpoint = new TransactionOutPoint(params, NO_SEQUENCE, (Transaction)null);
|
||||
this.sequence = NO_SEQUENCE;
|
||||
this.parentTransaction = parentTransaction;
|
||||
length = 40 + (scriptBytes == null ? 1 : VarInt.sizeOf(scriptBytes.length) + scriptBytes.length);
|
||||
this(params, parentTransaction, scriptBytes, new TransactionOutPoint(params, NO_SEQUENCE, (Transaction) null));
|
||||
}
|
||||
|
||||
public TransactionInput(NetworkParameters params, @Nullable Transaction parentTransaction, byte[] scriptBytes,
|
||||
TransactionOutPoint outpoint) {
|
||||
this(params, parentTransaction, scriptBytes, outpoint, null);
|
||||
}
|
||||
|
||||
public TransactionInput(NetworkParameters params, @Nullable Transaction parentTransaction, byte[] scriptBytes,
|
||||
TransactionOutPoint outpoint, @Nullable BigInteger value) {
|
||||
super(params);
|
||||
this.scriptBytes = scriptBytes;
|
||||
this.outpoint = outpoint;
|
||||
this.sequence = NO_SEQUENCE;
|
||||
this.parentTransaction = parentTransaction;
|
||||
this.value = value;
|
||||
length = 40 + (scriptBytes == null ? 1 : VarInt.sizeOf(scriptBytes.length) + scriptBytes.length);
|
||||
}
|
||||
|
||||
@@ -89,6 +95,7 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
||||
scriptBytes = EMPTY_ARRAY;
|
||||
sequence = NO_SEQUENCE;
|
||||
this.parentTransaction = parentTransaction;
|
||||
this.value = output.getValue();
|
||||
length = 41;
|
||||
}
|
||||
|
||||
@@ -99,6 +106,7 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
||||
byte[] payload, int offset) throws ProtocolException {
|
||||
super(params, payload, offset);
|
||||
this.parentTransaction = parentTransaction;
|
||||
this.value = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -118,6 +126,7 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
||||
throws ProtocolException {
|
||||
super(params, msg, offset, parentTransaction, parseLazy, parseRetain, UNKNOWN_LENGTH);
|
||||
this.parentTransaction = parentTransaction;
|
||||
this.value = null;
|
||||
}
|
||||
|
||||
protected void parseLite() throws ProtocolException {
|
||||
@@ -254,6 +263,14 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
||||
return parentTransaction;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Value of the output connected to this input, if known. Null if unknown.
|
||||
*/
|
||||
@Nullable
|
||||
public BigInteger getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable debug string.
|
||||
*/
|
||||
|
@@ -67,6 +67,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
* by anyone else.<p>
|
||||
*
|
||||
* @author Miron Cuperman
|
||||
* @author Andreas Schildbach
|
||||
*/
|
||||
public class WalletProtobufSerializer {
|
||||
private static final Logger log = LoggerFactory.getLogger(WalletProtobufSerializer.class);
|
||||
@@ -248,9 +249,10 @@ public class WalletProtobufSerializer {
|
||||
.setScriptBytes(ByteString.copyFrom(input.getScriptBytes()))
|
||||
.setTransactionOutPointHash(hashToByteString(input.getOutpoint().getHash()))
|
||||
.setTransactionOutPointIndex((int) input.getOutpoint().getIndex());
|
||||
if (input.hasSequence()) {
|
||||
inputBuilder.setSequence((int)input.getSequenceNumber());
|
||||
}
|
||||
if (input.hasSequence())
|
||||
inputBuilder.setSequence((int) input.getSequenceNumber());
|
||||
if (input.getValue() != null)
|
||||
inputBuilder.setValue(input.getValue().longValue());
|
||||
txBuilder.addTransactionInput(inputBuilder);
|
||||
}
|
||||
|
||||
@@ -541,15 +543,16 @@ public class WalletProtobufSerializer {
|
||||
tx.addOutput(output);
|
||||
}
|
||||
|
||||
for (Protos.TransactionInput transactionInput : txProto.getTransactionInputList()) {
|
||||
byte[] scriptBytes = transactionInput.getScriptBytes().toByteArray();
|
||||
for (Protos.TransactionInput inputProto : txProto.getTransactionInputList()) {
|
||||
byte[] scriptBytes = inputProto.getScriptBytes().toByteArray();
|
||||
TransactionOutPoint outpoint = new TransactionOutPoint(params,
|
||||
transactionInput.getTransactionOutPointIndex() & 0xFFFFFFFFL,
|
||||
byteStringToHash(transactionInput.getTransactionOutPointHash())
|
||||
inputProto.getTransactionOutPointIndex() & 0xFFFFFFFFL,
|
||||
byteStringToHash(inputProto.getTransactionOutPointHash())
|
||||
);
|
||||
TransactionInput input = new TransactionInput(params, tx, scriptBytes, outpoint);
|
||||
if (transactionInput.hasSequence()) {
|
||||
input.setSequenceNumber(transactionInput.getSequence());
|
||||
BigInteger value = inputProto.hasValue() ? BigInteger.valueOf(inputProto.getValue()) : null;
|
||||
TransactionInput input = new TransactionInput(params, tx, scriptBytes, outpoint, value);
|
||||
if (inputProto.hasSequence()) {
|
||||
input.setSequenceNumber(inputProto.getSequence());
|
||||
}
|
||||
tx.addInput(input);
|
||||
}
|
||||
|
@@ -3160,6 +3160,24 @@ public final class Protos {
|
||||
* </pre>
|
||||
*/
|
||||
int getSequence();
|
||||
|
||||
// optional int64 value = 5;
|
||||
/**
|
||||
* <code>optional int64 value = 5;</code>
|
||||
*
|
||||
* <pre>
|
||||
* Value of connected output, if known
|
||||
* </pre>
|
||||
*/
|
||||
boolean hasValue();
|
||||
/**
|
||||
* <code>optional int64 value = 5;</code>
|
||||
*
|
||||
* <pre>
|
||||
* Value of connected output, if known
|
||||
* </pre>
|
||||
*/
|
||||
long getValue();
|
||||
}
|
||||
/**
|
||||
* Protobuf type {@code wallet.TransactionInput}
|
||||
@@ -3232,6 +3250,11 @@ public final class Protos {
|
||||
sequence_ = input.readUInt32();
|
||||
break;
|
||||
}
|
||||
case 40: {
|
||||
bitField0_ |= 0x00000010;
|
||||
value_ = input.readInt64();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||
@@ -3368,11 +3391,36 @@ public final class Protos {
|
||||
return sequence_;
|
||||
}
|
||||
|
||||
// optional int64 value = 5;
|
||||
public static final int VALUE_FIELD_NUMBER = 5;
|
||||
private long value_;
|
||||
/**
|
||||
* <code>optional int64 value = 5;</code>
|
||||
*
|
||||
* <pre>
|
||||
* Value of connected output, if known
|
||||
* </pre>
|
||||
*/
|
||||
public boolean hasValue() {
|
||||
return ((bitField0_ & 0x00000010) == 0x00000010);
|
||||
}
|
||||
/**
|
||||
* <code>optional int64 value = 5;</code>
|
||||
*
|
||||
* <pre>
|
||||
* Value of connected output, if known
|
||||
* </pre>
|
||||
*/
|
||||
public long getValue() {
|
||||
return value_;
|
||||
}
|
||||
|
||||
private void initFields() {
|
||||
transactionOutPointHash_ = com.google.protobuf.ByteString.EMPTY;
|
||||
transactionOutPointIndex_ = 0;
|
||||
scriptBytes_ = com.google.protobuf.ByteString.EMPTY;
|
||||
sequence_ = 0;
|
||||
value_ = 0L;
|
||||
}
|
||||
private byte memoizedIsInitialized = -1;
|
||||
public final boolean isInitialized() {
|
||||
@@ -3410,6 +3458,9 @@ public final class Protos {
|
||||
if (((bitField0_ & 0x00000008) == 0x00000008)) {
|
||||
output.writeUInt32(4, sequence_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000010) == 0x00000010)) {
|
||||
output.writeInt64(5, value_);
|
||||
}
|
||||
getUnknownFields().writeTo(output);
|
||||
}
|
||||
|
||||
@@ -3435,6 +3486,10 @@ public final class Protos {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeUInt32Size(4, sequence_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000010) == 0x00000010)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeInt64Size(5, value_);
|
||||
}
|
||||
size += getUnknownFields().getSerializedSize();
|
||||
memoizedSerializedSize = size;
|
||||
return size;
|
||||
@@ -3559,6 +3614,8 @@ public final class Protos {
|
||||
bitField0_ = (bitField0_ & ~0x00000004);
|
||||
sequence_ = 0;
|
||||
bitField0_ = (bitField0_ & ~0x00000008);
|
||||
value_ = 0L;
|
||||
bitField0_ = (bitField0_ & ~0x00000010);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -3603,6 +3660,10 @@ public final class Protos {
|
||||
to_bitField0_ |= 0x00000008;
|
||||
}
|
||||
result.sequence_ = sequence_;
|
||||
if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
|
||||
to_bitField0_ |= 0x00000010;
|
||||
}
|
||||
result.value_ = value_;
|
||||
result.bitField0_ = to_bitField0_;
|
||||
onBuilt();
|
||||
return result;
|
||||
@@ -3631,6 +3692,9 @@ public final class Protos {
|
||||
if (other.hasSequence()) {
|
||||
setSequence(other.getSequence());
|
||||
}
|
||||
if (other.hasValue()) {
|
||||
setValue(other.getValue());
|
||||
}
|
||||
this.mergeUnknownFields(other.getUnknownFields());
|
||||
return this;
|
||||
}
|
||||
@@ -3872,6 +3936,55 @@ public final class Protos {
|
||||
return this;
|
||||
}
|
||||
|
||||
// optional int64 value = 5;
|
||||
private long value_ ;
|
||||
/**
|
||||
* <code>optional int64 value = 5;</code>
|
||||
*
|
||||
* <pre>
|
||||
* Value of connected output, if known
|
||||
* </pre>
|
||||
*/
|
||||
public boolean hasValue() {
|
||||
return ((bitField0_ & 0x00000010) == 0x00000010);
|
||||
}
|
||||
/**
|
||||
* <code>optional int64 value = 5;</code>
|
||||
*
|
||||
* <pre>
|
||||
* Value of connected output, if known
|
||||
* </pre>
|
||||
*/
|
||||
public long getValue() {
|
||||
return value_;
|
||||
}
|
||||
/**
|
||||
* <code>optional int64 value = 5;</code>
|
||||
*
|
||||
* <pre>
|
||||
* Value of connected output, if known
|
||||
* </pre>
|
||||
*/
|
||||
public Builder setValue(long value) {
|
||||
bitField0_ |= 0x00000010;
|
||||
value_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>optional int64 value = 5;</code>
|
||||
*
|
||||
* <pre>
|
||||
* Value of connected output, if known
|
||||
* </pre>
|
||||
*/
|
||||
public Builder clearValue() {
|
||||
bitField0_ = (bitField0_ & ~0x00000010);
|
||||
value_ = 0L;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(builder_scope:wallet.TransactionInput)
|
||||
}
|
||||
|
||||
@@ -14769,57 +14882,57 @@ public final class Protos {
|
||||
"label\030\004 \001(\t\022\032\n\022creation_timestamp\030\005 \001(\003\"" +
|
||||
".\n\004Type\022\014\n\010ORIGINAL\020\001\022\030\n\024ENCRYPTED_SCRYP",
|
||||
"T_AES\020\002\"5\n\006Script\022\017\n\007program\030\001 \002(\014\022\032\n\022cr" +
|
||||
"eation_timestamp\030\002 \002(\003\"\203\001\n\020TransactionIn" +
|
||||
"eation_timestamp\030\002 \002(\003\"\222\001\n\020TransactionIn" +
|
||||
"put\022\"\n\032transaction_out_point_hash\030\001 \002(\014\022" +
|
||||
"#\n\033transaction_out_point_index\030\002 \002(\r\022\024\n\014" +
|
||||
"script_bytes\030\003 \002(\014\022\020\n\010sequence\030\004 \001(\r\"\177\n\021" +
|
||||
"TransactionOutput\022\r\n\005value\030\001 \002(\003\022\024\n\014scri" +
|
||||
"pt_bytes\030\002 \002(\014\022!\n\031spent_by_transaction_h" +
|
||||
"ash\030\003 \001(\014\022\"\n\032spent_by_transaction_index\030" +
|
||||
"\004 \001(\005\"\234\003\n\025TransactionConfidence\0220\n\004type\030" +
|
||||
"\001 \001(\0162\".wallet.TransactionConfidence.Typ",
|
||||
"e\022\032\n\022appeared_at_height\030\002 \001(\005\022\036\n\026overrid" +
|
||||
"ing_transaction\030\003 \001(\014\022\r\n\005depth\030\004 \001(\005\022\021\n\t" +
|
||||
"work_done\030\005 \001(\003\022)\n\014broadcast_by\030\006 \003(\0132\023." +
|
||||
"wallet.PeerAddress\0224\n\006source\030\007 \001(\0162$.wal" +
|
||||
"let.TransactionConfidence.Source\"O\n\004Type" +
|
||||
"\022\013\n\007UNKNOWN\020\000\022\014\n\010BUILDING\020\001\022\013\n\007PENDING\020\002" +
|
||||
"\022\025\n\021NOT_IN_BEST_CHAIN\020\003\022\010\n\004DEAD\020\004\"A\n\006Sou" +
|
||||
"rce\022\022\n\016SOURCE_UNKNOWN\020\000\022\022\n\016SOURCE_NETWOR" +
|
||||
"K\020\001\022\017\n\013SOURCE_SELF\020\002\"\236\004\n\013Transaction\022\017\n\007" +
|
||||
"version\030\001 \002(\005\022\014\n\004hash\030\002 \002(\014\022&\n\004pool\030\003 \001(",
|
||||
"\0162\030.wallet.Transaction.Pool\022\021\n\tlock_time" +
|
||||
"\030\004 \001(\r\022\022\n\nupdated_at\030\005 \001(\003\0223\n\021transactio" +
|
||||
"n_input\030\006 \003(\0132\030.wallet.TransactionInput\022" +
|
||||
"5\n\022transaction_output\030\007 \003(\0132\031.wallet.Tra" +
|
||||
"nsactionOutput\022\022\n\nblock_hash\030\010 \003(\014\022 \n\030bl" +
|
||||
"ock_relativity_offsets\030\013 \003(\005\0221\n\nconfiden" +
|
||||
"ce\030\t \001(\0132\035.wallet.TransactionConfidence\022" +
|
||||
"5\n\007purpose\030\n \001(\0162\033.wallet.Transaction.Pu" +
|
||||
"rpose:\007UNKNOWN\"Y\n\004Pool\022\013\n\007UNSPENT\020\004\022\t\n\005S" +
|
||||
"PENT\020\005\022\014\n\010INACTIVE\020\002\022\010\n\004DEAD\020\n\022\013\n\007PENDIN",
|
||||
"G\020\020\022\024\n\020PENDING_INACTIVE\020\022\":\n\007Purpose\022\013\n\007" +
|
||||
"UNKNOWN\020\000\022\020\n\014USER_PAYMENT\020\001\022\020\n\014KEY_ROTAT" +
|
||||
"ION\020\002\"N\n\020ScryptParameters\022\014\n\004salt\030\001 \002(\014\022" +
|
||||
"\020\n\001n\030\002 \001(\003:\00516384\022\014\n\001r\030\003 \001(\005:\0018\022\014\n\001p\030\004 \001" +
|
||||
"(\005:\0011\"8\n\tExtension\022\n\n\002id\030\001 \002(\t\022\014\n\004data\030\002" +
|
||||
" \002(\014\022\021\n\tmandatory\030\003 \002(\010\" \n\003Tag\022\013\n\003tag\030\001 " +
|
||||
"\002(\t\022\014\n\004data\030\002 \002(\014\"\256\004\n\006Wallet\022\032\n\022network_" +
|
||||
"identifier\030\001 \002(\t\022\034\n\024last_seen_block_hash" +
|
||||
"\030\002 \001(\014\022\036\n\026last_seen_block_height\030\014 \001(\r\022!" +
|
||||
"\n\031last_seen_block_time_secs\030\016 \001(\003\022\030\n\003key",
|
||||
"\030\003 \003(\0132\013.wallet.Key\022(\n\013transaction\030\004 \003(\013" +
|
||||
"2\023.wallet.Transaction\022&\n\016watched_script\030" +
|
||||
"\017 \003(\0132\016.wallet.Script\022C\n\017encryption_type" +
|
||||
"\030\005 \001(\0162\035.wallet.Wallet.EncryptionType:\013U" +
|
||||
"NENCRYPTED\0227\n\025encryption_parameters\030\006 \001(" +
|
||||
"\0132\030.wallet.ScryptParameters\022\017\n\007version\030\007" +
|
||||
" \001(\005\022$\n\textension\030\n \003(\0132\021.wallet.Extensi" +
|
||||
"on\022\023\n\013description\030\013 \001(\t\022\031\n\021key_rotation_" +
|
||||
"time\030\r \001(\004\022\031\n\004tags\030\020 \003(\0132\013.wallet.Tag\";\n" +
|
||||
"\016EncryptionType\022\017\n\013UNENCRYPTED\020\001\022\030\n\024ENCR",
|
||||
"YPTED_SCRYPT_AES\020\002B\035\n\023org.bitcoinj.walle" +
|
||||
"tB\006Protos"
|
||||
"script_bytes\030\003 \002(\014\022\020\n\010sequence\030\004 \001(\r\022\r\n\005" +
|
||||
"value\030\005 \001(\003\"\177\n\021TransactionOutput\022\r\n\005valu" +
|
||||
"e\030\001 \002(\003\022\024\n\014script_bytes\030\002 \002(\014\022!\n\031spent_b" +
|
||||
"y_transaction_hash\030\003 \001(\014\022\"\n\032spent_by_tra" +
|
||||
"nsaction_index\030\004 \001(\005\"\234\003\n\025TransactionConf" +
|
||||
"idence\0220\n\004type\030\001 \001(\0162\".wallet.Transactio",
|
||||
"nConfidence.Type\022\032\n\022appeared_at_height\030\002" +
|
||||
" \001(\005\022\036\n\026overriding_transaction\030\003 \001(\014\022\r\n\005" +
|
||||
"depth\030\004 \001(\005\022\021\n\twork_done\030\005 \001(\003\022)\n\014broadc" +
|
||||
"ast_by\030\006 \003(\0132\023.wallet.PeerAddress\0224\n\006sou" +
|
||||
"rce\030\007 \001(\0162$.wallet.TransactionConfidence" +
|
||||
".Source\"O\n\004Type\022\013\n\007UNKNOWN\020\000\022\014\n\010BUILDING" +
|
||||
"\020\001\022\013\n\007PENDING\020\002\022\025\n\021NOT_IN_BEST_CHAIN\020\003\022\010" +
|
||||
"\n\004DEAD\020\004\"A\n\006Source\022\022\n\016SOURCE_UNKNOWN\020\000\022\022" +
|
||||
"\n\016SOURCE_NETWORK\020\001\022\017\n\013SOURCE_SELF\020\002\"\236\004\n\013" +
|
||||
"Transaction\022\017\n\007version\030\001 \002(\005\022\014\n\004hash\030\002 \002",
|
||||
"(\014\022&\n\004pool\030\003 \001(\0162\030.wallet.Transaction.Po" +
|
||||
"ol\022\021\n\tlock_time\030\004 \001(\r\022\022\n\nupdated_at\030\005 \001(" +
|
||||
"\003\0223\n\021transaction_input\030\006 \003(\0132\030.wallet.Tr" +
|
||||
"ansactionInput\0225\n\022transaction_output\030\007 \003" +
|
||||
"(\0132\031.wallet.TransactionOutput\022\022\n\nblock_h" +
|
||||
"ash\030\010 \003(\014\022 \n\030block_relativity_offsets\030\013 " +
|
||||
"\003(\005\0221\n\nconfidence\030\t \001(\0132\035.wallet.Transac" +
|
||||
"tionConfidence\0225\n\007purpose\030\n \001(\0162\033.wallet" +
|
||||
".Transaction.Purpose:\007UNKNOWN\"Y\n\004Pool\022\013\n" +
|
||||
"\007UNSPENT\020\004\022\t\n\005SPENT\020\005\022\014\n\010INACTIVE\020\002\022\010\n\004D",
|
||||
"EAD\020\n\022\013\n\007PENDING\020\020\022\024\n\020PENDING_INACTIVE\020\022" +
|
||||
"\":\n\007Purpose\022\013\n\007UNKNOWN\020\000\022\020\n\014USER_PAYMENT" +
|
||||
"\020\001\022\020\n\014KEY_ROTATION\020\002\"N\n\020ScryptParameters" +
|
||||
"\022\014\n\004salt\030\001 \002(\014\022\020\n\001n\030\002 \001(\003:\00516384\022\014\n\001r\030\003 " +
|
||||
"\001(\005:\0018\022\014\n\001p\030\004 \001(\005:\0011\"8\n\tExtension\022\n\n\002id\030" +
|
||||
"\001 \002(\t\022\014\n\004data\030\002 \002(\014\022\021\n\tmandatory\030\003 \002(\010\" " +
|
||||
"\n\003Tag\022\013\n\003tag\030\001 \002(\t\022\014\n\004data\030\002 \002(\014\"\256\004\n\006Wal" +
|
||||
"let\022\032\n\022network_identifier\030\001 \002(\t\022\034\n\024last_" +
|
||||
"seen_block_hash\030\002 \001(\014\022\036\n\026last_seen_block" +
|
||||
"_height\030\014 \001(\r\022!\n\031last_seen_block_time_se",
|
||||
"cs\030\016 \001(\003\022\030\n\003key\030\003 \003(\0132\013.wallet.Key\022(\n\013tr" +
|
||||
"ansaction\030\004 \003(\0132\023.wallet.Transaction\022&\n\016" +
|
||||
"watched_script\030\017 \003(\0132\016.wallet.Script\022C\n\017" +
|
||||
"encryption_type\030\005 \001(\0162\035.wallet.Wallet.En" +
|
||||
"cryptionType:\013UNENCRYPTED\0227\n\025encryption_" +
|
||||
"parameters\030\006 \001(\0132\030.wallet.ScryptParamete" +
|
||||
"rs\022\017\n\007version\030\007 \001(\005\022$\n\textension\030\n \003(\0132\021" +
|
||||
".wallet.Extension\022\023\n\013description\030\013 \001(\t\022\031" +
|
||||
"\n\021key_rotation_time\030\r \001(\004\022\031\n\004tags\030\020 \003(\0132" +
|
||||
"\013.wallet.Tag\";\n\016EncryptionType\022\017\n\013UNENCR",
|
||||
"YPTED\020\001\022\030\n\024ENCRYPTED_SCRYPT_AES\020\002B\035\n\023org" +
|
||||
".bitcoinj.walletB\006Protos"
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||
@@ -14855,7 +14968,7 @@ public final class Protos {
|
||||
internal_static_wallet_TransactionInput_fieldAccessorTable = new
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||
internal_static_wallet_TransactionInput_descriptor,
|
||||
new java.lang.String[] { "TransactionOutPointHash", "TransactionOutPointIndex", "ScriptBytes", "Sequence", });
|
||||
new java.lang.String[] { "TransactionOutPointHash", "TransactionOutPointIndex", "ScriptBytes", "Sequence", "Value", });
|
||||
internal_static_wallet_TransactionOutput_descriptor =
|
||||
getDescriptor().getMessageTypes().get(5);
|
||||
internal_static_wallet_TransactionOutput_fieldAccessorTable = new
|
||||
|
@@ -1983,6 +1983,23 @@ public class WalletTest extends TestWithWallet {
|
||||
assertEquals(2, request1.tx.getOutputs().size()); // and gotten change back
|
||||
}
|
||||
|
||||
@Test
|
||||
public void transactionGetFeeTest() throws Exception {
|
||||
Address notMyAddr = new ECKey().toAddress(params);
|
||||
|
||||
// Prepare wallet to spend
|
||||
StoredBlock block = new StoredBlock(makeSolvedTestBlock(blockStore, notMyAddr), BigInteger.ONE, 1);
|
||||
Transaction tx = createFakeTx(params, Utils.COIN, myAddress);
|
||||
wallet.receiveFromBlock(tx, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||
|
||||
// Create a transaction
|
||||
SendRequest request = SendRequest.to(notMyAddr, Utils.CENT);
|
||||
request.feePerKb = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
||||
wallet.completeTx(request);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request.fee);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request.tx.getFee());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void feePerKbCategoryJumpTest() throws Exception {
|
||||
// Simple test of boundary condition on fee per kb in category fee solver
|
||||
|
Reference in New Issue
Block a user