From ba7a4ff570a12c801ae8e149e86ddd98aa07f315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Malte=20Mo=CC=88ser?= Date: Mon, 6 Apr 2020 16:17:59 -0400 Subject: [PATCH 1/2] refactor: replace in(s)/out(s) with input(s)/output(s) Also prints a deprecation warning for users to switch to the consistent syntax. # Conflicts: # blockscipy/src/scripts/equiv_address/equiv_address_proxy_py.cpp --- .../src/cluster/cluster/cluster_proxy_py.cpp | 23 ++++++++++- blockscipy/src/cluster/cluster/cluster_py.cpp | 12 +++++- blockscipy/src/scripts/address_proxy_py.cpp | 38 +++++++++++++++++-- .../equiv_address/equiv_address_proxy_py.cpp | 24 ++++++++++++ .../equiv_address/equiv_address_py.cpp | 12 +++++- 5 files changed, 101 insertions(+), 8 deletions(-) diff --git a/blockscipy/src/cluster/cluster/cluster_proxy_py.cpp b/blockscipy/src/cluster/cluster/cluster_proxy_py.cpp index 150fdd6a..47f2fce6 100644 --- a/blockscipy/src/cluster/cluster/cluster_proxy_py.cpp +++ b/blockscipy/src/cluster/cluster/cluster_proxy_py.cpp @@ -24,18 +24,39 @@ struct AddClusterMethods { func(method_tag, "address_count", &Cluster::getSize, "The number of addresses in the cluster"); func(property_tag, "type_equiv_size", &Cluster::getTypeEquivSize, "The number of addresses in the cluster not counting type equivalent addresses"); func(method_tag, "balance", &Cluster::calculateBalance, "Calculates the balance held by this cluster at the height (Defaults to the full chain)", pybind11::arg("height") = -1); + func(method_tag, "out_txes_count", +[](Cluster &cluster) -> int64_t { + pybind11::print("Warning: `out_txes_count` is deprecated. Use `output_txes_count` instead."); + return cluster.getOutputTransactions().size(); + }, "Return the number of transactions where an address in this cluster was used in an output"); + func(method_tag, "output_txes_count", +[](Cluster &cluster) -> int64_t { return cluster.getOutputTransactions().size(); - }, "Return the number of transactions where this cluster was an output"); + }, "Return the number of transactions where an address in this cluster was used in an output"); + func(method_tag, "in_txes_count", +[](Cluster &cluster) -> int64_t { + pybind11::print("Warning: `in_txes_count` is deprecated. Use `input_txes_count` instead."); return cluster.getInputTransactions().size(); }, "Return the number of transactions where this cluster was an input"); + func(method_tag, "input_txes_count", +[](Cluster &cluster) -> int64_t { + return cluster.getInputTransactions().size(); + }, "Return the number of transactions where this cluster was an input"); + func(method_tag, "outs", +[](Cluster &cluster) -> RawIterator { + pybind11::print("Warning: `outs` is deprecated. Use `outputs` instead."); return cluster.getOutputs(); }, "Returns an iterator over all outputs sent to this cluster"); + func(method_tag, "outputs", +[](Cluster &cluster) -> RawIterator { + return cluster.getOutputs(); + }, "Returns an iterator over all outputs sent to this cluster"); + func(method_tag, "ins", +[](Cluster &cluster) -> RawIterator { + pybind11::print("Warning: `ins` is deprecated. Use `inputs` instead."); return cluster.getInputs(); }, "Returns an iterator over all inputs spent from this cluster"); + func(method_tag, "inputs", +[](Cluster &cluster) -> RawIterator { + return cluster.getInputs(); + }, "Returns an iterator over all inputs spent from this cluster"); + func(property_tag, "addresses", +[](const Cluster &cluster) -> RawIterator { return ranges::any_view{ranges::views::transform(cluster.getAddresses(), [](Address && address) -> AnyScript { return address.getScript(); diff --git a/blockscipy/src/cluster/cluster/cluster_py.cpp b/blockscipy/src/cluster/cluster/cluster_py.cpp index d86595a1..a47b1e03 100644 --- a/blockscipy/src/cluster/cluster/cluster_py.cpp +++ b/blockscipy/src/cluster/cluster/cluster_py.cpp @@ -84,8 +84,16 @@ void init_cluster(py::class_ &cl) { return cluster.clusterNum; }) .def("txes", &Cluster::getTransactions, "Returns a list of all transactions involving this cluster") - .def("in_txes",&Cluster::getInputTransactions, "Returns a list of all transaction where this cluster was an input") - .def("out_txes", &Cluster::getOutputTransactions, "Returns a list of all transaction where this cluster was an output") + .def("in_txes", [](Cluster &cluster){ + pybind11::print("Warning: `in_txes` is deprecated. Use `input_txes` instead."); + return cluster.getInputTransactions(); + }, "Returns a list of all transaction where this cluster was an input") + .def("input_txes", &Cluster::getInputTransactions, "Returns a list of all transaction where this cluster was an input") + .def("out_txes", [](Cluster &cluster){ + pybind11::print("Warning: `out_txes` is deprecated. Use `output_txes` instead."); + return cluster.getOutputTransactions(); + }, "Returns a list of all transaction where this cluster was an output") + .def("output_txes", &Cluster::getOutputTransactions, "Returns a list of all transaction where this cluster was an output") ; } diff --git a/blockscipy/src/scripts/address_proxy_py.cpp b/blockscipy/src/scripts/address_proxy_py.cpp index 6855b5a3..28cbacb4 100644 --- a/blockscipy/src/scripts/address_proxy_py.cpp +++ b/blockscipy/src/scripts/address_proxy_py.cpp @@ -55,27 +55,59 @@ struct AddAddressMethods { }, "The type of address"); func(method_tag, "equiv", &AnyScript::getEquivAddresses, "Returns a list of all addresses equivalent to this address", pybind11::arg("equiv_script") = true); func(method_tag, "balance", &AnyScript::calculateBalance, "Calculates the balance held by this address at the height (Defaults to the full chain)", pybind11::arg("height") = -1); + func(method_tag, "out_txes_count", +[](AnyScript &address) -> int64_t { + pybind11::print("Warning: `out_txes_count` is deprecated. Use `output_txes_count` instead."); + return ranges::distance(address.getOutputTransactions()); + }, "Return the number of transactions where this address appeared in an output"); + func(method_tag, "output_txes_count", +[](AnyScript &address) -> int64_t { return ranges::distance(address.getOutputTransactions()); - }, "Return the number of transactions where this address was an output"); + }, "Return the number of transactions where this address appeared in an output"); + func(method_tag, "in_txes_count", +[](AnyScript &address) -> int64_t { + pybind11::print("Warning: `in_txes_count` is deprecated. Use `input_txes_count` instead."); + return ranges::distance(address.getInputTransactions()); + }, "Return the number of transactions where this address appeared in an input"); + func(method_tag, "input_txes_count", +[](AnyScript &address) -> int64_t { return ranges::distance(address.getInputTransactions()); }, "Return the number of transactions where this address was an input"); + func(property_tag, "first_tx", &AnyScript::getFirstTransaction, "Get the first transaction that was sent to a type equivalent address"); func(property_tag, "revealed_tx", &AnyScript::getTransactionRevealed, "The transaction where a type equivalent address was first revealed"); func(property_tag, "has_been_spent", &AnyScript::hasBeenSpent, "Check if a type equivalent address has ever been spent"); + func(property_tag, "outs", +[](AnyScript &address) -> RawIterator { + pybind11::print("Warning: `outs` is deprecated. Use `outputs` instead."); + return address.getOutputs(); + }, "Returns a iterator over all outputs sent to this address"); + func(property_tag, "outputs", +[](AnyScript &address) -> RawIterator { return address.getOutputs(); }, "Returns a iterator over all outputs sent to this address"); + func(property_tag, "ins", +[](AnyScript &address) -> RawIterator { + pybind11::print("Warning: `ins` is deprecated. Use `inputs` instead."); + return address.getInputs(); + }, "Returns an iterator over all inputs spent from this address"); + func(property_tag, "inputs", +[](AnyScript &address) -> RawIterator { return address.getInputs(); }, "Returns an iterator over all inputs spent from this address"); + func(property_tag, "out_txes", +[](AnyScript &address) -> RawIterator { + pybind11::print("Warning: `out_txes` is deprecated. Use `output_txes` instead."); return address.getOutputTransactions(); - }, "Returns an iterator over all transactions where this address was an output"); + }, "Returns an iterator over all transactions where this address appeared in an output"); + func(property_tag, "output_txes", +[](AnyScript &address) -> RawIterator { + return address.getOutputTransactions(); + }, "Returns an iterator over all transactions where this address appeared in an output"); + func(property_tag, "in_txes", +[](AnyScript &address) -> RawIterator { + pybind11::print("Warning: `in_txes` is deprecated. Use `input_txes` instead."); return address.getInputTransactions(); - }, "Returns an iterator over all transactions where this address was an input"); + }, "Returns an iterator over all transactions where this address appeared an input"); + func(property_tag, "input_txes", +[](AnyScript &address) -> RawIterator { + return address.getInputTransactions(); + }, "Returns an iterator over all transactions where this address appeared an input"); + func(property_tag, "txes", +[](AnyScript &address) -> RawIterator { return address.getTransactions(); }, "Returns an iterator over all transactions involving this address"); diff --git a/blockscipy/src/scripts/equiv_address/equiv_address_proxy_py.cpp b/blockscipy/src/scripts/equiv_address/equiv_address_proxy_py.cpp index c7912ab7..d6c841d7 100644 --- a/blockscipy/src/scripts/equiv_address/equiv_address_proxy_py.cpp +++ b/blockscipy/src/scripts/equiv_address/equiv_address_proxy_py.cpp @@ -35,20 +35,44 @@ struct AddEquivAddressMethods { }); }) | ranges::views::join; }, "Calculate balance"); + + func(property_tag, "outputs", +[](const EquivAddress &address) -> RawIterator { + return ranges::views::ints(0, 1) | ranges::views::transform([address](int) { + return address.getOutputs(); + }) | ranges::views::join; + }, "Returns an iterator over all outputs sent to these equivalent addresses"); func(property_tag, "outs", +[](const EquivAddress &address) -> RawIterator { + pybind11::print("Warning: `outs` is deprecated. Use `outputs` instead."); return ranges::views::ints(0, 1) | ranges::views::transform([address](int) { return address.getOutputs(); }) | ranges::views::join; }, "Returns an iterator over all outputs sent to these equivalent addresses"); + + func(property_tag, "inputs", +[](EquivAddress &address) -> RawIterator { + return ranges::views::ints(0, 1) | ranges::views::transform([address](int) { + return address.getInputs(); + }) | ranges::views::join; + }, "Returns an iterator over all inputs spent from these equivalent addresses"); func(property_tag, "ins", +[](EquivAddress &address) -> RawIterator { + pybind11::print("Warning: `ins` is deprecated. Use `inputs` instead."); return ranges::views::ints(0, 1) | ranges::views::transform([address](int) { return address.getInputs(); }) | ranges::views::join; }, "Returns an iterator over all inputs spent from these equivalent addresses"); + + func(method_tag, "output_txes_count", +[](EquivAddress &address) -> int64_t { + return address.getOutputTransactions().size(); + }, "Return the number of transactions where these equivalent addresses were an output"); func(method_tag, "out_txes_count", +[](EquivAddress &address) -> int64_t { + pybind11::print("Warning: `out_txes_count` is deprecated. Use `output_txes_count` instead."); return address.getOutputTransactions().size(); }, "Return the number of transactions where these equivalent addresses were an output"); + + func(method_tag, "input_txes_count", +[](EquivAddress &address) -> int64_t { + return address.getInputTransactions().size(); + }, "Return the number of transactions where these equivalent addresses were an input"); func(method_tag, "in_txes_count", +[](EquivAddress &address) -> int64_t { + pybind11::print("Warning: `in_txes_count` is deprecated. Use `input_txes_count` instead."); return address.getInputTransactions().size(); }, "Return the number of transactions where these equivalent addresses were an input"); } diff --git a/blockscipy/src/scripts/equiv_address/equiv_address_py.cpp b/blockscipy/src/scripts/equiv_address/equiv_address_py.cpp index 9ad3c14a..a650276a 100644 --- a/blockscipy/src/scripts/equiv_address/equiv_address_py.cpp +++ b/blockscipy/src/scripts/equiv_address/equiv_address_py.cpp @@ -27,8 +27,16 @@ void init_equiv_address(py::class_ &cl) { .def("__len__", [](const EquivAddress &address) { return address.size(); }) .def("__bool__", [](const EquivAddress &address) { return address.size() == 0; }) .def("txes", &EquivAddress::getTransactions, "Returns a list of all transactions involving these equivalent addresses") - .def("out_txes", &EquivAddress::getOutputTransactions, "Returns a range of all transaction where these equivalent addresses were an output") - .def("in_txes", &EquivAddress::getInputTransactions, "Returns a list of all transaction where these equivalent addresses were an input") + .def("output_txes", &EquivAddress::getOutputTransactions, "Returns a range of all transaction where these equivalent addresses were an output") + .def("out_txes", [](EquivAddress &address) { + pybind11::print("Warning: `out_txes` is deprecated. Use `output_txes` instead."); + return address.getOutputTransactions(); + }, "Returns a range of all transaction where these equivalent addresses were an output") + .def("input_txes", &EquivAddress::getInputTransactions, "Returns a list of all transaction where these equivalent addresses were an input") + .def("in_txes", [](EquivAddress &address) { + pybind11::print("Warning: `in_txes` is deprecated. Use `input_txes` instead."); + return address.getInputTransactions(); + }, "Returns a list of all transaction where these equivalent addresses were an input") .def_property_readonly("addresses", +[](EquivAddress &address) -> std::unordered_set
{ return {address.begin(), address.end()}; }, "Returns an iterator over the addresses that make up this equivalent address"); From 74d8a72b46667c037f32ac6d399c1b047f320877 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Malte=20Mo=CC=88ser?= Date: Tue, 7 Apr 2020 13:23:10 -0400 Subject: [PATCH 2/2] test: replace deprecated methods in regression tests --- test/blockscipy/test_addresses.py | 12 ++++++------ test/blockscipy/test_clustering.py | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/test/blockscipy/test_addresses.py b/test/blockscipy/test_addresses.py index 570c0e4c..cdaf0042 100644 --- a/test/blockscipy/test_addresses.py +++ b/test/blockscipy/test_addresses.py @@ -86,12 +86,12 @@ def test_address_regression(chain, json_data, regtest, chain_name): print(addr.balance(), file=regtest) print(addr.equiv(), file=regtest) print(addr.has_been_spent, file=regtest) - print(addr.ins.to_list(), file=regtest) - print(sorted_tx_list(addr.in_txes), file=regtest) - print(addr.in_txes_count(), file=regtest) - print(sorted_tx_list(addr.out_txes), file=regtest) - print(addr.out_txes_count(), file=regtest) - print(addr.outs.to_list(), file=regtest) + print(addr.inputs.to_list(), file=regtest) + print(sorted_tx_list(addr.input_txes), file=regtest) + print(addr.input_txes_count(), file=regtest) + print(sorted_tx_list(addr.output_txes), file=regtest) + print(addr.output_txes_count(), file=regtest) + print(addr.outputs.to_list(), file=regtest) if addr_type == "p2pkh" or addr_type == "p2wpkh": print(addr.pubkey, file=regtest) print(addr.pubkeyhash, file=regtest) diff --git a/test/blockscipy/test_clustering.py b/test/blockscipy/test_clustering.py index f8e8700a..8f486aa5 100644 --- a/test/blockscipy/test_clustering.py +++ b/test/blockscipy/test_clustering.py @@ -83,13 +83,13 @@ def test_clustering_no_change(chain, json_data, regtest, tmpdir_factory): print(cluster.count_of_type(blocksci.address_type.scripthash), file=regtest) print(cluster.count_of_type(blocksci.address_type.witness_pubkeyhash), file=regtest) print(cluster.count_of_type(blocksci.address_type.witness_scripthash), file=regtest) - print(sorted_tx_list(cluster.in_txes()), file=regtest) - print(cluster.in_txes_count(), file=regtest) - print(cluster.ins().to_list(), file=regtest) + print(sorted_tx_list(cluster.input_txes()), file=regtest) + print(cluster.input_txes_count(), file=regtest) + print(cluster.inputs().to_list(), file=regtest) print(sorted_tx_list(cluster.txes()), file=regtest) - print(sorted_tx_list(cluster.out_txes()), file=regtest) - print(cluster.out_txes_count(), file=regtest) - print(cluster.outs().to_list(), file=regtest) + print(sorted_tx_list(cluster.output_txes()), file=regtest) + print(cluster.output_txes_count(), file=regtest) + print(cluster.outputs().to_list(), file=regtest) print(cluster.address_count(), file=regtest) print(cluster.txes(), file=regtest) print(cluster.type_equiv_size, file=regtest)