Browse Source

In progress of adding ETH tx validations.

patch-3
Artem Pikulin 7 years ago
parent
commit
9a9b1a10ae
  1. 24
      iguana/exchanges/LP_etomic.c
  2. 26
      iguana/exchanges/LP_transaction.c
  3. 64
      iguana/exchanges/etomicswap/bob.c
  4. 198
      iguana/exchanges/etomicswap/etomiccurl.c
  5. 21
      iguana/exchanges/etomicswap/etomiccurl.h

24
iguana/exchanges/LP_etomic.c

@ -404,3 +404,27 @@ int32_t LP_etomic_pub2addr(char *coinaddr,uint8_t pub64[64])
}
return(-1);
}
int32_t LP_etomic_wait_for_confirmation(char *txId)
{
EthTxReceipt receipt;
EthTxData txData;
do {
sleep(15);
printf("waiting for ETH txId to be confirmed: %s\n", txId);
receipt = getEthTxReceipt(txId);
if (receipt.confirmations < 1) {
txData = getEthTxData(txId);
if (txData.exists == 0) {
return(-1);
}
}
} while (receipt.confirmations < 1);
if (strcmp(receipt.status, "0x1") != 0) {
printf("ETH txid %s receipt status failed\n", txId);
return(-1);
}
return(receipt.confirmations);
}

26
iguana/exchanges/LP_transaction.c

@ -13,7 +13,6 @@
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
//
// LP_transaction.c
// marketmaker
@ -104,7 +103,7 @@ int32_t LP_gettx_presence(int32_t *numconfirmsp,char *symbol,bits256 expectedtxi
bits256 LP_broadcast(char *txname,char *symbol,char *txbytes,bits256 expectedtxid)
{
char *retstr,*errstr; bits256 txid; uint8_t *ptr; cJSON *retjson,*errorobj; struct iguana_info *coin; int32_t i,totalretries=0,len,sentflag = 0;
char *retstr,*errstr; bits256 txid; uint8_t *ptr; cJSON *retjson,*errorobj; struct iguana_info *coin; int32_t i,totalretries=0,len,sentflag = 0,numconfirms=-1;
coin = LP_coinfind(symbol);
memset(&txid,0,sizeof(txid));
if ( txbytes == 0 || txbytes[0] == 0 )
@ -120,7 +119,7 @@ bits256 LP_broadcast(char *txname,char *symbol,char *txbytes,bits256 expectedtxi
for (i=0; i<2; i++)
{
//char str[65]; printf("LP_broadcast.%d (%s) %s i.%d sentflag.%d\n",i,symbol,bits256_str(str,expectedtxid),i,sentflag);
if ( sentflag == 0 && LP_gettx_presence(0,symbol,expectedtxid,0) != 0 )
if ( sentflag == 0 && LP_gettx_presence(&numconfirms,symbol,expectedtxid,0) != 0 )
sentflag = 1;
if ( sentflag == 0 && (retstr= LP_sendrawtransaction(symbol,txbytes)) != 0 )
{
@ -2204,6 +2203,13 @@ int32_t LP_verify_bobdeposit(struct basilisk_swap *swap,uint8_t *data,int32_t da
printf("%02x",swap->aliceclaim.txbytes[i]);
printf(" <- aliceclaim\n");*/
//basilisk_txlog(swap,&swap->aliceclaim,swap->I.putduration+swap->I.callduration);
#ifndef NOTETOMIC
if (swap->bobdeposit.I.ethTxid[0] != 0) {
if (LP_etomic_wait_for_confirmation(swap->bobdeposit.I.ethTxid) < 0) {
return(-1);
}
}
#endif
return(LP_waitmempool(coin->symbol,swap->bobdeposit.I.destaddr,swap->bobdeposit.I.signedtxid,0,60));
} else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->aliceclaim.I.suppress_pubkeys,swap->bobdeposit.I.destaddr);
}
@ -2227,6 +2233,13 @@ int32_t LP_verify_alicepayment(struct basilisk_swap *swap,uint8_t *data,int32_t
if ( bits256_nonz(swap->alicepayment.I.signedtxid) != 0 )
swap->aliceunconf = 1;
basilisk_dontforget_update(swap,&swap->alicepayment);
#ifndef NOTETOMIC
if (swap->alicepayment.I.ethTxid[0] != 0) {
if (LP_etomic_wait_for_confirmation(swap->alicepayment.I.ethTxid) < 0) {
return(-1);
}
}
#endif
return(LP_waitmempool(coin->symbol,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,60));
//printf("import alicepayment address.(%s)\n",swap->alicepayment.p2shaddr);
//LP_importaddress(coin->symbol,swap->alicepayment.p2shaddr);
@ -2279,6 +2292,13 @@ int32_t LP_verify_bobpayment(struct basilisk_swap *swap,uint8_t *data,int32_t da
memcpy(swap->alicespend.I.pubkey33,swap->persistent_pubkey33,33);
bitcoin_address(coin->symbol,swap->alicespend.I.destaddr,coin->taddr,coin->pubtype,swap->persistent_pubkey33,33);
//char str[65],str2[65]; printf("bobpaid privAm.(%s) myprivs[0].(%s)\n",bits256_str(str,swap->I.privAm),bits256_str(str2,swap->I.myprivs[0]));
#ifndef NOTETOMIC
if (swap->bobpayment.I.ethTxid[0] != 0) {
if (LP_etomic_wait_for_confirmation(swap->bobpayment.I.ethTxid) < 0) {
return (-1);
}
}
#endif
if ( (retval= basilisk_rawtx_sign(coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,swap,&swap->alicespend,&swap->bobpayment,swap->I.myprivs[0],0,userdata,len,1,swap->changermd160,swap->bobpayment.I.destaddr,coin->zcash)) == 0 )
{
/*for (i=0; i<swap->bobpayment.I.datalen; i++)

64
iguana/exchanges/etomicswap/bob.c

@ -28,7 +28,8 @@ int main(int argc, char** argv)
BOB_APPROVES_ERC20,
BOB_ETH_BALANCE,
BOB_ERC20_BALANCE,
TX_RECEIPT
TX_RECEIPT,
TX_DATA
};
if (argc < 2) {
return 1;
@ -51,8 +52,12 @@ int main(int argc, char** argv)
strcpy(input.bobHash, argv[3]);
result = bobSendsEthDeposit(input, txData);
if (result != NULL) {
printf("%s\n", result);
free(result);
} else {
printf("Tx send result was NULL\n");
}
break;
case BOB_ERC20_DEPOSIT:
strcpy(txData.amount, "0");
@ -70,8 +75,13 @@ int main(int argc, char** argv)
strcpy(input1.tokenAddress, tokenAddress);
result = bobSendsErc20Deposit(input1, txData);
if (result != NULL) {
printf("%s\n", result);
free(result);
} else {
printf("Tx send result was NULL\n");
}
free(result);
break;
case BOB_CLAIMS_DEPOSIT:
strcpy(txData.amount, "0");
@ -88,8 +98,13 @@ int main(int argc, char** argv)
strcpy(input2.bobSecret, argv[5]);
result = bobRefundsDeposit(input2, txData);
if (result != NULL) {
printf("%s\n", result);
free(result);
} else {
printf("Tx send result was NULL\n");
}
free(result);
break;
case ALICE_CLAIMS_DEPOSIT:
strcpy(txData.amount, "0");
@ -106,8 +121,13 @@ int main(int argc, char** argv)
strcpy(input3.bobHash, argv[5]);
result = aliceClaimsBobDeposit(input3, txData);
if (result != NULL) {
printf("%s\n", result);
free(result);
} else {
printf("Tx send result was NULL\n");
}
free(result);
break;
case BOB_ETH_PAYMENT:
strcpy(txData.amount, "1000000000000000000");
@ -121,8 +141,13 @@ int main(int argc, char** argv)
strcpy(input4.aliceAddress, aliceAddress);
result = bobSendsEthPayment(input4, txData);
if (result != NULL) {
printf("%s\n", result);
free(result);
} else {
printf("Tx send result was NULL\n");
}
free(result);
break;
case BOB_ERC20_PAYMENT:
strcpy(txData.amount, "0");
@ -139,8 +164,13 @@ int main(int argc, char** argv)
strcpy(input5.aliceHash, argv[3]);
result = bobSendsErc20Payment(input5, txData);
if (result != NULL) {
printf("%s\n", result);
free(result);
} else {
printf("Tx send result was NULL\n");
}
free(result);
break;
case BOB_CLAIMS_PAYMENT:
strcpy(txData.amount, "0");
@ -158,8 +188,13 @@ int main(int argc, char** argv)
strcpy(input6.aliceHash, argv[5]);
result = bobReclaimsBobPayment(input6, txData);
if (result != NULL) {
printf("%s\n", result);
free(result);
} else {
printf("Tx send result was NULL\n");
}
free(result);
break;
case ALICE_CLAIMS_PAYMENT:
strcpy(txData.amount, "0");
@ -177,8 +212,12 @@ int main(int argc, char** argv)
strcpy(input7.aliceSecret, argv[5]);
result = aliceSpendsBobPayment(input7, txData);
if (result != NULL) {
printf("%s\n", result);
free(result);
} else {
printf("Tx send result was NULL\n");
}
break;
case BOB_APPROVES_ERC20:
result = approveErc20(
@ -187,8 +226,12 @@ int main(int argc, char** argv)
getenv("BOB_PK")
);
if (result != NULL) {
printf("%s\n", result);
free(result);
} else {
printf("Tx send result was NULL\n");
}
break;
case BOB_ETH_BALANCE:
printf("%" PRIu64 "\n", getEthBalance(bobAddress));
@ -199,9 +242,21 @@ int main(int argc, char** argv)
case TX_RECEIPT:
printf("getTxReceipt\n");
EthTxReceipt txReceipt;
txReceipt = getEthTxReceipt("0x82afa1b00f8a63e1a91430162e5cb2d4ebe915831ffd56e6e3227814913e23e6");
printf("%" PRIu64 "\n", txReceipt.blockNumber);
printf("%s\n", txReceipt.blockHash);
txReceipt = getEthTxReceipt("0xc337b9cfe76aaa9022d9399a9e4ecdc1b7044d65ef74e8911a4b47874bee60c6");
printf("blockNumber: %" PRIu64 "\n", txReceipt.blockNumber);
printf("blockHash: %s\n", txReceipt.blockHash);
printf("status: %s\n", txReceipt.status);
printf("confirmations: %" PRIu64 "\n", txReceipt.confirmations);
break;
case TX_DATA:
printf("getTxData\n");
EthTxData ethTxData;
ethTxData = getEthTxData("0xc337b9cfe76aaa9022d9399a9e4ecdc1b7044d65ef74e8911a4b47874bee60c6");
printf("from : %s\n", ethTxData.from);
printf("to: %s\n", ethTxData.to);
printf("value: %s\n", ethTxData.valueHex);
printf("input: %s\n", ethTxData.input);
printf("exists: %d\n", ethTxData.exists);
break;
default:
return 1;
@ -214,5 +269,6 @@ int main(int argc, char** argv)
char weiBuffer[100];
satoshisToWei(weiBuffer, satoshis);
printf("wei: %s\n", weiBuffer);
return 0;
}

198
iguana/exchanges/etomicswap/etomiccurl.c

@ -1,8 +1,5 @@
#include "etomiccurl.h"
#include <curl/curl.h>
#include <memory.h>
#include <stdlib.h>
#include "../../../includes/cJSON.h"
static char *ethRpcUrl = ETOMIC_URL;
@ -36,6 +33,28 @@ size_t writefunc(void *ptr, size_t size, size_t nmemb, struct string *s)
return size*nmemb;
}
cJSON *parseEthRpcResponse(char *requestResult)
{
printf("Trying to parse ETH RPC response: %s\n", requestResult);
cJSON *json = cJSON_Parse(requestResult);
if (json == NULL) {
printf("ETH RPC response parse failed!\n");
return NULL;
}
cJSON *tmp = cJSON_GetObjectItem(json, "result");
cJSON *error = cJSON_GetObjectItem(json, "error");
cJSON *result = NULL;
if (!is_cJSON_Null(tmp)) {
result = cJSON_Duplicate(tmp, 1);
} else if (error != NULL && !is_cJSON_Null(error)) {
char *errorString = cJSON_PrintUnformatted(error);
printf("Got ETH rpc error: %s\n", errorString);
free(errorString);
}
cJSON_Delete(json);
return result;
}
char* sendRequest(char* request)
{
CURL *curl;
@ -69,128 +88,145 @@ char* sendRequest(char* request)
}
}
char* sendRawTx(char* rawTx)
cJSON *sendRpcRequest(char *method, cJSON *params)
{
char* string;
cJSON *request = cJSON_CreateObject();
cJSON *params = cJSON_CreateArray();
cJSON_AddItemToObject(request, "jsonrpc", cJSON_CreateString("2.0"));
cJSON_AddItemToObject(request, "method", cJSON_CreateString("eth_sendRawTransaction"));
cJSON_AddItemToArray(params, cJSON_CreateString(rawTx));
cJSON_AddItemToObject(request, "params", params);
cJSON_AddItemToObject(request, "id", cJSON_CreateNumber(2));
cJSON_AddStringToObject(request, "jsonrpc", "2.0");
cJSON_AddStringToObject(request, "method", method);
cJSON_AddItemToObject(request, "params", cJSON_Duplicate(params, 1));
cJSON_AddNumberToObject(request, "id", 1);
string = cJSON_PrintUnformatted(request);
char* requestResult = sendRequest(string);
cJSON *json = cJSON_Parse(requestResult);
free(string);
cJSON_Delete(request);
char* tmp = cJSON_GetObjectItem(json, "result")->valuestring;
char* txId = (char*)malloc(strlen(tmp) + 1);
strcpy(txId, tmp);
cJSON_Delete(json);
cJSON *result = parseEthRpcResponse(requestResult);
free(requestResult);
free(string);
return result;
}
char* sendRawTx(char* rawTx)
{
cJSON *params = cJSON_CreateArray();
cJSON_AddItemToArray(params, cJSON_CreateString(rawTx));
cJSON *resultJson = sendRpcRequest("eth_sendRawTransaction", params);
cJSON_Delete(params);
char *txId = NULL;
if (resultJson != NULL && is_cJSON_String(resultJson) && resultJson->valuestring != NULL) {
char* tmp = resultJson->valuestring;
txId = (char*)malloc(strlen(tmp) + 1);
strcpy(txId, tmp);
}
cJSON_Delete(resultJson);
return txId;
}
int getNonce(char* address)
int64_t getNonce(char* address)
{
char* string;
cJSON *request = cJSON_CreateObject();
cJSON *params = cJSON_CreateArray();
cJSON_AddItemToObject(request, "jsonrpc", cJSON_CreateString("2.0"));
cJSON_AddItemToObject(request, "method", cJSON_CreateString("eth_getTransactionCount"));
cJSON_AddItemToArray(params, cJSON_CreateString(address));
cJSON_AddItemToArray(params, cJSON_CreateString("pending"));
cJSON_AddItemToObject(request, "params", params);
cJSON_AddItemToObject(request, "id", cJSON_CreateNumber(2));
string = cJSON_PrintUnformatted(request);
char* requestResult = sendRequest(string);
cJSON_Delete(request);
cJSON *json = cJSON_Parse(requestResult);
int nonce = (int)strtol(cJSON_GetObjectItem(json, "result")->valuestring, NULL, 0);
cJSON_Delete(json);
free(requestResult);
free(string);
int64_t nonce = -1;
cJSON *nonceJson = sendRpcRequest("eth_getTransactionCount", params);
cJSON_Delete(params);
if (nonceJson != NULL && is_cJSON_String(nonceJson) && nonceJson != NULL) {
nonce = (int64_t) strtol(nonceJson->valuestring, NULL, 0);
}
cJSON_Delete(nonceJson);
return nonce;
}
char* getEthBalanceRequest(char* address)
{
char* string;
cJSON *request = cJSON_CreateObject();
cJSON *params = cJSON_CreateArray();
cJSON_AddItemToObject(request, "jsonrpc", cJSON_CreateString("2.0"));
cJSON_AddItemToObject(request, "method", cJSON_CreateString("eth_getBalance"));
cJSON_AddItemToArray(params, cJSON_CreateString(address));
cJSON_AddItemToArray(params, cJSON_CreateString("latest"));
cJSON_AddItemToObject(request, "params", params);
cJSON_AddItemToObject(request, "id", cJSON_CreateNumber(2));
string = cJSON_PrintUnformatted(request);
char* requestResult = sendRequest(string);
cJSON_Delete(request);
cJSON *json = cJSON_Parse(requestResult);
char* tmp = cJSON_GetObjectItem(json, "result")->valuestring;
char* balance = (char*)malloc(strlen(tmp) + 1);
strcpy(balance, tmp);
cJSON_Delete(json);
free(requestResult);
free(string);
cJSON *balanceJson = sendRpcRequest("eth_getBalance", params);
cJSON_Delete(params);
char *balance = NULL;
if (balanceJson != NULL && is_cJSON_String(balanceJson) && balanceJson->valuestring != NULL) {
balance = (char *) malloc(strlen(balanceJson->valuestring) + 1);
strcpy(balance, balanceJson->valuestring);
}
cJSON_Delete(balanceJson);
return balance;
}
char* ethCall(char* to, const char* data)
{
char* string;
cJSON *request = cJSON_CreateObject();
cJSON *params = cJSON_CreateArray();
cJSON *txObject = cJSON_CreateObject();
cJSON_AddItemToObject(request, "jsonrpc", cJSON_CreateString("2.0"));
cJSON_AddItemToObject(request, "method", cJSON_CreateString("eth_call"));
cJSON_AddStringToObject(txObject, "to", to);
cJSON_AddStringToObject(txObject, "data", data);
cJSON_AddItemToArray(params, txObject);
cJSON_AddItemToArray(params, cJSON_CreateString("latest"));
cJSON_AddItemToObject(request, "params", params);
cJSON_AddItemToObject(request, "id", cJSON_CreateNumber(2));
string = cJSON_PrintUnformatted(request);
char* requestResult = sendRequest(string);
cJSON_Delete(request);
cJSON *json = cJSON_Parse(requestResult);
char* tmp = cJSON_GetObjectItem(json, "result")->valuestring;
char* result = (char*)malloc(strlen(tmp) + 1);
strcpy(result, tmp);
cJSON_Delete(json);
free(requestResult);
free(string);
cJSON *resultJson = sendRpcRequest("eth_call", params);
cJSON_Delete(params);
char* result = NULL;
if (resultJson != NULL && is_cJSON_String(resultJson) && resultJson->valuestring != NULL) {
result = (char *) malloc(strlen(resultJson->valuestring) + 1);
strcpy(result, resultJson->valuestring);
}
cJSON_Delete(resultJson);
return result;
}
EthTxReceipt getEthTxReceipt(char *txId)
{
EthTxReceipt result;
char* string;
cJSON *request = cJSON_CreateObject();
memset(&result, 0, sizeof(result));
cJSON *params = cJSON_CreateArray();
cJSON_AddItemToObject(request, "jsonrpc", cJSON_CreateString("2.0"));
cJSON_AddItemToObject(request, "method", cJSON_CreateString("eth_getTransactionReceipt"));
cJSON_AddItemToArray(params, cJSON_CreateString(txId));
cJSON_AddItemToObject(request, "params", params);
cJSON_AddItemToObject(request, "id", cJSON_CreateNumber(2));
string = cJSON_PrintUnformatted(request);
char *requestResult = sendRequest(string);
cJSON_Delete(request);
cJSON *json = cJSON_Parse(requestResult);
cJSON *tmp = cJSON_GetObjectItem(json, "result");
if (is_cJSON_Null(tmp)) {
cJSON *receiptJson = sendRpcRequest("eth_getTransactionReceipt", params);
cJSON_Delete(params);
if (receiptJson == NULL) {
printf("ETH tx %s is not confirmed yet or does not exist at all\n", txId);
strcpy(result.blockHash, "0x0000000000000000000000000000000000000000000000000000000000000000");
result.blockNumber = 0;
} else {
strcpy(result.blockHash, cJSON_GetObjectItem(tmp, "blockHash")->valuestring);
result.blockNumber = (uint64_t) strtol(cJSON_GetObjectItem(tmp, "blockNumber")->valuestring, NULL, 0);
uint64_t currentBlockNumber = getEthBlockNumber();
strcpy(result.blockHash, cJSON_GetObjectItem(receiptJson, "blockHash")->valuestring);
strcpy(result.status, cJSON_GetObjectItem(receiptJson, "status")->valuestring);
result.blockNumber = (uint64_t) strtol(cJSON_GetObjectItem(receiptJson, "blockNumber")->valuestring, NULL, 0);
if (currentBlockNumber >= result.blockNumber) {
result.confirmations = currentBlockNumber - result.blockNumber + 1;
}
cJSON_Delete(json);
free(requestResult);
free(string);
}
cJSON_Delete(receiptJson);
return result;
}
uint64_t getEthBlockNumber()
{
uint64_t result = 0;
cJSON *params = cJSON_CreateArray();
cJSON *blockNumberJson = sendRpcRequest("eth_blockNumber", params);
cJSON_Delete(params);
if (blockNumberJson != NULL && is_cJSON_String(blockNumberJson) && blockNumberJson->valuestring != NULL) {
result = (uint64_t) strtol(blockNumberJson->valuestring, NULL, 0);
}
cJSON_Delete(blockNumberJson);
return result;
}
EthTxData getEthTxData(char *txId)
{
EthTxData result;
memset(&result, 0, sizeof(result));
cJSON *params = cJSON_CreateArray();
cJSON_AddItemToArray(params, cJSON_CreateString(txId));
cJSON *dataJson = sendRpcRequest("eth_getTransactionByHash", params);
cJSON_Delete(params);
if (dataJson == NULL) {
result.exists = 0;
printf("ETH tx %s get data error or txId does not exist\n", txId);
} else {
result.exists = 1;
strcpy(result.from, cJSON_GetObjectItem(dataJson, "from")->valuestring);
strcpy(result.to, cJSON_GetObjectItem(dataJson, "to")->valuestring);
strcpy(result.input, cJSON_GetObjectItem(dataJson, "input")->valuestring);
strcpy(result.valueHex, cJSON_GetObjectItem(dataJson, "value")->valuestring);
}
free(dataJson);
return result;
}

21
iguana/exchanges/etomicswap/etomiccurl.h

@ -1,4 +1,8 @@
#ifndef ETOMIC_CURL_HEADER
#define ETOMIC_CURL_HEADER
#include <stdint.h>
#include <includes/cJSON.h>
#ifdef __cplusplus
extern "C"{
@ -14,15 +18,30 @@ extern "C"{
typedef struct
{
uint64_t blockNumber;
uint64_t confirmations;
char blockHash[75];
char status[10];
} EthTxReceipt;
typedef struct
{
char from[50];
char to[50];
char input[1000];
char valueHex[70];
uint8_t exists;
} EthTxData;
char* sendRawTx(char* rawTx);
char* ethCall(char* to, const char* data);
int getNonce(char* address);
int64_t getNonce(char* address);
char* getEthBalanceRequest(char* address);
EthTxReceipt getEthTxReceipt(char *txId);
EthTxData getEthTxData(char *txId);
uint64_t getEthBlockNumber();
#ifdef __cplusplus
}
#endif
#endif
Loading…
Cancel
Save