Ejemplo n.º 1
0
        public void ScriptSignTest()
        {
            ExtPrivkey  privkey   = new ExtPrivkey("xprv9zt1onyw8BdEf7SQ6wUVH3bQQdGD9iy9QzXveQQRhX7i5iUN7jZgLbqFEe491LfjozztYa6bJAGZ65GmDCNcbjMdjZcgmdisPJwVjcfcDhV");
            Transaction tx        = new Transaction("020000000201000000000000000000000000000000000000000000000000000000000000000200000000ffffffff01000000000000000000000000000000000000000000000000000000000000000300000000ffffffff0310270000000000001600148b756cbd98f4f55e985f80437a619d47f0732a941027000000000000160014c0a3dd0b7c1b3281be91112e16ce931dbac2a97950c3000000000000160014ad3abd3c325e40e20d89aa054dd980b97494f16c00000000");
            OutPoint    outpoint2 = new OutPoint("0000000000000000000000000000000000000000000000000000000000000001", 3);
            long        amount    = 25000;

            Privkey privkey21      = privkey.DerivePrivkey(21).GetPrivkey();
            Privkey privkey22      = privkey.DerivePrivkey(22).GetPrivkey();
            Privkey privkey23      = privkey.DerivePrivkey(23).GetPrivkey();
            Pubkey  pubkey21       = privkey21.GetPubkey();
            Pubkey  pubkey22       = privkey22.GetPubkey();
            Pubkey  pubkey23       = privkey23.GetPubkey();
            Script  multisigScript = Script.CreateMultisigScript(2, new[] {
                pubkey21, pubkey22, pubkey23,
            });
            SignatureHashType sighashType = new SignatureHashType(CfdSighashType.All, false);
            ByteData          sighash     = tx.GetSignatureHash(outpoint2, CfdHashType.P2shP2wsh, multisigScript, amount, sighashType);
            SignParameter     sig22       = privkey22.CalculateEcSignature(sighash);
            SignParameter     sig23       = privkey23.CalculateEcSignature(sighash);

            sig22.SetDerEncode(sighashType);
            sig22.SetRelatedPubkey(pubkey22);
            sig23.SetDerEncode(sighashType);
            sig23.SetRelatedPubkey(pubkey23);
            tx.AddScriptSign(outpoint2, CfdHashType.P2shP2wsh, new[] { new SignParameter(), sig22, sig23 }, multisigScript);
            output.WriteLine("tx:\n" + tx.ToHexString());
            Assert.Equal("0200000000010201000000000000000000000000000000000000000000000000000000000000000200000000ffffffff0100000000000000000000000000000000000000000000000000000000000000030000002322002064a0e02e723ce71d8f18441a39bedd5cefc9c5411c3045614c34bba1a8fbd94fffffffff0310270000000000001600148b756cbd98f4f55e985f80437a619d47f0732a941027000000000000160014c0a3dd0b7c1b3281be91112e16ce931dbac2a97950c3000000000000160014ad3abd3c325e40e20d89aa054dd980b97494f16c0004004730440220749cbe5080a3ce49c2a89f897be537b2b5449b75c64b57030dea1859b22c183f02200573f5be5170bfe4ca617edec0eb021638dd78b90209bbd8eede8a9e8138a32c01473044022019105df75884ff34111282f32c22986db295596983a87bf0df1d16905b4f9a50022075f8a2c8e3335a4265265b428df185fb045d9614ed1b08929bfa9f3f9d294a72016952210334bd4f1bab7f3e6f6bfc4a4aeaa890b858a9a146c6bd6bc5a3fbc00a12524ca72103ff743075c59596729d74b79694ca99b2c57bed6a77a06871b123b6e0d729823021036759d0dc7623e781de940a9bc9162f69c6ad68cc5be1c748e960ae4613e658e053ae00000000",
                         tx.ToHexString());
        }
Ejemplo n.º 2
0
        public void AdaptorUtilTest()
        {
            var msg          = new ByteData("024bdd11f2144e825db05759bdd9041367a420fad14b665fd08af5b42056e5e2");
            var adaptor      = new Pubkey("038d48057fc4ce150482114d43201b333bf3706f3cd527e8767ceb4b443ab5d349");
            var sk           = new Privkey("90ac0d5dc0a1a9ab352afb02005a5cc6c4df0da61d8149d729ff50db9b5a5215");
            var pubkey       = new Pubkey("03490cec9a53cd8f2f664aea61922f26ee920c42d2489778bb7c9d9ece44d149a7");
            var adaptorSig   = new ByteData("00cbe0859638c3600ea1872ed7a55b8182a251969f59d7d2da6bd4afedf25f5021a49956234cbbbbede8ca72e0113319c84921bf1224897a6abd89dc96b9c5b208");
            var adaptorProof = new ByteData("00b02472be1ba09f5675488e841a10878b38c798ca63eff3650c8e311e3e2ebe2e3b6fee5654580a91cc5149a71bf25bcbeae63dea3ac5ad157a0ab7373c3011d0fc2592a07f719c5fc1323f935569ecd010db62f045e965cc1d564eb42cce8d6d");
            var adaptorSig2  = new ByteData("01099c91aa1fe7f25c41085c1d3c9e73fe04a9d24dac3f9c2172d6198628e57f47bb90e2ad6630900b69f55674c8ad74a419e6ce113c10a21a79345a6e47bc74c1");
            // var sigDer = new ByteData("30440220099c91aa1fe7f25c41085c1d3c9e73fe04a9d24dac3f9c2172d6198628e57f4702204d13456e98d8989043fd4674302ce90c432e2f8bb0269f02c72aafec60b72de101");
            var sig    = new ByteData("099c91aa1fe7f25c41085c1d3c9e73fe04a9d24dac3f9c2172d6198628e57f474d13456e98d8989043fd4674302ce90c432e2f8bb0269f02c72aafec60b72de1");
            var secret = new Privkey("475697a71a74ff3f2a8f150534e9b67d4b0b6561fab86fcaa51f8c9d6c9db8c6");

            var pair = EcdsaAdaptorUtil.Sign(msg, sk, adaptor);

            Assert.Equal(adaptorSig.ToHexString(), pair.Signature.ToHexString());
            Assert.Equal(adaptorProof.ToHexString(), pair.Proof.ToHexString());

            var isVerify = EcdsaAdaptorUtil.Verify(pair.Signature, pair.Proof, adaptor, msg, pubkey);

            Assert.True(isVerify);

            var adaptSig = EcdsaAdaptorUtil.Adapt(adaptorSig2, secret);

            Assert.Equal(sig.ToHexString(), adaptSig.ToHexString());

            var adaptorSecret = EcdsaAdaptorUtil.ExtractSecret(adaptorSig2, adaptSig, adaptor);

            Assert.Equal(secret.ToHexString(), adaptorSecret.ToHexString());
        }
Ejemplo n.º 3
0
 private static void NewPubkey(Pubkey pubkey)
 {
     Console.WriteLine("Pubkey " + pubkey);
     if (pubkey.Name == "BM-2DAV89w336ovy6BUJnfVRD5B9qipFbRgmr")
     {
         Bitmessage.AddSubscription(pubkey);
     }
 }
Ejemplo n.º 4
0
 public void OnReceiveInvalidPubkey(Pubkey pubkey)
 {
     Pubkey.EventHandler handler = ReceiveInvalidPubkey;
     if (handler != null)
     {
         handler(pubkey);
     }
 }
Ejemplo n.º 5
0
    public void CombineTest()
    {
      Pubkey[] list = new Pubkey[2];
      list[0] = new Pubkey("03662a01c232918c9deb3b330272483c3e4ec0c6b5da86df59252835afeb4ab5f9");
      list[1] = new Pubkey("0261e37f277f02a977b4f11eb5055abab4990bbf8dee701119d88df382fcc1fafe");
      Pubkey extPubkey = new Pubkey("022a66efd1ea9b1ad3acfcc62a5ce8c756fa6fc3917fce3d4952a8701244ed1049");

      Pubkey combinedPubkey = Pubkey.Combine(list);
      Assert.True(combinedPubkey.IsValid());
      Assert.Equal(combinedPubkey.ToHexString(), extPubkey.ToHexString());
    }
Ejemplo n.º 6
0
        public void DeleteSubscription(Pubkey pubkey)
        {
            if (pubkey.SubscriptionIndex != 0)
            {
                pubkey.SubscriptionIndex = 0;
                pubkey.SaveAsync(DB);

                lock (_lock4pubkeysCache)
                    _pubkeysCache = null;
            }
        }
Ejemplo n.º 7
0
        public void AddSubscription(Pubkey pubkey)
        {
            if (pubkey.SubscriptionIndex == 0)
            {
                pubkey.SubscriptionIndex = 1;
                pubkey.SaveAsync(DB);

                lock (_lock4pubkeysCache)
                    _pubkeysCache = null;
            }
        }
Ejemplo n.º 8
0
    public void ConstructorTest()
    {
      Pubkey pubkey = new Pubkey("031d7463018f867de51a27db866f869ceaf52abab71827a6051bab8a0fd020f4c1");
      Assert.True(pubkey.IsValid());

      byte[] byteData = pubkey.ToBytes();
      Pubkey pubkeyBytes = new Pubkey(byteData);
      Assert.Equal(pubkeyBytes.ToHexString(), pubkey.ToHexString());

      Pubkey emptyPubkey = new Pubkey();
      Assert.False(emptyPubkey.IsValid());
    }
Ejemplo n.º 9
0
    public void CompressTest()
    {
      Pubkey uncompressed = new Pubkey("076468efc14b8512007bb720d6e7d4217a6686095a79b57e50dd48355110422955400e1a8f159b5dcea116049d09eb756b80d52aeaabb195b343cf713f62f01a73");
      Pubkey extUncompressed = new Pubkey("046468efc14b8512007bb720d6e7d4217a6686095a79b57e50dd48355110422955400e1a8f159b5dcea116049d09eb756b80d52aeaabb195b343cf713f62f01a73");
      Pubkey extCompressed = new Pubkey("036468efc14b8512007bb720d6e7d4217a6686095a79b57e50dd48355110422955");
      Pubkey compressPubkey = uncompressed.Compress();
      Assert.True(compressPubkey.IsCompressed());
      Assert.False(uncompressed.IsCompressed());
      Assert.Equal(compressPubkey.ToHexString(), extCompressed.ToHexString());

      Pubkey uncompPubkey = compressPubkey.Uncompress();
      Assert.False(uncompPubkey.IsCompressed());
      Assert.Equal(uncompPubkey.ToHexString(), extUncompressed.ToHexString());
    }
Ejemplo n.º 10
0
        public void CreateRawTransactionTest()
        {
            ExtPrivkey privkey = new ExtPrivkey("xprv9zt1onyw8BdEf7SQ6wUVH3bQQdGD9iy9QzXveQQRhX7i5iUN7jZgLbqFEe491LfjozztYa6bJAGZ65GmDCNcbjMdjZcgmdisPJwVjcfcDhV");
            Address    addr1   = new Address(privkey.DerivePubkey(1).GetPubkey(), CfdAddressType.P2wpkh, CfdNetworkType.Regtest);
            Address    addr2   = new Address(privkey.DerivePubkey(2).GetPubkey(), CfdAddressType.P2wpkh, CfdNetworkType.Regtest);
            Address    addr3   = new Address(privkey.DerivePubkey(3).GetPubkey(), CfdAddressType.P2wpkh, CfdNetworkType.Regtest);

            OutPoint    outpoint1 = new OutPoint("0000000000000000000000000000000000000000000000000000000000000001", 2);
            OutPoint    outpoint2 = new OutPoint("0000000000000000000000000000000000000000000000000000000000000001", 3);
            Transaction tx        = new Transaction("02000000000000000000", new[] {
                new TxIn(outpoint1),
                new TxIn(outpoint2),
            }, new[] {
                new TxOut(10000, addr1.GetLockingScript()),
                new TxOut(10000, addr2.GetLockingScript()),
            });

            tx.AddTxOut(50000, addr3);
            output.WriteLine("tx:\n" + tx.ToHexString());
            Assert.Equal("020000000201000000000000000000000000000000000000000000000000000000000000000200000000ffffffff01000000000000000000000000000000000000000000000000000000000000000300000000ffffffff0310270000000000001600148b756cbd98f4f55e985f80437a619d47f0732a941027000000000000160014c0a3dd0b7c1b3281be91112e16ce931dbac2a97950c3000000000000160014ad3abd3c325e40e20d89aa054dd980b97494f16c00000000",
                         tx.ToHexString());

            Privkey           privkey1    = privkey.DerivePrivkey(11).GetPrivkey();
            Pubkey            pubkey1     = privkey1.GetPubkey();
            SignatureHashType sighashType = new SignatureHashType(CfdSighashType.All, false);
            ByteData          sighash     = tx.GetSignatureHash(outpoint1, CfdHashType.P2wpkh, pubkey1, 50000, sighashType);
            SignParameter     signature   = privkey1.CalculateEcSignature(sighash);

            signature.SetDerEncode(sighashType);
            tx.AddSign(outpoint1, CfdHashType.P2wpkh, signature, true);
            tx.AddSign(outpoint1, CfdHashType.P2wpkh, new SignParameter(pubkey1.ToHexString()), false);
            output.WriteLine("tx:\n" + tx.ToHexString());
            Assert.Equal("0200000000010201000000000000000000000000000000000000000000000000000000000000000200000000ffffffff01000000000000000000000000000000000000000000000000000000000000000300000000ffffffff0310270000000000001600148b756cbd98f4f55e985f80437a619d47f0732a941027000000000000160014c0a3dd0b7c1b3281be91112e16ce931dbac2a97950c3000000000000160014ad3abd3c325e40e20d89aa054dd980b97494f16c02473044022034db802aad655cd9be589075fc8ef325b6ffb8c24e5b27eb87bde8ad38f5fd7a0220364c916c8e8fc0adf714d7148cd1c6dc6f3e67d55471e57233b1870c65ec2727012103782f0ea892d7000e5f0f82b6ff283382a76500137a542bb0a616530094a8f54c0000000000",
                         tx.ToHexString());

            Address addr11 = new Address(pubkey1, CfdAddressType.P2wpkh, CfdNetworkType.Regtest);

            try
            {
                tx.VerifySign(outpoint1, addr11, addr11.GetAddressType(), 50000);
            }
            catch (Exception e)
            {
                Assert.Null(e);
            }

            string json = Transaction.DecodeRawTransaction(tx);

            output.WriteLine(json);
        }
Ejemplo n.º 11
0
    public void TweakTest()
    {
      Pubkey pubkey = new Pubkey("03662a01c232918c9deb3b330272483c3e4ec0c6b5da86df59252835afeb4ab5f9");
      ByteData tweak = new ByteData("98430d10471cf697e2661e31ceb8720750b59a85374290e175799ba5dd06508e");

      Pubkey tweakedAdd = pubkey.TweakAdd(tweak);
      Assert.Equal("02b05cf99a2f556177a38f5108445472316e87eb4f5b243d79d7e5829d3d53babc", tweakedAdd.ToHexString());
      Pubkey tweakedMul = pubkey.TweakMul(tweak);
      Assert.Equal("0305d10e760a529d0523e98892d2deff59b91593a0d670bd82271cfa627c9e7e18", tweakedMul.ToHexString());

      Pubkey negate = pubkey.Negate();
      Assert.Equal("02662a01c232918c9deb3b330272483c3e4ec0c6b5da86df59252835afeb4ab5f9", negate.ToHexString());
      Assert.Equal(pubkey.ToHexString(), negate.Negate().ToHexString());
      Assert.True(pubkey.Equals(negate.Negate()));
    }
Ejemplo n.º 12
0
        public void AddressP2shSegwitTest()
        {
            Pubkey  pubkey = new Pubkey("031d7463018f867de51a27db866f869ceaf52abab71827a6051bab8a0fd020f4c1");
            Address addr   = new Address(pubkey, CfdAddressType.P2shP2wpkh, CfdNetworkType.ElementsRegtest);

            Assert.Equal("XBsZoa2ueqj8TJA52KzNrHGtjzAeqTf6DS", addr.ToAddressString());
            Assert.Equal("a91405bc4d5d12925f008cef06ba387ade16a49d7a3187", addr.GetLockingScript().ToHexString());
            Assert.Equal("0014f4b7463a98e4c248fecc737f180e204efc5a99b5", addr.GetP2shLockingScript());

            Address addr2 = Address.GetAddressByLockingScript(addr.GetLockingScript(), CfdNetworkType.ElementsRegtest);

            Assert.Equal(CfdAddressType.P2sh, addr2.GetAddressType());
            addr2.SetAddressType(CfdAddressType.P2shP2wpkh);
            Assert.Equal(CfdAddressType.P2shP2wpkh, addr2.GetAddressType());
        }
Ejemplo n.º 13
0
        public void ConstructorTest()
        {
            string  addrStr = "bcrt1q576jgpgewxwu205cpjq4s4j5tprxlq38l7kd85";
            Address addr    = new Address(addrStr);

            Assert.Equal(addrStr, addr.ToAddressString());
            Assert.Equal("0014a7b5240519719dc53e980c8158565458466f8227", addr.GetLockingScript().ToHexString());
            Assert.Equal("a7b5240519719dc53e980c8158565458466f8227", addr.GetHash());

            Pubkey pubkey = new Pubkey("031d7463018f867de51a27db866f869ceaf52abab71827a6051bab8a0fd020f4c1");

            addr = new Address(pubkey, CfdAddressType.P2wpkh, CfdNetworkType.ElementsRegtest);
            Assert.Equal("ert1q7jm5vw5cunpy3lkvwdl3sr3qfm794xd4zr6z3k", addr.ToAddressString());
            Assert.Equal("0014f4b7463a98e4c248fecc737f180e204efc5a99b5", addr.GetLockingScript().ToHexString());
            Assert.True(addr.Equals(new Address("ert1q7jm5vw5cunpy3lkvwdl3sr3qfm794xd4zr6z3k")));
        }
Ejemplo n.º 14
0
        public void PubkeySignTest()
        {
            ExtPrivkey  privkey   = new ExtPrivkey("xprv9zt1onyw8BdEf7SQ6wUVH3bQQdGD9iy9QzXveQQRhX7i5iUN7jZgLbqFEe491LfjozztYa6bJAGZ65GmDCNcbjMdjZcgmdisPJwVjcfcDhV");
            Transaction tx        = new Transaction("020000000201000000000000000000000000000000000000000000000000000000000000000200000000ffffffff01000000000000000000000000000000000000000000000000000000000000000300000000ffffffff0310270000000000001600148b756cbd98f4f55e985f80437a619d47f0732a941027000000000000160014c0a3dd0b7c1b3281be91112e16ce931dbac2a97950c3000000000000160014ad3abd3c325e40e20d89aa054dd980b97494f16c00000000");
            OutPoint    outpoint1 = new OutPoint("0000000000000000000000000000000000000000000000000000000000000001", 2);

            Privkey           privkey1    = privkey.DerivePrivkey(11).GetPrivkey();
            Pubkey            pubkey1     = privkey1.GetPubkey();
            SignatureHashType sighashType = new SignatureHashType(CfdSighashType.All, false);
            ByteData          sighash     = tx.GetSignatureHash(outpoint1, CfdHashType.P2wpkh, pubkey1, 50000, sighashType);
            SignParameter     signature   = privkey1.CalculateEcSignature(sighash);

            signature.SetDerEncode(sighashType);
            tx.AddPubkeySign(outpoint1, CfdHashType.P2wpkh, pubkey1, signature);
            // output.WriteLine("tx:\n" + tx.ToHexString());
            Assert.Equal("0200000000010201000000000000000000000000000000000000000000000000000000000000000200000000ffffffff01000000000000000000000000000000000000000000000000000000000000000300000000ffffffff0310270000000000001600148b756cbd98f4f55e985f80437a619d47f0732a941027000000000000160014c0a3dd0b7c1b3281be91112e16ce931dbac2a97950c3000000000000160014ad3abd3c325e40e20d89aa054dd980b97494f16c02473044022034db802aad655cd9be589075fc8ef325b6ffb8c24e5b27eb87bde8ad38f5fd7a0220364c916c8e8fc0adf714d7148cd1c6dc6f3e67d55471e57233b1870c65ec2727012103782f0ea892d7000e5f0f82b6ff283382a76500137a542bb0a616530094a8f54c0000000000",
                         tx.ToHexString());

            bool isVerify = tx.VerifySignature(outpoint1, CfdHashType.P2wpkh, signature, pubkey1, sighashType, 50000);

            Assert.True(isVerify);
        }
Ejemplo n.º 15
0
        public void ConfidentialAddressTest()
        {
            string ctAddr             = "VTpvKKc1SNmLG4H8CnR1fGJdHdyWGEQEvdP9gfeneJR7n81S5kiwNtgF7vrZjC8mp63HvwxM81nEbTxU";
            string address            = "Q7wegLt2qMGhm28vch6VTzvpzs8KXvs4X7";
            string ctKey              = "025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357";
            ConfidentialAddress caddr = new ConfidentialAddress(ctAddr);

            Assert.Equal(ctAddr, caddr.ToAddressString());
            Assert.Equal(address, caddr.GetAddress().ToAddressString());
            Assert.Equal("76a914751e76e8199196d454941c45d1b3a323f1433bd688ac", caddr.GetAddress().GetLockingScript().ToHexString());
            Assert.Equal(ctKey, caddr.GetConfidentialKey().ToHexString());
            Assert.True(caddr.Equals(new ConfidentialAddress(ctAddr)));

            Address addr   = new Address(address);
            Pubkey  pubkey = new Pubkey(ctKey);

            caddr = new ConfidentialAddress(addr, pubkey);
            Assert.Equal(ctAddr, caddr.ToAddressString());
            Assert.Equal(address, caddr.GetAddress().ToAddressString());
            Assert.Equal("76a914751e76e8199196d454941c45d1b3a323f1433bd688ac", caddr.GetAddress().GetLockingScript().ToHexString());
            Assert.Equal(ctKey, caddr.GetConfidentialKey().ToHexString());
        }
Ejemplo n.º 16
0
        public void SchnorrKeyTest()
        {
            var tweak        = new ByteData("e48441762fb75010b2aa31a512b62b4148aa3fb08eb0765d76b252559064a614");
            var sk           = new Privkey("688c77bc2d5aaff5491cf309d4753b732135470d05b7b2cd21add0744fe97bef");
            var pk           = new Pubkey("03b33cc9edc096d0a83416964bd3c6247b8fecd256e4efa7870d2c854bdeb33390");
            var pubkey       = new SchnorrPubkey("b33cc9edc096d0a83416964bd3c6247b8fecd256e4efa7870d2c854bdeb33390");
            var expTweakedPk = new SchnorrPubkey("1fc8e882e34cc7942a15f39ffaebcbdf58a19239bcb17b7f5aa88e0eb808f906");
            // bool expTweakedParity = true;
            var expTweakedSk = new Privkey("7bf7c9ba025ca01b698d3e9b3e40efce2774f8a388f8c390550481e1407b2a25");

            var schnorrPubkey = SchnorrPubkey.GetPubkeyFromPrivkey(sk, out bool parity);

            Assert.Equal(pubkey.ToHexString(), schnorrPubkey.ToHexString());
            Assert.True(parity);

            var spk2 = SchnorrPubkey.GetPubkeyFromPubkey(pk, out parity);

            Assert.Equal(pubkey.ToHexString(), spk2.ToHexString());
            Assert.True(parity);

            var tweakedPubkey = schnorrPubkey.TweakAdd(tweak, out parity);

            Assert.Equal(expTweakedPk.ToHexString(), tweakedPubkey.ToHexString());
            Assert.True(parity);

            SchnorrPubkey.GetTweakAddKeyPair(sk, tweak, out SchnorrPubkey tweakedPubkey2, out parity, out Privkey tweakedPrivkey);
            Assert.Equal(expTweakedPk.ToHexString(), tweakedPubkey2.ToHexString());
            Assert.True(parity);
            Assert.Equal(expTweakedSk.ToHexString(), tweakedPrivkey.ToHexString());

            var isValid = tweakedPubkey.IsTweaked(parity, pubkey, tweak);

            Assert.True(isValid);
            isValid = tweakedPubkey.IsTweaked(!parity, pubkey, tweak);
            Assert.False(isValid);
        }
Ejemplo n.º 17
0
 public IEnumerable <Pubkey> ListOtherAddresses()
 {
     return(Pubkey.GetAll(DB));
 }
Ejemplo n.º 18
0
 private static void NewPubkey(Pubkey pubkey)
 {
     _bm.AddSubscription(pubkey);
     Console.WriteLine("Pubkey " + pubkey);
 }
Ejemplo n.º 19
0
 public string ToDiagnosticString()
 {
     return($"{{ endpoint: {Endpoint}, key: {Pubkey.ToHex().Substring(0, 45)}... }}");
 }
Ejemplo n.º 20
0
        private void ListenerLoop()
        {
            try
            {
                NetworkStream ns = _tcpClient.GetStream();

                while (ns.CanRead)
                {
                    #region Read header and payload from network

                    Header  header;
                    Payload payload;
                    try
                    {
                        header  = new Header(BinaryReader);
                        payload =
                            (header.Length == 0)
                                                        ? new Payload(header.Command, null)
                                                        : new Payload(header.Command, BinaryReader.ReadBytes(header.Length));
                    }
                    catch (Exception e)
                    {
                        string excptionStr = e.ToString();
                        if ((e is IOException) || (e is SocketException))
                        {
                            excptionStr = "";
                        }
                        Debug.WriteLine("соединение " + NetworkAddress + " потерено " + excptionStr);
                        Bitmessage.NodeIsDisconnected.Set();
                        break;
                    }

                    #endregion Read header and payload from network

                    bool checksum = header.Checksum.SequenceEqual(payload.Checksum());

                    if (checksum && payload.IsValid)
                    {
                        debug("Command=" + header.Command);

                        #region Save payload to Inventory

                        if ((header.Command == "msg") || (header.Command == "pubkey") || (header.Command == "broadcast") || (header.Command == "getpubkey"))
                        {
                            _nodeConnectionInventory.Insert(payload.InventoryVector);
                            payload.SaveAsync(Bitmessage);
                        }

                        #endregion Save to Inventory

                        #region VERSION

                        if (header.Command == "version")
                        {
                            var v = new Version(payload);
                            debug("Подключились с " + v.UserAgent);
                            if ((v.Value != 1) && (v.Value != 2))
                            {
                                Stop("Version = " + v.Value);
                            }
                            else if (v.Nonce == Version.EightBytesOfRandomDataUsedToDetectConnectionsToSelf)
                            {
                                Bitmessage.DeleteNode(NetworkAddress);
                                Stop("DetectConnectionsToSelf");
                            }
                            else
                            {
                                Send(new Verack());
                            }
                        }

                        #endregion VERSION

                        #region INV

                        else if (header.Command == "inv")
                        {
                            var inputInventory = new Inv(payload.SentData);
                            var buff4GetData   = new MemoryInventory(inputInventory.Count);

                            debug("прислали inv. Inventory.Count=" + inputInventory.Count);

                            //lock (Bitmessage.MemoryInventory)
                            //{
                            foreach (byte[] inventoryVector in inputInventory)
                            {
                                _nodeConnectionInventory.Insert(inventoryVector);
                                if (!Bitmessage.MemoryInventory.Exists(inventoryVector))
                                {
                                    Bitmessage.MemoryInventory.AddWait(inventoryVector);
                                    buff4GetData.Insert(inventoryVector);
                                }
                            }
                            //}

                            if (buff4GetData.Count > 0)
                            {
                                debug("SendGetdata count=" + buff4GetData.Count);
                                Send(new GetData(buff4GetData));
                            }
                            else
                            {
                                debug("All know, don't send GetData");
                            }
                        }

                        #endregion

                        #region verack

                        else if (header.Command == "verack")
                        {
                            Send(new Inv(Bitmessage.MemoryInventory));

                            NetworkAddress.TimeLastSeen = DateTime.UtcNow;
                            NetworkAddress.SaveAsync(Bitmessage.DB);
                        }

                        #endregion

                        #region getpubkey

                        else if (header.Command == "getpubkey")
                        {
                            var getpubkey = new GetPubkey(payload);

                            PrivateKey pk = Bitmessage.FindPrivateKey(getpubkey);
                            if ((pk != null) &&
                                (pk.LastPubkeySendTime.ToUnix() <
                                 (DateTime.UtcNow.ToUnix() - Payload.LengthOfTimeToHoldOnToAllPubkeys)))
                            {
                                pk.SendAsync(Bitmessage);
                            }
                        }

                        #endregion getpubkey

                        #region pubkey

                        else if (header.Command == "pubkey")
                        {
                            int pos    = payload.FirstByteAfterTime;
                            var pubkey = new Pubkey(payload.SentData, ref pos, true);

                            if (pubkey.Status == Status.Valid)
                            {
                                pubkey.SaveAsync(Bitmessage.DB);
                                Bitmessage.OnReceivePubkey(pubkey);
                            }
                            else
                            {
                                Bitmessage.OnReceiveInvalidPubkey(pubkey);
                            }
                        }

                        #endregion PUBKEY

                        #region msg

                        else if (header.Command == "msg")
                        {
                            var msg = new Msg(Bitmessage, payload);
                            msg.SaveAsync(Bitmessage.DB);

                            if (msg.Status == Status.Valid)
                            {
                                Bitmessage.OnReceiveMsg(msg);
                            }
                            else
                            {
                                Bitmessage.OnReceiveInvalidMsg(msg);
                            }
                        }

                        #endregion MSG

                        #region broadcast

                        else if (header.Command == "broadcast")
                        {
                            var broadcast = new Broadcast(Bitmessage, payload);
                            broadcast.SaveAsync(Bitmessage.DB);

                            if (broadcast.Status == Status.Valid)
                            {
                                Bitmessage.OnReceiveBroadcast(broadcast);
                            }
                            else
                            {
                                Bitmessage.OnReceiveInvalidBroadcast(broadcast);
                            }
                        }

                        #endregion BROADCAST

                        #region addr

                        else if (header.Command == "addr")
                        {
                            int    pos = 0;
                            UInt64 numberOfAddressesIncluded = payload.SentData.ReadVarInt(ref pos);
                            if ((numberOfAddressesIncluded > 0) && (numberOfAddressesIncluded < 1001))
                            {
                                if (payload.Length != (pos + (38 * (int)numberOfAddressesIncluded)))
                                {
                                    throw new Exception(
                                              "addr message does not contain the correct amount of data. Ignoring.");
                                }

                                while (pos < payload.Length)
                                {
                                    NetworkAddress networkAddress = NetworkAddress.GetFromAddrList(payload.SentData,
                                                                                                   ref pos);
                                    Bitmessage.AddNode(networkAddress);
                                }
                            }
                        }

                        #endregion addr

                        #region getdata

                        else if (header.Command == "getdata")
                        {
                            debug("Load getdata");
                            var getData = new GetData(payload.SentData);

                            foreach (byte[] hash in getData.Inventory)
                            {
                                Payload.SendAsync(this, hash.ToHex(false));
                            }
                        }

                        #endregion getdata

                        #region ping

                        else if (header.Command == "ping")
                        {
                            Send(new Pong());
                        }

                        #endregion ping

                        #region pong

                        else if (header.Command == "pong")
                        {
                        }

                        #endregion pong

                        else
                        {
                            debug("unknown command");
                        }
                    }
                    else
                    {
                        debug("checksum error");
                    }
                }
                _tcpClient.Close();
            }
            // ReSharper disable EmptyGeneralCatchClause
            catch (Exception e)
            {
                debug("Закрываю соединение " + e);
            }             // ReSharper restore EmptyGeneralCatchClause

            Bitmessage.NodeIsDisconnected.Set();
        }