private CommitmentTransactionParameters CreateRemoteCommitmentTxParameters(OpenChannelMessage openMessage, AcceptChannelMessage acceptMessage) { PublicKeyDerivation publicKeyDerivation = new PublicKeyDerivation(acceptMessage.FirstPerCommitmentPoint); RevocationPublicKeyDerivation revocationPublicKeyDerivation = new RevocationPublicKeyDerivation(acceptMessage.FirstPerCommitmentPoint); PublicKeyDerivation remotePublicKeyDerivation = new PublicKeyDerivation(openMessage.FirstPerCommitmentPoint); CommitmentTransactionParameters parameters = new CommitmentTransactionParameters { TransactionNumber = 0, HtlcBasepoint = acceptMessage.HtlcBasepoint, HtlcPublicKey = remotePublicKeyDerivation.Derive(acceptMessage.HtlcBasepoint), PaymentBasepoint = acceptMessage.PaymentBasepoint, PaymentPublicKey = remotePublicKeyDerivation.Derive(acceptMessage.PaymentBasepoint), DelayedPaymentBasepoint = acceptMessage.DelayedPaymentBasepoint, DelayedPaymentPublicKey = publicKeyDerivation.Derive(acceptMessage.DelayedPaymentBasepoint), RevocationBasepoint = acceptMessage.RevocationBasepoint, RevocationPublicKey = revocationPublicKeyDerivation.DerivePublicKey(openMessage.RevocationBasepoint), PerCommitmentKey = acceptMessage.FirstPerCommitmentPoint, FundingKey = acceptMessage.FundingPubKey, ToRemoteMsat = openMessage.FundingSatoshis * 1000 - openMessage.PushMSat, ToLocalMsat = openMessage.PushMSat }; return(parameters); }
public PendingChannel(IPeer peer, OpenChannelMessage openMessage, ECKeyPair revocationKey, uint channelIndex) { Peer = peer; OpenMessage = openMessage; RevocationKey = revocationKey; ChannelIndex = channelIndex; TemporaryChannelId = openMessage.TemporaryChannelId.ToHex(); }
public static ChannelParameters CreateFromOpenMessage(OpenChannelMessage openMessage) { ChannelParameters channelParameters = new ChannelParameters(); channelParameters.DustLimitSatoshis = openMessage.DustLimitSatoshis; channelParameters.MaxHtlcValueInFlightMSat = openMessage.MaxHtlcValueInFlightMSat; channelParameters.ChannelReserveSatoshis = openMessage.ChannelReserveSatoshis; channelParameters.ToSelfDelay = openMessage.ToSelfDelay; channelParameters.HtlcMinimumMSat = openMessage.HtlcMinimumMSat; channelParameters.MaxAcceptedHtlcs = openMessage.MaxAcceptedHtlcs; channelParameters.ShutdownScriptPubKey = openMessage.ShutdownScriptPubKey; return(channelParameters); }
public void HandleInvalidRemoteSignatureTest() { var mocks = new ChannelEstablishmentMocks(); var revocationKey = new ECKeyPair("DD06232AE9A50384A72D85CED6351DCB35C798231D4985615C77D6847F83FC65", true); var handler = new FundingMessageSignedHandler(mocks.ChannelLoggingService.Object, mocks.FundingService.Object, mocks.CommTxService.Object, mocks.ChannelService.Object, mocks.BlockchainMonitorService.Object); OpenChannelMessage openChannelMessage = new OpenChannelMessage() { ChainHash = NetworkParameters.BitcoinTestnet.ChainHash, TemporaryChannelId = "43497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea3309000000".HexToByteArray(), FundingSatoshis = 420000, PushMSat = 1000, DustLimitSatoshis = 500, MaxHtlcValueInFlightMSat = 50000, ChannelReserveSatoshis = 5000, HtlcMinimumMSat = 1100, FeeratePerKw = 150, ToSelfDelay = 133, MaxAcceptedHtlcs = 156, FundingPubKey = new ECKeyPair("0250d049da6b5832a9f2416df3b0db52da127426c2b70a35ca9c270a72f3f840b5", false), RevocationBasepoint = new ECKeyPair("022ecc432552ff86d053514ffb133d3025fb14c39aa5ae2a5169b0367174cabfa4", false), PaymentBasepoint = new ECKeyPair("029d100efe40aa3f58985fa12bd0f5c75711449ff4d30adca6f1968a2200bbbf1a", false), DelayedPaymentBasepoint = new ECKeyPair("0250d049da6b5832a9f2416df3b0db52da127426c2b70a35ca9c270a72f3f840b5", false), HtlcBasepoint = new ECKeyPair("03d029229db8f594adcd545b4a42acbb1013286908d2905fa05c9a4e2083fe3fe2", false), FirstPerCommitmentPoint = new ECKeyPair("02846726efa57378ad8370acf094f26902a7f1e21903791ef4ab6f989da86679f2", false), ChannelFlags = 1 }; var signature = "2f26e967305b4d422116a7c876d338bc4298263f329a54c0d1655f55d594de4955356386addd0bc15ced36dacece0af439694195654c838769583409eeac5d3f".HexToByteArray(); FundingSignedMessage fundingSignedMessage = new FundingSignedMessage() { ChannelId = "43497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea3309000000".HexToByteArray(), Signature = signature }; PendingChannel pendingChannel = new PendingChannel(mocks.Peer.Object, openChannelMessage, revocationKey, 0); pendingChannel.Channel = mocks.CreateChannelMock(); pendingChannel.Channel.LocalCommitmentTxParameters = new CommitmentTransactionParameters(); mocks.CommTxService.Setup(c => c.IsValidRemoteCommitmentSignature(pendingChannel.Channel, It.IsAny <TransactionSignature>())).Returns(false); mocks.Peer.Setup(m => m.Messaging).Returns(new Mock <IMessagingClient>().Object); Assert.Throws <ChannelException>(() => handler.Handle(mocks.Peer.Object, fundingSignedMessage, pendingChannel)); }
private LocalChannel CreateChannel(uint index, FundingTransaction fundingTx, OpenChannelMessage openMessage, AcceptChannelMessage acceptMessage) { LocalChannel channel = new LocalChannel(); channel.ChannelIndex = index; channel.TemporaryChannelId = openMessage.TemporaryChannelId.ToHex(); channel.LocalChannelParameters = ChannelParameters.CreateFromOpenMessage(openMessage); channel.RemoteChannelParameters = ChannelParameters.CreateFromAcceptMessage(acceptMessage); channel.FundingSatoshis = openMessage.FundingSatoshis; channel.PushMSat = openMessage.PushMSat; channel.MinimumDepth = acceptMessage.MinimumDepth; channel.FundingTransactionId = fundingTx.Transaction.GetHash().ToString(); channel.FundingOutputIndex = fundingTx.FundingOutputIndex; channel.ChannelId = LocalChannel.DeriveChannelId(fundingTx.Transaction, fundingTx.FundingOutputIndex); channel.FeeRatePerKw = openMessage.FeeratePerKw; return(channel); }
public OpenChannelAckMessage AckOpenChannel(OpenChannelMessage openMsg, Key payeeKey) { if(payeeKey.PubKey != Arguments.Payee.PaymentPubKey) throw new ArgumentException("Invalid payeeKey", "payeeKey"); Arguments.Assert(openMsg.UnsignedRefund, true, Arguments.Fees); var fundCoin = new Coin(openMsg.UnsignedRefund.Inputs[0].PrevOut, new TxOut(Arguments.Amount + Arguments.Fees, Arguments.Redeem.Hash)).ToScriptCoin(Arguments.Redeem); var signed = new TransactionBuilder() .AddCoins(fundCoin) .AddKeys(payeeKey) .SignTransaction(openMsg.UnsignedRefund); Refund = signed; return new OpenChannelAckMessage() { SignedRefund = signed }; }
private bool VerifyOpenMessage(OpenChannelMessage message) { Assert.Equal(0, message.ChannelFlags); Assert.Equal((ulong)42000, message.FundingSatoshis); Assert.Equal((ulong)4200, message.ChannelReserveSatoshis); Assert.Equal((ulong)546, message.DustLimitSatoshis); Assert.Equal((ulong)253, message.FeeratePerKw); Assert.Equal((ulong)483, message.MaxAcceptedHtlcs); Assert.Equal((ulong)100, message.PushMSat); Assert.Equal((ulong)144, message.ToSelfDelay); Assert.Equal((ulong)1000, message.HtlcMinimumMSat); Assert.Equal((ulong)5000000000, message.MaxHtlcValueInFlightMSat); Assert.Equal("43497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea330900000000".HexToByteArray(), message.ChainHash); Assert.Equal("029d100efe40aa3f58985fa12bd0f5c75711449ff4d30adca6f1968a2200bbbf1a", message.HtlcBasepoint.PublicKeyCompressed.ToHex()); Assert.Equal("022b2aa486f5a8aca1898824ac3b2a8a15c92de813362846b992f94d923b143f92", message.PaymentBasepoint.PublicKeyCompressed.ToHex()); Assert.Equal("02d91224d91760f477df21d24713b713c681b084e508f48dc77ca14db549ba8ceb", message.RevocationBasepoint.PublicKeyCompressed.ToHex()); Assert.Equal("0250d049da6b5832a9f2416df3b0db52da127426c2b70a35ca9c270a72f3f840b5", message.DelayedPaymentBasepoint.PublicKeyCompressed.ToHex()); Assert.Equal("0245b02f6672c2342fe3ced57118fcf4a0309327e32c335ce494365eb0d15b7200", message.FundingPubKey.PublicKeyCompressed.ToHex()); Assert.Equal("022b2aa486f5a8aca1898824ac3b2a8a15c92de813362846b992f94d923b143f92", message.FirstPerCommitmentPoint.PublicKeyCompressed.ToHex()); Assert.Equal("76a914f75d1c854c52abee075916b41cf0ca76fa515b4c88ac", message.ShutdownScriptPubKey.ToHex()); return(true); }
public void CreateInitialCommitmentTransactions(OpenChannelMessage openMessage, AcceptChannelMessage acceptMessage, LocalChannel channel, ECKeyPair revocationKey) { channel.LocalCommitmentTxParameters = CreateLocalCommitmentTxParameters(openMessage, acceptMessage, revocationKey); channel.RemoteCommitmentTxParameters = CreateRemoteCommitmentTxParameters(openMessage, acceptMessage); SignRemoteCommitmentTx(channel); }
public void HandleTest() { var mocks = new ChannelEstablishmentMocks(); var revocationKey = new ECKeyPair("DD06232AE9A50384A72D85CED6351DCB35C798231D4985615C77D6847F83FC65", true); var handler = new AcceptChannelMessageHandler(mocks.ChannelLoggingService.Object, mocks.FundingService.Object, mocks.CommTxService.Object); var localSig = "3045022100a5c01383d3ec646d97e40f44318d49def817fcd61a0ef18008a665b3e151785502203e648efddd5838981ef55ec954be69c4a652d021e6081a100d034de366815e9b".HexToByteArray(); OpenChannelMessage openChannelMessage = new OpenChannelMessage() { ChainHash = NetworkParameters.BitcoinTestnet.ChainHash, TemporaryChannelId = "43497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea3309000000".HexToByteArray(), FundingSatoshis = 420000, PushMSat = 1000, DustLimitSatoshis = 500, MaxHtlcValueInFlightMSat = 50000, ChannelReserveSatoshis = 5000, HtlcMinimumMSat = 1100, FeeratePerKw = 150, ToSelfDelay = 133, MaxAcceptedHtlcs = 156, FundingPubKey = new ECKeyPair("0245b02f6672c2342fe3ced57118fcf4a0309327e32c335ce494365eb0d15b7200", false), RevocationBasepoint = new ECKeyPair("02d91224d91760f477df21d24713b713c681b084e508f48dc77ca14db549ba8ceb", false), PaymentBasepoint = new ECKeyPair("022b2aa486f5a8aca1898824ac3b2a8a15c92de813362846b992f94d923b143f92", false), DelayedPaymentBasepoint = new ECKeyPair("0250d049da6b5832a9f2416df3b0db52da127426c2b70a35ca9c270a72f3f840b5", false), HtlcBasepoint = new ECKeyPair("029d100efe40aa3f58985fa12bd0f5c75711449ff4d30adca6f1968a2200bbbf1a", false), FirstPerCommitmentPoint = new ECKeyPair("022b2aa486f5a8aca1898824ac3b2a8a15c92de813362846b992f94d923b143f92", false), ChannelFlags = 1 }; AcceptChannelMessage acceptChannelMessage = new AcceptChannelMessage() { TemporaryChannelId = "43497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea3309000000".HexToByteArray(), DustLimitSatoshis = 500, MaxHtlcValueInFlightMSat = 50000, ChannelReserveSatoshis = 5000, HtlcMinimumMSat = 1100, ToSelfDelay = 133, MaxAcceptedHtlcs = 156, FundingPubKey = new ECKeyPair("0299de4bbf495e5bbeb2456c2beb3f40450a3fa41aaa50819ae201f8ad69226bfe", false), RevocationBasepoint = new ECKeyPair("022b2aa486f5a8aca1898824ac3b2a8a15c92de813362846b992f94d923b143f92", false), PaymentBasepoint = new ECKeyPair("02d91224d91760f477df21d24713b713c681b084e508f48dc77ca14db549ba8ceb", false), DelayedPaymentBasepoint = new ECKeyPair("0341665cedb568e09f0ab2ab4a28bc2749620deacefb3dce61aac8251c91709d3a", false), HtlcBasepoint = new ECKeyPair("0336439e36e2bc1f264c6d3bc6e12db6256389bef2056c32e6267d6e285c2b2122", false), FirstPerCommitmentPoint = new ECKeyPair("039360132ab07e7f56d6782a644233da9c4c24845609fcd302cbedd69f69848358", false) }; PendingChannel pendingChannel = new PendingChannel(mocks.Peer.Object, openChannelMessage, revocationKey, 0); FundingTransaction fundingTransactionMock = mocks.CreateFundingTxMock(openChannelMessage.FundingPubKey, acceptChannelMessage.FundingPubKey); mocks.FundingService.Setup(f => f.CreateFundingTransaction(openChannelMessage.FundingSatoshis, openChannelMessage.FeeratePerKw, openChannelMessage.FundingPubKey, acceptChannelMessage.FundingPubKey)) .Returns(fundingTransactionMock); mocks.CommTxService.Setup(f => f.CreateInitialCommitmentTransactions(openChannelMessage, acceptChannelMessage, It.IsAny <LocalChannel>(), revocationKey)) .Callback <OpenChannelMessage, AcceptChannelMessage, LocalChannel, ECKeyPair>((openMessage, acceptMessage, channel, rkey) => { channel.RemoteCommitmentTxParameters = new CommitmentTransactionParameters(); channel.RemoteCommitmentTxParameters.LocalSignature = new TransactionSignature(localSig, SigHash.All); }); FundingCreatedMessage fundingCreatedMessage = handler.Handle(acceptChannelMessage, pendingChannel); Assert.Equal("15fadebd5a68d2d9f216a2dc5531c4dbc977eac0c42ab97899e21d549dddbefa", fundingCreatedMessage.FundingTransactionId.ToHex()); Assert.Equal(new TransactionSignature(localSig, SigHash.All).ToRawSignature().ToHex(), fundingCreatedMessage.Signature.ToHex()); Assert.Equal(0, fundingCreatedMessage.FundingOutputIndex); Assert.Equal("43497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea3309000000", fundingCreatedMessage.TemporaryChannelId.ToHex()); }
public void HandleTest() { var mocks = new ChannelEstablishmentMocks(); var revocationKey = new ECKeyPair("DD06232AE9A50384A72D85CED6351DCB35C798231D4985615C77D6847F83FC65", true); var handler = new FundingMessageSignedHandler(mocks.ChannelLoggingService.Object, mocks.FundingService.Object, mocks.CommTxService.Object, mocks.ChannelService.Object, mocks.BlockchainMonitorService.Object); OpenChannelMessage openChannelMessage = new OpenChannelMessage() { ChainHash = NetworkParameters.BitcoinTestnet.ChainHash, TemporaryChannelId = "43497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea3309000000".HexToByteArray(), FundingSatoshis = 420000, PushMSat = 1000, DustLimitSatoshis = 500, MaxHtlcValueInFlightMSat = 50000, ChannelReserveSatoshis = 5000, HtlcMinimumMSat = 1100, FeeratePerKw = 150, ToSelfDelay = 133, MaxAcceptedHtlcs = 156, FundingPubKey = new ECKeyPair("0250d049da6b5832a9f2416df3b0db52da127426c2b70a35ca9c270a72f3f840b5", false), RevocationBasepoint = new ECKeyPair("022ecc432552ff86d053514ffb133d3025fb14c39aa5ae2a5169b0367174cabfa4", false), PaymentBasepoint = new ECKeyPair("029d100efe40aa3f58985fa12bd0f5c75711449ff4d30adca6f1968a2200bbbf1a", false), DelayedPaymentBasepoint = new ECKeyPair("0250d049da6b5832a9f2416df3b0db52da127426c2b70a35ca9c270a72f3f840b5", false), HtlcBasepoint = new ECKeyPair("03d029229db8f594adcd545b4a42acbb1013286908d2905fa05c9a4e2083fe3fe2", false), FirstPerCommitmentPoint = new ECKeyPair("02846726efa57378ad8370acf094f26902a7f1e21903791ef4ab6f989da86679f2", false), ChannelFlags = 1 }; // AcceptChannelMessage acceptChannelMessage = new AcceptChannelMessage() // { // TemporaryChannelId = "43497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea3309000000".HexToByteArray(), // DustLimitSatoshis = 500, // MaxHtlcValueInFlightMSat = 50000, // ChannelReserveSatoshis = 5000, // HtlcMinimumMSat = 1100, // ToSelfDelay = 133, // MaxAcceptedHtlcs = 156, // FundingPubKey = new ECKeyPair("0299de4bbf495e5bbeb2456c2beb3f40450a3fa41aaa50819ae201f8ad69226bfe", false), // RevocationBasepoint = new ECKeyPair("022b2aa486f5a8aca1898824ac3b2a8a15c92de813362846b992f94d923b143f92", false), // PaymentBasepoint = new ECKeyPair("02d91224d91760f477df21d24713b713c681b084e508f48dc77ca14db549ba8ceb", false), // DelayedPaymentBasepoint = new ECKeyPair("0341665cedb568e09f0ab2ab4a28bc2749620deacefb3dce61aac8251c91709d3a", false), // HtlcBasepoint = new ECKeyPair("0336439e36e2bc1f264c6d3bc6e12db6256389bef2056c32e6267d6e285c2b2122", false), // FirstPerCommitmentPoint = new ECKeyPair("039360132ab07e7f56d6782a644233da9c4c24845609fcd302cbedd69f69848358", false) // }; var signature = "2f26e967305b4d422116a7c876d338bc4298263f329a54c0d1655f55d594de4955356386addd0bc15ced36dacece0af439694195654c838769583409eeac5d3f".HexToByteArray(); FundingSignedMessage fundingSignedMessage = new FundingSignedMessage() { ChannelId = "43497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea3309000000".HexToByteArray(), Signature = signature }; PendingChannel pendingChannel = new PendingChannel(mocks.Peer.Object, openChannelMessage, revocationKey, 0); pendingChannel.Channel = mocks.CreateChannelMock(); pendingChannel.Channel.LocalCommitmentTxParameters = new CommitmentTransactionParameters(); pendingChannel.Channel.FundingTransactionId = "txId"; mocks.CommTxService.Setup(c => c.IsValidRemoteCommitmentSignature(pendingChannel.Channel, It.IsAny <TransactionSignature>())).Returns(true); handler.Handle(mocks.Peer.Object, fundingSignedMessage, pendingChannel); Assert.Equal(LocalChannelState.FundingSigned, pendingChannel.Channel.State); Assert.Equal(signature, pendingChannel.Channel.LocalCommitmentTxParameters.RemoteSignature.ToRawSignature()); mocks.FundingService.Verify(f => f.BroadcastFundingTransaction(pendingChannel.Channel), Times.Once); mocks.BlockchainMonitorService.Verify(m => m.WatchForTransactionId(pendingChannel.Channel.FundingTransactionId, 3), Times.Once); mocks.ChannelService.Verify(c => c.RemovePendingChannel(pendingChannel), Times.Once); }