3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-12 10:15:52 +00:00

Narrow PeerGroup -> TransactionBroadcaster in the channels code.

This commit is contained in:
Mike Hearn 2013-07-01 13:17:57 +02:00
parent ec51162ae4
commit 93abc34e08
5 changed files with 32 additions and 30 deletions

View File

@ -95,7 +95,7 @@ public class PaymentChannelServer {
// The wallet and peergroup which are used to complete/broadcast transactions // The wallet and peergroup which are used to complete/broadcast transactions
private final Wallet wallet; private final Wallet wallet;
private final PeerGroup peerGroup; private final TransactionBroadcaster broadcaster;
// The key used for multisig in this channel // The key used for multisig in this channel
@GuardedBy("lock") private ECKey myKey; @GuardedBy("lock") private ECKey myKey;
@ -121,7 +121,7 @@ public class PaymentChannelServer {
/** /**
* Creates a new server-side state manager which handles a single client connection. * Creates a new server-side state manager which handles a single client connection.
* *
* @param peerGroup The PeerGroup on which transactions will be broadcast - should have multiple connections. * @param broadcaster The PeerGroup on which transactions will be broadcast - should have multiple connections.
* @param wallet The wallet which will be used to complete transactions. * @param wallet The wallet which will be used to complete transactions.
* Unlike {@link PaymentChannelClient}, this does not have to already contain a StoredState manager * Unlike {@link PaymentChannelClient}, this does not have to already contain a StoredState manager
* @param minAcceptedChannelSize The minimum value the client must lock into this channel. A value too large will be * @param minAcceptedChannelSize The minimum value the client must lock into this channel. A value too large will be
@ -132,8 +132,9 @@ public class PaymentChannelServer {
* @param conn A callback listener which represents the connection to the client (forwards messages we generate to * @param conn A callback listener which represents the connection to the client (forwards messages we generate to
* the client and will close the connection on request) * the client and will close the connection on request)
*/ */
public PaymentChannelServer(PeerGroup peerGroup, Wallet wallet, BigInteger minAcceptedChannelSize, ServerConnection conn) { public PaymentChannelServer(TransactionBroadcaster broadcaster, Wallet wallet,
this.peerGroup = checkNotNull(peerGroup); BigInteger minAcceptedChannelSize, ServerConnection conn) {
this.broadcaster = checkNotNull(broadcaster);
this.wallet = checkNotNull(wallet); this.wallet = checkNotNull(wallet);
this.minAcceptedChannelSize = checkNotNull(minAcceptedChannelSize); this.minAcceptedChannelSize = checkNotNull(minAcceptedChannelSize);
this.conn = checkNotNull(conn); this.conn = checkNotNull(conn);
@ -159,7 +160,7 @@ public class PaymentChannelServer {
if (storedServerChannel.setConnectedHandler(this)) { if (storedServerChannel.setConnectedHandler(this)) {
log.info("Got resume version message, responding with VERSIONS and CHANNEL_OPEN"); log.info("Got resume version message, responding with VERSIONS and CHANNEL_OPEN");
state = storedServerChannel.getState(wallet, peerGroup); state = storedServerChannel.getState(wallet, broadcaster);
step = InitStep.CHANNEL_OPEN; step = InitStep.CHANNEL_OPEN;
conn.sendToClient(Protos.TwoWayChannelMessage.newBuilder() conn.sendToClient(Protos.TwoWayChannelMessage.newBuilder()
.setType(Protos.TwoWayChannelMessage.MessageType.CHANNEL_OPEN) .setType(Protos.TwoWayChannelMessage.MessageType.CHANNEL_OPEN)
@ -195,7 +196,7 @@ public class PaymentChannelServer {
log.info("Got refund transaction, returning signature"); log.info("Got refund transaction, returning signature");
Protos.ProvideRefund providedRefund = msg.getProvideRefund(); Protos.ProvideRefund providedRefund = msg.getProvideRefund();
state = new PaymentChannelServerState(peerGroup, wallet, myKey, expireTime); state = new PaymentChannelServerState(broadcaster, wallet, myKey, expireTime);
byte[] signature = state.provideRefundTransaction(new Transaction(wallet.getParams(), providedRefund.getTx().toByteArray()), byte[] signature = state.provideRefundTransaction(new Transaction(wallet.getParams(), providedRefund.getTx().toByteArray()),
providedRefund.getMultisigKey().toByteArray()); providedRefund.getMultisigKey().toByteArray());

View File

@ -24,8 +24,8 @@ import java.net.SocketAddress;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import com.google.bitcoin.core.PeerGroup;
import com.google.bitcoin.core.Sha256Hash; import com.google.bitcoin.core.Sha256Hash;
import com.google.bitcoin.core.TransactionBroadcaster;
import com.google.bitcoin.core.Wallet; import com.google.bitcoin.core.Wallet;
import com.google.bitcoin.protocols.niowrapper.ProtobufParser; import com.google.bitcoin.protocols.niowrapper.ProtobufParser;
import com.google.bitcoin.protocols.niowrapper.ProtobufParserFactory; import com.google.bitcoin.protocols.niowrapper.ProtobufParserFactory;
@ -42,7 +42,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
public class PaymentChannelServerListener { public class PaymentChannelServerListener {
// The wallet and peergroup which are used to complete/broadcast transactions // The wallet and peergroup which are used to complete/broadcast transactions
private final Wallet wallet; private final Wallet wallet;
private final PeerGroup peerGroup; private final TransactionBroadcaster broadcaster;
// The event handler factory which creates new ServerConnectionEventHandler per connection // The event handler factory which creates new ServerConnectionEventHandler per connection
private final HandlerFactory eventHandlerFactory; private final HandlerFactory eventHandlerFactory;
@ -63,7 +63,7 @@ public class PaymentChannelServerListener {
private class ServerHandler { private class ServerHandler {
public ServerHandler(final SocketAddress address, final int timeoutSeconds) { public ServerHandler(final SocketAddress address, final int timeoutSeconds) {
paymentChannelManager = new PaymentChannelServer(peerGroup, wallet, minAcceptedChannelSize, new PaymentChannelServer.ServerConnection() { paymentChannelManager = new PaymentChannelServer(broadcaster, wallet, minAcceptedChannelSize, new PaymentChannelServer.ServerConnection() {
@Override public void sendToClient(Protos.TwoWayChannelMessage msg) { @Override public void sendToClient(Protos.TwoWayChannelMessage msg) {
socketProtobufHandler.write(msg); socketProtobufHandler.write(msg);
} }
@ -142,7 +142,7 @@ public class PaymentChannelServerListener {
/** /**
* Sets up a new payment channel server which listens on the given port. * Sets up a new payment channel server which listens on the given port.
* *
* @param peerGroup The PeerGroup on which transactions will be broadcast - should have multiple connections. * @param broadcaster The PeerGroup on which transactions will be broadcast - should have multiple connections.
* @param wallet The wallet which will be used to complete transactions * @param wallet The wallet which will be used to complete transactions
* @param timeoutSeconds The read timeout between messages. This should accommodate latency and client ECDSA * @param timeoutSeconds The read timeout between messages. This should accommodate latency and client ECDSA
* signature operations. * signature operations.
@ -152,10 +152,11 @@ public class PaymentChannelServerListener {
* channel) should generally be chosen. * channel) should generally be chosen.
* @param eventHandlerFactory A factory which generates event handlers which are created for each new connection * @param eventHandlerFactory A factory which generates event handlers which are created for each new connection
*/ */
public PaymentChannelServerListener(PeerGroup peerGroup, Wallet wallet, final int timeoutSeconds, BigInteger minAcceptedChannelSize, public PaymentChannelServerListener(TransactionBroadcaster broadcaster, Wallet wallet,
final int timeoutSeconds, BigInteger minAcceptedChannelSize,
HandlerFactory eventHandlerFactory) throws IOException { HandlerFactory eventHandlerFactory) throws IOException {
this.wallet = checkNotNull(wallet); this.wallet = checkNotNull(wallet);
this.peerGroup = checkNotNull(peerGroup); this.broadcaster = checkNotNull(broadcaster);
this.eventHandlerFactory = checkNotNull(eventHandlerFactory); this.eventHandlerFactory = checkNotNull(eventHandlerFactory);
this.minAcceptedChannelSize = checkNotNull(minAcceptedChannelSize); this.minAcceptedChannelSize = checkNotNull(minAcceptedChannelSize);

View File

@ -90,8 +90,8 @@ public class PaymentChannelServerState {
// Package-local for checkArguments in StoredServerChannel // Package-local for checkArguments in StoredServerChannel
final Wallet wallet; final Wallet wallet;
// The peer group we will broadcast transactions to // The object that will broadcast transactions for us - usually a peer group.
private final PeerGroup peerGroup; private final TransactionBroadcaster broadcaster;
// The multi-sig contract and the output script from it // The multi-sig contract and the output script from it
private Transaction multisigContract = null; private Transaction multisigContract = null;
@ -113,10 +113,10 @@ public class PaymentChannelServerState {
private StoredServerChannel storedServerChannel = null; private StoredServerChannel storedServerChannel = null;
PaymentChannelServerState(StoredServerChannel storedServerChannel, Wallet wallet, PeerGroup peerGroup) throws VerificationException { PaymentChannelServerState(StoredServerChannel storedServerChannel, Wallet wallet, TransactionBroadcaster broadcaster) throws VerificationException {
synchronized (storedServerChannel) { synchronized (storedServerChannel) {
this.wallet = checkNotNull(wallet); this.wallet = checkNotNull(wallet);
this.peerGroup = checkNotNull(peerGroup); this.broadcaster = checkNotNull(broadcaster);
this.multisigContract = checkNotNull(storedServerChannel.contract); this.multisigContract = checkNotNull(storedServerChannel.contract);
this.multisigScript = multisigContract.getOutput(0).getScriptPubKey(); this.multisigScript = multisigContract.getOutput(0).getScriptPubKey();
this.clientKey = new ECKey(null, multisigScript.getChunks().get(1).data); this.clientKey = new ECKey(null, multisigScript.getChunks().get(1).data);
@ -136,17 +136,17 @@ public class PaymentChannelServerState {
/** /**
* Creates a new state object to track the server side of a payment channel. * Creates a new state object to track the server side of a payment channel.
* *
* @param peerGroup The peer group which we will broadcast transactions to, this should have multiple peers * @param broadcaster The peer group which we will broadcast transactions to, this should have multiple peers
* @param wallet The wallet which will be used to complete transactions * @param wallet The wallet which will be used to complete transactions
* @param serverKey The private key which we use for our part of the multi-sig contract * @param serverKey The private key which we use for our part of the multi-sig contract
* (this MUST be fresh and CANNOT be used elsewhere) * (this MUST be fresh and CANNOT be used elsewhere)
* @param minExpireTime The earliest time at which the client can claim the refund transaction (UNIX timestamp of block) * @param minExpireTime The earliest time at which the client can claim the refund transaction (UNIX timestamp of block)
*/ */
public PaymentChannelServerState(PeerGroup peerGroup, Wallet wallet, ECKey serverKey, long minExpireTime) { public PaymentChannelServerState(TransactionBroadcaster broadcaster, Wallet wallet, ECKey serverKey, long minExpireTime) {
this.state = State.WAITING_FOR_REFUND_TRANSACTION; this.state = State.WAITING_FOR_REFUND_TRANSACTION;
this.serverKey = checkNotNull(serverKey); this.serverKey = checkNotNull(serverKey);
this.wallet = checkNotNull(wallet); this.wallet = checkNotNull(wallet);
this.peerGroup = checkNotNull(peerGroup); this.broadcaster = checkNotNull(broadcaster);
this.minExpireTime = minExpireTime; this.minExpireTime = minExpireTime;
} }
@ -237,7 +237,7 @@ public class PaymentChannelServerState {
log.info("Broadcasting multisig contract: {}", multisigContract); log.info("Broadcasting multisig contract: {}", multisigContract);
state = State.WAITING_FOR_MULTISIG_ACCEPTANCE; state = State.WAITING_FOR_MULTISIG_ACCEPTANCE;
final SettableFuture<PaymentChannelServerState> future = SettableFuture.create(); final SettableFuture<PaymentChannelServerState> future = SettableFuture.create();
Futures.addCallback(peerGroup.broadcastTransaction(multisigContract), new FutureCallback<Transaction>() { Futures.addCallback(broadcaster.broadcastTransaction(multisigContract), new FutureCallback<Transaction>() {
@Override public void onSuccess(Transaction transaction) { @Override public void onSuccess(Transaction transaction) {
log.info("Successfully broadcast multisig contract {}. Channel now open.", transaction.getHashAsString()); log.info("Successfully broadcast multisig contract {}. Channel now open.", transaction.getHashAsString());
state = State.READY; state = State.READY;
@ -387,7 +387,7 @@ public class PaymentChannelServerState {
state = State.CLOSING; state = State.CLOSING;
log.info("Closing channel, broadcasting tx {}", tx); log.info("Closing channel, broadcasting tx {}", tx);
// The act of broadcasting the transaction will add it to the wallet. // The act of broadcasting the transaction will add it to the wallet.
ListenableFuture<Transaction> future = peerGroup.broadcastTransaction(tx); ListenableFuture<Transaction> future = broadcaster.broadcastTransaction(tx);
Futures.addCallback(future, new FutureCallback<Transaction>() { Futures.addCallback(future, new FutureCallback<Transaction>() {
@Override public void onSuccess(Transaction transaction) { @Override public void onSuccess(Transaction transaction) {
log.info("TX {} propagated, channel successfully closed.", transaction.getHash()); log.info("TX {} propagated, channel successfully closed.", transaction.getHash());
@ -463,7 +463,7 @@ public class PaymentChannelServerState {
log.info("Storing state with contract hash {}.", multisigContract.getHash()); log.info("Storing state with contract hash {}.", multisigContract.getHash());
StoredPaymentChannelServerStates channels = (StoredPaymentChannelServerStates) StoredPaymentChannelServerStates channels = (StoredPaymentChannelServerStates)
wallet.addOrGetExistingExtension(new StoredPaymentChannelServerStates(wallet, peerGroup)); wallet.addOrGetExistingExtension(new StoredPaymentChannelServerStates(wallet, broadcaster));
storedServerChannel = new StoredServerChannel(this, multisigContract, clientOutput, refundTransactionUnlockTimeSecs, serverKey, bestValueToMe, bestValueSignature); storedServerChannel = new StoredServerChannel(this, multisigContract, clientOutput, refundTransactionUnlockTimeSecs, serverKey, bestValueToMe, bestValueSignature);
checkState(storedServerChannel.setConnectedHandler(connectedHandler)); checkState(storedServerChannel.setConnectedHandler(connectedHandler));
channels.putChannel(storedServerChannel); channels.putChannel(storedServerChannel);

View File

@ -34,7 +34,7 @@ public class StoredPaymentChannelServerStates implements WalletExtension {
@VisibleForTesting final Map<Sha256Hash, StoredServerChannel> mapChannels = new HashMap<Sha256Hash, StoredServerChannel>(); @VisibleForTesting final Map<Sha256Hash, StoredServerChannel> mapChannels = new HashMap<Sha256Hash, StoredServerChannel>();
private final Wallet wallet; private final Wallet wallet;
private final PeerGroup announcePeerGroup; private final TransactionBroadcaster broadcaster;
private final Timer channelTimeoutHandler = new Timer(); private final Timer channelTimeoutHandler = new Timer();
@ -49,11 +49,11 @@ public class StoredPaymentChannelServerStates implements WalletExtension {
/** /**
* Creates a new PaymentChannelServerStateManager and associates it with the given {@link Wallet} and * Creates a new PaymentChannelServerStateManager and associates it with the given {@link Wallet} and
* {@link PeerGroup} which are used to complete and announce payment transactions. * {@link TransactionBroadcaster} which are used to complete and announce payment transactions.
*/ */
public StoredPaymentChannelServerStates(Wallet wallet, PeerGroup announcePeerGroup) { public StoredPaymentChannelServerStates(Wallet wallet, TransactionBroadcaster broadcaster) {
this.wallet = checkNotNull(wallet); this.wallet = checkNotNull(wallet);
this.announcePeerGroup = checkNotNull(announcePeerGroup); this.broadcaster = checkNotNull(broadcaster);
} }
/** /**
@ -69,7 +69,7 @@ public class StoredPaymentChannelServerStates implements WalletExtension {
if (channel.connectedHandler != null) if (channel.connectedHandler != null)
channel.connectedHandler.close(); // connectedHandler will be reset to null in connectionClosed channel.connectedHandler.close(); // connectedHandler will be reset to null in connectionClosed
try {//TODO add event listener to PaymentChannelServerStateManager try {//TODO add event listener to PaymentChannelServerStateManager
channel.getState(wallet, announcePeerGroup).close(); // Closes the actual connection, not the channel channel.getState(wallet, broadcaster).close(); // Closes the actual connection, not the channel
} catch (ValueOutOfRangeException e) { } catch (ValueOutOfRangeException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (VerificationException e) { } catch (VerificationException e) {

View File

@ -78,11 +78,11 @@ public class StoredServerChannel implements Serializable {
* *
* @param wallet The wallet which holds the {@link com.google.bitcoin.protocols.channels.PaymentChannelServerState} in which this is saved and which will * @param wallet The wallet which holds the {@link com.google.bitcoin.protocols.channels.PaymentChannelServerState} in which this is saved and which will
* be used to complete transactions * be used to complete transactions
* @param peerGroup The {@link com.google.bitcoin.core.PeerGroup} which will be used to broadcast contract/payment transactions. * @param broadcaster The {@link com.google.bitcoin.core.TransactionBroadcaster} which will be used to broadcast contract/payment transactions.
*/ */
public synchronized PaymentChannelServerState getState(Wallet wallet, PeerGroup peerGroup) throws VerificationException { public synchronized PaymentChannelServerState getState(Wallet wallet, TransactionBroadcaster broadcaster) throws VerificationException {
if (state == null) if (state == null)
state = new PaymentChannelServerState(this, wallet, peerGroup); state = new PaymentChannelServerState(this, wallet, broadcaster);
checkArgument(wallet == state.wallet); checkArgument(wallet == state.wallet);
return state; return state;
} }