Skip to content

Commit

Permalink
Fix some gaps and mistakes in the python interface
Browse files Browse the repository at this point in the history
  • Loading branch information
hkalodner committed Apr 24, 2018
1 parent 00bcfe1 commit 9a9901d
Show file tree
Hide file tree
Showing 18 changed files with 251 additions and 79 deletions.
3 changes: 3 additions & 0 deletions src/blocksci/include/blocksci/scripts/nonstandard_script.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

#include <range/v3/utility/optional.hpp>

#include <string>
#include <sstream>

namespace blocksci {
template <>
class BLOCKSCI_EXPORT ScriptAddress<AddressType::NONSTANDARD> : public ScriptBase {
Expand Down
1 change: 1 addition & 0 deletions src/clusterer/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <blocksci/chain/blockchain.hpp>
#include <blocksci/cluster/cluster_manager.hpp>
#include <blocksci/heuristics/change_address.hpp>

#include <clipp.h>

Expand Down
3 changes: 0 additions & 3 deletions src/python-interface/blockchain_py.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,6 @@ void init_blockchain(py::module &m) {
;

auto blockchainCl = addRangeClass<Blockchain>(m, "Blockchain", "Class representing the blockchain. This class is contructed by passing it a string representing a file path to your BlockSci data files generated by blocksci_parser", py::dynamic_attr());
addBlockRangeMethods(blockchainCl, [](Blockchain &view, auto func) {
return func(view);
});
blockchainCl
.def(py::init<std::string>())
.def(py::init<DataConfiguration>())
Expand Down
19 changes: 9 additions & 10 deletions src/python-interface/caster_py.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,15 @@
#include <mpark/variant.hpp>

namespace pybind11 { namespace detail {

// Specifies the function used to visit the variant -- `apply_visitor` instead of `visit`
template <>
struct visit_helper<mpark::variant> {
template <typename... Args>
static auto call(Args &&...args) -> decltype(mpark::visit(args...)) {
return mpark::visit(args...);
}
};

template <> struct type_caster<blocksci::AnyScript> {
private:
using value_conv = make_caster<blocksci::ScriptVariant>;
Expand All @@ -44,15 +52,6 @@ namespace pybind11 { namespace detail {

template <typename... Ts>
struct type_caster<mpark::variant<Ts...>> : variant_caster<mpark::variant<Ts...>> {};

// Specifies the function used to visit the variant -- `apply_visitor` instead of `visit`
template <>
struct visit_helper<mpark::variant> {
template <typename... Args>
static auto call(Args &&...args) -> decltype(mpark::visit(args...)) {
return mpark::visit(args...);
}
};
}}

#endif /* caster_py_hpp */
1 change: 1 addition & 0 deletions src/python-interface/cluster_py.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include <blocksci/cluster/cluster.hpp>
#include <blocksci/cluster/cluster_manager.hpp>
#include <blocksci/heuristics/change_address.hpp>

#include <blocksci/chain/blockchain.hpp>
#include <blocksci/chain/block.hpp>
Expand Down
15 changes: 9 additions & 6 deletions src/python-interface/input_range_py.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,26 @@
#include "ranges_py.hpp"
#include "range_apply_py.hpp"

namespace py = pybind11;
using namespace blocksci;

template <typename Range, typename Class, typename FuncApplication>
struct AddInputRangeMethods {
void operator()(Class &cl, FuncApplication func) {
cl
.def("sent_before", func([](Range &range, BlockHeight height) {
return inputsCreatedBeforeHeight(r, height);
.def("sent_before", func([](Range &&range, BlockHeight height) {
return inputsCreatedBeforeHeight(range, height);
}), "Returns a range including the subset of inputs which spent an output created before the given height")
.def("sent_after", func([](Range &range, blocksci::BlockHeight height) {
.def("sent_after", func([](Range &&range, BlockHeight height) {
return inputsCreatedAfterHeight(range, height);
}), "Returns a range including the subset of inputs which spent an output created after the given height")
.def("sent_within", func([](Range &range, blocksci::BlockHeight height) {
.def("sent_within", func([](Range &&range, BlockHeight height) {
return inputsCreatedWithinRelativeHeight(range, height);
}), "Returns a range including the subset of inputs which spent an output created more than a given number of blocks before the input")
.def("sent_outside", func([](Range &range, blocksci::BlockHeight height) {
.def("sent_outside", func([](Range &&range, BlockHeight height) {
return inputsCreatedOutsideRelativeHeight(range, height);
}), "Returns a range including the subset of inputs which spent an output created less than a given number of blocks before the input")
.def("with_type", func([](Range &range, AddressType::Enum type) {
.def("with_type", func([](Range && range, AddressType::Enum type) {
return inputsOfType(range, type);
}), "Return a range including only inputs sent to the given address type")
;
Expand Down
19 changes: 19 additions & 0 deletions src/python-interface/multisig_pubkey_range_py.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// multisig_pubkey_range_py.cpp
// blocksci
//
// Created by Harry Kalodner on 4/23/18.
//
//

#include "pubkey_range_py.hpp"

#include <blocksci/scripts/pubkey_script.hpp>
#include <blocksci/scripts/multisig_pubkey_script.hpp>

using namespace blocksci;
namespace py = pybind11;

void init_multisig_pubkey_range(py::module &m) {
setupRanges<script::MultisigPubkey>(m, "MultisigPubkey");
}
15 changes: 15 additions & 0 deletions src/python-interface/multisig_py.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//

#include "multisig_py.hpp"
#include "address_py.hpp"
#include "caster_py.hpp"
#include "ranges_py.hpp"
#include "range_apply_py.hpp"
Expand All @@ -18,6 +19,13 @@ namespace py = pybind11;
template <typename T>
auto addMultisigRange(py::module &m, const std::string &name) {
auto cl = addRangeClass<T>(m, name);
addAddressMethods<ScriptBase>(cl, [](auto func) {
return applyMethodsToRange<T>(func);
}, [](std::string docstring) {
std::stringstream ss;
ss << "For each multisig: " << docstring;
return strdup(ss.str().c_str());
});
addMultisigMethods(cl, [](auto func) {
return applyMethodsToRange<T>(func);
}, [](std::string docstring) {
Expand All @@ -31,6 +39,13 @@ auto addMultisigRange(py::module &m, const std::string &name) {
template <typename T>
auto addOptionalMultisigRange(py::module &m, const std::string &name) {
auto cl = addOptionalRangeClass<T>(m, name);
addAddressMethods<ScriptBase>(cl, [](auto func) {
return applyMethodsToRange<T>(func);
}, [](std::string docstring) {
std::stringstream ss;
ss << "For each multisig: " << docstring;
return strdup(ss.str().c_str());
});
addMultisigMethods(cl, [](auto func) {
return applyMethodsToRange<T>(func);
}, [](std::string docstring) {
Expand Down
19 changes: 17 additions & 2 deletions src/python-interface/nonstandard_py.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//

#include "nonstandard_py.hpp"
#include "address_py.hpp"
#include "caster_py.hpp"
#include "ranges_py.hpp"
#include "range_apply_py.hpp"
Expand All @@ -18,11 +19,18 @@ namespace py = pybind11;
template <typename T>
auto addNonstandardRange(py::module &m, const std::string &name) {
auto cl = addRangeClass<T>(m, name);
addAddressMethods<ScriptBase>(cl, [](auto func) {
return applyMethodsToRange<T>(func);
}, [](std::string docstring) {
std::stringstream ss;
ss << "For each nonstandard address: " << docstring;
return strdup(ss.str().c_str());
});
addNonstandardMethods(cl, [](auto func) {
return applyMethodsToRange<T>(func);
}, [](std::string docstring) {
std::stringstream ss;
ss << "For each multisig: " << docstring;
ss << "For each nonstandard address: " << docstring;
return strdup(ss.str().c_str());
});
return cl;
Expand All @@ -31,11 +39,18 @@ auto addNonstandardRange(py::module &m, const std::string &name) {
template <typename T>
auto addOptionalNonstandardRange(py::module &m, const std::string &name) {
auto cl = addOptionalRangeClass<T>(m, name);
addAddressMethods<ScriptBase>(cl, [](auto func) {
return applyMethodsToRange<T>(func);
}, [](std::string docstring) {
std::stringstream ss;
ss << "For each nonstandard address: " << docstring;
return strdup(ss.str().c_str());
});
addNonstandardMethods(cl, [](auto func) {
return applyMethodsToRange<T>(func);
}, [](std::string docstring) {
std::stringstream ss;
ss << "For each multisig: " << docstring;
ss << "For each nonstandard address: " << docstring;
return strdup(ss.str().c_str());
});
return cl;
Expand Down
19 changes: 17 additions & 2 deletions src/python-interface/nulldata_py.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//

#include "nulldata_py.hpp"
#include "address_py.hpp"
#include "caster_py.hpp"
#include "ranges_py.hpp"
#include "range_apply_py.hpp"
Expand All @@ -18,11 +19,18 @@ namespace py = pybind11;
template <typename T>
auto addNulldataRange(py::module &m, const std::string &name) {
auto cl = addRangeClass<T>(m, name);
addAddressMethods<ScriptBase>(cl, [](auto func) {
return applyMethodsToRange<T>(func);
}, [](std::string docstring) {
std::stringstream ss;
ss << "For each op_return: " << docstring;
return strdup(ss.str().c_str());
});
addOpReturnMethods(cl, [](auto func) {
return applyMethodsToRange<T>(func);
}, [](std::string docstring) {
std::stringstream ss;
ss << "For each multisig: " << docstring;
ss << "For each op_return: " << docstring;
return strdup(ss.str().c_str());
});
return cl;
Expand All @@ -31,11 +39,18 @@ auto addNulldataRange(py::module &m, const std::string &name) {
template <typename T>
auto addOptionalNulldataRange(py::module &m, const std::string &name) {
auto cl = addOptionalRangeClass<T>(m, name);
addAddressMethods<ScriptBase>(cl, [](auto func) {
return applyMethodsToRange<T>(func);
}, [](std::string docstring) {
std::stringstream ss;
ss << "For each op_return: " << docstring;
return strdup(ss.str().c_str());
});
addOpReturnMethods(cl, [](auto func) {
return applyMethodsToRange<T>(func);
}, [](std::string docstring) {
std::stringstream ss;
ss << "For each multisig: " << docstring;
ss << "For each op_return: " << docstring;
return strdup(ss.str().c_str());
});
return cl;
Expand Down
18 changes: 11 additions & 7 deletions src/python-interface/output_range_py.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,31 @@
#include "ranges_py.hpp"
#include "range_apply_py.hpp"

namespace py = pybind11;

using namespace blocksci;

template <typename Range, typename Class, typename FuncApplication>
struct AddOutputRangeMethods {
void operator()(Class &cl, FuncApplication func) {
cl
.def_property_readonly("unspent", func([=](Range &range) {
.def_property_readonly("unspent", func([=](Range && range) {
return outputsUnspent(range);
}), "Returns a range including the subset of outputs which were never spent")
.def("spent_before", func([=](Range &range, blocksci::BlockHeight height) {
.def("spent_before", func([](Range && range, BlockHeight height) {
return outputsSpentBeforeHeight(range, height);
}), "Returns a range including the subset of outputs which were spent before the given height")
.def("spent_after", func([=](Range &range, blocksci::BlockHeight height) {
.def("spent_after", func([](Range && range, BlockHeight height) {
return outputsSpentAfterHeight(range, height);
}), "Returns a range including the subset of outputs which were spent after the given height")
.def("spent_within", func([=](Range &range, blocksci::BlockHeight height) {
.def("spent_within", func([](Range && range, BlockHeight height) {
return outputsSpentWithinRelativeHeight(range, height);
}), "Returns a range including the subset of outputs which were spent within the given number of blocks")
.def("spent_outside", func([=](Range &range, blocksci::BlockHeight height) {
.def("spent_outside", func([](Range && range, BlockHeight height) {
return outputsSpentOutsideRelativeHeight(range, height);
}), "Returns a range including the subset of outputs which were spent later than the given number of blocks")
.def("with_type", func([=](Range &range, blocksci::AddressType::Enum type) {
return outputsOfType(std::forward<decltype(r)>(r), type);
.def("with_type", func([](Range && range, AddressType::Enum type) {
return outputsOfType(range, type);
}), "Returns a range including the subset of outputs which were sent to the given address type")
;
}
Expand Down
50 changes: 1 addition & 49 deletions src/python-interface/pubkey_py.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@
//

#include "pubkey_py.hpp"
#include "address_py.hpp"
#include "caster_py.hpp"
#include "ranges_py.hpp"
#include "range_apply_py.hpp"
#include "self_apply_py.hpp"

#include <blocksci/scripts/pubkey_script.hpp>
Expand All @@ -18,48 +17,6 @@
using namespace blocksci;
namespace py = pybind11;

template <typename T, typename T2>
auto addPubkeyRange(py::module &m, const std::string &name) {
auto cl = addRangeClass<T>(m, name);
addPubkeyBaseMethods<T2>(cl, [](auto func) {
return applyMethodsToRange<T>(func);
}, [](std::string docstring) {
std::stringstream ss;
ss << "For each scripthash: " << docstring;
return strdup(ss.str().c_str());
});
return cl;
}

template <typename T, typename T2>
auto addOptionalPubkeyRange(py::module &m, const std::string &name) {
auto cl = addOptionalRangeClass<T>(m, name);
addPubkeyBaseMethods<T2>(cl, [](auto func) {
return applyMethodsToRange<T>(func);
}, [](std::string docstring) {
std::stringstream ss;
ss << "For each scripthash: " << docstring;
return strdup(ss.str().c_str());
});
return cl;
}

template <typename T>
void setupRanges(py::module &m, const std::string &name) {
std::stringstream ss;
ss << "Any" << name << "Range";
addPubkeyRange<ranges::any_view<T>, T>(m, ss.str());
ss.clear();
ss << name << "Range";
addPubkeyRange<ranges::any_view<T, ranges::category::random_access>, T>(m, ss.str());
ss.clear();
ss << name << "AnyOptional" << name << "Range";
addOptionalPubkeyRange<ranges::any_view<ranges::optional<T>>, T>(m, ss.str());
ss.clear();
ss << name << "Optional" << name << "Range";
addOptionalPubkeyRange<ranges::any_view<ranges::optional<T>, ranges::category::random_access>, T>(m, ss.str());
}

void init_pubkey(py::module &m, py::class_<blocksci::ScriptBase> &addressCl) {
py::class_<script::Pubkey> pubkeyAddressCl(m, "PubkeyAddress", addressCl, "Extra data about pay to pubkey address");
pubkeyAddressCl
Expand Down Expand Up @@ -108,9 +65,4 @@ void init_pubkey(py::module &m, py::class_<blocksci::ScriptBase> &addressCl) {
}, [](auto && docstring) {
return std::forward<decltype(docstring)>(docstring);
});

setupRanges<script::Pubkey>(m, "PubkeyAddress");
setupRanges<script::PubkeyHash>(m, "PubkeyHashAddress");
setupRanges<script::WitnessPubkeyHash>(m, "WitnessPubkeyHashAddress");
setupRanges<script::MultisigPubkey>(m, "MultisigPubkey");
}
16 changes: 16 additions & 0 deletions src/python-interface/pubkey_range_py.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// pubkey_range_py.cpp
// blocksci
//
// Created by Harry Kalodner on 4/23/18.
//
//

#include "pubkey_range_py.hpp"

using namespace blocksci;
namespace py = pybind11;

void init_pubkey_range(py::module &m) {
setupRanges<script::Pubkey>(m, "PubkeyAddress");
}
Loading

0 comments on commit 9a9901d

Please sign in to comment.