public class PaymentChannelClient extends Object implements IPaymentChannelClient
A class which handles most of the complexity of creating a payment channel connection by providing a simple in/out interface which is provided with protobufs from the server and which generates protobufs which should be sent to the server.
Does all required verification of server messages and properly stores state objects in the wallet-attached
StoredPaymentChannelClientStates
so that they are automatically closed when necessary and refund
transactions are not lost if the application crashes before it unlocks.
Though this interface is largely designed with stateful protocols (eg simple TCP connections) in mind, it is also possible to use it with stateless protocols (eg sending protobufs when required over HTTP headers). In this case, the "connection" translates roughly into the server-client relationship. See the javadocs for specific functions for more details.
IPaymentChannelClient.ClientConnection, IPaymentChannelClient.Factory
Modifier and Type | Field and Description |
---|---|
protected ReentrantLock |
lock |
long |
MAX_TIME_WINDOW
The maximum amount of time for which we will accept the server locking up our funds for the multisig
contract.
|
Constructor and Description |
---|
PaymentChannelClient(Wallet wallet,
ECKey myKey,
BigInteger maxValue,
Sha256Hash serverId,
IPaymentChannelClient.ClientConnection conn)
Constructs a new channel manager which waits for
connectionOpen() before acting. |
Modifier and Type | Method and Description |
---|---|
void |
connectionClosed()
Called when the connection terminates.
|
void |
connectionOpen()
Called to indicate the connection has been opened and messages can now be generated for the server.
|
BigInteger |
getMissing()
Returns the amount of satoshis missing when a server requests too much value.
|
com.google.common.util.concurrent.ListenableFuture<BigInteger> |
incrementPayment(BigInteger size)
Increments the total value which we pay the server.
|
void |
receiveMessage(Protos.TwoWayChannelMessage msg)
Called when a message is received from the server.
|
void |
settle()
Closes the connection, notifying the server it should settle the channel by broadcasting the most recent
payment transaction.
|
PaymentChannelClientState |
state()
Gets the
PaymentChannelClientState object which stores the current state of the connection with the
server. |
protected final ReentrantLock lock
public long MAX_TIME_WINDOW
The maximum amount of time for which we will accept the server locking up our funds for the multisig contract.
Note that though this is not final, it is in all caps because it should generally not be modified unless you have some guarantee that the server will not request at least this (channels will fail if this is too small).
24 hours is the default as it is expected that clients limit risk exposure by limiting channel size instead of limiting lock time when dealing with potentially malicious servers.
public PaymentChannelClient(Wallet wallet, ECKey myKey, BigInteger maxValue, Sha256Hash serverId, IPaymentChannelClient.ClientConnection conn)
connectionOpen()
before acting.wallet
- The wallet which will be paid from, and where completed transactions will be committed.
Must already have a StoredPaymentChannelClientStates
object in its extensions set.myKey
- A freshly generated keypair used for the multisig contract and refund output.maxValue
- The maximum value the server is allowed to request that we lock into this channel until the
refund transaction unlocks. Note that if there is a previously open channel, the refund
transaction used in this channel may be larger than maxValue. Thus, maxValue is not a method for
limiting the amount payable through this channel.serverId
- An arbitrary hash representing this channel. This must uniquely identify the server. If an
existing stored channel exists in the wallet's StoredPaymentChannelClientStates
, then an
attempt will be made to resume that channel.conn
- A callback listener which represents the connection to the server (forwards messages we generate to
the server)public BigInteger getMissing()
Returns the amount of satoshis missing when a server requests too much value.
When InsufficientMoneyException is thrown due to the server requesting too much value, an instance of PaymentChannelClient needs access to how many satoshis are missing.
public void receiveMessage(Protos.TwoWayChannelMessage msg) throws InsufficientMoneyException
receiveMessage
in interface IPaymentChannelClient
InsufficientMoneyException
public void connectionClosed()
Called when the connection terminates. Notifies the StoredClientChannel
object that we can attempt to
resume this channel in the future and stops generating messages for the server.
For stateless protocols, this translates to a client not using the channel for the immediate future, but intending to reopen the channel later. There is likely little reason to use this in a stateless protocol.
Note that this MUST still be called even after either
ClientConnection#destroyConnection(com.google.bitcoin.protocols.channels.PaymentChannelCloseException.CloseReason)
or
settle()
is called, to actually handle the connection close logic.
connectionClosed
in interface IPaymentChannelClient
public void settle() throws IllegalStateException
Closes the connection, notifying the server it should settle the channel by broadcasting the most recent payment transaction.
Note that this only generates a CLOSE message for the server and calls
ClientConnection#destroyConnection(CloseReason)
to settle the connection, it does not
actually handle connection close logic, and connectionClosed()
must still be called
after the connection fully closes.
settle
in interface IPaymentChannelClient
IllegalStateException
- If the connection is not currently open (ie the CLOSE message cannot be sent)public void connectionOpen()
Called to indicate the connection has been opened and messages can now be generated for the server.
Attempts to find a channel to resume and generates a CLIENT_VERSION message for the server based on the result.
connectionOpen
in interface IPaymentChannelClient
public PaymentChannelClientState state()
Gets the PaymentChannelClientState
object which stores the current state of the connection with the
server.
Note that if you call any methods which update state directly the server will not be notified and channel initialization logic in the connection may fail unexpectedly.
public com.google.common.util.concurrent.ListenableFuture<BigInteger> incrementPayment(BigInteger size) throws ValueOutOfRangeException, IllegalStateException
incrementPayment
in interface IPaymentChannelClient
size
- How many satoshis to increment the payment by (note: not the new total).ValueOutOfRangeException
- If the size is negative or would pay more than this channel's total value
(PaymentChannelClientConnection.state()
.getTotalValue())IllegalStateException
- If the channel has been closed or is not yet open
(see PaymentChannelClientConnection.getChannelOpenFuture()
for the second)Copyright © 2014. All rights reserved.