Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
leonardotc committed Nov 29, 2021
2 parents dba622a + ac64300 commit 4a36e47
Show file tree
Hide file tree
Showing 7 changed files with 337 additions and 218 deletions.
2 changes: 1 addition & 1 deletion c/ci-analyse.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ format:
cpd:
stage: analysis
needs: []
image: rawdee/pmd
image: rawdee/pmd:6.40.0
tags:
- short-jobs
script:
Expand Down
2 changes: 1 addition & 1 deletion c/ci-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ readthedocs:
- ./update_examples.sh
- cd ..
- export PRE_DOC=`cat wasm/docs/*.md`
- git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@git.slock.it/in3/doc.git
- git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@git.slock.it/in3/c/in3-doc.git doc
- git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@git.slock.it/tools/generator.git
- cp python_multilib/docs/documentation.md doc/docs/api-python.md
- cp dotnet/docs/api-dotnet.md doc/docs/
Expand Down
135 changes: 75 additions & 60 deletions c/src/verifier/btc/btc.c
Original file line number Diff line number Diff line change
Expand Up @@ -518,77 +518,114 @@ static in3_ret_t in3_verify_btc(btc_target_conf_t* conf, in3_vctx_t* vc) {
// }
// #endif

#if !defined(RPC_ONLY) || defined(RPC_SIGNTRANSACTION)
// #if !defined(RPC_ONLY) || defined(RPC_SIGNTRANSACTION)

if (VERIFY_RPC("signtransaction")) {
REQUIRE_EXPERIMENTAL(vc->req, "btc")
// Get raw unsigned transaction
// As we will have custody of the user priv keys, this should be obtained from our server somehow
// sign transaction
// return raw signed transaction
}
#endif
// if (VERIFY_RPC("signtransaction")) {
// REQUIRE_EXPERIMENTAL(vc->req, "btc")
// // Get raw unsigned transaction
// // As we will have custody of the user priv keys, this should be obtained from our server somehow
// // sign transaction
// // return raw signed transaction
// }
// #endif

#if !defined(RPC_ONLY) || defined(RPC_SENDRAWTRANSACTION)
// #if !defined(RPC_ONLY) || defined(RPC_SENDRAWTRANSACTION)

if (VERIFY_RPC("sendrawtransaction")) {
REQUIRE_EXPERIMENTAL(vc->req, "btc")
// Get raw signed transaction
// verify if transaction is well-formed and signed before sending
// send transaction to in3 server
// return success or error code
}
#endif
// if (VERIFY_RPC("sendrawtransaction")) {
// REQUIRE_EXPERIMENTAL(vc->req, "btc")
// // Get raw signed transaction
// // verify if transaction is well-formed and signed before sending
// // send transaction to in3 server
// // return success or error code
// }
// #endif
return IN3_EIGNORE;
}

in3_ret_t send_transaction(btc_target_conf_t* conf, in3_rpc_handle_ctx_t* ctx) {
UNUSED_VAR(conf);

in3_req_t* req = ctx->req;
// This is the RPC that abstracts most of what is done in the background before sending a transaction:
// Get outputs we want to send

in3_req_t* sub = req_find_required(ctx->req, "sendrawtransaction", NULL);
if (sub) { // do we have a result?
switch (in3_req_state(sub)) {
case REQ_ERROR:
return req_set_error(ctx->req, sub->error, sub->verification_state ? sub->verification_state : IN3_ERPC);
case REQ_SUCCESS: {
d_token_t* result = d_get(sub->responses[0], K_RESULT);
if (result) {
sb_add_json(in3_rpc_handle_start(ctx), "", result);
}
else {
char* error_msg = d_get_string(d_get(sub->responses[0], K_ERROR), K_MESSAGE);
return req_set_error(ctx->req, error_msg ? error_msg : "Unable to send transaction", IN3_ERPC);
}
return in3_rpc_handle_finish(ctx);
}
case REQ_WAITING_TO_SEND:
case REQ_WAITING_FOR_RESPONSE:
return IN3_WAITING;
}
}

in3_req_t* req = ctx->req;
d_token_t* params = ctx->params;
char* pub_key_str;
bytes_t account;
bytes_t pub_key;
pub_key.len = 20;
TRY_PARAM_GET_REQUIRED_ADDRESS(pub_key.data, ctx, 0)
d_token_t* outputs = d_get_at(params, 1);
d_token_t* utxo_list = d_get_at(params, 2);
pub_key.len = 65; // TODO: Implement support to compressed public keys as well (33-bytes)
pub_key.data = alloca(pub_key.len * sizeof(uint8_t));
account.len = 20;
TRY_PARAM_GET_REQUIRED_ADDRESS(account.data, ctx, 0)
TRY_PARAM_GET_REQUIRED_STRING(pub_key_str, ctx, 1)
hex_to_bytes(pub_key_str, -1, pub_key.data, pub_key.len);
d_token_t* outputs = d_get_at(params, 2);
d_token_t* utxo_list = d_get_at(params, 3);

// select "best" set of UTXOs
// btc_utxo_t* utxo_list = NULL;
uint32_t miner_fee = 0, outputs_total = 0, utxo_total = 0;
// ---- select utxos here

// create output for receiving the transaction "change", discounting miner fee
btc_tx_out_t tx_out_change;
btc_init_tx_out(&tx_out_change);
tx_out_change.value = utxo_total - miner_fee - outputs_total;
// create raw unsigned transaction using selected set of utxos (inputs) and outputs (both received in Command Line and created "change")

// {"method":"sendrawtransaction", "params":["0100000001f90c6776e0aff73fdc67d57beadc283cea8c63cc7b8d48249bd79ce6a7823fc0000000008a47304402201955addf93c52fe20ce468603e97d3ea495c3072d3ebe92120ad0a200abbb51902204a9fe8e85fcee5621fc902796bbdf7ce490dc06cbfe7acb37eeb2f8c9406710e0141046d6caac248af96f6afa7f904f550253a0f3ef3f5aa2fe6838a95b216691468e2487e6222a6664e079c8edf7518defd562dbeda1e7593dfd7f0be285880a24dabffffffff01e803000000000000015100000000"]}

// create unsigned transaction
bytes_t signed_tx = NULL_BYTES;
btc_tx_t tx;
btc_init_tx(&tx);
add_outputs_to_tx(req, outputs, &tx);

// select "best" set of UTXOs
btc_utxo_t* selected_utxo_list = NULL;
uint32_t utxo_list_len = 0;
btc_prepare_utxo(utxo_list, &selected_utxo_list, &utxo_list_len);
// TODO: prepare tx
TRY(btc_sign_tx(ctx->req, &tx, selected_utxo_list, utxo_list_len, &pub_key));
btc_prepare_utxos(&tx, utxo_list, &selected_utxo_list, &utxo_list_len);
btc_set_segwit(&tx, selected_utxo_list, utxo_list_len);

TRY(btc_sign_tx(ctx->req, &tx, selected_utxo_list, utxo_list_len, &account, &pub_key));

btc_serialize_tx(&tx, &signed_tx);
sb_t sb = {0};
sb_add_rawbytes(&sb, "\"", signed_tx, 0);
sb_add_chars(&sb, "\"");

// now that we included the signature in the rpc-request, we can free it + the old rpc-request.
_free(signed_tx.data);
// Now that we wrote the request, we can free all allocated memory
if (signed_tx.data) _free(signed_tx.data);

if (selected_utxo_list) {
for (uint32_t i = 0; i < utxo_list_len; i++) {
_free(selected_utxo_list[i].tx_hash);
_free(selected_utxo_list[i].tx_out.script.data);
}
_free(selected_utxo_list);
}

if (tx.input.data) _free(tx.input.data);
if (tx.output.data) _free(tx.output.data);
if (tx.witnesses.data) _free(tx.witnesses.data);

// finally, send transaction
d_token_t* result = NULL;
TRY_FINAL(req_send_sub_request(req, "sendrawtransaction", sb.data, NULL, &result, NULL), _free(sb.data));
sb_add_json(in3_rpc_handle_start(ctx), "", result);
return in3_rpc_handle_finish(ctx);
}

Expand Down Expand Up @@ -651,26 +688,4 @@ in3_ret_t in3_register_btc(in3_t* c) {
tc->max_diff = 10;
tc->dap_limit = 20;
return in3_plugin_register(c, PLGN_ACT_RPC_VERIFY | PLGN_ACT_TERM | PLGN_ACT_CONFIG_GET | PLGN_ACT_CONFIG_SET | PLGN_ACT_RPC_HANDLE, handle_btc, tc, false);
}
/*
static void print_hex(char* prefix, uint8_t* data, int len) {
printf("%s0x", prefix);
for (int i = 0; i < len; i++) printf("%02x", data[i]);
printf("\n");
}
static void print(char* prefix, bytes_t data, char* type) {
uint8_t tmp[32];
if (strcmp(type, "hash") == 0) {
rev_copy(tmp, data.data);
data.data = tmp;
}
if (strcmp(type, "int") == 0) {
printf("%s%i\n", prefix, le_to_int(data.data));
return;
}
print_hex(prefix, data.data, data.len);
}
*/
}
Loading

0 comments on commit 4a36e47

Please sign in to comment.