Beispiel #1
0
        public void CanGetMerkleRoot()
        {
            using (var builder = NodeBuilder.Create())
            {
                var node = builder.CreateNode(true).CreateNodeClient();
                builder.Nodes[0].Generate(101);
                var rpc = builder.Nodes[0].CreateRPCClient();
                builder.Nodes[0].Split(Money.Coins(50m), 50);
                builder.Nodes[0].SelectMempoolTransactions();
                builder.Nodes[0].Generate(1);
                for (int i = 0; i < 20; i++)
                {
                    rpc.SendToAddress(new Key().PubKey.GetAddress(rpc.Network), Money.Coins(0.5m));
                }
                builder.Nodes[0].SelectMempoolTransactions();
                builder.Nodes[0].Generate(1);
                var block        = builder.Nodes[0].CreateRPCClient().GetBlock(103);
                var knownTx      = block.Transactions[0].GetHash();
                var knownAddress = block.Transactions[0].Outputs[0].ScriptPubKey.GetDestination();
                node.VersionHandshake();
                using (var list = node.CreateListener()
                                  .Where(m => m.Message.Payload is MerkleBlockPayload || m.Message.Payload is TxPayload))
                {
                    BloomFilter filter = new BloomFilter(1, 0.005, 50, BloomFlags.UPDATE_NONE);
                    filter.Insert(knownAddress.ToBytes());
                    node.SendMessageAsync(new FilterLoadPayload(filter));
                    node.SendMessageAsync(new GetDataPayload(new InventoryVector(InventoryType.MSG_FILTERED_BLOCK, block.GetHash())));
                    var merkle = list.ReceivePayload <MerkleBlockPayload>();
                    var tree   = merkle.Object.PartialMerkleTree;
                    Assert.True(tree.Check(block.Header.HashMerkleRoot));
                    Assert.True(tree.GetMatchedTransactions().Count() > 1);
                    Assert.True(tree.GetMatchedTransactions().Contains(knownTx));

                    List <Transaction> matched = new List <Transaction>();
                    for (int i = 0; i < tree.GetMatchedTransactions().Count(); i++)
                    {
                        matched.Add(list.ReceivePayload <TxPayload>().Object);
                    }
                    Assert.True(matched.Count > 1);
                    tree = tree.Trim(knownTx);
                    Assert.True(tree.GetMatchedTransactions().Count() == 1);
                    Assert.True(tree.GetMatchedTransactions().Contains(knownTx));

                    Action act = () =>
                    {
                        foreach (var match in matched)
                        {
                            Assert.True(filter.IsRelevantAndUpdate(match));
                        }
                    };
                    act();
                    filter = filter.Clone();
                    act();

                    var unknownBlock = uint256.Parse("00000000ad262227291eaf90cafdc56a8f8451e2d7653843122c5bb0bf2dfcdd");
                    node.SendMessageAsync(new GetDataPayload(new InventoryVector(InventoryType.MSG_FILTERED_BLOCK, Network.RegTest.GetGenesis().GetHash())));

                    merkle = list.ReceivePayload <MerkleBlockPayload>();
                    tree   = merkle.Object.PartialMerkleTree;
                    Assert.True(tree.Check(merkle.Object.Header.HashMerkleRoot));
                    Assert.True(!tree.GetMatchedTransactions().Contains(knownTx));
                }
            }
        }
Beispiel #2
0
        public void CanImportMultiAddresses()
        {
            // Test cases borrowed from: https://github.com/bitcoin/bitcoin/blob/master/test/functional/importmulti.py
            using (var builder = NodeBuilder.Create())
            {
                var rpc = builder.CreateNode().CreateRPCClient();
                builder.StartAll();

                Key          key;
                RPCException response;
                List <ImportMultiAddress> multiAddresses;
                Network network = Network.RegTest;

                // 20 total test cases

                #region Bitcoin Address
                Console.WriteLine("Should import an address");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            Address = key.PubKey.GetAddress(network)
                        },
                        Timestamp = Utils.UnixTimeToDateTime(0)
                    }
                };

                rpc.ImportMulti(multiAddresses.ToArray(), false);

                #endregion

                #region ScriptPubKey + internal
                Console.WriteLine("Should import a scriptPubKey with internal flag");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject(key.ScriptPubKey),
                        Internal     = true
                    }
                };

                rpc.ImportMulti(multiAddresses.ToArray(), false);
                #endregion

                #region ScriptPubKey + !internal
                Console.WriteLine("Should not import a scriptPubKey without internal flag");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            ScriptPubKey = key.ScriptPubKey
                        },
                    }
                };

                response = Assert.Throws <RPCException>(() => rpc.ImportMulti(multiAddresses.ToArray(), false));
                Assert.Equal(response.RPCCode, RPCErrorCode.RPC_INVALID_PARAMETER);
                Assert.Equal(response.Message, "Internal must be set for hex scriptPubKey");
                #endregion

                #region Address + Public key + !internal
                Console.WriteLine("Should import an address with public key");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject(key.PubKey.GetAddress(network)),
                        PubKeys      = new string[] { key.PubKey.ToString() }
                    }
                };

                rpc.ImportMulti(multiAddresses.ToArray(), false);
                #endregion

                #region ScriptPubKey + Public key + internal
                Console.WriteLine("Should import a scriptPubKey with internal and with public key");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            ScriptPubKey = key.ScriptPubKey
                        },
                        PubKeys  = new string[] { key.PubKey.ToString() },
                        Internal = true
                    }
                };

                rpc.ImportMulti(multiAddresses.ToArray(), false);
                #endregion

                #region ScriptPubKey + Public key + !internal
                // Console.WriteLine("Should not import a scriptPubKey without internal and with public key");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            ScriptPubKey = key.ScriptPubKey
                        },
                        PubKeys = new string[] { key.PubKey.ToString() }
                    }
                };

                response = Assert.Throws <RPCException>(() => rpc.ImportMulti(multiAddresses.ToArray(), false));
                Assert.Equal(response.RPCCode, RPCErrorCode.RPC_INVALID_PARAMETER);
                Assert.Equal(response.Message, "Internal must be set for hex scriptPubKey");
                #endregion

                #region Address + Private key + !watchonly
                // Console.WriteLine("Should import an address with private key");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            Address = key.PubKey.GetAddress(network)
                        },
                        Keys = new string[] { key.GetWif(network).ToString() }
                    }
                };

                rpc.ImportMulti(multiAddresses.ToArray(), false);

                Console.WriteLine("Should not import an address with private key if is already imported");
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            Address = key.PubKey.GetAddress(network)
                        },
                        Keys = new string[] { key.GetWif(network).ToString() }
                    }
                };

                response = Assert.Throws <RPCException>(() => rpc.ImportMulti(multiAddresses.ToArray(), false));

                //Assert.False(response.Result[0].Value<bool>());

                #endregion

                #region Address + Private key + watchonly
                Console.WriteLine("Should not import an address with private key and with watchonly");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            Address = key.PubKey.GetAddress(network)
                        },
                        Keys      = new string[] { key.GetWif(network).ToString() },
                        WatchOnly = true
                    }
                };

                response = Assert.Throws <RPCException>(() => rpc.ImportMulti(multiAddresses.ToArray(), false));
                Assert.Equal(response.RPCCode, RPCErrorCode.RPC_INVALID_PARAMETER);
                Assert.Equal(response.Message, "Incompatibility found between watchonly and keys");
                #endregion

                #region ScriptPubKey + Private key + internal
                Console.WriteLine("Should import a scriptPubKey with internal and with private key");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            ScriptPubKey = key.ScriptPubKey
                        },
                        Keys     = new string[] { key.GetWif(network).ToString() },
                        Internal = true
                    }
                };

                rpc.ImportMulti(multiAddresses.ToArray(), false);
                #endregion

                #region ScriptPubKey + Private key + !internal
                Console.WriteLine("Should not import a scriptPubKey without internal and with private key");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            ScriptPubKey = key.ScriptPubKey
                        },
                        Keys = new string[] { key.GetWif(network).ToString() }
                    }
                };

                response = Assert.Throws <RPCException>(() => rpc.ImportMulti(multiAddresses.ToArray(), false));
                #endregion

                #region P2SH address
                //Blocked : Dependent on implementation of rpc.CreateMultiSig()
                #endregion

                #region P2SH + Redeem script
                //Blocked : Dependent on implementation of rpc.CreateMultiSig()
                #endregion

                #region P2SH + Redeem script + Private Keys + !Watchonly
                //Blocked : Dependent on implementation of rpc.CreateMultiSig()
                #endregion

                #region P2SH + Redeem script + Private Keys + Watchonly
                //Blocked : Dependent on implementation of rpc.CreateMultiSig()
                #endregion

                #region Address + Public key + !Internal + Wrong pubkey
                Console.WriteLine("Should not import an address with a wrong public key");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            Address = key.PubKey.GetAddress(network)
                        },
                        PubKeys = new string[] { new Key().PubKey.ToString() }
                    }
                };

                response = Assert.Throws <RPCException>(() => rpc.ImportMulti(multiAddresses.ToArray(), false));
                Assert.Equal(response.RPCCode, RPCErrorCode.RPC_INVALID_ADDRESS_OR_KEY);
                Assert.Equal(response.Message, "Consistency check failed");
                #endregion

                #region ScriptPubKey + Public key + internal + Wrong pubkey
                Console.WriteLine("Should not import a scriptPubKey with internal and with a wrong public key");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            ScriptPubKey = key.ScriptPubKey
                        },
                        PubKeys  = new string[] { new Key().PubKey.ToString() },
                        Internal = true
                    }
                };

                response = Assert.Throws <RPCException>(() => rpc.ImportMulti(multiAddresses.ToArray(), false));
                Assert.Equal(response.RPCCode, RPCErrorCode.RPC_INVALID_ADDRESS_OR_KEY);
                Assert.Equal(response.Message, "Consistency check failed");
                #endregion

                #region Address + Private key + !watchonly + Wrong private key
                Console.WriteLine("Should not import an address with a wrong private key");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            Address = key.PubKey.GetAddress(network)
                        },
                        Keys = new string[] { new Key().GetWif(network).ToString() }
                    }
                };

                response = Assert.Throws <RPCException>(() => rpc.ImportMulti(multiAddresses.ToArray(), false));
                Assert.Equal(response.RPCCode, RPCErrorCode.RPC_INVALID_ADDRESS_OR_KEY);
                Assert.Equal(response.Message, "Consistency check failed");
                #endregion

                #region ScriptPubKey + Private key + internal + Wrong private key
                Console.WriteLine("Should not import a scriptPubKey with internal and with a wrong private key");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            ScriptPubKey = key.ScriptPubKey
                        },
                        Keys     = new string[] { new Key().GetWif(network).ToString() },
                        Internal = true
                    }
                };

                response = Assert.Throws <RPCException>(() => rpc.ImportMulti(multiAddresses.ToArray(), false));
                Assert.Equal(response.RPCCode, RPCErrorCode.RPC_INVALID_ADDRESS_OR_KEY);
                Assert.Equal(response.Message, "Consistency check failed");
                #endregion

                #region Importing existing watch only address with new timestamp should replace saved timestamp.
                //TODO
                #endregion

                #region restart nodes to check for proper serialization/deserialization of watch only address
                //TODO
                #endregion
            }
        }
Beispiel #3
0
        public static NodeBuilder Create([CallerMemberName] string caller = null)
        {
            //var builder = NodeBuilder.Create(NodeDownloadData.Litecoin.v0_17_1, Altcoins.Litecoin.Instance.Regtest, caller);

            //var builder = NodeBuilder.Create(NodeDownloadData.Viacoin.v0_15_1, Altcoins.Viacoin.Instance.Regtest, caller);

            //var builder = NodeBuilder.Create(NodeDownloadData.BCash.v0_16_2, Altcoins.BCash.Instance.Regtest, caller);

            //var builder = NodeBuilder.Create(NodeDownloadData.Dogecoin.v1_10_0, Altcoins.Dogecoin.Instance.Regtest, caller);

            //var builder = NodeBuilder.Create(NodeDownloadData.Verge.v6_0_2, Altcoins.Verge.Instance.Regtest, caller);

            //var builder = NodeBuilder.Create(NodeDownloadData.Dash.v0_13_0, Altcoins.Dash.Instance.Regtest, caller);

            //var builder = NodeBuilder.Create(NodeDownloadData.Terracoin.v0_12_2, Altcoins.Terracoin.Instance.Regtest, caller);

            //var builder = NodeBuilder.Create(NodeDownloadData.BGold.v0_15_0, Altcoins.BGold.Instance.Regtest, caller);

            //var builder = NodeBuilder.Create(NodeDownloadData.Polis.v1_4_3, Altcoins.Polis.Instance.Regtest, caller);

            //var builder = NodeBuilder.Create(NodeDownloadData.Monoeci.v0_12_2_3, Altcoins.Monoeci.Instance.Regtest, caller);

            //var builder = NodeBuilder.Create(NodeDownloadData.Colossus.v1_1_1, Altcoins.Colossus.Instance.Regtest, caller);

            //var builder = NodeBuilder.Create(NodeDownloadData.GoByte.v0_12_2_4, Altcoins.GoByte.Instance.Regtest, caller);

            //var builder = NodeBuilder.Create(NodeDownloadData.Monacoin.v0_15_1, Altcoins.Monacoin.Regtest, caller);

            //var builder = NodeBuilder.Create(NodeDownloadData.Feathercoin.v0_16_0, Altcoins.AltNetworkSets.Feathercoin.Regtest, caller);

            //var builder = NodeBuilder.Create(NodeDownloadData.Ufo.v0_16_0, Altcoins.AltNetworkSets.Ufo.Regtest, caller);

            //var builder = NodeBuilder.Create(NodeDownloadData.Groestlcoin.v2_19_1, Altcoins.AltNetworkSets.Groestlcoin.Regtest, caller);

            //var builder = NodeBuilder.Create(NodeDownloadData.Mogwai.v0_12_2, Altcoins.AltNetworkSets.Mogwai.Regtest, caller);

            //var builder = NodeBuilder.Create(NodeDownloadData.Dystem.v1_0_9_9, Altcoins.Dystem.Instance.Regtest, caller);
            //var builder = NodeBuilder.Create(NodeDownloadData.Bitcoinplus.v2_7_0, Altcoins.AltNetworkSets.Bitcoinplus.Regtest, caller);

            //var builder = NodeBuilder.Create(NodeDownloadData.Liquid.v3_14_1_21, Altcoins.AltNetworkSets.Liquid.Regtest, caller);
            //var builder = NodeBuilder.Create(NodeDownloadData.Bitcore.v0_90_9_1, Altcoins.Bitcore.Instance.Regtest, caller);
            //var builder = NodeBuilder.Create(NodeDownloadData.Gincoin.v1_1_0_0, Altcoins.Gincoin.Instance.Regtest, caller);
            //var builder = NodeBuilder.Create(NodeDownloadData.Koto.v2_0_0, Altcoins.Koto.Regtest, caller);
            //var builder = NodeBuilder.Create(NodeDownloadData.Chaincoin.v0_16_4 , Altcoins.AltNetworkSets.Chaincoin.Regtest, caller);
            //var builder = NodeBuilder.Create(NodeDownloadData.Stratis.v3_0_0, Altcoins.AltNetworkSets.Stratis.Regtest, caller);
            //var builder = NodeBuilder.Create(NodeDownloadData.ZCoin.v0_13_8_3, Altcoins.ZCoin.Instance.Regtest, caller);
            //var builder = NodeBuilder.Create(NodeDownloadData.DogeCash.v5_1_1, Altcoins.DogeCash.Instance.Regtest, caller);

            //var builder = NodeBuilder.Create(NodeDownloadData.Elements.v0_18_1_1, Altcoins.AltNetworkSets.Liquid.Regtest, caller);

            //var builder = NodeBuilder.Create(NodeDownloadData.Argoneum.v1_4_1, Altcoins.Argoneum.Instance.Regtest, caller);

            //var builder = NodeBuilder.Create(NodeDownloadData.Qtum.v0_18_3, Altcoins.Qtum.Instance.Regtest, caller);

            //var builder = NodeBuilder.Create(NodeDownloadData.MonetaryUnit.v2_1_6, Altcoins.MonetaryUnit.Instance.Regtest, caller);

            var builder = NodeBuilder.Create(NodeDownloadData.Blocknet.v4_3_0, Altcoins.Blocknet.Instance.Regtest, caller);

            //var builder = Create(NodeDownloadData.Bitcoin.v0_19_0_1, caller);

            //var builder = Create(NodeDownloadData.Bitcoin.v0_20_0, caller);
            return(builder);
        }
Beispiel #4
0
        public void CanImportMultiAddresses()
        {
            // Test cases borrowed from: https://github.com/bitcoin/bitcoin/blob/master/test/functional/importmulti.py
            using (var builder = NodeBuilder.Create(version: "0.15.1"))
            {
                var rpc = builder.CreateNode().CreateRPCClient();
                builder.StartAll();

                Key key;
                List <ImportMultiAddress> multiAddresses;
                RPCResponse response;
                Network     network = Network.RegTest;

                // 20 total test cases

                #region Bitcoin Address
                Console.WriteLine("Should import an address");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            Address = key.PubKey.GetAddress(network).ToString()
                        },
                        Timestamp = "now"
                    }
                };

                response = rpc.ImportMulti(multiAddresses.ToArray(), false);
                Assert.True(response.Result[0]["success"].Value <bool>());

                Console.WriteLine("Should not import an invalid address");
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            Address = "not valid address"
                        },
                        Timestamp = DateTimeOffset.Now.AddDays(-1)
                    }
                };

                response = rpc.ImportMulti(multiAddresses.ToArray(), false);
                Assert.False(response.Result[0]["success"].Value <bool>());
                #endregion

                #region ScriptPubKey + internal
                Console.WriteLine("Should import a scriptPubKey with internal flag");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            ScriptPubKey = key.ScriptPubKey.ToHex()
                        },
                        Timestamp = "now",
                        Internal  = true
                    }
                };

                response = rpc.ImportMulti(multiAddresses.ToArray(), false);
                Assert.True(response.Result[0]["success"].Value <bool>());
                #endregion

                #region ScriptPubKey + !internal
                Console.WriteLine("Should not import a scriptPubKey without internal flag");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            ScriptPubKey = key.ScriptPubKey.ToHex()
                        },
                        Timestamp = "now"
                    }
                };

                response = rpc.ImportMulti(multiAddresses.ToArray(), false);
                Assert.False(response.Result[0]["success"].Value <bool>());
                Assert.Equal(response.Result[0]["error"]["code"].Value <int>(), -8);
                Assert.Equal(response.Result[0]["error"]["message"].Value <string>(), "Internal must be set for hex scriptPubKey");
                #endregion

                #region Address + Public key + !internal
                Console.WriteLine("Should import an address with public key");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            Address = key.PubKey.GetAddress(network).ToString()
                        },
                        Timestamp = "now",
                        PubKeys   = new string[] { key.PubKey.ToString() }
                    }
                };

                response = rpc.ImportMulti(multiAddresses.ToArray(), false);
                Assert.True(response.Result[0]["success"].Value <bool>());
                #endregion

                #region ScriptPubKey + Public key + internal
                Console.WriteLine("Should import a scriptPubKey with internal and with public key");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            ScriptPubKey = key.ScriptPubKey.ToHex()
                        },
                        Timestamp = "now",
                        PubKeys   = new string[] { key.PubKey.ToString() },
                        Internal  = true
                    }
                };

                response = rpc.ImportMulti(multiAddresses.ToArray(), false);
                Assert.True(response.Result[0]["success"].Value <bool>());
                #endregion

                #region ScriptPubKey + Public key + !internal
                Console.WriteLine("Should not import a scriptPubKey without internal and with public key");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            ScriptPubKey = key.ScriptPubKey.ToHex()
                        },
                        Timestamp = "now",
                        PubKeys   = new string[] { key.PubKey.ToString() }
                    }
                };

                response = rpc.ImportMulti(multiAddresses.ToArray(), false);
                Assert.False(response.Result[0]["success"].Value <bool>());
                Assert.Equal(response.Result[0]["error"]["code"].Value <int>(), -8);
                Assert.Equal(response.Result[0]["error"]["message"].Value <string>(), "Internal must be set for hex scriptPubKey");
                #endregion

                #region Address + Private key + !watchonly
                Console.WriteLine("Should import an address with private key");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            Address = key.PubKey.GetAddress(network).ToString()
                        },
                        Timestamp = "now",
                        Keys      = new string[] { key.GetWif(network).ToString() }
                    }
                };

                response = rpc.ImportMulti(multiAddresses.ToArray(), false);
                Assert.True(response.Result[0]["success"].Value <bool>());

                Console.WriteLine("Should not import an address with private key if is already imported");
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            Address = key.PubKey.GetAddress(network).ToString()
                        },
                        Timestamp = "now",
                        Keys      = new string[] { key.GetWif(network).ToString() }
                    }
                };

                response = rpc.ImportMulti(multiAddresses.ToArray(), false);

                //Assert.False(response.Result[0].Value<bool>());
                Assert.False(response.Result[0]["success"].Value <bool>());

                #endregion

                #region Address + Private key + watchonly
                Console.WriteLine("Should not import an address with private key and with watchonly");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            Address = key.PubKey.GetAddress(network).ToString()
                        },
                        Timestamp = "now",
                        Keys      = new string[] { key.GetWif(network).ToString() },
                        WatchOnly = true
                    }
                };

                response = rpc.ImportMulti(multiAddresses.ToArray(), false);
                Assert.False(response.Result[0]["success"].Value <bool>());
                Assert.Equal(response.Result[0]["error"]["code"].Value <int>(), -8);
                Assert.Equal(response.Result[0]["error"]["message"].Value <string>(), "Incompatibility found between watchonly and keys");
                #endregion

                #region ScriptPubKey + Private key + internal
                Console.WriteLine("Should import a scriptPubKey with internal and with private key");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            ScriptPubKey = key.ScriptPubKey.ToHex()
                        },
                        Timestamp = "now",
                        Keys      = new string[] { key.GetWif(network).ToString() },
                        Internal  = true
                    }
                };

                response = rpc.ImportMulti(multiAddresses.ToArray(), false);
                Assert.True(response.Result[0]["success"].Value <bool>());
                #endregion

                #region ScriptPubKey + Private key + !internal
                Console.WriteLine("Should not import a scriptPubKey without internal and with private key");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            ScriptPubKey = key.ScriptPubKey.ToHex()
                        },
                        Timestamp = "now",
                        Keys      = new string[] { key.GetWif(network).ToString() }
                    }
                };

                response = rpc.ImportMulti(multiAddresses.ToArray(), false);
                Assert.False(response.Result[0]["success"].Value <bool>());
                #endregion

                #region P2SH address
                //Blocked : Dependent on implementation of rpc.CreateMultiSig()
                #endregion

                #region P2SH + Redeem script
                //Blocked : Dependent on implementation of rpc.CreateMultiSig()
                #endregion

                #region P2SH + Redeem script + Private Keys + !Watchonly
                //Blocked : Dependent on implementation of rpc.CreateMultiSig()
                #endregion

                #region P2SH + Redeem script + Private Keys + Watchonly
                //Blocked : Dependent on implementation of rpc.CreateMultiSig()
                #endregion

                #region Address + Public key + !Internal + Wrong pubkey
                Console.WriteLine("Should not import an address with a wrong public key");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            Address = key.PubKey.GetAddress(network).ToString()
                        },
                        Timestamp = "now",
                        PubKeys   = new string[] { new Key().PubKey.ToString() }
                    }
                };

                response = rpc.ImportMulti(multiAddresses.ToArray(), false);
                Assert.False(response.Result[0]["success"].Value <bool>());
                Assert.Equal(response.Result[0]["error"]["code"].Value <int>(), -5);
                Assert.Equal(response.Result[0]["error"]["message"].Value <string>(), "Consistency check failed");
                #endregion

                #region ScriptPubKey + Public key + internal + Wrong pubkey
                Console.WriteLine("Should not import a scriptPubKey with internal and with a wrong public key");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            ScriptPubKey = key.ScriptPubKey.ToHex()
                        },
                        Timestamp = "now",
                        PubKeys   = new string[] { new Key().PubKey.ToString() },
                        Internal  = true
                    }
                };

                response = rpc.ImportMulti(multiAddresses.ToArray(), false);
                Assert.False(response.Result[0]["success"].Value <bool>());
                Assert.Equal(response.Result[0]["error"]["code"].Value <int>(), -5);
                Assert.Equal(response.Result[0]["error"]["message"].Value <string>(), "Consistency check failed");
                #endregion

                #region Address + Private key + !watchonly + Wrong private key
                Console.WriteLine("Should not import an address with a wrong private key");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            Address = key.PubKey.GetAddress(network).ToString()
                        },
                        Timestamp = "now",
                        Keys      = new string[] { new Key().GetWif(network).ToString() }
                    }
                };

                response = rpc.ImportMulti(multiAddresses.ToArray(), false);
                Assert.False(response.Result[0]["success"].Value <bool>());
                Assert.Equal(response.Result[0]["error"]["code"].Value <int>(), -5);
                Assert.Equal(response.Result[0]["error"]["message"].Value <string>(), "Consistency check failed");
                #endregion

                #region ScriptPubKey + Private key + internal + Wrong private key
                Console.WriteLine("Should not import a scriptPubKey with internal and with a wrong private key");
                key            = new Key();
                multiAddresses = new List <ImportMultiAddress>
                {
                    new ImportMultiAddress
                    {
                        ScriptPubKey = new ImportMultiAddress.ScriptPubKeyObject {
                            ScriptPubKey = key.ScriptPubKey.ToHex()
                        },
                        Timestamp = "now",
                        Keys      = new string[] { new Key().GetWif(network).ToString() },
                        Internal  = true
                    }
                };

                response = rpc.ImportMulti(multiAddresses.ToArray(), false);
                Assert.False(response.Result[0]["success"].Value <bool>());
                Assert.Equal(response.Result[0]["error"]["code"].Value <int>(), -5);
                Assert.Equal(response.Result[0]["error"]["message"].Value <string>(), "Consistency check failed");
                #endregion

                #region Importing existing watch only address with new timestamp should replace saved timestamp.
                //TODO
                #endregion

                #region restart nodes to check for proper serialization/deserialization of watch only address
                //TODO
                #endregion
            }
        }
Beispiel #5
0
        public void CanSyncWallet2()
        {
            using (var builder = NodeBuilder.Create())
            {
                NodesGroup aliceConnection = CreateGroup(builder, 1);
                NodesGroup bobConnection   = CreateGroup(builder, new[] { builder.Nodes[0] }, 1);
                builder.Nodes[0].Generate(101);
                var    rpc      = builder.Nodes[0].CreateRPCClient();
                var    aliceKey = new ExtKey();
                Wallet alice    = new Wallet(new WalletCreation()
                {
                    Network           = Network.RegTest,
                    RootKeys          = new[] { aliceKey.Neuter() },
                    SignatureRequired = 1,
                    UseP2SH           = false
                }, 11);
                Wallet bob = new Wallet(new WalletCreation()
                {
                    Network           = Network.RegTest,
                    RootKeys          = new[] { new ExtKey().Neuter() },
                    SignatureRequired = 1,
                    UseP2SH           = false
                }, 11);

                alice.Configure(aliceConnection);
                alice.Connect();

                bob.Configure(bobConnection);
                bob.Connect();

                TestUtils.Eventually(() => aliceConnection.ConnectedNodes.Count == 1);

                //New address tracked
                var addressAlice = alice.GetNextScriptPubKey();
                builder.Nodes[0].GiveMoney(addressAlice, Money.Coins(1.0m));
                TestUtils.Eventually(() => aliceConnection.ConnectedNodes.Count == 1);                 //Reconnect
                //////

                TestUtils.Eventually(() => alice.GetTransactions().Count == 1);

                //Alice send tx to bob
                var coins = alice.GetTransactions().GetSpendableCoins();
                var keys  = coins.Select(c => alice.GetKeyPath(c.ScriptPubKey))
                            .Select(k => aliceKey.Derive(k))
                            .ToArray();
                var txBuilder = new TransactionBuilder();
                var tx        =
                    txBuilder
                    .SetTransactionPolicy(new Policy.StandardTransactionPolicy()
                {
                    MinRelayTxFee = new FeeRate(0)
                })
                    .AddCoins(coins)
                    .AddKeys(keys)
                    .Send(bob.GetNextScriptPubKey(), Money.Coins(0.4m))
                    .SetChange(alice.GetNextScriptPubKey(true))
                    .SendFees(Money.Coins(0.0001m))
                    .BuildTransaction(true);

                Assert.True(txBuilder.Verify(tx));

                builder.Nodes[0].Broadcast(tx);

                //Alice get change
                TestUtils.Eventually(() => alice.GetTransactions().Count == 2);
                coins = alice.GetTransactions().GetSpendableCoins();
                Assert.True(coins.Single().Amount == Money.Coins(0.5999m));
                //////

                //Bob get coins
                TestUtils.Eventually(() => bob.GetTransactions().Count == 1);
                coins = bob.GetTransactions().GetSpendableCoins();
                Assert.True(coins.Single().Amount == Money.Coins(0.4m));
                //////

                MemoryStream bobWalletBackup = new MemoryStream();
                bob.Save(bobWalletBackup);
                bobWalletBackup.Position = 0;

                MemoryStream bobTrakerBackup = new MemoryStream();
                bob.Tracker.Save(bobTrakerBackup);
                bobTrakerBackup.Position = 0;

                bob.Disconnect();

                //Restore bob
                bob = Wallet.Load(bobWalletBackup);
                bobConnection.NodeConnectionParameters.TemplateBehaviors.Remove <TrackerBehavior>();
                bobConnection.NodeConnectionParameters.TemplateBehaviors.Add(new TrackerBehavior(Tracker.Load(bobTrakerBackup), alice.Chain));
                /////

                bob.Configure(bobConnection);

                //Bob still has coins
                TestUtils.Eventually(() => bob.GetTransactions().Count == 1);
                coins = bob.GetTransactions().GetSpendableCoins();
                Assert.True(coins.Single().Amount == Money.Coins(0.4m));
                //////

                bob.Connect();
                TestUtils.Eventually(() => bobConnection.ConnectedNodes.Count == 1);

                //New block found !
                builder.Nodes[0].SelectMempoolTransactions();
                builder.Nodes[0].Generate(1);

                //Alice send tx to bob
                coins = alice.GetTransactions().GetSpendableCoins();
                keys  = coins.Select(c => alice.GetKeyPath(c.ScriptPubKey))
                        .Select(k => aliceKey.Derive(k))
                        .ToArray();
                txBuilder = new TransactionBuilder();
                tx        =
                    txBuilder
                    .SetTransactionPolicy(new Policy.StandardTransactionPolicy()
                {
                    MinRelayTxFee = new FeeRate(0)
                })
                    .AddCoins(coins)
                    .AddKeys(keys)
                    .Send(bob.GetNextScriptPubKey(), Money.Coins(0.1m))
                    .SetChange(alice.GetNextScriptPubKey(true))
                    .SendFees(Money.Coins(0.0001m))
                    .BuildTransaction(true);

                Assert.True(txBuilder.Verify(tx));

                builder.Nodes[0].Broadcast(tx);

                //Bob still has coins
                TestUtils.Eventually(() => bob.GetTransactions().Count == 2);                 //Bob has both, old and new tx
                coins = bob.GetTransactions().GetSpendableCoins();
                //////
            }
        }