mirror of
https://github.com/sparrowwallet/sparrow.git
synced 2024-12-24 12:46:45 +00:00
parse transactions by wallet node
This commit is contained in:
parent
b1785f352b
commit
0836273c8f
3 changed files with 34 additions and 29 deletions
2
drongo
2
drongo
|
@ -1 +1 @@
|
||||||
Subproject commit d0a75fd26809d47fddf0c432bd8f6e6a9a522c64
|
Subproject commit f88e3d442357e514421b993155062f7ea8177d06
|
|
@ -2,16 +2,12 @@ package com.sparrowwallet.sparrow.io;
|
||||||
|
|
||||||
import com.github.arteam.simplejsonrpc.client.*;
|
import com.github.arteam.simplejsonrpc.client.*;
|
||||||
import com.github.arteam.simplejsonrpc.client.builder.BatchRequestBuilder;
|
import com.github.arteam.simplejsonrpc.client.builder.BatchRequestBuilder;
|
||||||
import com.github.arteam.simplejsonrpc.client.generator.CurrentTimeIdGenerator;
|
|
||||||
import com.github.arteam.simplejsonrpc.core.annotation.JsonRpcMethod;
|
|
||||||
import com.github.arteam.simplejsonrpc.core.annotation.JsonRpcParam;
|
|
||||||
import com.github.arteam.simplejsonrpc.core.annotation.JsonRpcService;
|
|
||||||
import com.google.common.net.HostAndPort;
|
import com.google.common.net.HostAndPort;
|
||||||
import com.sparrowwallet.drongo.KeyPurpose;
|
import com.sparrowwallet.drongo.KeyPurpose;
|
||||||
import com.sparrowwallet.drongo.Utils;
|
import com.sparrowwallet.drongo.Utils;
|
||||||
import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
||||||
import com.sparrowwallet.drongo.protocol.Transaction;
|
import com.sparrowwallet.drongo.protocol.Transaction;
|
||||||
import com.sparrowwallet.drongo.wallet.TransactionReference;
|
import com.sparrowwallet.drongo.wallet.BlockchainTransactionHash;
|
||||||
import com.sparrowwallet.drongo.wallet.Wallet;
|
import com.sparrowwallet.drongo.wallet.Wallet;
|
||||||
import com.sparrowwallet.drongo.wallet.WalletNode;
|
import com.sparrowwallet.drongo.wallet.WalletNode;
|
||||||
import javafx.concurrent.Service;
|
import javafx.concurrent.Service;
|
||||||
|
@ -101,13 +97,13 @@ public class ElectrumServer {
|
||||||
Optional<WalletNode> optionalNode = nodes.stream().filter(n -> n.getDerivationPath().equals(path)).findFirst();
|
Optional<WalletNode> optionalNode = nodes.stream().filter(n -> n.getDerivationPath().equals(path)).findFirst();
|
||||||
if(optionalNode.isPresent()) {
|
if(optionalNode.isPresent()) {
|
||||||
WalletNode node = optionalNode.get();
|
WalletNode node = optionalNode.get();
|
||||||
Set<TransactionReference> references = Arrays.stream(txes).map(ScriptHashTx::getTransactionReference).collect(Collectors.toSet());
|
Set<BlockchainTransactionHash> references = Arrays.stream(txes).map(ScriptHashTx::getBlockchainTransactionHash).collect(Collectors.toSet());
|
||||||
|
|
||||||
for(TransactionReference reference : references) {
|
for(BlockchainTransactionHash reference : references) {
|
||||||
if(!node.getHistory().add(reference)) {
|
if(!node.getHistory().add(reference)) {
|
||||||
Optional<TransactionReference> optionalReference = node.getHistory().stream().filter(tr -> tr.getTransactionId().equals(reference.getTransactionId())).findFirst();
|
Optional<BlockchainTransactionHash> optionalReference = node.getHistory().stream().filter(tr -> tr.getHash().equals(reference.getHash())).findFirst();
|
||||||
if(optionalReference.isPresent()) {
|
if(optionalReference.isPresent()) {
|
||||||
TransactionReference existingReference = optionalReference.get();
|
BlockchainTransactionHash existingReference = optionalReference.get();
|
||||||
if(existingReference.getHeight() < reference.getHeight()) {
|
if(existingReference.getHeight() < reference.getHeight()) {
|
||||||
node.getHistory().remove(existingReference);
|
node.getHistory().remove(existingReference);
|
||||||
node.getHistory().add(reference);
|
node.getHistory().add(reference);
|
||||||
|
@ -131,29 +127,30 @@ public class ElectrumServer {
|
||||||
|
|
||||||
public void getReferencedTransactions(Wallet wallet, KeyPurpose keyPurpose) throws ServerException {
|
public void getReferencedTransactions(Wallet wallet, KeyPurpose keyPurpose) throws ServerException {
|
||||||
WalletNode purposeNode = wallet.getNode(keyPurpose);
|
WalletNode purposeNode = wallet.getNode(keyPurpose);
|
||||||
Set<TransactionReference> references = new HashSet<>();
|
Set<BlockchainTransactionHash> references = new HashSet<>();
|
||||||
for(WalletNode addressNode : purposeNode.getChildren()) {
|
for(WalletNode addressNode : purposeNode.getChildren()) {
|
||||||
references.addAll(addressNode.getHistory());
|
references.addAll(addressNode.getHistory());
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, Transaction> transactionMap = getTransactions(references);
|
Map<Sha256Hash, Transaction> transactionMap = getTransactions(references);
|
||||||
wallet.getTransactions().putAll(transactionMap);
|
wallet.getTransactions().putAll(transactionMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Transaction> getTransactions(Set<TransactionReference> references) throws ServerException {
|
public Map<Sha256Hash, Transaction> getTransactions(Set<BlockchainTransactionHash> references) throws ServerException {
|
||||||
try {
|
try {
|
||||||
JsonRpcClient client = new JsonRpcClient(getTransport());
|
JsonRpcClient client = new JsonRpcClient(getTransport());
|
||||||
BatchRequestBuilder<String, String> batchRequest = client.createBatchRequest().keysType(String.class).returnType(String.class);
|
BatchRequestBuilder<String, String> batchRequest = client.createBatchRequest().keysType(String.class).returnType(String.class);
|
||||||
for(TransactionReference reference : references) {
|
for(BlockchainTransactionHash reference : references) {
|
||||||
batchRequest.add(reference.getTransactionId(), "blockchain.transaction.get", reference.getTransactionId());
|
batchRequest.add(reference.getHashAsString(), "blockchain.transaction.get", reference.getHashAsString());
|
||||||
}
|
}
|
||||||
Map<String, String> result = batchRequest.execute();
|
Map<String, String> result = batchRequest.execute();
|
||||||
|
|
||||||
Map<String, Transaction> transactionMap = new HashMap<>();
|
Map<Sha256Hash, Transaction> transactionMap = new HashMap<>();
|
||||||
for(String txid : result.keySet()) {
|
for(String txid : result.keySet()) {
|
||||||
|
Sha256Hash hash = Sha256Hash.wrap(txid);
|
||||||
byte[] rawtx = Utils.hexToBytes(result.get(txid));
|
byte[] rawtx = Utils.hexToBytes(result.get(txid));
|
||||||
Transaction transaction = new Transaction(rawtx);
|
Transaction transaction = new Transaction(rawtx);
|
||||||
transactionMap.put(txid, transaction);
|
transactionMap.put(hash, transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
return transactionMap;
|
return transactionMap;
|
||||||
|
@ -175,8 +172,9 @@ public class ElectrumServer {
|
||||||
public String tx_hash;
|
public String tx_hash;
|
||||||
public long fee;
|
public long fee;
|
||||||
|
|
||||||
public TransactionReference getTransactionReference() {
|
public BlockchainTransactionHash getBlockchainTransactionHash() {
|
||||||
return new TransactionReference(tx_hash, height, fee);
|
Sha256Hash hash = Sha256Hash.wrap(tx_hash);
|
||||||
|
return new BlockchainTransactionHash(hash, height, fee);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -189,16 +187,6 @@ public class ElectrumServer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonRpcService
|
|
||||||
@JsonRpcId(CurrentTimeIdGenerator.class)
|
|
||||||
@JsonRpcParams(ParamsType.MAP)
|
|
||||||
private interface ELectrumXService {
|
|
||||||
|
|
||||||
@JsonRpcMethod("blockchain.scripthash.get_history")
|
|
||||||
List<ScriptHashTx> getHistory(@JsonRpcParam("scripthash") String scriptHash);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class TcpTransport implements Transport {
|
private static class TcpTransport implements Transport {
|
||||||
private static final int DEFAULT_PORT = 50001;
|
private static final int DEFAULT_PORT = 50001;
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import com.sparrowwallet.drongo.ExtendedKey;
|
||||||
import com.sparrowwallet.drongo.SecureString;
|
import com.sparrowwallet.drongo.SecureString;
|
||||||
import com.sparrowwallet.drongo.Utils;
|
import com.sparrowwallet.drongo.Utils;
|
||||||
import com.sparrowwallet.drongo.crypto.*;
|
import com.sparrowwallet.drongo.crypto.*;
|
||||||
|
import com.sparrowwallet.drongo.protocol.Sha256Hash;
|
||||||
import com.sparrowwallet.drongo.protocol.Transaction;
|
import com.sparrowwallet.drongo.protocol.Transaction;
|
||||||
import com.sparrowwallet.drongo.wallet.Keystore;
|
import com.sparrowwallet.drongo.wallet.Keystore;
|
||||||
import com.sparrowwallet.drongo.wallet.MnemonicException;
|
import com.sparrowwallet.drongo.wallet.MnemonicException;
|
||||||
|
@ -59,6 +60,8 @@ public class Storage {
|
||||||
gsonBuilder.registerTypeAdapter(ExtendedKey.class, new ExtendedPublicKeyDeserializer());
|
gsonBuilder.registerTypeAdapter(ExtendedKey.class, new ExtendedPublicKeyDeserializer());
|
||||||
gsonBuilder.registerTypeAdapter(byte[].class, new ByteArraySerializer());
|
gsonBuilder.registerTypeAdapter(byte[].class, new ByteArraySerializer());
|
||||||
gsonBuilder.registerTypeAdapter(byte[].class, new ByteArrayDeserializer());
|
gsonBuilder.registerTypeAdapter(byte[].class, new ByteArrayDeserializer());
|
||||||
|
gsonBuilder.registerTypeAdapter(Sha256Hash.class, new Sha256HashSerializer());
|
||||||
|
gsonBuilder.registerTypeAdapter(Sha256Hash.class, new Sha256HashDeserializer());
|
||||||
gsonBuilder.registerTypeAdapter(Transaction.class, new TransactionSerializer());
|
gsonBuilder.registerTypeAdapter(Transaction.class, new TransactionSerializer());
|
||||||
gsonBuilder.registerTypeAdapter(Transaction.class, new TransactionDeserializer());
|
gsonBuilder.registerTypeAdapter(Transaction.class, new TransactionDeserializer());
|
||||||
if(includeWalletSerializers) {
|
if(includeWalletSerializers) {
|
||||||
|
@ -271,6 +274,20 @@ public class Storage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class Sha256HashSerializer implements JsonSerializer<Sha256Hash> {
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(Sha256Hash src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return new JsonPrimitive(src.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Sha256HashDeserializer implements JsonDeserializer<Sha256Hash> {
|
||||||
|
@Override
|
||||||
|
public Sha256Hash deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||||
|
return Sha256Hash.wrap(json.getAsJsonPrimitive().getAsString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static class TransactionSerializer implements JsonSerializer<Transaction> {
|
private static class TransactionSerializer implements JsonSerializer<Transaction> {
|
||||||
@Override
|
@Override
|
||||||
public JsonElement serialize(Transaction src, Type typeOfSrc, JsonSerializationContext context) {
|
public JsonElement serialize(Transaction src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
|
Loading…
Reference in a new issue