Browse Source

Use mutex lock to allow only 1 concurrent ETH tx send.

patch-3
Artem Pikulin 7 years ago
parent
commit
754fab7b07
  1. 21
      iguana/exchanges/LP_etomic.c
  2. 6
      iguana/exchanges/etomicswap/CMakeLists.txt
  3. 29
      iguana/exchanges/etomicswap/bob.c
  4. 46
      iguana/exchanges/etomicswap/etomiccurl.c
  5. 4
      iguana/exchanges/etomicswap/etomiccurl.h
  6. 1
      iguana/exchanges/etomicswap/etomiclib.cpp

21
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)

6
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)

29
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;
}

46
iguana/exchanges/etomicswap/etomiccurl.c

@ -2,7 +2,7 @@
#include <curl/curl.h>
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);
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);
}

4
iguana/exchanges/etomicswap/etomiccurl.h

@ -3,6 +3,9 @@
#include <stdint.h>
#include <includes/cJSON.h>
#ifdef _WIN32
#include "../../../OSlibs/win/pthread.h"
#endif
#ifdef __cplusplus
extern "C"{
@ -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
}

1
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"

Loading…
Cancel
Save