正在查看: imToken v3.28.8 应用的 WalletProtobufSerializer.java JAVA 源代码文件
本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。
正在查看: imToken v3.28.8 应用的 WalletProtobufSerializer.java JAVA 源代码文件
本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。
package org.bitcoinj.wallet;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.protobuf.ByteString;
import com.google.protobuf.CodedInputStream;
import com.google.protobuf.TextFormat;
import com.google.protobuf.WireFormat;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import javax.annotation.Nullable;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.core.PeerAddress;
import org.bitcoinj.core.ScriptException;
import org.bitcoinj.core.Sha256Hash;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.TransactionConfidence;
import org.bitcoinj.core.TransactionInput;
import org.bitcoinj.core.TransactionOutPoint;
import org.bitcoinj.core.TransactionOutput;
import org.bitcoinj.crypto.KeyCrypter;
import org.bitcoinj.crypto.KeyCrypterScrypt;
import org.bitcoinj.script.Script;
import org.bitcoinj.signers.LocalTransactionSigner;
import org.bitcoinj.signers.TransactionSigner;
import org.bitcoinj.utils.ExchangeRate;
import org.bitcoinj.utils.Fiat;
import org.bitcoinj.wallet.Protos;
import org.bitcoinj.wallet.UnreadableWalletException;
import org.bitcoinj.wallet.WalletTransaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class WalletProtobufSerializer {
private static final int WALLET_SIZE_LIMIT = 536870912;
private final WalletFactory factory;
private KeyChainFactory keyChainFactory;
private boolean requireMandatoryExtensions;
protected Map<ByteString, Transaction> txMap;
private static final Logger log = LoggerFactory.getLogger(WalletProtobufSerializer.class);
public static final int CURRENT_WALLET_VERSION = Protos.Wallet.getDefaultInstance().getVersion();
public interface WalletFactory {
Wallet create(NetworkParameters networkParameters, KeyChainGroup keyChainGroup);
}
public WalletProtobufSerializer() {
this(new WalletFactory() {
@Override
public Wallet create(NetworkParameters networkParameters, KeyChainGroup keyChainGroup) {
return new Wallet(networkParameters, keyChainGroup);
}
});
}
public WalletProtobufSerializer(WalletFactory walletFactory) {
this.requireMandatoryExtensions = true;
this.txMap = new HashMap();
this.factory = walletFactory;
this.keyChainFactory = new DefaultKeyChainFactory();
}
public void setKeyChainFactory(KeyChainFactory keyChainFactory) {
this.keyChainFactory = keyChainFactory;
}
public void setRequireMandatoryExtensions(boolean z) {
this.requireMandatoryExtensions = z;
}
public void writeWallet(Wallet wallet, OutputStream outputStream) throws IOException {
walletToProto(wallet).writeTo(outputStream);
}
public String walletToText(Wallet wallet) {
return TextFormat.printToString(walletToProto(wallet));
}
public Protos.Wallet walletToProto(Wallet wallet) {
Protos.Wallet.Builder newBuilder = Protos.Wallet.newBuilder();
newBuilder.setNetworkIdentifier(wallet.getNetworkParameters().getId());
if (wallet.getDescription() != null) {
newBuilder.setDescription(wallet.getDescription());
}
Iterator<WalletTransaction> it = wallet.getWalletTransactions().iterator();
while (it.hasNext()) {
newBuilder.addTransaction(makeTxProto(it.next()));
}
newBuilder.addAllKey(wallet.serializeKeyChainGroupToProtobuf());
for (Script script : wallet.getWatchedScripts()) {
newBuilder.addWatchedScript(Protos.Script.newBuilder().setProgram(ByteString.copyFrom(script.getProgram())).setCreationTimestamp(script.getCreationTimeSeconds() * 1000).m2352build());
}
Sha256Hash lastBlockSeenHash = wallet.getLastBlockSeenHash();
if (lastBlockSeenHash != null) {
newBuilder.setLastSeenBlockHash(hashToByteString(lastBlockSeenHash));
newBuilder.setLastSeenBlockHeight(wallet.getLastBlockSeenHeight());
}
if (wallet.getLastBlockSeenTimeSecs() > 0) {
newBuilder.setLastSeenBlockTimeSecs(wallet.getLastBlockSeenTimeSecs());
}
KeyCrypter keyCrypter = wallet.getKeyCrypter();
if (keyCrypter == null) {
newBuilder.setEncryptionType(Protos.Wallet.EncryptionType.UNENCRYPTED);
} else {
newBuilder.setEncryptionType(keyCrypter.getUnderstoodEncryptionType());
if (keyCrypter instanceof KeyCrypterScrypt) {
newBuilder.setEncryptionParameters(((KeyCrypterScrypt) keyCrypter).getScryptParameters());
} else {
throw new RuntimeException("The wallet has encryption of type '" + keyCrypter.getUnderstoodEncryptionType() + "' but this WalletProtobufSerializer does not know how to persist this.");
}
}
if (wallet.getKeyRotationTime() != null) {
newBuilder.setKeyRotationTime(wallet.getKeyRotationTime().getTime() / 1000);
}
populateExtensions(wallet, newBuilder);
for (Map.Entry<String, ByteString> entry : wallet.getTags().entrySet()) {
newBuilder.addTags(Protos.Tag.newBuilder().setTag(entry.getKey()).setData(entry.getValue()));
}
for (TransactionSigner transactionSigner : wallet.getTransactionSigners()) {
if (!(transactionSigner instanceof LocalTransactionSigner)) {
Protos.TransactionSigner.Builder newBuilder2 = Protos.TransactionSigner.newBuilder();
newBuilder2.setClassName(transactionSigner.getClass().getName());
newBuilder2.setData(ByteString.copyFrom(transactionSigner.serialize()));
newBuilder.addTransactionSigners(newBuilder2);
}
}
newBuilder.setVersion(wallet.getVersion());
return newBuilder.m2596build();
}
private static void populateExtensions(Wallet wallet, Protos.Wallet.Builder builder) {
for (WalletExtension walletExtension : wallet.getExtensions().values()) {
Protos.Extension.Builder newBuilder = Protos.Extension.newBuilder();
newBuilder.setId(walletExtension.getWalletExtensionID());
newBuilder.setMandatory(walletExtension.isWalletExtensionMandatory());
newBuilder.setData(ByteString.copyFrom(walletExtension.serializeWalletExtension()));
builder.addExtension(newBuilder);
}
}
private static Protos.Transaction makeTxProto(WalletTransaction walletTransaction) {
Protos.Transaction.Purpose purpose;
Transaction transaction = walletTransaction.getTransaction();
Protos.Transaction.Builder newBuilder = Protos.Transaction.newBuilder();
newBuilder.setPool(getProtoPool(walletTransaction)).setHash(hashToByteString(transaction.getHash())).setVersion((int) transaction.getVersion());
if (transaction.getUpdateTime() != null) {
newBuilder.setUpdatedAt(transaction.getUpdateTime().getTime());
}
if (transaction.getLockTime() > 0) {
newBuilder.setLockTime((int) transaction.getLockTime());
}
for (TransactionInput transactionInput : transaction.getInputs()) {
Protos.TransactionInput.Builder transactionOutPointIndex = Protos.TransactionInput.newBuilder().setScriptBytes(ByteString.copyFrom(transactionInput.getScriptBytes())).setTransactionOutPointHash(hashToByteString(transactionInput.getOutpoint().getHash())).setTransactionOutPointIndex((int) transactionInput.getOutpoint().getIndex());
if (transactionInput.hasSequence()) {
transactionOutPointIndex.setSequence((int) transactionInput.getSequenceNumber());
}
if (transactionInput.getValue() != null) {
transactionOutPointIndex.setValue(transactionInput.getValue().value);
}
newBuilder.addTransactionInput(transactionOutPointIndex);
}
for (TransactionOutput transactionOutput : transaction.getOutputs()) {
Protos.TransactionOutput.Builder value = Protos.TransactionOutput.newBuilder().setScriptBytes(ByteString.copyFrom(transactionOutput.getScriptBytes())).setValue(transactionOutput.getValue().value);
TransactionInput spentBy = transactionOutput.getSpentBy();
if (spentBy != null) {
Sha256Hash hash = spentBy.getParentTransaction().getHash();
value.setSpentByTransactionHash(hashToByteString(hash)).setSpentByTransactionIndex(spentBy.getParentTransaction().getInputs().indexOf(spentBy));
}
newBuilder.addTransactionOutput(value);
}
Map<Sha256Hash, Integer> appearsInHashes = transaction.getAppearsInHashes();
if (appearsInHashes != null) {
for (Map.Entry<Sha256Hash, Integer> entry : appearsInHashes.entrySet()) {
newBuilder.addBlockHash(hashToByteString(entry.getKey()));
newBuilder.addBlockRelativityOffsets(entry.getValue().intValue());
}
}
if (transaction.hasConfidence()) {
writeConfidence(newBuilder, transaction.getConfidence(), Protos.TransactionConfidence.newBuilder());
}
switch (AnonymousClass2.$SwitchMap$org$bitcoinj$core$Transaction$Purpose[transaction.getPurpose().ordinal()]) {
case 1:
purpose = Protos.Transaction.Purpose.UNKNOWN;
break;
case 2:
purpose = Protos.Transaction.Purpose.USER_PAYMENT;
break;
case 3:
purpose = Protos.Transaction.Purpose.KEY_ROTATION;
break;
case 4:
purpose = Protos.Transaction.Purpose.ASSURANCE_CONTRACT_CLAIM;
break;
case 5:
purpose = Protos.Transaction.Purpose.ASSURANCE_CONTRACT_PLEDGE;
break;
case 6:
purpose = Protos.Transaction.Purpose.ASSURANCE_CONTRACT_STUB;
break;
case 7:
purpose = Protos.Transaction.Purpose.RAISE_FEE;
break;
default:
throw new RuntimeException("New tx purpose serialization not implemented.");
}
newBuilder.setPurpose(purpose);
ExchangeRate exchangeRate = transaction.getExchangeRate();
if (exchangeRate != null) {
newBuilder.setExchangeRate(Protos.ExchangeRate.newBuilder().setCoinValue(exchangeRate.coin.value).setFiatValue(exchangeRate.fiat.value).setFiatCurrencyCode(exchangeRate.fiat.currencyCode));
}
if (transaction.getMemo() != null) {
newBuilder.setMemo(transaction.getMemo());
}
return newBuilder.m2442build();
}
private static Protos.Transaction.Pool getProtoPool(WalletTransaction walletTransaction) {
int i = AnonymousClass2.$SwitchMap$org$bitcoinj$wallet$WalletTransaction$Pool[walletTransaction.getPool().ordinal()];
if (i == 1) {
return Protos.Transaction.Pool.UNSPENT;
}
if (i == 2) {
return Protos.Transaction.Pool.SPENT;
}
if (i == 3) {
return Protos.Transaction.Pool.DEAD;
}
if (i == 4) {
return Protos.Transaction.Pool.PENDING;
}
throw new RuntimeException("Unreachable");
}
private static void writeConfidence(Protos.Transaction.Builder builder, TransactionConfidence transactionConfidence, Protos.TransactionConfidence.Builder builder2) {
synchronized (transactionConfidence) {
builder2.setType(Protos.TransactionConfidence.Type.valueOf(transactionConfidence.getConfidenceType().getValue()));
if (transactionConfidence.getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING) {
builder2.setAppearedAtHeight(transactionConfidence.getAppearedAtChainHeight());
builder2.setDepth(transactionConfidence.getDepthInBlocks());
}
if (transactionConfidence.getConfidenceType() == TransactionConfidence.ConfidenceType.DEAD && transactionConfidence.getOverridingTransaction() != null) {
builder2.setOverridingTransaction(hashToByteString(transactionConfidence.getOverridingTransaction().getHash()));
}
int i = AnonymousClass2.$SwitchMap$org$bitcoinj$core$TransactionConfidence$Source[transactionConfidence.getSource().ordinal()];
if (i == 1) {
builder2.setSource(Protos.TransactionConfidence.Source.SOURCE_SELF);
} else if (i == 2) {
builder2.setSource(Protos.TransactionConfidence.Source.SOURCE_NETWORK);
} else {
builder2.setSource(Protos.TransactionConfidence.Source.SOURCE_UNKNOWN);
}
}
for (PeerAddress peerAddress : transactionConfidence.getBroadcastBy()) {
builder2.addBroadcastBy(Protos.PeerAddress.newBuilder().setIpAddress(ByteString.copyFrom(peerAddress.getAddr().getAddress())).setPort(peerAddress.getPort()).setServices(peerAddress.getServices().longValue()).m2322build());
}
Date lastBroadcastedAt = transactionConfidence.getLastBroadcastedAt();
if (lastBroadcastedAt != null) {
builder2.setLastBroadcastedAt(lastBroadcastedAt.getTime());
}
builder.setConfidence(builder2);
}
public static ByteString hashToByteString(Sha256Hash sha256Hash) {
return ByteString.copyFrom(sha256Hash.getBytes());
}
public static Sha256Hash byteStringToHash(ByteString byteString) {
return Sha256Hash.wrap(byteString.toByteArray());
}
public Wallet readWallet(InputStream inputStream, @Nullable WalletExtension... walletExtensionArr) throws UnreadableWalletException {
return readWallet(inputStream, false, walletExtensionArr);
}
public Wallet readWallet(InputStream inputStream, boolean z, @Nullable WalletExtension[] walletExtensionArr) throws UnreadableWalletException {
try {
Protos.Wallet parseToProto = parseToProto(inputStream);
String networkIdentifier = parseToProto.getNetworkIdentifier();
NetworkParameters fromID = NetworkParameters.fromID(networkIdentifier);
if (fromID == null) {
throw new UnreadableWalletException("Unknown network parameters ID " + networkIdentifier);
}
return readWallet(fromID, walletExtensionArr, parseToProto, z);
} catch (IOException e) {
throw new UnreadableWalletException("Could not parse input stream to protobuf", e);
} catch (IllegalArgumentException e2) {
throw new UnreadableWalletException("Could not parse input stream to protobuf", e2);
} catch (IllegalStateException e3) {
throw new UnreadableWalletException("Could not parse input stream to protobuf", e3);
}
}
public Wallet readWallet(NetworkParameters networkParameters, @Nullable WalletExtension[] walletExtensionArr, Protos.Wallet wallet) throws UnreadableWalletException {
return readWallet(networkParameters, walletExtensionArr, wallet, false);
}
public Wallet readWallet(NetworkParameters networkParameters, @Nullable WalletExtension[] walletExtensionArr, Protos.Wallet wallet, boolean z) throws UnreadableWalletException {
KeyChainGroup fromProtobufUnencrypted;
if (wallet.getVersion() > CURRENT_WALLET_VERSION) {
throw new UnreadableWalletException.FutureVersion();
}
if (!wallet.getNetworkIdentifier().equals(networkParameters.getId())) {
throw new UnreadableWalletException.WrongNetwork();
}
if (wallet.hasEncryptionParameters()) {
fromProtobufUnencrypted = KeyChainGroup.fromProtobufEncrypted(networkParameters, wallet.getKeyList(), new KeyCrypterScrypt(wallet.getEncryptionParameters()), this.keyChainFactory);
} else {
fromProtobufUnencrypted = KeyChainGroup.fromProtobufUnencrypted(networkParameters, wallet.getKeyList(), this.keyChainFactory);
}
Wallet create = this.factory.create(networkParameters, fromProtobufUnencrypted);
ArrayList newArrayList = Lists.newArrayList();
for (Protos.Script script : wallet.getWatchedScriptList()) {
try {
newArrayList.add(new Script(script.getProgram().toByteArray(), script.getCreationTimestamp() / 1000));
} catch (ScriptException unused) {
throw new UnreadableWalletException("Unparseable script in wallet");
}
}
create.addWatchedScripts(newArrayList);
if (wallet.hasDescription()) {
create.setDescription(wallet.getDescription());
}
if (z) {
create.setLastBlockSeenHash(null);
create.setLastBlockSeenHeight(-1);
create.setLastBlockSeenTimeSecs(0L);
} else {
Iterator<Protos.Transaction> it = wallet.getTransactionList().iterator();
while (it.hasNext()) {
readTransaction(it.next(), create.getParams());
}
Iterator<Protos.Transaction> it2 = wallet.getTransactionList().iterator();
while (it2.hasNext()) {
create.addWalletTransaction(connectTransactionOutputs(networkParameters, it2.next()));
}
if (!wallet.hasLastSeenBlockHash()) {
create.setLastBlockSeenHash(null);
} else {
create.setLastBlockSeenHash(byteStringToHash(wallet.getLastSeenBlockHash()));
}
if (!wallet.hasLastSeenBlockHeight()) {
create.setLastBlockSeenHeight(-1);
} else {
create.setLastBlockSeenHeight(wallet.getLastSeenBlockHeight());
}
create.setLastBlockSeenTimeSecs(wallet.getLastSeenBlockTimeSecs());
if (wallet.hasKeyRotationTime()) {
create.setKeyRotationTime(new Date(wallet.getKeyRotationTime() * 1000));
}
}
if (walletExtensionArr == null) {
walletExtensionArr = new WalletExtension[0];
}
loadExtensions(create, walletExtensionArr, wallet);
for (Protos.Tag tag : wallet.getTagsList()) {
create.setTag(tag.getTag(), tag.getData());
}
for (Protos.TransactionSigner transactionSigner : wallet.getTransactionSignersList()) {
try {
TransactionSigner transactionSigner2 = (TransactionSigner) Class.forName(transactionSigner.getClassName()).newInstance();
transactionSigner2.deserialize(transactionSigner.getData().toByteArray());
create.addTransactionSigner(transactionSigner2);
} catch (Exception e) {
throw new UnreadableWalletException("Unable to deserialize TransactionSigner instance: " + transactionSigner.getClassName(), e);
}
}
if (wallet.hasVersion()) {
create.setVersion(wallet.getVersion());
}
this.txMap.clear();
return create;
}
private void loadExtensions(Wallet wallet, WalletExtension[] walletExtensionArr, Protos.Wallet wallet2) throws UnreadableWalletException {
HashMap hashMap = new HashMap();
for (WalletExtension walletExtension : walletExtensionArr) {
hashMap.put(walletExtension.getWalletExtensionID(), walletExtension);
}
hashMap.putAll(wallet.getExtensions());
for (Protos.Extension extension : wallet2.getExtensionList()) {
String id = extension.getId();
WalletExtension walletExtension2 = (WalletExtension) hashMap.get(id);
if (walletExtension2 == null) {
if (!extension.getMandatory()) {
continue;
} else {
if (this.requireMandatoryExtensions) {
throw new UnreadableWalletException("Unknown mandatory extension in wallet: " + id);
}
log.error("Unknown extension in wallet {}, ignoring", id);
}
} else {
log.info("Loading wallet extension {}", id);
try {
wallet.deserializeExtension(walletExtension2, extension.getData().toByteArray());
} catch (Exception unused) {
if (!extension.getMandatory()) {
continue;
} else if (this.requireMandatoryExtensions) {
log.error("Error whilst reading mandatory extension {}, failing to read wallet", id);
throw new UnreadableWalletException("Could not parse mandatory extension in wallet: " + id);
}
}
}
}
}
public static Protos.Wallet parseToProto(InputStream inputStream) throws IOException {
CodedInputStream newInstance = CodedInputStream.newInstance(inputStream);
newInstance.setSizeLimit(WALLET_SIZE_LIMIT);
return Protos.Wallet.parseFrom(newInstance);
}
private void readTransaction(Protos.Transaction transaction, NetworkParameters networkParameters) throws UnreadableWalletException {
Transaction transaction2 = new Transaction(networkParameters);
transaction2.setVersion(transaction.getVersion());
if (transaction.hasUpdatedAt()) {
transaction2.setUpdateTime(new Date(transaction.getUpdatedAt()));
}
for (Protos.TransactionOutput transactionOutput : transaction.getTransactionOutputList()) {
transaction2.addOutput(new TransactionOutput(networkParameters, transaction2, Coin.valueOf(transactionOutput.getValue()), transactionOutput.getScriptBytes().toByteArray()));
}
for (Protos.TransactionInput transactionInput : transaction.getTransactionInputList()) {
TransactionInput transactionInput2 = new TransactionInput(networkParameters, transaction2, transactionInput.getScriptBytes().toByteArray(), new TransactionOutPoint(networkParameters, transactionInput.getTransactionOutPointIndex() & TransactionInput.NO_SEQUENCE, byteStringToHash(transactionInput.getTransactionOutPointHash())), transactionInput.hasValue() ? Coin.valueOf(transactionInput.getValue()) : null);
if (transactionInput.hasSequence()) {
transactionInput2.setSequenceNumber(transactionInput.getSequence() & TransactionInput.NO_SEQUENCE);
}
transaction2.addInput(transactionInput2);
}
for (int i = 0; i < transaction.getBlockHashCount(); i++) {
transaction2.addBlockAppearance(byteStringToHash(transaction.getBlockHash(i)), transaction.getBlockRelativityOffsetsCount() > 0 ? transaction.getBlockRelativityOffsets(i) : 0);
}
if (transaction.hasLockTime()) {
transaction2.setLockTime(transaction.getLockTime() & TransactionInput.NO_SEQUENCE);
}
if (transaction.hasPurpose()) {
switch (AnonymousClass2.$SwitchMap$org$bitcoinj$wallet$Protos$Transaction$Purpose[transaction.getPurpose().ordinal()]) {
case 1:
transaction2.setPurpose(Transaction.Purpose.UNKNOWN);
break;
case 2:
transaction2.setPurpose(Transaction.Purpose.USER_PAYMENT);
break;
case 3:
transaction2.setPurpose(Transaction.Purpose.KEY_ROTATION);
break;
case 4:
transaction2.setPurpose(Transaction.Purpose.ASSURANCE_CONTRACT_CLAIM);
break;
case 5:
transaction2.setPurpose(Transaction.Purpose.ASSURANCE_CONTRACT_PLEDGE);
break;
case 6:
transaction2.setPurpose(Transaction.Purpose.ASSURANCE_CONTRACT_STUB);
break;
case 7:
transaction2.setPurpose(Transaction.Purpose.RAISE_FEE);
break;
default:
throw new RuntimeException("New purpose serialization not implemented");
}
} else {
transaction2.setPurpose(Transaction.Purpose.USER_PAYMENT);
}
if (transaction.hasExchangeRate()) {
Protos.ExchangeRate exchangeRate = transaction.getExchangeRate();
transaction2.setExchangeRate(new ExchangeRate(Coin.valueOf(exchangeRate.getCoinValue()), Fiat.valueOf(exchangeRate.getFiatCurrencyCode(), exchangeRate.getFiatValue())));
}
if (transaction.hasMemo()) {
transaction2.setMemo(transaction.getMemo());
}
Sha256Hash byteStringToHash = byteStringToHash(transaction.getHash());
if (!transaction2.getHash().equals(byteStringToHash)) {
throw new UnreadableWalletException(String.format(Locale.US, "Transaction did not deserialize completely: %s vs %s", transaction2.getHash(), byteStringToHash));
}
if (this.txMap.containsKey(transaction.getHash())) {
throw new UnreadableWalletException("Wallet contained duplicate transaction " + byteStringToHash(transaction.getHash()));
}
this.txMap.put(transaction.getHash(), transaction2);
}
private WalletTransaction connectTransactionOutputs(NetworkParameters networkParameters, Protos.Transaction transaction) throws UnreadableWalletException {
WalletTransaction.Pool pool;
Transaction transaction2 = this.txMap.get(transaction.getHash());
switch (AnonymousClass2.$SwitchMap$org$bitcoinj$wallet$Protos$Transaction$Pool[transaction.getPool().ordinal()]) {
case 1:
pool = WalletTransaction.Pool.DEAD;
break;
case 2:
pool = WalletTransaction.Pool.PENDING;
break;
case 3:
pool = WalletTransaction.Pool.SPENT;
break;
case 4:
pool = WalletTransaction.Pool.UNSPENT;
break;
case 5:
case 6:
pool = WalletTransaction.Pool.PENDING;
break;
default:
throw new UnreadableWalletException("Unknown transaction pool: " + transaction.getPool());
}
for (int i = 0; i < transaction2.getOutputs().size(); i++) {
TransactionOutput transactionOutput = transaction2.getOutputs().get(i);
Protos.TransactionOutput transactionOutput2 = transaction.getTransactionOutput(i);
if (transactionOutput2.hasSpentByTransactionHash()) {
ByteString spentByTransactionHash = transactionOutput2.getSpentByTransactionHash();
Transaction transaction3 = this.txMap.get(spentByTransactionHash);
if (transaction3 == null) {
throw new UnreadableWalletException(String.format(Locale.US, "Could not connect %s to %s", transaction2.getHashAsString(), byteStringToHash(spentByTransactionHash)));
}
((TransactionInput) Preconditions.checkNotNull(transaction3.getInput(transactionOutput2.getSpentByTransactionIndex()))).connect(transactionOutput);
}
}
if (transaction.hasConfidence()) {
readConfidence(networkParameters, transaction2, transaction.getConfidence(), transaction2.getConfidence());
}
return new WalletTransaction(pool, transaction2);
}
private void readConfidence(NetworkParameters networkParameters, Transaction transaction, Protos.TransactionConfidence transactionConfidence, TransactionConfidence transactionConfidence2) throws UnreadableWalletException {
TransactionConfidence.ConfidenceType confidenceType;
if (!transactionConfidence.hasType()) {
log.warn("Unknown confidence type for tx {}", transaction.getHashAsString());
return;
}
int i = AnonymousClass2.$SwitchMap$org$bitcoinj$wallet$Protos$TransactionConfidence$Type[transactionConfidence.getType().ordinal()];
if (i == 1) {
confidenceType = TransactionConfidence.ConfidenceType.BUILDING;
} else if (i == 2) {
confidenceType = TransactionConfidence.ConfidenceType.DEAD;
} else if (i == 3) {
confidenceType = TransactionConfidence.ConfidenceType.PENDING;
} else if (i == 4) {
confidenceType = TransactionConfidence.ConfidenceType.PENDING;
} else if (i == 5) {
confidenceType = TransactionConfidence.ConfidenceType.IN_CONFLICT;
} else {
confidenceType = TransactionConfidence.ConfidenceType.UNKNOWN;
}
transactionConfidence2.setConfidenceType(confidenceType);
if (transactionConfidence.hasAppearedAtHeight()) {
if (transactionConfidence2.getConfidenceType() != TransactionConfidence.ConfidenceType.BUILDING) {
log.warn("Have appearedAtHeight but not BUILDING for tx {}", transaction.getHashAsString());
return;
}
transactionConfidence2.setAppearedAtChainHeight(transactionConfidence.getAppearedAtHeight());
}
if (transactionConfidence.hasDepth()) {
if (transactionConfidence2.getConfidenceType() != TransactionConfidence.ConfidenceType.BUILDING) {
log.warn("Have depth but not BUILDING for tx {}", transaction.getHashAsString());
return;
}
transactionConfidence2.setDepthInBlocks(transactionConfidence.getDepth());
}
if (transactionConfidence.hasOverridingTransaction()) {
if (transactionConfidence2.getConfidenceType() != TransactionConfidence.ConfidenceType.DEAD) {
log.warn("Have overridingTransaction but not OVERRIDDEN for tx {}", transaction.getHashAsString());
return;
}
Transaction transaction2 = this.txMap.get(transactionConfidence.getOverridingTransaction());
if (transaction2 == null) {
log.warn("Have overridingTransaction that is not in wallet for tx {}", transaction.getHashAsString());
return;
}
transactionConfidence2.setOverridingTransaction(transaction2);
}
for (Protos.PeerAddress peerAddress : transactionConfidence.getBroadcastByList()) {
try {
PeerAddress peerAddress2 = new PeerAddress(networkParameters, InetAddress.getByAddress(peerAddress.getIpAddress().toByteArray()), peerAddress.getPort());
peerAddress2.setServices(BigInteger.valueOf(peerAddress.getServices()));
transactionConfidence2.markBroadcastBy(peerAddress2);
} catch (UnknownHostException e) {
throw new UnreadableWalletException("Peer IP address does not have the right length", e);
}
}
if (transactionConfidence.hasLastBroadcastedAt()) {
transactionConfidence2.setLastBroadcastedAt(new Date(transactionConfidence.getLastBroadcastedAt()));
}
int i2 = AnonymousClass2.$SwitchMap$org$bitcoinj$wallet$Protos$TransactionConfidence$Source[transactionConfidence.getSource().ordinal()];
if (i2 == 1) {
transactionConfidence2.setSource(TransactionConfidence.Source.SELF);
} else if (i2 == 2) {
transactionConfidence2.setSource(TransactionConfidence.Source.NETWORK);
} else {
transactionConfidence2.setSource(TransactionConfidence.Source.UNKNOWN);
}
}
static class AnonymousClass2 {
static final int[] $SwitchMap$org$bitcoinj$core$Transaction$Purpose;
static final int[] $SwitchMap$org$bitcoinj$core$TransactionConfidence$Source;
static final int[] $SwitchMap$org$bitcoinj$wallet$Protos$Transaction$Pool;
static final int[] $SwitchMap$org$bitcoinj$wallet$Protos$Transaction$Purpose;
static final int[] $SwitchMap$org$bitcoinj$wallet$Protos$TransactionConfidence$Source;
static final int[] $SwitchMap$org$bitcoinj$wallet$Protos$TransactionConfidence$Type;
static final int[] $SwitchMap$org$bitcoinj$wallet$WalletTransaction$Pool;
static {
int[] iArr = new int[Protos.TransactionConfidence.Source.values().length];
$SwitchMap$org$bitcoinj$wallet$Protos$TransactionConfidence$Source = iArr;
try {
iArr[Protos.TransactionConfidence.Source.SOURCE_SELF.ordinal()] = 1;
} catch (NoSuchFieldError unused) {
}
try {
$SwitchMap$org$bitcoinj$wallet$Protos$TransactionConfidence$Source[Protos.TransactionConfidence.Source.SOURCE_NETWORK.ordinal()] = 2;
} catch (NoSuchFieldError unused2) {
}
try {
$SwitchMap$org$bitcoinj$wallet$Protos$TransactionConfidence$Source[Protos.TransactionConfidence.Source.SOURCE_UNKNOWN.ordinal()] = 3;
} catch (NoSuchFieldError unused3) {
}
int[] iArr2 = new int[Protos.TransactionConfidence.Type.values().length];
$SwitchMap$org$bitcoinj$wallet$Protos$TransactionConfidence$Type = iArr2;
try {
iArr2[Protos.TransactionConfidence.Type.BUILDING.ordinal()] = 1;
} catch (NoSuchFieldError unused4) {
}
try {
$SwitchMap$org$bitcoinj$wallet$Protos$TransactionConfidence$Type[Protos.TransactionConfidence.Type.DEAD.ordinal()] = 2;
} catch (NoSuchFieldError unused5) {
}
try {
$SwitchMap$org$bitcoinj$wallet$Protos$TransactionConfidence$Type[Protos.TransactionConfidence.Type.NOT_IN_BEST_CHAIN.ordinal()] = 3;
} catch (NoSuchFieldError unused6) {
}
try {
$SwitchMap$org$bitcoinj$wallet$Protos$TransactionConfidence$Type[Protos.TransactionConfidence.Type.PENDING.ordinal()] = 4;
} catch (NoSuchFieldError unused7) {
}
try {
$SwitchMap$org$bitcoinj$wallet$Protos$TransactionConfidence$Type[Protos.TransactionConfidence.Type.IN_CONFLICT.ordinal()] = 5;
} catch (NoSuchFieldError unused8) {
}
try {
$SwitchMap$org$bitcoinj$wallet$Protos$TransactionConfidence$Type[Protos.TransactionConfidence.Type.UNKNOWN.ordinal()] = 6;
} catch (NoSuchFieldError unused9) {
}
int[] iArr3 = new int[Protos.Transaction.Pool.values().length];
$SwitchMap$org$bitcoinj$wallet$Protos$Transaction$Pool = iArr3;
try {
iArr3[Protos.Transaction.Pool.DEAD.ordinal()] = 1;
} catch (NoSuchFieldError unused10) {
}
try {
$SwitchMap$org$bitcoinj$wallet$Protos$Transaction$Pool[Protos.Transaction.Pool.PENDING.ordinal()] = 2;
} catch (NoSuchFieldError unused11) {
}
try {
$SwitchMap$org$bitcoinj$wallet$Protos$Transaction$Pool[Protos.Transaction.Pool.SPENT.ordinal()] = 3;
} catch (NoSuchFieldError unused12) {
}
try {
$SwitchMap$org$bitcoinj$wallet$Protos$Transaction$Pool[Protos.Transaction.Pool.UNSPENT.ordinal()] = 4;
} catch (NoSuchFieldError unused13) {
}
try {
$SwitchMap$org$bitcoinj$wallet$Protos$Transaction$Pool[Protos.Transaction.Pool.INACTIVE.ordinal()] = 5;
} catch (NoSuchFieldError unused14) {
}
try {
$SwitchMap$org$bitcoinj$wallet$Protos$Transaction$Pool[Protos.Transaction.Pool.PENDING_INACTIVE.ordinal()] = 6;
} catch (NoSuchFieldError unused15) {
}
int[] iArr4 = new int[Protos.Transaction.Purpose.values().length];
$SwitchMap$org$bitcoinj$wallet$Protos$Transaction$Purpose = iArr4;
try {
iArr4[Protos.Transaction.Purpose.UNKNOWN.ordinal()] = 1;
} catch (NoSuchFieldError unused16) {
}
try {
$SwitchMap$org$bitcoinj$wallet$Protos$Transaction$Purpose[Protos.Transaction.Purpose.USER_PAYMENT.ordinal()] = 2;
} catch (NoSuchFieldError unused17) {
}
try {
$SwitchMap$org$bitcoinj$wallet$Protos$Transaction$Purpose[Protos.Transaction.Purpose.KEY_ROTATION.ordinal()] = 3;
} catch (NoSuchFieldError unused18) {
}
try {
$SwitchMap$org$bitcoinj$wallet$Protos$Transaction$Purpose[Protos.Transaction.Purpose.ASSURANCE_CONTRACT_CLAIM.ordinal()] = 4;
} catch (NoSuchFieldError unused19) {
}
try {
$SwitchMap$org$bitcoinj$wallet$Protos$Transaction$Purpose[Protos.Transaction.Purpose.ASSURANCE_CONTRACT_PLEDGE.ordinal()] = 5;
} catch (NoSuchFieldError unused20) {
}
try {
$SwitchMap$org$bitcoinj$wallet$Protos$Transaction$Purpose[Protos.Transaction.Purpose.ASSURANCE_CONTRACT_STUB.ordinal()] = 6;
} catch (NoSuchFieldError unused21) {
}
try {
$SwitchMap$org$bitcoinj$wallet$Protos$Transaction$Purpose[Protos.Transaction.Purpose.RAISE_FEE.ordinal()] = 7;
} catch (NoSuchFieldError unused22) {
}
int[] iArr5 = new int[TransactionConfidence.Source.values().length];
$SwitchMap$org$bitcoinj$core$TransactionConfidence$Source = iArr5;
try {
iArr5[TransactionConfidence.Source.SELF.ordinal()] = 1;
} catch (NoSuchFieldError unused23) {
}
try {
$SwitchMap$org$bitcoinj$core$TransactionConfidence$Source[TransactionConfidence.Source.NETWORK.ordinal()] = 2;
} catch (NoSuchFieldError unused24) {
}
try {
$SwitchMap$org$bitcoinj$core$TransactionConfidence$Source[TransactionConfidence.Source.UNKNOWN.ordinal()] = 3;
} catch (NoSuchFieldError unused25) {
}
int[] iArr6 = new int[WalletTransaction.Pool.values().length];
$SwitchMap$org$bitcoinj$wallet$WalletTransaction$Pool = iArr6;
try {
iArr6[WalletTransaction.Pool.UNSPENT.ordinal()] = 1;
} catch (NoSuchFieldError unused26) {
}
try {
$SwitchMap$org$bitcoinj$wallet$WalletTransaction$Pool[WalletTransaction.Pool.SPENT.ordinal()] = 2;
} catch (NoSuchFieldError unused27) {
}
try {
$SwitchMap$org$bitcoinj$wallet$WalletTransaction$Pool[WalletTransaction.Pool.DEAD.ordinal()] = 3;
} catch (NoSuchFieldError unused28) {
}
try {
$SwitchMap$org$bitcoinj$wallet$WalletTransaction$Pool[WalletTransaction.Pool.PENDING.ordinal()] = 4;
} catch (NoSuchFieldError unused29) {
}
int[] iArr7 = new int[Transaction.Purpose.values().length];
$SwitchMap$org$bitcoinj$core$Transaction$Purpose = iArr7;
try {
iArr7[Transaction.Purpose.UNKNOWN.ordinal()] = 1;
} catch (NoSuchFieldError unused30) {
}
try {
$SwitchMap$org$bitcoinj$core$Transaction$Purpose[Transaction.Purpose.USER_PAYMENT.ordinal()] = 2;
} catch (NoSuchFieldError unused31) {
}
try {
$SwitchMap$org$bitcoinj$core$Transaction$Purpose[Transaction.Purpose.KEY_ROTATION.ordinal()] = 3;
} catch (NoSuchFieldError unused32) {
}
try {
$SwitchMap$org$bitcoinj$core$Transaction$Purpose[Transaction.Purpose.ASSURANCE_CONTRACT_CLAIM.ordinal()] = 4;
} catch (NoSuchFieldError unused33) {
}
try {
$SwitchMap$org$bitcoinj$core$Transaction$Purpose[Transaction.Purpose.ASSURANCE_CONTRACT_PLEDGE.ordinal()] = 5;
} catch (NoSuchFieldError unused34) {
}
try {
$SwitchMap$org$bitcoinj$core$Transaction$Purpose[Transaction.Purpose.ASSURANCE_CONTRACT_STUB.ordinal()] = 6;
} catch (NoSuchFieldError unused35) {
}
try {
$SwitchMap$org$bitcoinj$core$Transaction$Purpose[Transaction.Purpose.RAISE_FEE.ordinal()] = 7;
} catch (NoSuchFieldError unused36) {
}
}
}
public static boolean isWallet(InputStream inputStream) {
try {
CodedInputStream newInstance = CodedInputStream.newInstance(inputStream);
if (WireFormat.getTagFieldNumber(newInstance.readTag()) != 1) {
return false;
}
return NetworkParameters.fromID(newInstance.readString()) != null;
} catch (IOException unused) {
return false;
}
}
}