mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-12 18:25:51 +00:00
Store states in protobufs instead of using Java Serialization.
Saves having to use reflection.
This commit is contained in:
parent
4b4405b7bc
commit
c98badcf1c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -28,6 +28,7 @@ import com.google.bitcoin.core.*;
|
||||
import com.google.bitcoin.utils.Threading;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.protobuf.ByteString;
|
||||
import net.jcip.annotations.GuardedBy;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
@ -157,14 +158,22 @@ public class StoredPaymentChannelClientStates implements WalletExtension {
|
||||
public byte[] serializeWalletExtension() {
|
||||
lock.lock();
|
||||
try {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(out);
|
||||
ClientState.StoredClientPaymentChannels.Builder builder = ClientState.StoredClientPaymentChannels.newBuilder();
|
||||
for (StoredClientChannel channel : mapChannels.values()) {
|
||||
oos.writeObject(channel);
|
||||
// First a few asserts to make sure things won't break
|
||||
checkState(channel.valueToMe.compareTo(BigInteger.ZERO) >= 0 && channel.valueToMe.compareTo(NetworkParameters.MAX_MONEY) < 0);
|
||||
checkState(channel.refundFees.compareTo(BigInteger.ZERO) >= 0 && channel.refundFees.compareTo(NetworkParameters.MAX_MONEY) < 0);
|
||||
checkNotNull(channel.myKey.getPrivKeyBytes());
|
||||
checkState(channel.refund.getConfidence().getSource() == TransactionConfidence.Source.SELF);
|
||||
builder.addChannels(ClientState.StoredClientPaymentChannel.newBuilder()
|
||||
.setId(ByteString.copyFrom(channel.id.getBytes()))
|
||||
.setContractTransaction(ByteString.copyFrom(channel.contract.bitcoinSerialize()))
|
||||
.setRefundTransaction(ByteString.copyFrom(channel.refund.bitcoinSerialize()))
|
||||
.setMyKey(ByteString.copyFrom(channel.myKey.getPrivKeyBytes()))
|
||||
.setValueToMe(channel.valueToMe.longValue())
|
||||
.setRefundFees(channel.refundFees.longValue()));
|
||||
}
|
||||
return out.toByteArray();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
return builder.build().toByteArray();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
@ -176,10 +185,17 @@ public class StoredPaymentChannelClientStates implements WalletExtension {
|
||||
try {
|
||||
checkState(this.containingWallet == null || this.containingWallet == containingWallet);
|
||||
this.containingWallet = containingWallet;
|
||||
ByteArrayInputStream inStream = new ByteArrayInputStream(data);
|
||||
ObjectInputStream ois = new ObjectInputStream(inStream);
|
||||
while (inStream.available() > 0) {
|
||||
StoredClientChannel channel = (StoredClientChannel)ois.readObject();
|
||||
NetworkParameters params = containingWallet.getParams();
|
||||
ClientState.StoredClientPaymentChannels states = ClientState.StoredClientPaymentChannels.parseFrom(data);
|
||||
for (ClientState.StoredClientPaymentChannel storedState : states.getChannelsList()) {
|
||||
Transaction refundTransaction = new Transaction(params, storedState.getRefundTransaction().toByteArray());
|
||||
refundTransaction.getConfidence().setSource(TransactionConfidence.Source.SELF);
|
||||
StoredClientChannel channel = new StoredClientChannel(new Sha256Hash(storedState.getId().toByteArray()),
|
||||
new Transaction(params, storedState.getContractTransaction().toByteArray()),
|
||||
refundTransaction,
|
||||
new ECKey(storedState.getMyKey().toByteArray(), null),
|
||||
BigInteger.valueOf(storedState.getValueToMe()),
|
||||
BigInteger.valueOf(storedState.getRefundFees()));
|
||||
putChannel(channel, false);
|
||||
}
|
||||
} finally {
|
||||
@ -193,14 +209,14 @@ public class StoredPaymentChannelClientStates implements WalletExtension {
|
||||
* channel which was interrupted (eg on connection failure) or keep track of refund transactions which need broadcast
|
||||
* when they expire.
|
||||
*/
|
||||
class StoredClientChannel implements Serializable {
|
||||
class StoredClientChannel {
|
||||
Sha256Hash id;
|
||||
Transaction contract, refund;
|
||||
ECKey myKey;
|
||||
BigInteger valueToMe, refundFees;
|
||||
|
||||
// In-memory flag to indicate intent to resume this channel (or that the channel is already in use)
|
||||
transient boolean active = false;
|
||||
boolean active = false;
|
||||
|
||||
StoredClientChannel(Sha256Hash id, Transaction contract, Transaction refund, ECKey myKey, BigInteger valueToMe, BigInteger refundFees) {
|
||||
this.id = id;
|
||||
|
@ -17,16 +17,19 @@
|
||||
package com.google.bitcoin.protocols.channels;
|
||||
|
||||
import java.io.*;
|
||||
import java.math.BigInteger;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import com.google.bitcoin.core.*;
|
||||
import com.google.bitcoin.utils.Threading;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.protobuf.ByteString;
|
||||
import net.jcip.annotations.GuardedBy;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
/**
|
||||
* Keeps track of a set of {@link StoredServerChannel}s and expires them 2 hours before their refund transactions
|
||||
@ -142,14 +145,23 @@ public class StoredPaymentChannelServerStates implements WalletExtension {
|
||||
public byte[] serializeWalletExtension() {
|
||||
lock.lock();
|
||||
try {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(out);
|
||||
ServerState.StoredServerPaymentChannels.Builder builder = ServerState.StoredServerPaymentChannels.newBuilder();
|
||||
for (StoredServerChannel channel : mapChannels.values()) {
|
||||
oos.writeObject(channel);
|
||||
// First a few asserts to make sure things won't break
|
||||
checkState(channel.bestValueToMe.compareTo(BigInteger.ZERO) >= 0 && channel.bestValueToMe.compareTo(NetworkParameters.MAX_MONEY) < 0);
|
||||
checkState(channel.refundTransactionUnlockTimeSecs > 0);
|
||||
checkNotNull(channel.myKey.getPrivKeyBytes());
|
||||
ServerState.StoredServerPaymentChannel.Builder channelBuilder = ServerState.StoredServerPaymentChannel.newBuilder()
|
||||
.setBestValueToMe(channel.bestValueToMe.longValue())
|
||||
.setRefundTransactionUnlockTimeSecs(channel.refundTransactionUnlockTimeSecs)
|
||||
.setContractTransaction(ByteString.copyFrom(channel.contract.bitcoinSerialize()))
|
||||
.setClientOutput(ByteString.copyFrom(channel.clientOutput.bitcoinSerialize()))
|
||||
.setMyKey(ByteString.copyFrom(channel.myKey.getPrivKeyBytes()));
|
||||
if (channel.bestValueSignature != null)
|
||||
channelBuilder.setBestValueSignature(ByteString.copyFrom(channel.bestValueSignature));
|
||||
builder.addChannels(channelBuilder);
|
||||
}
|
||||
return out.toByteArray();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
return builder.build().toByteArray();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
@ -160,10 +172,16 @@ public class StoredPaymentChannelServerStates implements WalletExtension {
|
||||
lock.lock();
|
||||
try {
|
||||
checkArgument(containingWallet == wallet);
|
||||
ByteArrayInputStream inStream = new ByteArrayInputStream(data);
|
||||
ObjectInputStream ois = new ObjectInputStream(inStream);
|
||||
while (inStream.available() > 0) {
|
||||
StoredServerChannel channel = (StoredServerChannel)ois.readObject();
|
||||
ServerState.StoredServerPaymentChannels states = ServerState.StoredServerPaymentChannels.parseFrom(data);
|
||||
NetworkParameters params = containingWallet.getParams();
|
||||
for (ServerState.StoredServerPaymentChannel storedState : states.getChannelsList()) {
|
||||
StoredServerChannel channel = new StoredServerChannel(null,
|
||||
new Transaction(params, storedState.getContractTransaction().toByteArray()),
|
||||
new TransactionOutput(params, null, storedState.getClientOutput().toByteArray(), 0),
|
||||
storedState.getRefundTransactionUnlockTimeSecs(),
|
||||
new ECKey(storedState.getMyKey().toByteArray(), null),
|
||||
BigInteger.valueOf(storedState.getBestValueToMe()),
|
||||
storedState.hasBestValueSignature() ? storedState.getBestValueSignature().toByteArray() : null);
|
||||
putChannel(channel);
|
||||
}
|
||||
} finally {
|
||||
|
@ -28,7 +28,7 @@ import static com.google.common.base.Preconditions.checkArgument;
|
||||
* channel which was interrupted (eg on connection failure) or close the channel automatically as the channel expire
|
||||
* time approaches.
|
||||
*/
|
||||
public class StoredServerChannel implements Serializable {
|
||||
public class StoredServerChannel {
|
||||
BigInteger bestValueToMe;
|
||||
byte[] bestValueSignature;
|
||||
long refundTransactionUnlockTimeSecs;
|
||||
@ -38,8 +38,8 @@ public class StoredServerChannel implements Serializable {
|
||||
|
||||
// In-memory pointer to the event handler which handles this channel if the client is connected.
|
||||
// Used as a flag to prevent duplicate connections and to disconnect the channel if its expire time approaches.
|
||||
transient PaymentChannelServer connectedHandler = null;
|
||||
transient PaymentChannelServerState state = null;
|
||||
PaymentChannelServer connectedHandler = null;
|
||||
PaymentChannelServerState state = null;
|
||||
|
||||
StoredServerChannel(PaymentChannelServerState state, Transaction contract, TransactionOutput clientOutput,
|
||||
long refundTransactionUnlockTimeSecs, ECKey myKey, BigInteger bestValueToMe, byte[] bestValueSignature) {
|
||||
|
45
core/src/storedclientpaymentchannel.proto
Normal file
45
core/src/storedclientpaymentchannel.proto
Normal file
@ -0,0 +1,45 @@
|
||||
/** Copyright 2013 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors: Mike Hearn, Matt Corallo
|
||||
*/
|
||||
|
||||
/* Notes:
|
||||
* - Endianness: All byte arrays that represent numbers (such as hashes and private keys) are Big Endian
|
||||
* - To regenerate after editing, run mvn clean package -DupdateProtobuf
|
||||
*/
|
||||
|
||||
package paymentchannels;
|
||||
|
||||
option java_package = "com.google.bitcoin.protocols.channels";
|
||||
option java_outer_classname = "ClientState";
|
||||
|
||||
|
||||
// A set of StoredPaymentChannel's
|
||||
message StoredClientPaymentChannels {
|
||||
repeated StoredClientPaymentChannel channels = 1;
|
||||
}
|
||||
|
||||
// A client-side payment channel in serialized form, which can be reloaded later if the client restarts and wants to
|
||||
// reopen an existing channel
|
||||
message StoredClientPaymentChannel {
|
||||
required bytes id = 1;
|
||||
required bytes contractTransaction = 2;
|
||||
required bytes refundTransaction = 3;
|
||||
required bytes myKey = 4;
|
||||
required uint64 valueToMe = 5;
|
||||
required uint64 refundFees = 6;
|
||||
}
|
44
core/src/storedserverpaymentchannel.proto
Normal file
44
core/src/storedserverpaymentchannel.proto
Normal file
@ -0,0 +1,44 @@
|
||||
/** Copyright 2013 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Authors: Mike Hearn, Matt Corallo
|
||||
*/
|
||||
|
||||
/* Notes:
|
||||
* - Endianness: All byte arrays that represent numbers (such as hashes and private keys) are Big Endian
|
||||
* - To regenerate after editing, run mvn clean package -DupdateProtobuf
|
||||
*/
|
||||
|
||||
package paymentchannels;
|
||||
|
||||
option java_package = "com.google.bitcoin.protocols.channels";
|
||||
option java_outer_classname = "ServerState";
|
||||
|
||||
|
||||
// A set of StoredPaymentChannel's
|
||||
message StoredServerPaymentChannels {
|
||||
repeated StoredServerPaymentChannel channels = 1;
|
||||
}
|
||||
|
||||
// A server-side payment channel in serialized form, which can be reloaded later if the server restarts
|
||||
message StoredServerPaymentChannel {
|
||||
required uint64 bestValueToMe = 1;
|
||||
optional bytes bestValueSignature = 2;
|
||||
required uint64 refundTransactionUnlockTimeSecs = 3;
|
||||
required bytes contractTransaction = 4;
|
||||
required bytes clientOutput = 5;
|
||||
required bytes myKey = 6;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user