Verified Commit ae6fb566 authored by Tom Zander's avatar Tom Zander

Merge branch 'master' into httpengine

parents 01641773 e168e390
Pipeline #65148271 passed with stages
in 26 minutes and 3 seconds
......@@ -108,9 +108,6 @@ flowee-deb:
- dpkg-deb --build $PACKAGE_NAME
dependencies:
- build-static
only:
- master
- "2019.05"
artifacts:
paths:
- ${PACKAGE_NAME}.deb
......@@ -127,9 +124,6 @@ flowee-linux.zip:
- ${PACKAGE_NAME}
dependencies:
- build-static
only:
- master
- "2019.05"
createHubDocker:
stage: deploy
......@@ -144,6 +138,13 @@ createHubDocker:
dependencies:
- build-static
allow_failure: true
only:
refs:
- branches
variables:
- $DOCKER_TOKEN
except:
- master
##### Build as standard as it gets.
......
......@@ -25,6 +25,7 @@
#include <qsettings.h>
#include <qdatetime.h>
#include <primitives/pubkey.h>
#include <netbase.h>
#include <qfile.h>
#include <qcoreapplication.h>
......@@ -61,24 +62,73 @@ void Indexer::tryConnectHub(const EndPoint &ep)
void Indexer::bind(boost::asio::ip::tcp::endpoint endpoint)
{
m_network.bind(endpoint, std::bind(&Indexer::clientConnected, this, std::placeholders::_1));
m_isServer = true;
}
void Indexer::loadConfig(const QString &filename)
{
using boost::asio::ip::tcp;
if (!QFile::exists(filename))
return;
QSettings settings(filename, QSettings::IniFormat);
const QStringList groups = settings.childGroups();
if (groups.contains("addressdb")) {
m_enableAddressDb = settings.value("addressdb/enabled", "true").toBool();
if (m_enableAddressDb)
m_addressdb.loadSetting(settings);
}
if (groups.contains("txdb")) {
m_enableTxDB = settings.value("txdb/enabled", "true").toBool();
// no config there yet
for (auto group : groups) {
if (group == "addressdb") {
m_enableAddressDb = settings.value("addressdb/enabled", "true").toBool();
if (m_enableAddressDb)
m_addressdb.loadSetting(settings);
}
else if (group == "txdb") {
m_enableTxDB = settings.value("txdb/enabled", "true").toBool();
// no config there yet
}
else if (group == "services") {
if (!m_serverConnection.isValid()) { // only if user didn't override using commandline
QString connectionString = settings.value("services/hub").toString();
EndPoint ep("", 1234);
SplitHostPort(connectionString.toStdString(), ep.announcePort, ep.hostname);
try {
tryConnectHub(ep);
} catch (const std::exception &e) {
logFatal() << "Config: Hub connection string invalid.";
}
}
}
else {
EndPoint ep("", 1234);
auto portVar = settings.value(group + "/port");
if (portVar.isValid()) {
bool ok;
ep.announcePort = portVar.toInt(&ok);
if (!ok) {
logCritical() << "Config file has 'port' value that is not a number.";
continue;
}
}
try {
QString bindAddress = settings.value(group + "/ip").toString();
ep.ipAddress = bindAddress == "localhost"
? boost::asio::ip::address_v4::loopback()
: boost::asio::ip::address::from_string(bindAddress.toStdString());
} catch (const std::runtime_error &e) {
logCritical() << "Config file has invalid IP address value to bind to.";
continue;
}
logCritical().nospace() << "Binding to " << ep.ipAddress.to_string().c_str() << ":" << ep.announcePort;
try {
bind(tcp::endpoint(ep.ipAddress, ep.announcePort));
} catch (std::exception &e) {
logCritical() << " " << e << "skipping";
}
}
}
if (!m_isServer) // then add localhost
bind(tcp::endpoint(boost::asio::ip::address_v4::loopback(), 1234));
if (!m_isServer) // then add localhost ipv6
bind(tcp::endpoint(boost::asio::ip::address_v6::loopback(), 1234));
}
void Indexer::onIncomingMessage(NetworkService::Remote *con, const Message &message, const EndPoint &)
......
......@@ -69,6 +69,7 @@ private:
bool m_enableTxDB = true, m_enableAddressDb = false;
bool m_indexingFinished = false;
bool m_isServer = false; /// remembers if we (successfully) called m_network::bind() once.
int m_lastRequestedBlock = 0;
quint64 m_timeLastRequest = 0;
......
......@@ -70,8 +70,8 @@ void IndexerClient::tryConnectIndexer(const EndPoint &ep)
throw std::runtime_error("Invalid Endpoint, can't create connection");
#ifndef NDEBUG
m_indexConnection.setOnConnected(std::bind(&IndexerClient::indexerConnected, this, std::placeholders::_1));
m_indexConnection.setOnDisconnected(std::bind(&IndexerClient::indexerDisconnected, this));
#endif
m_indexConnection.setOnDisconnected(std::bind(&IndexerClient::indexerDisconnected, this));
m_indexConnection.setOnIncomingMessage(std::bind(&IndexerClient::onIncomingIndexerMessage, this, std::placeholders::_1));
m_indexConnection.connect();
}
......@@ -185,7 +185,15 @@ void IndexerClient::onIncomingIndexerMessage(const Message &message)
QCoreApplication::quit();
m_txIdsRequested = usageId;
}
else
else if (message.messageId() == Api::Indexer::GetAvailableIndexersReply) {
Streaming::MessageParser parser(message);
while (parser.next() == Streaming::FoundTag) {
if (parser.tag() == Api::Indexer::AddressIndexer)
logCritical() << "Info: remote indexer has Address Index";
else if (parser.tag() == Api::Indexer::TxIdIndexer)
logCritical() << "Info: remote indexer has TXID Index";
}
} else
Streaming::MessageParser::debugMessage(message);
}
else if (message.serviceId() == Api::BlockChainService && message.messageId() == Api::BlockChain::GetTransactionReply) {
......
Indexer
There are 2 executables in this directory;
* indexer
* indexer-cli
The first is meant to be run as a server, connecting to a running instance
of the Hub, and making available services of its own. By default listening
on port 1234.
The indexer-cli app is essentially a testing application for this service,
but likely people can find nice usages for it as-is.
# Setup Indexer
###############
The indexer has the following --help message;
Usage: ./bin/indexer [options]
Indexing server
Options:
-h, --help Displays this help.
--datadir, -d <DIR> The directory to put the data in
--conf <FILENAME> config file
--debug Use debug level logging
--version Display version
--connect <ADDRESS> server location and port
--bind <IP-ADDRESS> Bind to this IP:port
The indexer has two (optional) indexes it can make and those take a good
amount of space and a relatively large amount of time to build.
They both store data (various gigabytes of it) in a datadirectory.
The default is `~/.local/share/flowee/indexer`, you can pass a different
directory to the command line to change this.
To connect to a running Hub you can pass an hostname:port string to the
--connect commandline argument, or you can specify it in the config file.
See below for an example config file.
TO allow others to connect you can bind to one or more addresses by
providing one or more --bind options on the commandline or providing
the connection data in the config file.
#Indexer example config file
###########################
[txdb]
enabled=true
# The AddressDB is pretty big, we can turn it on later..
[addressdb]
enabled=false
# Indexer 'addressdb' requires a SQL server.
db_driver=QSQLITE
db_hostname=myServer
db_database=flowee
db_username=flowee_indexer
# The Hub server address, with optional port.
[services]
#hub=router:1235
hub=localhost
# Listen on localhost
[localhost]
ip=localhost
port=1234
# Listen on another network as well
[intranet]
ip=192.168.4.120
port=1234
#######################
# Indexer-cli example usage
###########################
Usage: ./indexer/indexer-cli [options] [TXID|ADDRESS]
Indexing client
Options:
-h, --help Displays this help.
--hub <HOSTNAME> Hub server address
--version Display version
--connect <ADDRESS> server location and port
--verbose, -v Be more verbose
--quiet, -q Be quiet, only errors are shown
Arguments:
[TXID|ADDRESS] The things you want to lookup
Here a simple output of the lookup of a transaction, by txid.
The first line prints the transaction location. Which is a block-height and
an offset-in-block (in bytes).
In this case we also connect the 'cli' app to a running Hub and thus we
manage to get the actual transaction as well.
Note; the '8000' on both lines is the logging category of the indexer
component.
$./indexer-cli --hub=localhost 1a7482a97b77f11d9d6b903512143a20a61a8bc84e2d5b9ff9552ee5eb76c1ca
18:07:21 [8000] Transaction location is: [block=119999+2897]
.966 [8000] 01000000019150d4f86cfb3805f0cf03ef3f227a3815e47fb46c4358db2b4689baa4d6c1ba000000008b4830450220373f49be9518df175e226053a402ebd850f622927fbd575907fbf99305abaa0d022100f2e84d2e1ca31924234f6f0a851dd3057df808ef4a758eed63d6eefc7b54e76301410437eb0c82969d76cddbf237dc9ff22c19389901c2b552e4ad824230b791cdfe067e1f62b9415225d7c6dddb906eab7dd6604f29f30f25bc07eb07999f691f2ac9ffffffff0280c3db7b000000001976a914bd9df061f893b011d1640104c2fd817039d0596388ac008c7d0a000000001976a9147b67c513d9091489299ec4f3eb0028da61502ee588ac00000000
......@@ -31,7 +31,7 @@ int main(int argc, char **argv)
QCommandLineParser parser;
parser.setApplicationDescription("Indexing client");
parser.addHelpOption();
parser.addPositionalArgument("[TXID|ADDERSS]", "The things you want to lookup");
parser.addPositionalArgument("[TXID|ADDRESS]", "The things you want to lookup");
QCommandLineOption hub(QStringList() << "hub", "Hub server address", "HOSTNAME");
parser.addOption(hub);
......@@ -42,15 +42,8 @@ int main(int argc, char **argv)
auto args = parser.positionalArguments();
if (args.isEmpty())
parser.showHelp(1);
if (args.size() == 1) // nothing to lookup
return 0;
IndexerClient client;
client.tryConnectIndexer(app.serverAddressFromArguments(1234));
for (auto a : args.mid(1)) {
client.resolve(a);
}
if (parser.isSet(hub)) {
EndPoint ep;
uint16_t port = 1235;
......@@ -58,5 +51,10 @@ int main(int argc, char **argv)
ep.announcePort = port;
client.tryConnectHub(ep);
}
client.tryConnectIndexer(app.serverAddressFromArguments(1234));
for (auto a : args) {
client.resolve(a);
}
return app.exec();
}
......@@ -48,27 +48,23 @@ int main(int argc, char **argv)
basedir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
Indexer indexer(basedir.toStdString());
QString confFile;
if (parser.isSet(conf))
confFile = parser.value(conf);
else
confFile = QStandardPaths::locate(QStandardPaths::AppConfigLocation, "indexer.conf");
indexer.loadConfig(confFile);
// become a server
bool server = false;
for (auto ep : app.bindingEndPoints(parser, 1234)) {
logCritical().nospace() << "Binding to " << ep.address().to_string().c_str() << ":" << ep.port();
server = true;
try {
indexer.bind(ep);
} catch (std::exception &e) {
logCritical() << " " << e << "skipping";
}
}
if (!server)
logCritical() << "Please note you need pass 'bind' to the commandline to be a server";
indexer.tryConnectHub(app.serverAddressFromArguments(1235));
QString confFile;
if (parser.isSet(conf))
confFile = parser.value(conf);
else
confFile = QStandardPaths::locate(QStandardPaths::AppConfigLocation, "indexer.conf");
indexer.loadConfig(confFile);
return app.exec();
}
......@@ -247,13 +247,13 @@ struct TransactionSerializationOptions
CScript scriptPubKey(iter.byteData());
std::vector<std::vector<unsigned char> > vSolutions;
txnouttype whichType;
bool recognizedTx = Solver(scriptPubKey, whichType, vSolutions);
if (recognizedTx && (whichType == TX_PUBKEY || whichType == TX_PUBKEYHASH)) {
if (whichType == TX_PUBKEYHASH) {
Script::TxnOutType whichType;
bool recognizedTx = Script::solver(scriptPubKey, whichType, vSolutions);
if (recognizedTx && (whichType == Script::TX_PUBKEY || whichType == Script::TX_PUBKEYHASH)) {
if (whichType == Script::TX_PUBKEYHASH) {
assert(vSolutions[0].size() == 20);
builder.addByteArray(Api::BlockChain::Tx_Out_Address, vSolutions[0].data(), 20);
} else if (whichType == TX_PUBKEY) {
} else if (whichType == Script::TX_PUBKEY) {
CPubKey pubKey(vSolutions[0]);
assert (pubKey.IsValid());
CKeyID address = pubKey.GetID();
......@@ -402,13 +402,13 @@ public:
CScript scriptPubKey(iter.byteData());
std::vector<std::vector<unsigned char> > vSolutions;
txnouttype whichType;
bool recognizedTx = Solver(scriptPubKey, whichType, vSolutions);
if (recognizedTx && (whichType == TX_PUBKEY || whichType == TX_PUBKEYHASH)) {
Script::TxnOutType whichType;
bool recognizedTx = Script::solver(scriptPubKey, whichType, vSolutions);
if (recognizedTx && (whichType == Script::TX_PUBKEY || whichType == Script::TX_PUBKEYHASH)) {
CKeyID keyID;
if (whichType == TX_PUBKEYHASH)
if (whichType == Script::TX_PUBKEYHASH)
keyID = CKeyID(uint160(vSolutions[0]));
else if (whichType == TX_PUBKEY)
else if (whichType == Script::TX_PUBKEY)
keyID = CPubKey(vSolutions[0]).GetID();
if (session->keys.find(keyID) != session->keys.end())
txMatched = true;
......
......@@ -97,14 +97,14 @@ void AddressMonitorService::findTransactions(Tx::Iterator && iter, FindReason fi
CScript scriptPubKey(iter.byteData());
std::vector<std::vector<unsigned char> > vSolutions;
txnouttype whichType;
bool recognizedTx = Solver(scriptPubKey, whichType, vSolutions);
if (recognizedTx && whichType != TX_NULL_DATA) {
if (m_findP2PKH && (whichType == TX_PUBKEY || whichType == TX_PUBKEYHASH)) {
Script::TxnOutType whichType;
bool recognizedTx = Script::solver(scriptPubKey, whichType, vSolutions);
if (recognizedTx && whichType != Script::TX_NULL_DATA) {
if (m_findP2PKH && (whichType == Script::TX_PUBKEY || whichType == Script::TX_PUBKEYHASH)) {
CKeyID keyID;
if (whichType == TX_PUBKEY)
if (whichType == Script::TX_PUBKEY)
keyID = CPubKey(vSolutions[0]).GetID();
else if (whichType == TX_PUBKEYHASH)
else if (whichType == Script::TX_PUBKEYHASH)
keyID = CKeyID(uint160(vSolutions[0]));
for (size_t i = 0; i < remotes_.size(); ++i) {
RemoteWithKeys *rwk = static_cast<RemoteWithKeys*>(remotes_.at(i));
......@@ -228,12 +228,12 @@ void AddressMonitorService::findTxInMempool(int connectionId, const CKeyID &keyI
else if (type == Tx::OutputScript) {
CScript scriptPubKey(txIter.byteData());
std::vector<std::vector<unsigned char> > vSolutions;
txnouttype whichType;
bool recognizedTx = Solver(scriptPubKey, whichType, vSolutions);
if (recognizedTx && whichType != TX_NULL_DATA) {
if (whichType == TX_PUBKEY || whichType == TX_PUBKEYHASH) {
if ((whichType == TX_PUBKEY && keyId == CPubKey(vSolutions[0]).GetID())
|| (whichType == TX_PUBKEYHASH && keyId == CKeyID(uint160(vSolutions[0])))) {
Script::TxnOutType whichType;
bool recognizedTx = Script::solver(scriptPubKey, whichType, vSolutions);
if (recognizedTx && whichType != Script::TX_NULL_DATA) {
if (whichType == Script::TX_PUBKEY || whichType == Script::TX_PUBKEYHASH) {
if ((whichType == Script::TX_PUBKEY && keyId == CPubKey(vSolutions[0]).GetID())
|| (whichType == Script::TX_PUBKEYHASH && keyId == CKeyID(uint160(vSolutions[0])))) {
match = true;
matchedAmounts += curAmount;
......
......@@ -31,4 +31,4 @@ target_link_libraries(flowee_apputils Qt5::Core Qt5::Network flowee_networkmanag
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libflowee_apputils.a DESTINATION lib)
install(FILES
FloweeServiceApplication.h
DESTINATION include)
DESTINATION include/flowee)
......@@ -51,7 +51,7 @@ FloweeServiceApplication::FloweeServiceApplication(int &argc, char **argv, int a
m_version(QStringList() << "version", "Display version"),
m_bindAddress(QStringList() << "bind", "Bind to this IP:port", "IP-ADDRESS"),
m_appLogSection(appLogSection),
m_connect("connect", "server location and port", "<ADDERSS>")
m_connect("connect", "server location and port", "ADDRESS")
{
}
......
......@@ -63,8 +63,10 @@ add_library(flowee_crypto STATIC ${FLOWEE_LIBRARY_SOURCES})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libflowee_crypto.a DESTINATION lib)
install(FILES
common.h
DESTINATION include/crypto)
ripemd160.h
sha256.h
DESTINATION include/flowee/crypto)
install(FILES
compat/endian.h
compat/byteswap.h
DESTINATION include/crypto/compat/)
DESTINATION include/flowee/crypto/compat/)
......@@ -27,6 +27,6 @@ install(FILES
APIProtocol.h
NetworkEnums.h
validationinterface.h
DESTINATION include)
DESTINATION include/flowee/interfaces)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libflowee_interfaces.a DESTINATION lib)
......@@ -32,4 +32,4 @@ install(FILES
NetworkConnection.h
NetworkEndPoint.h
NetworkManager.h
DESTINATION include)
DESTINATION include/flowee/networkmanager)
......@@ -29,8 +29,7 @@ struct EndPoint
{
EndPoint()
: peerPort(0),
announcePort(0),
connectionId(-1)
announcePort(0)
{
}
EndPoint(const std::string &hostname, std::uint16_t port)
......@@ -47,9 +46,9 @@ struct EndPoint
}
boost::asio::ip::address ipAddress;
std::string hostname;
std::uint16_t peerPort;
std::uint16_t announcePort;
int connectionId;
std::uint16_t peerPort = 0;
std::uint16_t announcePort = 0;
int connectionId = -1;
};
inline Log::Item operator<<(Log::Item item, const EndPoint &ep) {
......
......@@ -923,9 +923,10 @@ void NetworkManagerConnection::close(bool reconnect)
}
}
void NetworkManagerConnection::sendPing(const boost::system::error_code& error)
void NetworkManagerConnection::sendPing(const boost::system::error_code &error)
{
logDebug(Log::NWM) << "ping";
if (error) return;
if (m_isClosingDown)
return;
......
......@@ -176,10 +176,10 @@ bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx)
insert(COutPoint(hash, i));
else if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_P2PUBKEY_ONLY)
{
txnouttype type;
Script::TxnOutType type;
std::vector<std::vector<unsigned char> > vSolutions;
if (Solver(txout.scriptPubKey, type, vSolutions) &&
(type == TX_PUBKEY || type == TX_MULTISIG))
if (Script::solver(txout.scriptPubKey, type, vSolutions) &&
(type == Script::TX_PUBKEY || type == Script::TX_MULTISIG))
insert(COutPoint(hash, i));
}
break;
......
......@@ -53,14 +53,13 @@
* DUP CHECKSIG DROP ... repeated 100 times... OP_1
*/
bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType)
bool IsStandard(const CScript& scriptPubKey, Script::TxnOutType& whichType)
{
std::vector<std::vector<unsigned char> > vSolutions;
if (!Solver(scriptPubKey, whichType, vSolutions))
if (!Script::solver(scriptPubKey, whichType, vSolutions))
return false;
if (whichType == TX_MULTISIG)
{
if (whichType == Script::TX_MULTISIG) {
unsigned char m = vSolutions.front()[0];
unsigned char n = vSolutions.back()[0];
// Support up to x-of-3 multisig txns as standard
......@@ -68,11 +67,11 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType)
return false;
if (m < 1 || m > n)
return false;
} else if (whichType == TX_NULL_DATA &&
} else if (whichType == Script::TX_NULL_DATA &&
(!fAcceptDatacarrier || scriptPubKey.size() > nMaxDatacarrierBytes))
return false;
return whichType != TX_NONSTANDARD;
return whichType != Script::TX_NONSTANDARD;
}
bool IsStandardTx(const CTransaction& tx, std::string& reason)
......@@ -111,16 +110,16 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason)
}
unsigned int nDataOut = 0;
txnouttype whichType;
Script::TxnOutType whichType;
for (const CTxOut& txout : tx.vout) {
if (!::IsStandard(txout.scriptPubKey, whichType)) {
reason = "scriptpubkey";
return false;
}
if (whichType == TX_NULL_DATA)
if (whichType == Script::TX_NULL_DATA)
nDataOut++;
else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) {
else if ((whichType == Script::TX_MULTISIG) && (!fIsBareMultisigStd)) {
reason = "bare-multisig";
return false;
} else if (txout.IsDust(::minRelayTxFee)) {
......@@ -141,10 +140,10 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason)
bool Policy::isInputStandard(const CScript &outputScript, const CScript &inputScript)
{
std::vector<std::vector<unsigned char> > vSolutions;
txnouttype whichType;
if (!Solver(outputScript, whichType, vSolutions))
Script::TxnOutType whichType;
if (!Script::solver(outputScript, whichType, vSolutions))
return false;
if (whichType == TX_SCRIPTHASH) {
if (whichType == Script::TX_SCRIPTHASH) {
std::vector<std::vector<unsigned char> > stack;
// convert the scriptSig into a stack, so we can inspect the redeemScript
if (!EvalScript(stack, inputScript, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), nullptr))
......
......@@ -60,7 +60,7 @@ static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_
static const unsigned int STANDARD_LOCKTIME_VERIFY_FLAGS = LOCKTIME_VERIFY_SEQUENCE |
LOCKTIME_MEDIAN_TIME_PAST;
bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType);
bool IsStandard(const CScript &scriptPubKey, Script::TxnOutType &whichType);
/**
* Check for standard transaction types
* @return True if all outputs (scriptPubKeys) use only standard transaction forms
......
......@@ -142,16 +142,16 @@ public:
obj.push_back(Pair("isscript", true));
if (pwalletMain && pwalletMain->GetCScript(scriptID, subscript)) {
std::vector<CTxDestination> addresses;
txnouttype whichType;
Script::TxnOutType whichType;
int nRequired;
ExtractDestinations(subscript, whichType, addresses, nRequired);
obj.push_back(Pair("script", GetTxnOutputType(whichType)));
obj.push_back(Pair("script", Script::getTxnOutputType(whichType)));
obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end())));
UniValue a(UniValue::VARR);
BOOST_FOREACH(const CTxDestination& addr, addresses)
for (const CTxDestination &addr : addresses)
a.push_back(CBitcoinAddress(addr).ToString());
obj.push_back(Pair("addresses", a));
if (whichType == TX_MULTISIG)
if (whichType == Script::TX_MULTISIG)
obj.push_back(Pair("sigsrequired", nRequired));
}
return obj;
......
......@@ -54,7 +54,7 @@
void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex)
{
txnouttype type;
Script::TxnOutType type;
std::vector<CTxDestination> addresses;
int nRequired;
......@@ -63,12 +63,12 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fInclud
out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) {
out.push_back(Pair("type", GetTxnOutputType(type)));
out.push_back(Pair("type", Script::getTxnOutputType(type)));
return;
}
out.push_back(Pair("reqSigs", nRequired));
out.push_back(Pair("type", GetTxnOutputType(type)));
out.push_back(Pair("type", Script::getTxnOutputType(type)));
UniValue a(UniValue::VARR);
BOOST_FOREACH(const CTxDestination& addr, addresses)
......
......@@ -75,24 +75,24 @@ static bool SignN(const std::vector<valtype>& multisigdata, const BaseSignatureC
* Returns false if scriptPubKey could not be completely satisfied.
*/
static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptPubKey,
CScript& scriptSigRet, txnouttype& whichTypeRet)
CScript& scriptSigRet, Script::TxnOutType& whichTypeRet)
{
scriptSigRet.clear();
std::vector<valtype> vSolutions;
if (!Solver(scriptPubKey, whichTypeRet, vSolutions))
if (!Script::solver(scriptPubKey, whichTypeRet, vSolutions))
return false;
CKeyID keyID;
switch (whichTypeRet)
{
case TX_NONSTANDARD:
case TX_NULL_DATA:
case Script::TX_NONSTANDARD:
case Script::TX_NULL_DATA:
return false;
case TX_PUBKEY:
case Script::TX_PUBKEY:
keyID = CPubKey(vSolutions[0]).GetID();
return Sign1(keyID, creator, scriptPubKey, scriptSigRet);
case TX_PUBKEYHASH:
case Script::TX_PUBKEYHASH:
keyID = CKeyID(uint160(vSolutions[0]));
if (!Sign1(keyID, creator, scriptPubKey, scriptSigRet))
return false;
......@@ -103,10 +103,10 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
scriptSigRet << ToByteVector(vch);
}
return true;
case TX_SCRIPTHASH:
case Script::TX_SCRIPTHASH:
return creator.KeyStore().GetCScript(uint160(vSolutions[0]), scriptSigRet);
case TX_MULTISIG:
case Script::TX_MULTISIG:
scriptSigRet << OP_0; // workaround CHECKMULTISIG bug
return (SignN(vSolutions, creator, scriptPubKey, scriptSigRet));
}
......@@ -115,20 +115,20 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
bool ProduceSignature(const BaseSignatureCreator& creator, const CScript& fromPubKey, CScript& scriptSig)
{
txnouttype whichType;
Script::TxnOutType whichType;
if (!SignStep(creator, fromPubKey, scriptSig, whichType))
return false;
if (whichType == TX_SCRIPTHASH)
if (whichType == Script::TX_SCRIPTHASH)
{
// Solver returns the subscript that need to be evaluated;
// the final scriptSig is the signatures from that
// and then the serialized subscript:
CScript subscript = scriptSig;
txnouttype subType;
Script::TxnOutType subType;
bool fSolved =
SignStep(creator, subscript, scriptSig, subType) && subType != TX_SCRIPTHASH;
SignStep(creator, subscript, scriptSig, subType) && subType != Script::TX_SCRIPTHASH;
// Append serialized subscript whether or not it is completely signed:
scriptSig << valtype(subscript.begin(), subscript.end());
if (!fSolved) return false;
......@@ -235,24 +235,24 @@ static CScript CombineMultisig(const CScript& scriptPubKey, const BaseSignatureC
}
static CScript CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecker& checker,