I'm new to crypto and I'm building my own mining pool for an altcoin.
I've run into the ("code":-32700,"message":"Parse error") error when trying to get the altcoin set up for mining. I tried googling around and all the solutions seemed to point to the command syntax/parameters not being formatted correctly but I'm pretty sure my formatting is correct, as the validateaddress returns the expected result when ran manually. Also, echojson (a daemon cli command which parses the given string to JSON) seems to parse the parameters correctly as well. I've been stuck on this for days and I'm not sure what else to do. What could I do to fix this?
Huge thanks in advance!!!
Sincerely,
newlymintedcryptolover
An excerpt from stratum.log (including my own debug messages):
12:13:34: 168
12:13:34: [rpc_send_raw] start, buffer is:
12:13:34: '{"method":"validateaddress","params":"tc1qv90nlgjc8rtseygndxghxuk60038aaeff3c6nh","id":"1"}'
12:13:34: [rpc_send_raw] sending >'{"method":"validateaddress","params":"tc1qv90nlgjc8rtseygndxghxuk60038aaeff3c6nh","id":"1"}'<
12:13:34: [rpc_send_raw] res to be returned is:
12:13:34: 93
12:13:34: [rpc_do_call] p is:
12:13:34: 500 Internal Server Error
Content-Type: application/json
Date: Wed, 09 Feb 2022 12:13:34 GMT
Content-Length: 74
{"result":null,"error":{"code":-32700,"message":"Parse error"},"id":null}
12:13:34: [rpc_do_call] databuf to be returned is:
12:13:34: {"result":null,"error":{"code":-32700,"message":"Parse error"},"id":null}
coind_validate_address method from coind.cpp:
{
stratumlog("coind_validate_address begin");
if(!coind->wallet[0]) return false;
stratumlog("return false passed by");
char params[YAAMP_SMALLBUFSIZE];
sprintf(params, "\"%s\"", coind->wallet); //[]
stratumlog("params is: ");
stratumlog(params);
json_value *json;
bool getaddressinfo = ((strcmp(coind->symbol,"DGB") == 0) || (strcmp(coind->symbol2, "DGB") == 0));
if(getaddressinfo) {
stratumlog("getaddressinfo true");
json = rpc_call(&coind->rpc, "getaddressinfo", params);
}
else {
stratumlog("getaddressinfo false");
json = rpc_call(&coind->rpc, "validateaddress", params);
}
if(!json) return false;
json_value *json_result = json_get_object(json, "result");
stratumlog("json_get_object");
if(!json_result)
{
stratumlog("json_result false");
json_value_free(json);
return false;
}
bool isvalid = getaddressinfo || json_get_bool(json_result, "isvalid");
if(!isvalid) stratumlog("%s wallet %s is not valid.\n", coind->name, coind->wallet);
bool ismine = json_get_bool(json_result, "ismine");
if(!ismine) stratumlog("%s wallet %s is not mine.\n", coind->name, coind->wallet);
else isvalid = ismine;
const char *p = json_get_string(json_result, "pubkey");
strcpy(coind->pubkey, p ? p : "");
stratumlog("pubkey done");
const char *acc = json_get_string(json_result, "account");
if (acc) strcpy(coind->account, acc);
stratumlog("account done");
if (!base58_decode(coind->wallet, coind->script_pubkey))
stratumlog("Warning: unable to decode %s %s script pubkey\n", coind->symbol, coind->wallet);
coind->p2sh_address = json_get_bool(json_result, "isscript");
stratumlog("isscript done");
// if base58 decode fails
if (!strlen(coind->script_pubkey)) {
const char *pk = json_get_string(json_result, "scriptPubKey");
if (pk && strlen(pk) > 10) {
strcpy(coind->script_pubkey, &pk[6]);
coind->script_pubkey[strlen(pk)-6-4] = '\0';
stratumlog("%s %s extracted script pubkey is %s\n", coind->symbol, coind->wallet, coind->script_pubkey);
} else {
stratumlog("%s wallet addr '%s' seems incorrect!'", coind->symbol, coind->wallet);
}
}
json_value_free(json);
stratumlog("coind_validate_address end");
return isvalid; //&& ismine;
}
rpc_send_raw method from rpc.cpp:
{
stratumlog("[rpc_send_raw] start, buffer is:");
stratumlog(buffer);
if(!rpc_connected(rpc)) return -1;
int res = send(rpc->sock, buffer, bytes, MSG_NOSIGNAL);
if(res <= 0) return res;
if (g_debuglog_rpc) {
debuglog("sending >%s<\n", buffer);
}
stratumlog("[rpc_send_raw] sending >%s<\n", buffer);
std::string s = std::to_string(res);
char const *pchar = s.c_str(); //use char const* as target type
stratumlog("[rpc_send_raw] res to be returned is:");
stratumlog(pchar);
return res;
}
int rpc_flush_soft(YAAMP_RPC *rpc)
{
if(!rpc_connected(rpc)) return -1;
int res = send(rpc->sock, rpc->buffer, rpc->bufpos, MSG_MORE);
rpc->bufpos = 0;
return res;
}
int rpc_flush(YAAMP_RPC *rpc)
{
if(!rpc_connected(rpc)) return -1;
int res = rpc_send_raw(rpc, rpc->buffer, rpc->bufpos);
rpc->bufpos = 0;
return res;
}
int rpc_send(YAAMP_RPC *rpc, const char *format, ...)
{
if(!rpc_connected(rpc)) return -1;
char buffer[YAAMP_SMALLBUFSIZE] = { 0 };
va_list args;
va_start(args, format);
vsprintf(buffer, format, args);
va_end(args);
int bytes = strlen(buffer);
if(bytes + rpc->bufpos > YAAMP_SMALLBUFSIZE)
return -1;
memcpy(rpc->buffer + rpc->bufpos, buffer, bytes);
rpc->bufpos += bytes;
return bytes;
}
rpc_do_call from rpc.cpp:
{
CommonLock(&rpc->mutex);
// HTTP 1.1 accepts chunked data, and keep the connection
rpc_send(rpc, "POST / HTTP/1.1\r\n");
rpc_send(rpc, "Authorization: Basic %s\r\n", rpc->credential);
rpc_send(rpc, "Host: %s:%d\n", rpc->host, rpc->port);
rpc_send(rpc, "Accept: */*\r\n");
rpc_send(rpc, "Content-Type: application/json\r\n");
rpc_send(rpc, "Content-Length: %d\r\n\r\n", strlen(data));
int res = rpc_flush(rpc);
if(res <= 0)
{
CommonUnlock(&rpc->mutex);
return NULL;
}
res = rpc_send_raw(rpc, data, strlen(data));
if(res <= 0)
{
CommonUnlock(&rpc->mutex);
return NULL;
}
int bufpos = 0;
char buffer[YAAMP_SMALLBUFSIZE] = { 0 };
while(!g_exiting)
{
int bytes = recv(rpc->sock, buffer+bufpos, YAAMP_SMALLBUFSIZE-bufpos-1, 0);
if (g_debuglog_rpc) {
debuglog("got %s\n", buffer+bufpos);
}
if(bytes <= 0)
{
debuglog("ERROR: recv1, %d, %d, %s, %s\n", bytes, errno, data, buffer);
CommonUnlock(&rpc->mutex);
return NULL;
}
bufpos += bytes;
buffer[bufpos] = 0;
if(strstr(buffer, "\r\n\r\n")) break;
}
///////////////////////////////////////////////////
const char *p = strchr(buffer, ' ');
if(!p)
{
CommonUnlock(&rpc->mutex);
return NULL;
} else {
stratumlog("[rpc_do_call] p is: ");
stratumlog(p);
}
int status = atoi(p+1);
if(status != 200)
debuglog("ERROR: rpc_do_call: %s:%d %d\n", rpc->host, rpc->port, status);
char tmp[1024];
header_value(buffer, "Transfer-Encoding:", tmp);
if (!strcmp(tmp, "chunked")) {
#ifdef HAVE_CURL
if (!rpc->curl) debuglog("%s chunked transfer detected, switching to curl!\n",
rpc->coind->symbol);
rpc->curl = 1;
#endif
CommonUnlock(&rpc->mutex);
rpc_connect(rpc);
return NULL;
}
int datalen = atoi(header_value(buffer, "Content-Length:", tmp));
if(!datalen)
{
debuglog("ERROR: rpc No Content-Length header!\n");
CommonUnlock(&rpc->mutex);
return NULL;
}
p = strstr(buffer, "\r\n\r\n");
bufpos = strlen(p+4);
char *databuf = (char *)malloc(datalen+1);
if(!databuf)
{
CommonUnlock(&rpc->mutex);
return NULL;
}
memcpy(databuf, p+4, bufpos+1);
while(bufpos < datalen)
{
int bytes = recv(rpc->sock, databuf+bufpos, datalen-bufpos, 0);
if(bytes <= 0)
{
debuglog("ERROR: recv2, %d, %d, %s\n", bytes, errno, data);
rpc_connect(rpc);
free(databuf);
CommonUnlock(&rpc->mutex);
return NULL;
}
bufpos += bytes;
databuf[bufpos] = 0;
}
CommonUnlock(&rpc->mutex);
header_value(buffer, "Connection:", tmp);
if(strcmp(tmp, "close") == 0)
{
// debuglog("closing connection from %s:%d\n", rpc->host, rpc->port);
rpc_connect(rpc);
}
stratumlog("[rpc_do_call] databuf to be returned is:");
stratumlog(databuf);
return databuf;
}
Results of validateaddress and echojson commands when ran manually on the server that hosts the pool and the altcoin daemon:
{
"isvalid": true,
"address": "tc1qv90nlgjc8rtseygndxghxuk60038aaeff3c6nh",
"scriptPubKey": "0014615f3fa25838d70c911369917372da7be27ef729",
"isscript": false,
"iswitness": true,
"witness_version": 0,
"witness_program": "615f3fa25838d70c911369917372da7be27ef729"
}
pool@b2-7-uk1:~/daemons/tech$ ./techcoin-cli echojson '{"method":"validateaddress","params":"tc1qv90nlgjc8rtseygndxghxuk60038aaeff3c6nh","id":"1"}'
[
{
"method": "validateaddress",
"params": "tc1qv90nlgjc8rtseygndxghxuk60038aaeff3c6nh",
"id": "1"
}
]