diff --git a/iguana/exchanges/LP_etomic.c b/iguana/exchanges/LP_etomic.c index f80f6fc81..444063e2a 100644 --- a/iguana/exchanges/LP_etomic.c +++ b/iguana/exchanges/LP_etomic.c @@ -27,26 +27,7 @@ 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); + return(waitForConfirmation(txId)); } char *LP_etomicalice_send_fee(struct basilisk_swap *swap) diff --git a/iguana/exchanges/etomicswap/CMakeLists.txt b/iguana/exchanges/etomicswap/CMakeLists.txt index eb23965a3..46c2d2adf 100644 --- a/iguana/exchanges/etomicswap/CMakeLists.txt +++ b/iguana/exchanges/etomicswap/CMakeLists.txt @@ -1,11 +1,11 @@ -cmake_minimum_required(VERSION 2.8.9) +cmake_minimum_required(VERSION 3.5.1) add_library(etomiclib-testnet etomiclib.cpp etomiccurl.c) add_library(etomiclib-mainnet etomiclib.cpp etomiccurl.c) target_compile_definitions(etomiclib-testnet PRIVATE ETOMIC_TESTNET) add_executable(alice alice.c) add_executable(bob bob.c) include_directories("${CMAKE_SOURCE_DIR}/cpp-ethereum") -target_link_libraries(etomiclib-testnet PUBLIC curl libcrypto777 ethcore devcrypto devcore) -target_link_libraries(etomiclib-mainnet PUBLIC curl libcrypto777 ethcore devcrypto devcore) +target_link_libraries(etomiclib-testnet PUBLIC curl libcrypto777 ethcore devcrypto devcore pthread) +target_link_libraries(etomiclib-mainnet PUBLIC curl libcrypto777 ethcore devcrypto devcore pthread) target_link_libraries(alice PUBLIC etomiclib-testnet) -target_link_libraries(bob PUBLIC etomiclib-testnet) \ No newline at end of file +target_link_libraries(bob PUBLIC etomiclib-testnet) diff --git a/iguana/exchanges/etomicswap/bob.c b/iguana/exchanges/etomicswap/bob.c index c2e75ab8c..ce6c90133 100644 --- a/iguana/exchanges/etomicswap/bob.c +++ b/iguana/exchanges/etomicswap/bob.c @@ -14,6 +14,11 @@ char* aliceAddress = "0x485d2cc2d13a9e12E4b53D606DB1c8adc884fB8a"; char* bobAddress = "0xbAB36286672fbdc7B250804bf6D14Be0dF69fa29"; char* tokenAddress = "0xc0eb7AeD740E1796992A08962c15661bDEB58003"; +void *erc20ApproveThread(ApproveErc20Input *input) { + char *result = approveErc20(*input); + free(result); +} + int main(int argc, char** argv) { enum { @@ -227,13 +232,32 @@ int main(int argc, char** argv) strcpy(input8.owner, bobAddress); strcpy(input8.tokenAddress, tokenAddress); strcpy(input8.secret, getenv("BOB_PK")); - result = approveErc20(input8); + ApproveErc20Input input123; + strcpy(input123.amount, "100"); + strcpy(input123.spender, bobContractAddress); + strcpy(input123.owner, bobAddress); + strcpy(input123.tokenAddress, tokenAddress); + strcpy(input123.secret, getenv("BOB_PK")); + pthread_t t1, t2; + pthread_create(&t1, NULL, erc20ApproveThread, &input8); + pthread_create(&t2, NULL, erc20ApproveThread, &input123); + pthread_join(t1, NULL); + pthread_join(t2, NULL); + /*result = approveErc20(input8); if (result != NULL) { printf("%s\n", result); free(result); } else { printf("Tx send result was NULL\n"); } + result = approveErc20(&input8); + 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)); @@ -263,6 +287,7 @@ int main(int argc, char** argv) default: return 1; } + /* char *pubkey = getPubKeyFromPriv(getenv("BOB_PK")); printf("pubkey: %s\n", pubkey); free(pubkey); @@ -288,6 +313,6 @@ int main(int argc, char** argv) uint64_t gasPrice = getGasPriceFromStation(); printf("gasPrice: %" PRIu64 "\n", gasPrice); - + */ return 0; } diff --git a/iguana/exchanges/etomicswap/etomiccurl.c b/iguana/exchanges/etomicswap/etomiccurl.c index b862615d5..10289b9d0 100644 --- a/iguana/exchanges/etomicswap/etomiccurl.c +++ b/iguana/exchanges/etomicswap/etomiccurl.c @@ -2,7 +2,7 @@ #include static char *ethRpcUrl = ETOMIC_URL; -static uint8_t gettingNonceFlag = 0; +pthread_mutex_t sendTxMutex = PTHREAD_MUTEX_INITIALIZER; struct string { char *ptr; @@ -115,20 +115,23 @@ char* sendRawTx(char* rawTx) 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); + if (waitForConfirmation(tmp) > 0) { + txId = (char *) malloc(strlen(tmp) + 1); + strcpy(txId, tmp); + } } cJSON_Delete(resultJson); + pthread_mutex_unlock(&sendTxMutex); return txId; } int64_t getNonce(char* address) { - while (gettingNonceFlag == 1) { - printf("Wait for other thread to get ETH nonce\n"); - sleep(5); - } - gettingNonceFlag = 1; + // we should lock this mutex and unlock it only when transaction was already sent. + // make sure that sendRawTx is called after getting a nonce! + if (pthread_mutex_lock(&sendTxMutex) != 0) { + printf("Nonce mutex lock failed\n"); + }; cJSON *params = cJSON_CreateArray(); cJSON_AddItemToArray(params, cJSON_CreateString(address)); cJSON_AddItemToArray(params, cJSON_CreateString("pending")); @@ -140,7 +143,6 @@ int64_t getNonce(char* address) } cJSON_Delete(nonceJson); printf("Got ETH nonce %d\n", (int)nonce); - gettingNonceFlag = 0; return nonce; } @@ -273,7 +275,11 @@ uint64_t getGasPriceFromStation() } if (is_cJSON_Number(cJSON_GetObjectItem(resultJson, "average"))) { +#ifdef ETOMIC_TESTNET + result = (uint64_t)(cJSON_GetObjectItem(resultJson, "average")->valuedouble / 10) + 10; +#else result = (uint64_t)(cJSON_GetObjectItem(resultJson, "average")->valuedouble / 10) + 1; +#endif } cJSON_Delete(resultJson); return result; @@ -281,3 +287,27 @@ uint64_t getGasPriceFromStation() return DEFAULT_GAS_PRICE; } } + +int32_t waitForConfirmation(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((int32_t)receipt.confirmations); +} diff --git a/iguana/exchanges/etomicswap/etomiccurl.h b/iguana/exchanges/etomicswap/etomiccurl.h index a27f67c11..584ce00e1 100644 --- a/iguana/exchanges/etomicswap/etomiccurl.h +++ b/iguana/exchanges/etomicswap/etomiccurl.h @@ -3,11 +3,14 @@ #include #include +#ifdef _WIN32 +#include "../../../OSlibs/win/pthread.h" +#endif #ifdef __cplusplus extern "C"{ #endif - + #ifdef ETOMIC_TESTNET #define ETOMIC_URL "https://ropsten.infura.io/y07GHxUyTgeN2mdfOonu" #define DEFAULT_GAS_PRICE 100 @@ -41,6 +44,7 @@ EthTxReceipt getEthTxReceipt(char *txId); EthTxData getEthTxData(char *txId); uint64_t getEthBlockNumber(); uint64_t getGasPriceFromStation(); +int32_t waitForConfirmation(char *txId); #ifdef __cplusplus } diff --git a/iguana/exchanges/etomicswap/etomiclib.cpp b/iguana/exchanges/etomicswap/etomiclib.cpp index 99390441d..368fbb3fc 100644 --- a/iguana/exchanges/etomicswap/etomiclib.cpp +++ b/iguana/exchanges/etomicswap/etomiclib.cpp @@ -52,7 +52,6 @@ char *approveErc20(ApproveErc20Input input) tx.gas = 300000; tx.gasPrice = getGasPriceFromStation() * boost::multiprecision::pow(u256(10), 9); tx.nonce = getNonce(input.owner); - uint8_t decimals = getErc20Decimals(input.tokenAddress); std::stringstream ss; ss << "0x095ea7b3" << "000000000000000000000000"