mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-07 23:03:04 +00:00
Deasymock PaymentChannelStateTest
This commit is contained in:
parent
a5940282d0
commit
2d84b3c27b
@ -19,7 +19,10 @@ package com.google.bitcoin.protocols.channels;
|
|||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
import com.google.bitcoin.core.*;
|
import com.google.bitcoin.core.*;
|
||||||
import com.google.bitcoin.script.Script;
|
import com.google.bitcoin.script.Script;
|
||||||
@ -43,6 +46,18 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
private Wallet serverWallet;
|
private Wallet serverWallet;
|
||||||
private PaymentChannelServerState serverState;
|
private PaymentChannelServerState serverState;
|
||||||
private PaymentChannelClientState clientState;
|
private PaymentChannelClientState clientState;
|
||||||
|
private TransactionBroadcaster mockBroadcaster;
|
||||||
|
private BlockingQueue<TxFuturePair> broadcasts;
|
||||||
|
|
||||||
|
private static class TxFuturePair {
|
||||||
|
Transaction tx;
|
||||||
|
SettableFuture<Transaction> future;
|
||||||
|
|
||||||
|
public TxFuturePair(Transaction tx, SettableFuture<Transaction> future) {
|
||||||
|
this.tx = tx;
|
||||||
|
this.future = future;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
@ -61,6 +76,16 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
serverWallet.addKey(serverKey);
|
serverWallet.addKey(serverKey);
|
||||||
chain.addWallet(serverWallet);
|
chain.addWallet(serverWallet);
|
||||||
halfCoin = Utils.toNanoCoins(0, 50);
|
halfCoin = Utils.toNanoCoins(0, 50);
|
||||||
|
|
||||||
|
broadcasts = new LinkedBlockingQueue<TxFuturePair>();
|
||||||
|
mockBroadcaster = new TransactionBroadcaster() {
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<Transaction> broadcastTransaction(Transaction tx) {
|
||||||
|
SettableFuture<Transaction> future = SettableFuture.create();
|
||||||
|
broadcasts.add(new TxFuturePair(tx, future));
|
||||||
|
return future;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -86,22 +111,10 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
public void basic() throws Exception {
|
public void basic() throws Exception {
|
||||||
// Check it all works when things are normal (no attacks, no problems).
|
// Check it all works when things are normal (no attacks, no problems).
|
||||||
|
|
||||||
// Set up a mock peergroup.
|
|
||||||
IMocksControl control = createStrictControl();
|
|
||||||
PeerGroup mockPeerGroup = control.createMock(PeerGroup.class);
|
|
||||||
// We'll broadcast two txns: multisig contract and close transaction.
|
|
||||||
SettableFuture<Transaction> multiSigFuture = SettableFuture.create();
|
|
||||||
SettableFuture<Transaction> closeFuture = SettableFuture.create();
|
|
||||||
Capture<Transaction> broadcastMultiSig = new Capture<Transaction>();
|
|
||||||
Capture<Transaction> broadcastClose = new Capture<Transaction>();
|
|
||||||
expect(mockPeerGroup.broadcastTransaction(capture(broadcastMultiSig))).andReturn(multiSigFuture);
|
|
||||||
expect(mockPeerGroup.broadcastTransaction(capture(broadcastClose))).andReturn(closeFuture);
|
|
||||||
control.replay();
|
|
||||||
|
|
||||||
Utils.rollMockClock(0); // Use mock clock
|
Utils.rollMockClock(0); // Use mock clock
|
||||||
final long EXPIRE_TIME = Utils.now().getTime()/1000 + 60*60*24;
|
final long EXPIRE_TIME = Utils.now().getTime()/1000 + 60*60*24;
|
||||||
|
|
||||||
serverState = new PaymentChannelServerState(mockPeerGroup, serverWallet, serverKey, EXPIRE_TIME);
|
serverState = new PaymentChannelServerState(mockBroadcaster, serverWallet, serverKey, EXPIRE_TIME);
|
||||||
assertEquals(PaymentChannelServerState.State.WAITING_FOR_REFUND_TRANSACTION, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.WAITING_FOR_REFUND_TRANSACTION, serverState.getState());
|
||||||
|
|
||||||
clientState = new PaymentChannelClientState(wallet, myKey, new ECKey(null, serverKey.getPubKey()), halfCoin, EXPIRE_TIME);
|
clientState = new PaymentChannelClientState(wallet, myKey, new ECKey(null, serverKey.getPubKey()), halfCoin, EXPIRE_TIME);
|
||||||
@ -130,7 +143,8 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
// Provide the server with the multisig contract and simulate successful propagation/acceptance.
|
// Provide the server with the multisig contract and simulate successful propagation/acceptance.
|
||||||
serverState.provideMultiSigContract(multisigContract);
|
serverState.provideMultiSigContract(multisigContract);
|
||||||
assertEquals(PaymentChannelServerState.State.WAITING_FOR_MULTISIG_ACCEPTANCE, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.WAITING_FOR_MULTISIG_ACCEPTANCE, serverState.getState());
|
||||||
multiSigFuture.set(broadcastMultiSig.getValue());
|
final TxFuturePair pair = broadcasts.take();
|
||||||
|
pair.future.set(pair.tx);
|
||||||
assertEquals(PaymentChannelServerState.State.READY, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.READY, serverState.getState());
|
||||||
|
|
||||||
// Make sure the refund transaction is not in the wallet and multisig contract's output is not connected to it
|
// Make sure the refund transaction is not in the wallet and multisig contract's output is not connected to it
|
||||||
@ -158,10 +172,10 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
// And close the channel.
|
// And close the channel.
|
||||||
serverState.close();
|
serverState.close();
|
||||||
assertEquals(PaymentChannelServerState.State.CLOSING, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.CLOSING, serverState.getState());
|
||||||
Transaction closeTx = broadcastClose.getValue();
|
final TxFuturePair pair2 = broadcasts.take();
|
||||||
closeFuture.set(closeTx);
|
Transaction closeTx = pair2.tx;
|
||||||
|
pair2.future.set(closeTx);
|
||||||
assertEquals(PaymentChannelServerState.State.CLOSED, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.CLOSED, serverState.getState());
|
||||||
control.verify();
|
|
||||||
|
|
||||||
// Create a block with multisig contract and payment transaction in it and give it to both wallets
|
// Create a block with multisig contract and payment transaction in it and give it to both wallets
|
||||||
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), multisigContract,
|
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), multisigContract,
|
||||||
@ -195,9 +209,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
if (!clientWalletCloseTransaction.getHash().equals(closeTx.getHash()))
|
if (!clientWalletCloseTransaction.getHash().equals(closeTx.getHash()))
|
||||||
clientWalletCloseTransaction = walletTransactionIterator.next();
|
clientWalletCloseTransaction = walletTransactionIterator.next();
|
||||||
assertEquals(closeTx.getHash(), clientWalletCloseTransaction.getHash());
|
assertEquals(closeTx.getHash(), clientWalletCloseTransaction.getHash());
|
||||||
assertTrue(clientWalletCloseTransaction.getInput(0).getConnectedOutput() != null);
|
assertNotNull(clientWalletCloseTransaction.getInput(0).getConnectedOutput());
|
||||||
|
|
||||||
control.verify();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -207,41 +219,18 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
|
|
||||||
// Spend the client wallet's one coin
|
// Spend the client wallet's one coin
|
||||||
Transaction spendCoinTx = wallet.sendCoinsOffline(Wallet.SendRequest.to(new ECKey().toAddress(params), Utils.COIN));
|
Transaction spendCoinTx = wallet.sendCoinsOffline(Wallet.SendRequest.to(new ECKey().toAddress(params), Utils.COIN));
|
||||||
assertEquals(wallet.getBalance(), BigInteger.ZERO);
|
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||||
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), spendCoinTx, createFakeTx(params, Utils.CENT, myAddress)));
|
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), spendCoinTx, createFakeTx(params, Utils.CENT, myAddress)));
|
||||||
assertEquals(wallet.getBalance(), Utils.CENT);
|
assertEquals(Utils.CENT, wallet.getBalance());
|
||||||
|
|
||||||
// Set up a mock peergroup.
|
|
||||||
IMocksControl control = createStrictControl();
|
|
||||||
final PeerGroup mockPeerGroup = control.createMock(PeerGroup.class);
|
|
||||||
// We'll broadcast three txns: multisig contract twice (both server and client) and refund transaction.
|
|
||||||
SettableFuture<Transaction> serverMultiSigFuture = SettableFuture.create();
|
|
||||||
SettableFuture<Transaction> paymentFuture = SettableFuture.create();
|
|
||||||
SettableFuture<Transaction> clientMultiSigFuture = SettableFuture.create();
|
|
||||||
SettableFuture<Transaction> refundFuture = SettableFuture.create();
|
|
||||||
Capture<Transaction> serverBroadcastMultiSig = new Capture<Transaction>();
|
|
||||||
Capture<Transaction> broadcastPayment = new Capture<Transaction>();
|
|
||||||
Capture<Transaction> clientBroadcastMultiSig = new Capture<Transaction>();
|
|
||||||
Capture<Transaction> broadcastRefund = new Capture<Transaction>();
|
|
||||||
expect(mockPeerGroup.broadcastTransaction(capture(serverBroadcastMultiSig))).andReturn(serverMultiSigFuture);
|
|
||||||
expect(mockPeerGroup.broadcastTransaction(capture(broadcastPayment))).andReturn(paymentFuture);
|
|
||||||
expect(mockPeerGroup.broadcastTransaction(capture(clientBroadcastMultiSig))).andReturn(clientMultiSigFuture);
|
|
||||||
expect(mockPeerGroup.broadcastTransaction(capture(broadcastRefund))).andReturn(refundFuture);
|
|
||||||
control.replay();
|
|
||||||
|
|
||||||
// Set the wallet's stored states to use our real test PeerGroup
|
// Set the wallet's stored states to use our real test PeerGroup
|
||||||
StoredPaymentChannelClientStates stateStorage = new StoredPaymentChannelClientStates(new TransactionBroadcaster() {
|
StoredPaymentChannelClientStates stateStorage = new StoredPaymentChannelClientStates(mockBroadcaster, wallet);
|
||||||
@Override
|
|
||||||
public ListenableFuture<Transaction> broadcastTransaction(Transaction tx) {
|
|
||||||
return mockPeerGroup.broadcastTransaction(tx);
|
|
||||||
}
|
|
||||||
}, wallet);
|
|
||||||
wallet.addOrUpdateExtension(stateStorage);
|
wallet.addOrUpdateExtension(stateStorage);
|
||||||
|
|
||||||
Utils.rollMockClock(0); // Use mock clock
|
Utils.rollMockClock(0); // Use mock clock
|
||||||
final long EXPIRE_TIME = Utils.now().getTime()/1000 + 60*60*24;
|
final long EXPIRE_TIME = Utils.now().getTime()/1000 + 60*60*24;
|
||||||
|
|
||||||
serverState = new PaymentChannelServerState(mockPeerGroup, serverWallet, serverKey, EXPIRE_TIME);
|
serverState = new PaymentChannelServerState(mockBroadcaster, serverWallet, serverKey, EXPIRE_TIME);
|
||||||
assertEquals(PaymentChannelServerState.State.WAITING_FOR_REFUND_TRANSACTION, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.WAITING_FOR_REFUND_TRANSACTION, serverState.getState());
|
||||||
|
|
||||||
clientState = new PaymentChannelClientState(wallet, myKey, new ECKey(null, serverKey.getPubKey()),
|
clientState = new PaymentChannelClientState(wallet, myKey, new ECKey(null, serverKey.getPubKey()),
|
||||||
@ -274,7 +263,8 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
// Provide the server with the multisig contract and simulate successful propagation/acceptance.
|
// Provide the server with the multisig contract and simulate successful propagation/acceptance.
|
||||||
serverState.provideMultiSigContract(multisigContract);
|
serverState.provideMultiSigContract(multisigContract);
|
||||||
assertEquals(PaymentChannelServerState.State.WAITING_FOR_MULTISIG_ACCEPTANCE, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.WAITING_FOR_MULTISIG_ACCEPTANCE, serverState.getState());
|
||||||
serverMultiSigFuture.set(serverBroadcastMultiSig.getValue());
|
final TxFuturePair pop = broadcasts.take();
|
||||||
|
pop.future.set(pop.tx);
|
||||||
assertEquals(PaymentChannelServerState.State.READY, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.READY, serverState.getState());
|
||||||
|
|
||||||
// Pay a tiny bit
|
// Pay a tiny bit
|
||||||
@ -285,40 +275,37 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
Utils.rollMockClock(60*60*22);
|
Utils.rollMockClock(60*60*22);
|
||||||
// ... and store server to get it to broadcast payment transaction
|
// ... and store server to get it to broadcast payment transaction
|
||||||
serverState.storeChannelInWallet(null);
|
serverState.storeChannelInWallet(null);
|
||||||
while (!broadcastPayment.hasCaptured())
|
TxFuturePair broadcastPaymentPair = broadcasts.take();
|
||||||
Thread.sleep(100);
|
|
||||||
Exception paymentException = new RuntimeException("I'm sorry, but the network really just doesn't like you");
|
Exception paymentException = new RuntimeException("I'm sorry, but the network really just doesn't like you");
|
||||||
paymentFuture.setException(paymentException);
|
broadcastPaymentPair.future.setException(paymentException);
|
||||||
try {
|
try {
|
||||||
serverState.close().get();
|
serverState.close().get();
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
assertTrue(e.getCause() == paymentException);
|
assertSame(e.getCause(), paymentException);
|
||||||
}
|
}
|
||||||
assertEquals(PaymentChannelServerState.State.ERROR, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.ERROR, serverState.getState());
|
||||||
|
|
||||||
// Now advance until client should rebroadcast
|
// Now advance until client should rebroadcast
|
||||||
Utils.rollMockClock(60*60*2 + 60*5);
|
Utils.rollMockClock(60 * 60 * 2 + 60 * 5);
|
||||||
|
|
||||||
// Now store the client state in a stored state object which handles the rebroadcasting
|
// Now store the client state in a stored state object which handles the rebroadcasting
|
||||||
clientState.storeChannelInWallet(Sha256Hash.create(new byte[] {}));
|
clientState.storeChannelInWallet(Sha256Hash.create(new byte[]{}));
|
||||||
while (!broadcastRefund.hasCaptured())
|
TxFuturePair clientBroadcastedMultiSig = broadcasts.take();
|
||||||
Thread.sleep(100);
|
TxFuturePair broadcastRefund = broadcasts.take();
|
||||||
|
assertEquals(clientBroadcastedMultiSig.tx.getHash(), multisigContract.getHash());
|
||||||
Transaction clientBroadcastedMultiSig = clientBroadcastMultiSig.getValue();
|
for (TransactionInput input : clientBroadcastedMultiSig.tx.getInputs())
|
||||||
assertTrue(clientBroadcastedMultiSig.getHash().equals(multisigContract.getHash()));
|
|
||||||
for (TransactionInput input : clientBroadcastedMultiSig.getInputs())
|
|
||||||
input.verify();
|
input.verify();
|
||||||
clientMultiSigFuture.set(clientBroadcastedMultiSig);
|
clientBroadcastedMultiSig.future.set(clientBroadcastedMultiSig.tx);
|
||||||
|
|
||||||
Transaction clientBroadcastedRefund = broadcastRefund.getValue();
|
Transaction clientBroadcastedRefund = broadcastRefund.tx;
|
||||||
assertTrue(clientBroadcastedRefund.getHash().equals(clientState.getCompletedRefundTransaction().getHash()));
|
assertEquals(clientBroadcastedRefund.getHash(), clientState.getCompletedRefundTransaction().getHash());
|
||||||
for (TransactionInput input : clientBroadcastedRefund.getInputs()) {
|
for (TransactionInput input : clientBroadcastedRefund.getInputs()) {
|
||||||
// If the multisig output is connected, the wallet will fail to deserialize
|
// If the multisig output is connected, the wallet will fail to deserialize
|
||||||
if (input.getOutpoint().getHash().equals(clientBroadcastedMultiSig.getHash()))
|
if (input.getOutpoint().getHash().equals(clientBroadcastedMultiSig.tx.getHash()))
|
||||||
assertNull(input.getConnectedOutput().getSpentBy());
|
assertNull(input.getConnectedOutput().getSpentBy());
|
||||||
input.verify(clientBroadcastedMultiSig.getOutput(0));
|
input.verify(clientBroadcastedMultiSig.tx.getOutput(0));
|
||||||
}
|
}
|
||||||
refundFuture.set(clientBroadcastedRefund);
|
broadcastRefund.future.set(clientBroadcastedRefund);
|
||||||
|
|
||||||
// Create a block with multisig contract and refund transaction in it and give it to both wallets,
|
// Create a block with multisig contract and refund transaction in it and give it to both wallets,
|
||||||
// making getBalance() include the transactions
|
// making getBalance() include the transactions
|
||||||
@ -332,28 +319,18 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
clientState.incrementPaymentBy(Utils.CENT);
|
clientState.incrementPaymentBy(Utils.CENT);
|
||||||
fail();
|
fail();
|
||||||
} catch (IllegalStateException e) { }
|
} catch (IllegalStateException e) { }
|
||||||
|
|
||||||
control.verify();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void checkBadData() throws Exception {
|
public void checkBadData() throws Exception {
|
||||||
// Check that if signatures/transactions/etc are corrupted, the protocol rejects them correctly.
|
// Check that if signatures/transactions/etc are corrupted, the protocol rejects them correctly.
|
||||||
|
|
||||||
// Set up a mock peergroup.
|
|
||||||
IMocksControl control = createStrictControl();
|
|
||||||
PeerGroup mockPeerGroup = control.createMock(PeerGroup.class);
|
|
||||||
|
|
||||||
// We'll broadcast only one tx: multisig contract
|
// We'll broadcast only one tx: multisig contract
|
||||||
SettableFuture<Transaction> multiSigFuture = SettableFuture.create();
|
|
||||||
Capture<Transaction> broadcastMultiSig = new Capture<Transaction>();
|
|
||||||
expect(mockPeerGroup.broadcastTransaction(capture(broadcastMultiSig))).andReturn(multiSigFuture);
|
|
||||||
control.replay();
|
|
||||||
|
|
||||||
Utils.rollMockClock(0); // Use mock clock
|
Utils.rollMockClock(0); // Use mock clock
|
||||||
final long EXPIRE_TIME = Utils.now().getTime()/1000 + 60*60*24;
|
final long EXPIRE_TIME = Utils.now().getTime()/1000 + 60*60*24;
|
||||||
|
|
||||||
serverState = new PaymentChannelServerState(mockPeerGroup, serverWallet, serverKey, EXPIRE_TIME);
|
serverState = new PaymentChannelServerState(mockBroadcaster, serverWallet, serverKey, EXPIRE_TIME);
|
||||||
assertEquals(PaymentChannelServerState.State.WAITING_FOR_REFUND_TRANSACTION, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.WAITING_FOR_REFUND_TRANSACTION, serverState.getState());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -473,7 +450,8 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
try { serverState.provideMultiSigContract(multisigContract); fail(); } catch (IllegalStateException e) {}
|
try { serverState.provideMultiSigContract(multisigContract); fail(); } catch (IllegalStateException e) {}
|
||||||
assertEquals(PaymentChannelServerState.State.WAITING_FOR_MULTISIG_ACCEPTANCE, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.WAITING_FOR_MULTISIG_ACCEPTANCE, serverState.getState());
|
||||||
assertFalse(multisigStateFuture.isDone());
|
assertFalse(multisigStateFuture.isDone());
|
||||||
multiSigFuture.set(broadcastMultiSig.getValue());
|
final TxFuturePair pair = broadcasts.take();
|
||||||
|
pair.future.set(pair.tx);
|
||||||
assertEquals(multisigStateFuture.get(), serverState);
|
assertEquals(multisigStateFuture.get(), serverState);
|
||||||
assertEquals(PaymentChannelServerState.State.READY, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.READY, serverState.getState());
|
||||||
|
|
||||||
@ -541,8 +519,6 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
clientState.incrementPaymentBy(halfCoin.subtract(size).add(BigInteger.ONE));
|
clientState.incrementPaymentBy(halfCoin.subtract(size).add(BigInteger.ONE));
|
||||||
fail();
|
fail();
|
||||||
} catch (ValueOutOfRangeException e) {}
|
} catch (ValueOutOfRangeException e) {}
|
||||||
|
|
||||||
control.verify();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -551,27 +527,15 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
|
|
||||||
// Spend the client wallet's one coin
|
// Spend the client wallet's one coin
|
||||||
wallet.sendCoinsOffline(Wallet.SendRequest.to(new ECKey().toAddress(params), Utils.COIN));
|
wallet.sendCoinsOffline(Wallet.SendRequest.to(new ECKey().toAddress(params), Utils.COIN));
|
||||||
assertEquals(wallet.getBalance(), BigInteger.ZERO);
|
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||||
|
|
||||||
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), createFakeTx(params, Utils.CENT, myAddress)));
|
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), createFakeTx(params, Utils.CENT, myAddress)));
|
||||||
assertEquals(wallet.getBalance(), Utils.CENT);
|
assertEquals(Utils.CENT, wallet.getBalance());
|
||||||
|
|
||||||
// Set up a mock peergroup.
|
|
||||||
IMocksControl control = createStrictControl();
|
|
||||||
PeerGroup mockPeerGroup = control.createMock(PeerGroup.class);
|
|
||||||
// We'll broadcast two txns: multisig contract and close transaction.
|
|
||||||
SettableFuture<Transaction> multiSigFuture = SettableFuture.create();
|
|
||||||
SettableFuture<Transaction> closeFuture = SettableFuture.create();
|
|
||||||
Capture<Transaction> broadcastMultiSig = new Capture<Transaction>();
|
|
||||||
Capture<Transaction> broadcastClose = new Capture<Transaction>();
|
|
||||||
expect(mockPeerGroup.broadcastTransaction(capture(broadcastMultiSig))).andReturn(multiSigFuture);
|
|
||||||
expect(mockPeerGroup.broadcastTransaction(capture(broadcastClose))).andReturn(closeFuture);
|
|
||||||
control.replay();
|
|
||||||
|
|
||||||
Utils.rollMockClock(0); // Use mock clock
|
Utils.rollMockClock(0); // Use mock clock
|
||||||
final long EXPIRE_TIME = Utils.now().getTime()/1000 + 60*60*24;
|
final long EXPIRE_TIME = Utils.now().getTime()/1000 + 60*60*24;
|
||||||
|
|
||||||
serverState = new PaymentChannelServerState(mockPeerGroup, serverWallet, serverKey, EXPIRE_TIME);
|
serverState = new PaymentChannelServerState(mockBroadcaster, serverWallet, serverKey, EXPIRE_TIME);
|
||||||
assertEquals(PaymentChannelServerState.State.WAITING_FOR_REFUND_TRANSACTION, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.WAITING_FOR_REFUND_TRANSACTION, serverState.getState());
|
||||||
|
|
||||||
// Clearly ONE is far too small to be useful
|
// Clearly ONE is far too small to be useful
|
||||||
@ -622,7 +586,8 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
// Provide the server with the multisig contract and simulate successful propagation/acceptance.
|
// Provide the server with the multisig contract and simulate successful propagation/acceptance.
|
||||||
serverState.provideMultiSigContract(multisigContract);
|
serverState.provideMultiSigContract(multisigContract);
|
||||||
assertEquals(PaymentChannelServerState.State.WAITING_FOR_MULTISIG_ACCEPTANCE, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.WAITING_FOR_MULTISIG_ACCEPTANCE, serverState.getState());
|
||||||
multiSigFuture.set(broadcastMultiSig.getValue());
|
TxFuturePair pair = broadcasts.take();
|
||||||
|
pair.future.set(pair.tx);
|
||||||
assertEquals(PaymentChannelServerState.State.READY, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.READY, serverState.getState());
|
||||||
|
|
||||||
// Both client and server are now in the ready state. Simulate a few micropayments
|
// Both client and server are now in the ready state. Simulate a few micropayments
|
||||||
@ -658,34 +623,21 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
// And close the channel.
|
// And close the channel.
|
||||||
serverState.close();
|
serverState.close();
|
||||||
assertEquals(PaymentChannelServerState.State.CLOSING, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.CLOSING, serverState.getState());
|
||||||
Transaction closeTx = broadcastClose.getValue();
|
pair = broadcasts.take(); // close
|
||||||
closeFuture.set(closeTx);
|
pair.future.set(pair.tx);
|
||||||
assertEquals(PaymentChannelServerState.State.CLOSED, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.CLOSED, serverState.getState());
|
||||||
serverState.close();
|
serverState.close();
|
||||||
assertEquals(PaymentChannelServerState.State.CLOSED, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.CLOSED, serverState.getState());
|
||||||
control.verify();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void serverAddsFeeTest() throws Exception {
|
public void serverAddsFeeTest() throws Exception {
|
||||||
// Test that the server properly adds the necessary fee at the end (or just drops the payment if its not worth it)
|
// Test that the server properly adds the necessary fee at the end (or just drops the payment if its not worth it)
|
||||||
|
|
||||||
// Set up a mock peergroup.
|
|
||||||
IMocksControl control = createStrictControl();
|
|
||||||
PeerGroup mockPeerGroup = control.createMock(PeerGroup.class);
|
|
||||||
// We'll broadcast two txns: multisig contract and close transaction.
|
|
||||||
SettableFuture<Transaction> multiSigFuture = SettableFuture.create();
|
|
||||||
SettableFuture<Transaction> closeFuture = SettableFuture.create();
|
|
||||||
Capture<Transaction> broadcastMultiSig = new Capture<Transaction>();
|
|
||||||
Capture<Transaction> broadcastClose = new Capture<Transaction>();
|
|
||||||
expect(mockPeerGroup.broadcastTransaction(capture(broadcastMultiSig))).andReturn(multiSigFuture);
|
|
||||||
expect(mockPeerGroup.broadcastTransaction(capture(broadcastClose))).andReturn(closeFuture);
|
|
||||||
control.replay();
|
|
||||||
|
|
||||||
Utils.rollMockClock(0); // Use mock clock
|
Utils.rollMockClock(0); // Use mock clock
|
||||||
final long EXPIRE_TIME = Utils.now().getTime()/1000 + 60*60*24;
|
final long EXPIRE_TIME = Utils.now().getTime()/1000 + 60*60*24;
|
||||||
|
|
||||||
serverState = new PaymentChannelServerState(mockPeerGroup, serverWallet, serverKey, EXPIRE_TIME);
|
serverState = new PaymentChannelServerState(mockBroadcaster, serverWallet, serverKey, EXPIRE_TIME);
|
||||||
assertEquals(PaymentChannelServerState.State.WAITING_FOR_REFUND_TRANSACTION, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.WAITING_FOR_REFUND_TRANSACTION, serverState.getState());
|
||||||
|
|
||||||
clientState = new PaymentChannelClientState(wallet, myKey, new ECKey(null, serverKey.getPubKey()), Utils.CENT, EXPIRE_TIME);
|
clientState = new PaymentChannelClientState(wallet, myKey, new ECKey(null, serverKey.getPubKey()), Utils.CENT, EXPIRE_TIME);
|
||||||
@ -714,7 +666,8 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
// Provide the server with the multisig contract and simulate successful propagation/acceptance.
|
// Provide the server with the multisig contract and simulate successful propagation/acceptance.
|
||||||
serverState.provideMultiSigContract(multisigContract);
|
serverState.provideMultiSigContract(multisigContract);
|
||||||
assertEquals(PaymentChannelServerState.State.WAITING_FOR_MULTISIG_ACCEPTANCE, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.WAITING_FOR_MULTISIG_ACCEPTANCE, serverState.getState());
|
||||||
multiSigFuture.set(broadcastMultiSig.getValue());
|
TxFuturePair pair = broadcasts.take();
|
||||||
|
pair.future.set(pair.tx);
|
||||||
assertEquals(PaymentChannelServerState.State.READY, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.READY, serverState.getState());
|
||||||
|
|
||||||
// Both client and server are now in the ready state, split the channel in half
|
// Both client and server are now in the ready state, split the channel in half
|
||||||
@ -750,9 +703,8 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
// And close the channel.
|
// And close the channel.
|
||||||
serverState.close();
|
serverState.close();
|
||||||
assertEquals(PaymentChannelServerState.State.CLOSING, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.CLOSING, serverState.getState());
|
||||||
Transaction closeTx = broadcastClose.getValue();
|
pair = broadcasts.take();
|
||||||
closeFuture.set(closeTx);
|
pair.future.set(pair.tx);
|
||||||
assertEquals(PaymentChannelServerState.State.CLOSED, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.CLOSED, serverState.getState());
|
||||||
control.verify();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user