Skip to content

Commit

Permalink
wallet: add dogecoin_p2pkh_address_to_wallet
Browse files Browse the repository at this point in the history
-remove frees on wallet init
-move wallet addr initialization within if no match section of dogecoin_p2pkh_address_to_wallet
-assign dogecoin_utxo* directly from vector_idx in dogecoin_wallet_scrape_utxos
-conditionally set wallet->unspent->elem_free_f to dogeocin_wallet_utxo_free in dogecoin_wallet_check_transaction
  • Loading branch information
xanimo committed Dec 14, 2023
1 parent 6759b39 commit e4aec01
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 24 deletions.
1 change: 1 addition & 0 deletions include/dogecoin/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ LIBDOGECOIN_API void dogecoin_wallet_set_master_key_copy(dogecoin_wallet* wallet
LIBDOGECOIN_API dogecoin_wallet_addr* dogecoin_wallet_next_addr(dogecoin_wallet* wallet);
LIBDOGECOIN_API dogecoin_wallet_addr* dogecoin_wallet_next_bip44_addr(dogecoin_wallet* wallet);
LIBDOGECOIN_API dogecoin_bool dogecoin_p2pkh_address_to_wallet_pubkeyhash(const char* address_in, dogecoin_wallet_addr* addr, dogecoin_wallet* wallet);
LIBDOGECOIN_API dogecoin_wallet_addr* dogecoin_p2pkh_address_to_wallet(const char* address_in, dogecoin_wallet* wallet);

/** writes all available addresses (P2PKH) to the addr_out vector */
LIBDOGECOIN_API void dogecoin_wallet_get_addresses(dogecoin_wallet* wallet, vector* addr_out);
Expand Down
81 changes: 57 additions & 24 deletions src/wallet.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,15 +223,15 @@ void dogecoin_wallet_wtx_cachehash(dogecoin_wtx* wtx) {
==========================================================
*/
dogecoin_utxo* dogecoin_wallet_utxo_new() {
dogecoin_utxo* utxo = dogecoin_calloc(1, sizeof(*utxo));
dogecoin_utxo* utxo = dogecoin_calloc(1, sizeof(dogecoin_utxo));
utxo->confirmations = 0;
utxo->spendable = true;
utxo->solvable = true;
utxo->account = NULL;
dogecoin_mem_zero(&utxo->script_pubkey, sizeof(utxo->script_pubkey));
dogecoin_mem_zero(&utxo->amount, sizeof(utxo->amount));
dogecoin_mem_zero(&utxo->address, sizeof(utxo->address));
dogecoin_mem_zero(&utxo->txid, sizeof(utxo->txid));
dogecoin_hash_clear(utxo->txid);
utxo->vout = 0;
return utxo;
}
Expand Down Expand Up @@ -310,7 +310,7 @@ dogecoin_wallet* dogecoin_wallet_new(const dogecoin_chainparams *params)
wallet->masterkey = NULL;
wallet->chain = params;
wallet->hdkeys_rbtree = 0;
wallet->unspent = vector_new(1, NULL);
wallet->unspent = vector_new(10, NULL);
wallet->unspent_rbtree = 0;
wallet->spends = vector_new(10, (void (*)(void *)) dogecoin_wallet_utxo_free);
wallet->spends_rbtree = 0;
Expand Down Expand Up @@ -433,8 +433,6 @@ dogecoin_wallet* dogecoin_wallet_init(const dogecoin_chainparams* chain, const c
}
}

dogecoin_wallet_addr* waddr;

if (address != NULL) {
char delim[] = " ";
// copy address into a new string, strtok modifies the string
Expand All @@ -444,27 +442,20 @@ dogecoin_wallet* dogecoin_wallet_init(const dogecoin_chainparams* chain, const c

while((ptr = strtok_r(temp_address_copy, delim, &temp_address_copy)))
{
waddr = dogecoin_wallet_addr_new();
if (!waddr->ignore) {
if (!dogecoin_p2pkh_address_to_wallet_pubkeyhash(ptr, waddr, wallet)) {
dogecoin_wallet_addr_free(waddr);
}
}
dogecoin_p2pkh_address_to_wallet(ptr, wallet);
}
dogecoin_free(address_copy);
}
#ifdef USE_UNISTRING
else if (wallet->waddr_vector->len == 0) {
int i=0;
for(;i<20;i++) {
waddr = dogecoin_wallet_next_bip44_addr(wallet);
dogecoin_wallet_next_bip44_addr(wallet);
}
char str[P2PKHLEN];
dogecoin_p2pkh_addr_from_hash160(waddr->pubkeyhash, wallet->chain, str, P2PKHLEN);
}
#else
else if (wallet->waddr_vector->len == 0) {
waddr = dogecoin_wallet_next_addr(wallet);
dogecoin_wallet_next_addr(wallet);
}
#endif
return wallet;
Expand Down Expand Up @@ -597,7 +588,7 @@ void dogecoin_wallet_scrape_utxos(dogecoin_wallet* wallet, dogecoin_wtx* wtx) {
size_t m = 0, n = 0;
for (; m < wallet->spends->len; m++) {
dogecoin_utxo* spent_utxo = vector_idx(wallet->spends, m);
if (memcmp(spent_utxo->txid, utxo->txid, 32) == 0 && spent_utxo->vout == utxo->vout) {
if (memcmp((const uint8_t*)spent_utxo->txid, (const uint8_t*)utxo->txid, 32) == 0 && spent_utxo->vout == utxo->vout) {
n++;
}
}
Expand Down Expand Up @@ -634,30 +625,32 @@ void dogecoin_wallet_scrape_utxos(dogecoin_wallet* wallet, dogecoin_wtx* wtx) {
char* addr = vector_idx(addrs, i);
// compare wtx->tx->vout with address from wallet->waddr_vector:
if (strncmp(p2pkh_from_script_pubkey, addr, P2PKHLEN - 1)==0) {
// match so we populate utxo struct:
dogecoin_utxo* utxo = dogecoin_wallet_utxo_new();
uint256 utxo_txid;
// make the txid:
dogecoin_tx_hash(wtx->tx, (uint8_t*)utxo->txid);
dogecoin_tx_hash(wtx->tx, (uint8_t*)&utxo_txid);
// convert from uint8_t to char*
char* hexbuf = utils_uint8_to_hex((const uint8_t*)utxo->txid, DOGECOIN_HASH_LENGTH);
char* hexbuf = utils_uint8_to_hex((const uint8_t*)&utxo_txid, DOGECOIN_HASH_LENGTH);
// reverse txid with double length:
utils_reverse_hex(hexbuf, DOGECOIN_HASH_LENGTH*2);
// copy back to utxo->txid as uint256 (uint8_t* or uint8_t[32]):
memcpy_safe(utxo->txid, utils_hex_to_uint8(hexbuf), 32);
memcpy_safe(utxo_txid, utils_hex_to_uint8(hexbuf), 32);
g = 0;
for (; h < wallet->unspent->len; h++) {
dogecoin_utxo* unspent_utxo = vector_idx(wallet->unspent, h);
if (memcmp(unspent_utxo->txid, utxo->txid, 32)==0 && (size_t)unspent_utxo->vout == j) {
if (memcmp(unspent_utxo->txid, &utxo_txid, 32)==0 && (size_t)unspent_utxo->vout == j) {
g++;
}
}
for (h = 0; h < wallet->spends->len; h++) {
dogecoin_utxo* spent_utxo = vector_idx(wallet->spends, h);
if (memcmp(spent_utxo->txid, utxo->txid, 32)==0 && (size_t)spent_utxo->vout == j) {
if (memcmp(spent_utxo->txid, &utxo_txid, 32)==0 && (size_t)spent_utxo->vout == j) {
g++;
}
}
if (g == 0) {
// match so we populate utxo struct:
dogecoin_utxo* utxo = dogecoin_wallet_utxo_new();
memcpy_safe(utxo->txid, &utxo_txid, DOGECOIN_HASH_LENGTH);
// copy matching script_pubkey:
memcpy_safe(utxo->script_pubkey, utils_uint8_to_hex((const uint8_t*)tx_out->script_pubkey->str, tx_out->script_pubkey->len), SCRIPT_PUBKEY_STRINGLEN);
// set tx->tx_in->prevout.n (utxo->vout):
Expand All @@ -669,7 +662,7 @@ void dogecoin_wallet_scrape_utxos(dogecoin_wallet* wallet, dogecoin_wtx* wtx) {
// finally add utxo to rbtree:
dogecoin_btree_tfind(utxo, &wallet->unspent_rbtree, dogecoin_utxo_compare);
// and vector:
vector_add(wallet->unspent, utxo);
vector_add(wallet->unspent, (dogecoin_utxo*)utxo);
}
}
}
Expand Down Expand Up @@ -1071,6 +1064,45 @@ dogecoin_bool dogecoin_p2pkh_address_to_wallet_pubkeyhash(const char* address_in
return true;
}

dogecoin_wallet_addr* dogecoin_p2pkh_address_to_wallet(const char* address_in, dogecoin_wallet* wallet) {
if (!address_in || !wallet || !wallet->masterkey) return false;

// lookup to see if we have address already:
dogecoin_bool match = false;
if (wallet->waddr_vector->len) {
vector* addrs = vector_new(1, free);
dogecoin_wallet_get_addresses(wallet, addrs);
unsigned int i;
for (i = 0; i < addrs->len; i++) {
char* watch_addr = vector_idx(addrs, i);
if (strncmp(watch_addr, address_in, strlen(watch_addr))==0) {
// addr->childindex = i;
match = true;
}
}
vector_free(addrs, true);
}

// if no match add to rbtree, vector and db:
if (!match) {
dogecoin_wallet_addr* addr = dogecoin_wallet_addr_new();
char* pubkey_hash = dogecoin_address_to_pubkey_hash((char*)address_in);
if (!pubkey_hash) return NULL;
memcpy_safe(addr->pubkeyhash, utils_hex_to_uint8(pubkey_hash), 20);
addr->childindex = wallet->next_childindex;
dogecoin_btree_tsearch(addr, &wallet->waddr_rbtree, dogecoin_wallet_addr_compare);
vector_add(wallet->waddr_vector, addr);
cstring* record = cstr_new_sz(256);
dogecoin_wallet_addr_serialize(record, wallet->chain, addr);
if (!wallet_write_record(wallet, record, WALLET_DB_REC_TYPE_ADDR)) fprintf(stderr, "Writing wallet address failed\n");
cstr_free(record, true);
dogecoin_file_commit(wallet->dbfile);
wallet->next_childindex++;
return addr;
}
return NULL;
}

void dogecoin_wallet_get_addresses(dogecoin_wallet* wallet, vector* addr_out)
{
unsigned int i;
Expand Down Expand Up @@ -1373,6 +1405,7 @@ void dogecoin_wallet_check_transaction(void *ctx, dogecoin_tx *tx, unsigned int
dogecoin_tx_copy(wtx->tx, tx);
dogecoin_wallet_scrape_utxos(wallet, wtx);
dogecoin_wallet_add_wtx_move(wallet, wtx);
wallet->unspent->elem_free_f = (void (*)(void*)) dogecoin_wallet_utxo_free;
}
}

Expand Down

0 comments on commit e4aec01

Please sign in to comment.