3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-01-31 07:12:17 +00:00

Support for applications recording exchange rate that was valid when transaction was sent. Use the new SendRequest.exchangeRate register.

Includes a test.
This commit is contained in:
Andreas Schildbach 2014-08-27 11:22:15 +02:00 committed by Mike Hearn
parent d9be6a62d2
commit 5be769d4ca
6 changed files with 1159 additions and 32 deletions

View File

@ -22,6 +22,7 @@ import com.google.bitcoin.crypto.TransactionSignature;
import com.google.bitcoin.script.Script;
import com.google.bitcoin.script.ScriptBuilder;
import com.google.bitcoin.script.ScriptOpCodes;
import com.google.bitcoin.utils.ExchangeRate;
import com.google.common.collect.ImmutableMap;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
@ -152,6 +153,13 @@ public class Transaction extends ChildMessage implements Serializable {
private Purpose purpose = Purpose.UNKNOWN;
/**
* This field can be used by applications to record the exchange rate that was valid when the transaction happened.
* It's optional.
*/
@Nullable
private ExchangeRate exchangeRate;
public Transaction(NetworkParameters params) {
super(params);
version = 1;
@ -1259,4 +1267,19 @@ public class Transaction extends ChildMessage implements Serializable {
public void setPurpose(Purpose purpose) {
this.purpose = purpose;
}
/**
* Getter for {@link #exchangeRate}.
*/
@Nullable
public ExchangeRate getExchangeRate() {
return exchangeRate;
}
/**
* Setter for {@link #exchangeRate}.
*/
public void setExchangeRate(ExchangeRate exchangeRate) {
this.exchangeRate = exchangeRate;
}
}

View File

@ -29,6 +29,7 @@ import com.google.bitcoin.signers.TransactionSigner;
import com.google.bitcoin.store.UnreadableWalletException;
import com.google.bitcoin.store.WalletProtobufSerializer;
import com.google.bitcoin.utils.BaseTaggableObject;
import com.google.bitcoin.utils.ExchangeRate;
import com.google.bitcoin.utils.ListenerRegistration;
import com.google.bitcoin.utils.Threading;
import com.google.bitcoin.wallet.*;
@ -3010,6 +3011,11 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
*/
public boolean useDummySignatures = true;
/**
* If not null, this exchange rate is recorded with the transaction during completion.
*/
public ExchangeRate exchangeRate = null;
// Tracks if this has been passed to wallet.completeTx already: just a safety check.
private boolean completed;
@ -3375,6 +3381,8 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
// transaction lists more appropriately, especially when the wallet starts to generate transactions itself
// for internal purposes.
req.tx.setPurpose(Transaction.Purpose.USER_PAYMENT);
// Record the exchange rate that was valid when the transaction was completed.
req.tx.setExchangeRate(req.exchangeRate);
req.completed = true;
req.fee = calculatedFee;
log.info(" completed: {}", req.tx);

View File

@ -24,6 +24,8 @@ import com.google.bitcoin.crypto.KeyCrypterScrypt;
import com.google.bitcoin.script.Script;
import com.google.bitcoin.signers.LocalTransactionSigner;
import com.google.bitcoin.signers.TransactionSigner;
import com.google.bitcoin.utils.ExchangeRate;
import com.google.bitcoin.utils.Fiat;
import com.google.bitcoin.wallet.KeyChainGroup;
import com.google.bitcoin.wallet.WalletTransaction;
import com.google.common.collect.Lists;
@ -290,6 +292,14 @@ public class WalletProtobufSerializer {
throw new RuntimeException("New tx purpose serialization not implemented.");
}
txBuilder.setPurpose(purpose);
ExchangeRate exchangeRate = tx.getExchangeRate();
if (exchangeRate != null) {
Protos.ExchangeRate.Builder exchangeRateBuilder = Protos.ExchangeRate.newBuilder()
.setCoinValue(exchangeRate.coin.value).setFiatValue(exchangeRate.fiat.value)
.setFiatCurrencyCode(exchangeRate.fiat.currencyCode);
txBuilder.setExchangeRate(exchangeRateBuilder);
}
return txBuilder.build();
}
@ -576,6 +586,12 @@ public class WalletProtobufSerializer {
tx.setPurpose(Transaction.Purpose.USER_PAYMENT);
}
if (txProto.hasExchangeRate()) {
Protos.ExchangeRate exchangeRateProto = txProto.getExchangeRate();
tx.setExchangeRate(new ExchangeRate(Coin.valueOf(exchangeRateProto.getCoinValue()), Fiat.valueOf(
exchangeRateProto.getFiatCurrencyCode(), exchangeRateProto.getFiatValue())));
}
// Transaction should now be complete.
Sha256Hash protoHash = byteStringToHash(txProto.getHash());
if (!tx.getHash().equals(protoHash))

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,8 @@ import com.google.bitcoin.testing.FakeTxBuilder;
import com.google.bitcoin.testing.MockTransactionBroadcaster;
import com.google.bitcoin.testing.NopTransactionSigner;
import com.google.bitcoin.testing.TestWithWallet;
import com.google.bitcoin.utils.ExchangeRate;
import com.google.bitcoin.utils.Fiat;
import com.google.bitcoin.utils.Threading;
import com.google.bitcoin.wallet.*;
import com.google.bitcoin.wallet.WalletTransaction.Pool;
@ -2555,4 +2557,12 @@ public class WalletTest extends TestWithWallet {
assertTrue(wallet.getTransactionSigners().get(1).isReady());
}
@Test
public void sendRequestExchangeRate() throws Exception {
receiveATransaction(wallet, myAddress);
SendRequest sendRequest = SendRequest.to(myAddress, Coin.COIN);
sendRequest.exchangeRate = new ExchangeRate(Fiat.parseFiat("EUR", "500"));
wallet.completeTx(sendRequest);
assertEquals(sendRequest.exchangeRate, sendRequest.tx.getExchangeRate());
}
}

View File

@ -263,7 +263,10 @@ message Transaction {
}
optional Purpose purpose = 10 [default = UNKNOWN];
// Next tag: 12
// Exchange rate that was valid when the transaction was sent.
optional ExchangeRate exchange_rate = 12;
// Next tag: 13
}
/** The parameters used in the scrypt key derivation function.
@ -366,3 +369,15 @@ message Wallet {
// Next tag: 18
}
/** An exchange rate between Bitcoin and some fiat currency. */
message ExchangeRate {
// This much of satoshis (1E-8 fractions)
required int64 coin_value = 1;
// is worth this much of fiat (1E-4 fractions).
required int64 fiat_value = 2;
// ISO 4217 currency code (if available) of the fiat currency.
required string fiat_currency_code = 3;
// Next tag: 4
}