hdac SDK
SDK for hdac blockchain development
rpcprotocol.h
1 #ifndef RPCPROTOCOL_H
2 #define RPCPROTOCOL_H
3 
4 #include <boost/iostreams/concepts.hpp>
5 #include <boost/iostreams/stream.hpp>
6 
7 #include <json_spirit/json_spirit.h>
8 
9 #ifdef WIN32
10 #include <SDKDDKVer.h>
11 #endif
12 #include <boost/asio.hpp>
13 #include <boost/asio/ssl.hpp>
14 
15 
17 enum HTTPStatusCode
18 {
19  HTTP_OK = 200,
20  HTTP_BAD_REQUEST = 400,
21  HTTP_UNAUTHORIZED = 401,
22  HTTP_FORBIDDEN = 403,
23  HTTP_NOT_FOUND = 404,
24  HTTP_INTERNAL_SERVER_ERROR = 500,
25  HTTP_SERVICE_UNAVAILABLE = 503,
26 };
27 
29 enum RPCErrorCode
30 {
32  RPC_INVALID_REQUEST = -32600,
33  RPC_METHOD_NOT_FOUND = -32601,
34  RPC_INVALID_PARAMS = -32602,
35  RPC_INTERNAL_ERROR = -32603,
36  RPC_PARSE_ERROR = -32700,
37 
39  RPC_MISC_ERROR = -1,
40  RPC_FORBIDDEN_BY_SAFE_MODE = -2,
41  RPC_TYPE_ERROR = -3,
42  RPC_INVALID_ADDRESS_OR_KEY = -5,
43  RPC_OUT_OF_MEMORY = -7,
44  RPC_INVALID_PARAMETER = -8,
45  RPC_DATABASE_ERROR = -20,
46  RPC_DESERIALIZATION_ERROR = -22,
47  RPC_VERIFY_ERROR = -25,
48  RPC_VERIFY_REJECTED = -26,
49  RPC_VERIFY_ALREADY_IN_CHAIN = -27,
50  RPC_IN_WARMUP = -28,
51 
53  RPC_TRANSACTION_ERROR = RPC_VERIFY_ERROR,
54  RPC_TRANSACTION_REJECTED = RPC_VERIFY_REJECTED,
55  RPC_TRANSACTION_ALREADY_IN_CHAIN= RPC_VERIFY_ALREADY_IN_CHAIN,
56 
58  RPC_CLIENT_NOT_CONNECTED = -9,
59  RPC_CLIENT_IN_INITIAL_DOWNLOAD = -10,
60  RPC_CLIENT_NODE_ALREADY_ADDED = -23,
61  RPC_CLIENT_NODE_NOT_ADDED = -24,
62 
64  RPC_WALLET_ERROR = -4,
65  RPC_WALLET_INSUFFICIENT_FUNDS = -6,
66  RPC_WALLET_INVALID_ACCOUNT_NAME = -11,
67  RPC_WALLET_KEYPOOL_RAN_OUT = -12,
68  RPC_WALLET_UNLOCK_NEEDED = -13,
69  RPC_WALLET_PASSPHRASE_INCORRECT = -14,
70  RPC_WALLET_WRONG_ENC_STATE = -15,
71  RPC_WALLET_ENCRYPTION_FAILED = -16,
72  RPC_WALLET_ALREADY_UNLOCKED = -17,
73 
75 
76  RPC_NOT_ALLOWED = -701,
77  RPC_NOT_SUPPORTED = -702,
78  RPC_NOT_SUBSCRIBED = -703,
79  RPC_INSUFFICIENT_PERMISSIONS = -704,
80  RPC_DUPLICATE_NAME = -705,
81  RPC_UNCONFIRMED_ENTITY = -706,
82  RPC_EXCHANGE_ERROR = -707,
83  RPC_ENTITY_NOT_FOUND = -708,
84  RPC_WALLET_ADDRESS_NOT_FOUND = -709,
85  RPC_TX_NOT_FOUND = -710,
86  RPC_BLOCK_NOT_FOUND = -711,
87  RPC_OUTPUT_NOT_FOUND = -712,
88  RPC_OUTPUT_NOT_DATA = -713,
89  RPC_INPUTS_NOT_MINE = -714,
90  RPC_WALLET_OUTPUT_NOT_FOUND = -715,
91  RPC_WALLET_NO_UNSPENT_OUTPUTS = -716,
92  RPC_GENERAL_FILE_ERROR = -717,
93  RPC_UPGRADE_REQUIRED = -718,
94 
95 };
96 
100 template <typename Protocol>
101 class SSLIOStreamDevice : public boost::iostreams::device<boost::iostreams::bidirectional> {
102 public:
103  SSLIOStreamDevice(boost::asio::ssl::stream<typename Protocol::socket> &streamIn, bool fUseSSLIn) : stream(streamIn)
104  {
105  fUseSSL = fUseSSLIn;
106  fNeedHandshake = fUseSSLIn;
107  }
108 
109  void handshake(boost::asio::ssl::stream_base::handshake_type role)
110  {
111  if (!fNeedHandshake) return;
112  fNeedHandshake = false;
113  stream.handshake(role);
114  }
115  std::streamsize read(char* s, std::streamsize n)
116  {
117  handshake(boost::asio::ssl::stream_base::server); // HTTPS servers read first
118  if (fUseSSL) return stream.read_some(boost::asio::buffer(s, n));
119  return stream.next_layer().read_some(boost::asio::buffer(s, n));
120  }
121  std::streamsize write(const char* s, std::streamsize n)
122  {
123  handshake(boost::asio::ssl::stream_base::client); // HTTPS clients write first
124  if (fUseSSL) return boost::asio::write(stream, boost::asio::buffer(s, n));
125  return boost::asio::write(stream.next_layer(), boost::asio::buffer(s, n));
126  }
127  bool connect(const std::string& server, const std::string& port)
128  {
129  using namespace boost::asio::ip;
130  tcp::resolver resolver(stream.get_io_service());
131  tcp::resolver::iterator endpoint_iterator;
132 #if BOOST_VERSION >= 104300
133  try {
134 #endif
135  // The default query (flags address_configured) tries IPv6 if
136  // non-localhost IPv6 configured, and IPv4 if non-localhost IPv4
137  // configured.
138  tcp::resolver::query query(server.c_str(), port.c_str());
139  endpoint_iterator = resolver.resolve(query);
140 #if BOOST_VERSION >= 104300
141  } catch(boost::system::system_error &)
142  {
143  // If we at first don't succeed, try blanket lookup (IPv4+IPv6 independent of configured interfaces)
144  tcp::resolver::query query(server.c_str(), port.c_str(), resolver_query_base::flags());
145  endpoint_iterator = resolver.resolve(query);
146  }
147 #endif
148  boost::system::error_code error = boost::asio::error::host_not_found;
149  tcp::resolver::iterator end;
150  while (error && endpoint_iterator != end)
151  {
152  stream.lowest_layer().close();
153  stream.lowest_layer().connect(*endpoint_iterator++, error);
154  }
155  if (error)
156  return false;
157  return true;
158  }
159 
160 private:
161  bool fNeedHandshake;
162  bool fUseSSL;
163  boost::asio::ssl::stream<typename Protocol::socket>& stream;
164 };
165 
166 std::string JSONRPCRequest(const std::string& strMethod, const json_spirit::Array& params, const json_spirit::Value& id, const std::string &chaninName = "hdac");
167 std::string HTTPPost(const std::string& strMsg, const std::map<std::string,std::string>& mapRequestHeaders);
168 int ReadHTTPStatus(std::basic_istream<char>& stream, int &proto);
169 int ReadHTTPMessage(std::basic_istream<char>& stream, std::map<std::string, std::string>& mapHeadersRet,
170  std::string& strMessageRet, int nProto, size_t max_size);
171 #endif // RPCPROTOCOL_H
Definition: rpcprotocol.h:101