mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-07 14:54:15 +00:00
Payment channels: Fix a dumb bug that caused the negotiated channel size to be wrong. Add a test.
This commit is contained in:
parent
c04708dd1e
commit
7d75e747e0
@ -1,9 +1,7 @@
|
|||||||
package com.google.bitcoin.protocols.channels;
|
package com.google.bitcoin.protocols.channels;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
|
||||||
|
|
||||||
import com.google.bitcoin.core.*;
|
import com.google.bitcoin.core.*;
|
||||||
|
import com.google.bitcoin.protocols.channels.PaymentChannelCloseException.CloseReason;
|
||||||
import com.google.bitcoin.utils.Threading;
|
import com.google.bitcoin.utils.Threading;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.protobuf.ByteString;
|
import com.google.protobuf.ByteString;
|
||||||
@ -11,7 +9,9 @@ import net.jcip.annotations.GuardedBy;
|
|||||||
import org.bitcoin.paymentchannel.Protos;
|
import org.bitcoin.paymentchannel.Protos;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.google.bitcoin.protocols.channels.PaymentChannelCloseException.CloseReason;
|
import java.math.BigInteger;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
|
||||||
@ -138,13 +138,12 @@ public class PaymentChannelClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GuardedBy("lock")
|
@GuardedBy("lock")
|
||||||
private void receiveInitiate(Protos.Initiate initiate, BigInteger minChannelSize) throws VerificationException, ValueOutOfRangeException {
|
private void receiveInitiate(Protos.Initiate initiate, BigInteger contractValue) throws VerificationException, ValueOutOfRangeException {
|
||||||
log.info("Got INITIATE message, providing refund transaction");
|
log.info("Got INITIATE message, providing refund transaction");
|
||||||
|
|
||||||
state = new PaymentChannelClientState(wallet, myKey,
|
state = new PaymentChannelClientState(wallet, myKey,
|
||||||
new ECKey(null, initiate.getMultisigKey().toByteArray()),
|
new ECKey(null, initiate.getMultisigKey().toByteArray()),
|
||||||
minChannelSize,
|
contractValue, initiate.getExpireTimeSecs());
|
||||||
initiate.getExpireTimeSecs());
|
|
||||||
state.initiate();
|
state.initiate();
|
||||||
step = InitStep.WAITING_FOR_REFUND_RETURN;
|
step = InitStep.WAITING_FOR_REFUND_RETURN;
|
||||||
|
|
||||||
@ -232,14 +231,14 @@ public class PaymentChannelClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BigInteger minChannelSize = BigInteger.valueOf(initiate.getMinAcceptedChannelSize());
|
BigInteger minChannelSize = BigInteger.valueOf(initiate.getMinAcceptedChannelSize());
|
||||||
if (minChannelSize.compareTo(maxValue) > 0) {
|
if (maxValue.compareTo(minChannelSize) < 0) {
|
||||||
errorBuilder = Protos.Error.newBuilder()
|
errorBuilder = Protos.Error.newBuilder()
|
||||||
.setCode(Protos.Error.ErrorCode.CHANNEL_VALUE_TOO_LARGE);
|
.setCode(Protos.Error.ErrorCode.CHANNEL_VALUE_TOO_LARGE);
|
||||||
closeReason = CloseReason.SERVER_REQUESTED_TOO_MUCH_VALUE;
|
closeReason = CloseReason.SERVER_REQUESTED_TOO_MUCH_VALUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
receiveInitiate(initiate, minChannelSize);
|
receiveInitiate(initiate, maxValue);
|
||||||
return;
|
return;
|
||||||
case RETURN_REFUND:
|
case RETURN_REFUND:
|
||||||
receiveRefund(msg);
|
receiveRefund(msg);
|
||||||
|
@ -473,7 +473,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testClientValueTooLarge() throws Exception {
|
public void testValuesAreRespected() throws Exception {
|
||||||
ChannelTestUtils.RecordingPair pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
|
ChannelTestUtils.RecordingPair pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
|
||||||
PaymentChannelServer server = pair.server;
|
PaymentChannelServer server = pair.server;
|
||||||
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, Utils.COIN, Sha256Hash.ZERO_HASH, pair.clientRecorder);
|
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, Utils.COIN, Sha256Hash.ZERO_HASH, pair.clientRecorder);
|
||||||
@ -493,6 +493,27 @@ public class ChannelConnectionTest extends TestWithWallet {
|
|||||||
client.incrementPayment(BigInteger.ONE);
|
client.incrementPayment(BigInteger.ONE);
|
||||||
fail();
|
fail();
|
||||||
} catch (IllegalStateException e) { }
|
} catch (IllegalStateException e) { }
|
||||||
|
|
||||||
|
// Now check that if the server has a lower min size than what we are willing to spend, we do actually open
|
||||||
|
// a channel of that size.
|
||||||
|
sendMoneyToWallet(Utils.COIN.multiply(BigInteger.TEN), AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||||
|
|
||||||
|
pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
|
||||||
|
server = pair.server;
|
||||||
|
final BigInteger myValue = Utils.COIN.multiply(BigInteger.TEN);
|
||||||
|
client = new PaymentChannelClient(wallet, myKey, myValue, Sha256Hash.ZERO_HASH, pair.clientRecorder);
|
||||||
|
client.connectionOpen();
|
||||||
|
server.connectionOpen();
|
||||||
|
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION));
|
||||||
|
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION));
|
||||||
|
client.receiveMessage(Protos.TwoWayChannelMessage.newBuilder()
|
||||||
|
.setInitiate(Protos.Initiate.newBuilder().setExpireTimeSecs(Utils.now().getTime() / 1000)
|
||||||
|
.setMinAcceptedChannelSize(Utils.COIN.add(BigInteger.ONE).longValue())
|
||||||
|
.setMultisigKey(ByteString.copyFrom(new ECKey().getPubKey())))
|
||||||
|
.setType(MessageType.INITIATE).build());
|
||||||
|
final Protos.TwoWayChannelMessage provideRefund = pair.clientRecorder.checkNextMsg(MessageType.PROVIDE_REFUND);
|
||||||
|
Transaction refund = new Transaction(params, provideRefund.getProvideRefund().getTx().toByteArray());
|
||||||
|
assertEquals(myValue, refund.getOutput(0).getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
Loading…
x
Reference in New Issue
Block a user