Convert SignalService, Database, Group, Payment, and other remaining protos to wire.

This commit is contained in:
Cody Henthorne
2023-09-18 15:32:43 -04:00
committed by Alex Hart
parent a6b7d0bcc5
commit efbd5cab85
267 changed files with 7100 additions and 7214 deletions

View File

@@ -16,28 +16,21 @@ public final class CryptoValueUtil {
}
public static @NonNull CryptoValue moneyToCryptoValue(@NonNull Money money) {
CryptoValue.Builder builder = CryptoValue.newBuilder();
CryptoValue.Builder builder = new CryptoValue.Builder();
if (money instanceof Money.MobileCoin) {
Money.MobileCoin mobileCoin = (Money.MobileCoin) money;
builder.setMobileCoinValue(CryptoValue.MobileCoinValue
.newBuilder()
.setPicoMobileCoin(mobileCoin.serializeAmountString()));
builder.mobileCoinValue(new CryptoValue.MobileCoinValue.Builder().picoMobileCoin(mobileCoin.serializeAmountString()).build());
}
return builder.build();
}
public static @NonNull Money cryptoValueToMoney(@NonNull CryptoValue amount) {
CryptoValue.ValueCase valueCase = amount.getValueCase();
switch (valueCase) {
case MOBILECOINVALUE:
return Money.picoMobileCoin(new BigInteger(amount.getMobileCoinValue().getPicoMobileCoin()));
case VALUE_NOT_SET:
throw new AssertionError();
if (amount.mobileCoinValue != null) {
return Money.picoMobileCoin(new BigInteger(amount.mobileCoinValue.picoMobileCoin));
} else {
throw new AssertionError();
}
throw new AssertionError();
}
}

View File

@@ -2,8 +2,6 @@ package org.thoughtcrime.securesms.payments;
import androidx.annotation.NonNull;
import com.google.protobuf.ByteString;
import org.thoughtcrime.securesms.payments.proto.MobileCoinLedger;
import org.whispersystems.signalservice.api.payments.Money;
@@ -12,17 +10,19 @@ import java.util.List;
import javax.annotation.Nullable;
import okio.ByteString;
public final class MobileCoinLedgerWrapper {
private final MobileCoinLedger ledger;
private final Balance balance;
public MobileCoinLedgerWrapper(@NonNull MobileCoinLedger ledger) {
Money.MobileCoin fullAmount = Money.picoMobileCoin(ledger.getBalance());
Money.MobileCoin transferableAmount = Money.picoMobileCoin(ledger.getTransferableBalance());
Money.MobileCoin fullAmount = Money.picoMobileCoin(ledger.balance);
Money.MobileCoin transferableAmount = Money.picoMobileCoin(ledger.transferableBalance);
this.ledger = ledger;
this.balance = new Balance(fullAmount, transferableAmount, ledger.getAsOfTimeStamp());
this.balance = new Balance(fullAmount, transferableAmount, ledger.asOfTimeStamp);
}
public @NonNull Balance getBalance() {
@@ -30,13 +30,13 @@ public final class MobileCoinLedgerWrapper {
}
public byte[] serialize() {
return ledger.toByteArray();
return ledger.encode();
}
public @NonNull List<OwnedTxo> getAllTxos() {
List<OwnedTxo> txoList = new ArrayList<>(ledger.getSpentTxosCount() + ledger.getUnspentTxosCount());
addAllMapped(txoList, ledger.getSpentTxosList());
addAllMapped(txoList, ledger.getUnspentTxosList());
List<OwnedTxo> txoList = new ArrayList<>(ledger.spentTxos.size() + ledger.unspentTxos.size());
addAllMapped(txoList, ledger.spentTxos);
addAllMapped(txoList, ledger.unspentTxos);
return txoList;
}
@@ -54,35 +54,35 @@ public final class MobileCoinLedgerWrapper {
}
public @NonNull Money.MobileCoin getValue() {
return Money.picoMobileCoin(ownedTXO.getAmount());
return Money.picoMobileCoin(ownedTXO.amount);
}
public @NonNull ByteString getKeyImage() {
return ownedTXO.getKeyImage();
return ownedTXO.keyImage;
}
public @NonNull ByteString getPublicKey() {
return ownedTXO.getPublicKey();
return ownedTXO.publicKey;
}
public long getReceivedInBlock() {
return ownedTXO.getReceivedInBlock().getBlockNumber();
return ownedTXO.receivedInBlock != null ? ownedTXO.receivedInBlock.blockNumber : 0;
}
public @Nullable Long getSpentInBlock() {
return nullIfZero(ownedTXO.getSpentInBlock().getBlockNumber());
return ownedTXO.spentInBlock != null ? nullIfZero(ownedTXO.spentInBlock.blockNumber) : null;
}
public boolean isSpent() {
return ownedTXO.getSpentInBlock().getBlockNumber() != 0;
return ownedTXO.spentInBlock != null && ownedTXO.spentInBlock.blockNumber != 0;
}
public @Nullable Long getReceivedInBlockTimestamp() {
return nullIfZero(ownedTXO.getReceivedInBlock().getTimestamp());
return ownedTXO.receivedInBlock != null ? nullIfZero(ownedTXO.receivedInBlock.timestamp) : null;
}
public @Nullable Long getSpentInBlockTimestamp() {
return nullIfZero(ownedTXO.getSpentInBlock().getTimestamp());
return ownedTXO.spentInBlock != null ? nullIfZero(ownedTXO.spentInBlock.timestamp) : null;
}
private @Nullable Long nullIfZero(long value) {

View File

@@ -2,11 +2,11 @@ package org.thoughtcrime.securesms.payments;
import androidx.annotation.NonNull;
import com.google.protobuf.ByteString;
import org.signal.libsignal.protocol.IdentityKey;
import org.signal.libsignal.protocol.IdentityKeyPair;
import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
import org.whispersystems.signalservice.internal.push.PaymentAddress;
import okio.ByteString;
public final class MobileCoinPublicAddressProfileUtil {
@@ -15,16 +15,17 @@ public final class MobileCoinPublicAddressProfileUtil {
/**
* Signs the supplied address bytes with the {@link IdentityKeyPair}'s private key and returns a proto that includes it and it's signature.
*/
public static @NonNull SignalServiceProtos.PaymentAddress signPaymentsAddress(@NonNull byte[] publicAddressBytes,
@NonNull IdentityKeyPair identityKeyPair)
public static @NonNull PaymentAddress signPaymentsAddress(@NonNull byte[] publicAddressBytes,
@NonNull IdentityKeyPair identityKeyPair)
{
byte[] signature = identityKeyPair.getPrivateKey().calculateSignature(publicAddressBytes);
return SignalServiceProtos.PaymentAddress.newBuilder()
.setMobileCoinAddress(SignalServiceProtos.PaymentAddress.MobileCoinAddress.newBuilder()
.setAddress(ByteString.copyFrom(publicAddressBytes))
.setSignature(ByteString.copyFrom(signature)))
.build();
return new PaymentAddress.Builder()
.mobileCoinAddress(new PaymentAddress.MobileCoinAddress.Builder()
.address(ByteString.of(publicAddressBytes))
.signature(ByteString.of(signature))
.build())
.build();
}
/**
@@ -32,16 +33,20 @@ public final class MobileCoinPublicAddressProfileUtil {
* <p>
* Returns the validated bytes if so, otherwise throws.
*/
public static @NonNull byte[] verifyPaymentsAddress(@NonNull SignalServiceProtos.PaymentAddress paymentAddress,
public static @NonNull byte[] verifyPaymentsAddress(@NonNull PaymentAddress paymentAddress,
@NonNull IdentityKey identityKey)
throws PaymentsAddressException
throws PaymentsAddressException
{
if (!paymentAddress.hasMobileCoinAddress()) {
if (paymentAddress.mobileCoinAddress == null) {
throw new PaymentsAddressException(PaymentsAddressException.Code.NO_ADDRESS);
}
byte[] bytes = paymentAddress.getMobileCoinAddress().getAddress().toByteArray();
byte[] signature = paymentAddress.getMobileCoinAddress().getSignature().toByteArray();
if (paymentAddress.mobileCoinAddress.address == null || paymentAddress.mobileCoinAddress.signature == null) {
throw new PaymentsAddressException(PaymentsAddressException.Code.INVALID_ADDRESS_SIGNATURE);
}
byte[] bytes = paymentAddress.mobileCoinAddress.address.toByteArray();
byte[] signature = paymentAddress.mobileCoinAddress.signature.toByteArray();
if (signature.length != 64 || !identityKey.getPublicKey().verifySignature(bytes, signature)) {
throw new PaymentsAddressException(PaymentsAddressException.Code.INVALID_ADDRESS_SIGNATURE);

View File

@@ -6,12 +6,11 @@ import android.os.Parcelable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.protobuf.InvalidProtocolBufferException;
import org.thoughtcrime.securesms.payments.preferences.model.PayeeParcelable;
import org.thoughtcrime.securesms.payments.proto.PaymentMetaData;
import org.whispersystems.signalservice.api.payments.Money;
import java.io.IOException;
import java.util.UUID;
/**
@@ -68,7 +67,7 @@ public class PaymentParcelable implements Parcelable {
dest.writeString(payment.getNote());
dest.writeString(payment.getAmount().serialize());
dest.writeString(payment.getFee().serialize());
dest.writeByteArray(payment.getPaymentMetaData().toByteArray());
dest.writeByteArray(payment.getPaymentMetaData().encode());
dest.writeByte(payment.isSeen() ? (byte) 1 : 0);
dest.writeString(payment.getAmountWithDirection().serialize());
dest.writeString(payment.getAmountPlusFeeWithDirection().serialize());
@@ -119,12 +118,12 @@ public class PaymentParcelable implements Parcelable {
note = in.readString();
amount = Money.parse(in.readString());
fee = Money.parse(in.readString());
paymentMetaData = PaymentMetaData.parseFrom(in.createByteArray());
paymentMetaData = PaymentMetaData.ADAPTER.decode(in.createByteArray());
isSeen = in.readByte() == 1;
amountWithDirection = Money.parse(in.readString());
amountPlusFeeWithDirection = Money.parse(in.readString());
isDefrag = in.readByte() == 1;
} catch (Money.ParseException | InvalidProtocolBufferException e) {
} catch (Money.ParseException | IOException e) {
throw new IllegalArgumentException();
}
}

View File

@@ -84,7 +84,7 @@ public final class ReconstructedPayment implements Payment {
@Override
public @NonNull PaymentMetaData getPaymentMetaData() {
return PaymentMetaData.getDefaultInstance();
return new PaymentMetaData();
}
@Override

View File

@@ -5,7 +5,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import com.google.protobuf.ByteString;
import com.mobilecoin.lib.AccountKey;
import com.mobilecoin.lib.AccountSnapshot;
import com.mobilecoin.lib.Amount;
@@ -52,6 +51,8 @@ import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeoutException;
import okio.ByteString;
public final class Wallet {
private static final String TAG = Log.tag(Wallet.class);
@@ -135,7 +136,7 @@ public final class Wallet {
@WorkerThread
public @Nullable MobileCoinLedgerWrapper tryGetFullLedger(@Nullable Long minimumBlockIndex) throws IOException, FogSyncException {
try {
MobileCoinLedger.Builder builder = MobileCoinLedger.newBuilder();
MobileCoinLedger.Builder builder = new MobileCoinLedger.Builder();
BigInteger totalUnspent = BigInteger.ZERO;
long highestBlockTimeStamp = 0;
UnsignedLong highestBlockIndex = UnsignedLong.ZERO;
@@ -159,21 +160,23 @@ public final class Wallet {
}
}
List<MobileCoinLedger.OwnedTXO> spentTxos = new LinkedList<>();
List<MobileCoinLedger.OwnedTXO> unspentTxos = new LinkedList<>();
for (OwnedTxOut txOut : accountSnapshot.getAccountActivity().getAllTokenTxOuts(TokenId.MOB)) {
final Amount txOutAmount = txOut.getAmount();
MobileCoinLedger.OwnedTXO.Builder txoBuilder = MobileCoinLedger.OwnedTXO.newBuilder()
.setAmount(Uint64Util.bigIntegerToUInt64(txOutAmount.getValue()))
.setReceivedInBlock(getBlock(txOut.getReceivedBlockIndex(), txOut.getReceivedBlockTimestamp()))
.setKeyImage(ByteString.copyFrom(txOut.getKeyImage().getData()))
.setPublicKey(ByteString.copyFrom(txOut.getPublicKey().getKeyBytes()));
MobileCoinLedger.OwnedTXO.Builder txoBuilder = new MobileCoinLedger.OwnedTXO.Builder()
.amount(Uint64Util.bigIntegerToUInt64(txOutAmount.getValue()))
.receivedInBlock(getBlock(txOut.getReceivedBlockIndex(), txOut.getReceivedBlockTimestamp()))
.keyImage(ByteString.of(txOut.getKeyImage().getData()))
.publicKey(ByteString.of(txOut.getPublicKey().getKeyBytes()));
if (txOut.getSpentBlockIndex() != null &&
(minimumBlockIndex == null || txOut.isSpent(UnsignedLong.valueOf(minimumBlockIndex))))
{
txoBuilder.setSpentInBlock(getBlock(txOut.getSpentBlockIndex(), txOut.getSpentBlockTimestamp()));
builder.addSpentTxos(txoBuilder);
txoBuilder.spentInBlock(getBlock(txOut.getSpentBlockIndex(), txOut.getSpentBlockTimestamp()));
spentTxos.add(txoBuilder.build());
} else {
totalUnspent = totalUnspent.add(txOutAmount.getValue());
builder.addUnspentTxos(txoBuilder);
unspentTxos.add(txoBuilder.build());
}
if (txOut.getSpentBlockIndex() != null && txOut.getSpentBlockIndex().compareTo(highestBlockIndex) > 0) {
@@ -192,12 +195,16 @@ public final class Wallet {
highestBlockTimeStamp = txOut.getReceivedBlockTimestamp().getTime();
}
}
builder.setBalance(Uint64Util.bigIntegerToUInt64(totalUnspent))
.setTransferableBalance(Uint64Util.bigIntegerToUInt64(accountSnapshot.getTransferableAmount(minimumTxFee).getValue()))
.setAsOfTimeStamp(asOfTimestamp)
.setHighestBlock(MobileCoinLedger.Block.newBuilder()
.setBlockNumber(highestBlockIndex.longValue())
.setTimestamp(highestBlockTimeStamp));
builder.spentTxos(spentTxos)
.unspentTxos(unspentTxos)
.balance(Uint64Util.bigIntegerToUInt64(totalUnspent))
.transferableBalance(Uint64Util.bigIntegerToUInt64(accountSnapshot.getTransferableAmount(minimumTxFee).getValue()))
.asOfTimeStamp(asOfTimestamp)
.highestBlock(new MobileCoinLedger.Block.Builder()
.blockNumber(highestBlockIndex.longValue())
.timestamp(highestBlockTimeStamp)
.build());
SignalStore.paymentsValues().setEnclaveFailure(false);
return new MobileCoinLedgerWrapper(builder.build());
} catch (InvalidFogResponse e) {
@@ -220,10 +227,10 @@ public final class Wallet {
}
private static @Nullable MobileCoinLedger.Block getBlock(@NonNull UnsignedLong blockIndex, @Nullable Date timeStamp) throws Uint64RangeException {
MobileCoinLedger.Block.Builder builder = MobileCoinLedger.Block.newBuilder();
builder.setBlockNumber(Uint64Util.bigIntegerToUInt64(blockIndex.toBigInteger()));
MobileCoinLedger.Block.Builder builder = new MobileCoinLedger.Block.Builder();
builder.blockNumber(Uint64Util.bigIntegerToUInt64(blockIndex.toBigInteger()));
if (timeStamp != null) {
builder.setTimestamp(timeStamp.getTime());
builder.timestamp(timeStamp.getTime());
}
return builder.build();
}

View File

@@ -6,7 +6,6 @@ import androidx.annotation.WorkerThread;
import com.annimon.stream.Collectors;
import com.annimon.stream.ComparatorCompat;
import com.annimon.stream.Stream;
import com.google.protobuf.ByteString;
import org.signal.core.util.MapUtil;
import org.signal.core.util.logging.Log;
@@ -32,6 +31,8 @@ import java.util.Set;
import javax.annotation.Nullable;
import okio.ByteString;
public final class LedgerReconcile {
private static final String TAG = Log.tag(LedgerReconcile.class);
@@ -53,14 +54,14 @@ public final class LedgerReconcile {
@NonNull List<MobileCoinLedgerWrapper.OwnedTxo> allTxOuts)
{
List<? extends Payment> nonFailedLocalPayments = Stream.of(allLocalPaymentTransactions).filter(i -> i.getState() != State.FAILED).toList();
Set<ByteString> allKnownPublicKeys = new HashSet<>(nonFailedLocalPayments.size());
Set<ByteString> allKnownKeyImages = new HashSet<>(nonFailedLocalPayments.size());
Set<ByteString> allKnownPublicKeys = new HashSet<>(nonFailedLocalPayments.size());
Set<ByteString> allKnownKeyImages = new HashSet<>(nonFailedLocalPayments.size());
for (Payment paymentTransaction : nonFailedLocalPayments) {
PaymentMetaData.MobileCoinTxoIdentification txoIdentification = paymentTransaction.getPaymentMetaData().getMobileCoinTxoIdentification();
PaymentMetaData.MobileCoinTxoIdentification txoIdentification = paymentTransaction.getPaymentMetaData().mobileCoinTxoIdentification;
allKnownPublicKeys.addAll(txoIdentification.getPublicKeyList());
allKnownKeyImages.addAll(txoIdentification.getKeyImagesList());
allKnownPublicKeys.addAll(txoIdentification.publicKey);
allKnownKeyImages.addAll(txoIdentification.keyImages);
}
Set<MobileCoinLedgerWrapper.OwnedTxo> knownTxosByKeyImage = Stream.of(allTxOuts)
@@ -120,7 +121,7 @@ public final class LedgerReconcile {
private static @NonNull Payment findBlock(@NonNull Payment local, @NonNull Map<ByteString, MobileCoinLedgerWrapper.OwnedTxo> allTxOuts) {
if (local.getDirection().isReceived()) {
for (ByteString publicKey : local.getPaymentMetaData().getMobileCoinTxoIdentification().getPublicKeyList()) {
for (ByteString publicKey : local.getPaymentMetaData().mobileCoinTxoIdentification.publicKey) {
MobileCoinLedgerWrapper.OwnedTxo ownedTxo = allTxOuts.get(publicKey);
if (ownedTxo != null) {
@@ -131,7 +132,7 @@ public final class LedgerReconcile {
}
}
} else {
for (ByteString keyImage : local.getPaymentMetaData().getMobileCoinTxoIdentification().getKeyImagesList()) {
for (ByteString keyImage : local.getPaymentMetaData().mobileCoinTxoIdentification.keyImages) {
MobileCoinLedgerWrapper.OwnedTxo ownedTxo = allTxOuts.get(keyImage);
if (ownedTxo != null && ownedTxo.getSpentInBlock() != null) {