From 830e16c12d4ebba89c71107a8f319e52d702a31d Mon Sep 17 00:00:00 2001 From: kexkey Date: Mon, 12 Nov 2018 12:01:01 -0500 Subject: [PATCH] OTS Stamping support, first pass --- api_auth_docker/api.properties | 3 + api_auth_docker/tests.sh | 57 ++- cron_docker/README.md | 3 +- cron_docker/callbacks_cron | 3 +- cron_docker/env.properties | 3 +- doc/INSTALL-MANUAL-STEPS.md | 3 + docker-compose.yml | 16 + otsclient_docker/Dockerfile | 27 ++ otsclient_docker/README.md | 24 ++ otsclient_docker/env.properties | 2 + otsclient_docker/script/otsclient.sh | 83 +++++ otsclient_docker/script/requesthandler.sh | 88 +++++ otsclient_docker/script/responsetoclient.sh | 21 ++ otsclient_docker/script/startotsclient.sh | 6 + otsclient_docker/script/trace.sh | 15 + proxy_docker/Dockerfile | 1 + proxy_docker/app/data/watching.sql | 10 + proxy_docker/app/script/ots.sh | 203 ++++++++++ proxy_docker/app/script/requesthandler.sh | 390 +++++++++++--------- proxy_docker/app/script/responsetoclient.sh | 19 + proxy_docker/app/script/watchrequest.sh | 111 +++--- proxy_docker/env.properties | 3 +- 22 files changed, 827 insertions(+), 264 deletions(-) create mode 100644 otsclient_docker/Dockerfile create mode 100644 otsclient_docker/README.md create mode 100644 otsclient_docker/env.properties create mode 100644 otsclient_docker/script/otsclient.sh create mode 100644 otsclient_docker/script/requesthandler.sh create mode 100644 otsclient_docker/script/responsetoclient.sh create mode 100644 otsclient_docker/script/startotsclient.sh create mode 100644 otsclient_docker/script/trace.sh create mode 100644 proxy_docker/app/script/ots.sh diff --git a/api_auth_docker/api.properties b/api_auth_docker/api.properties index 3ae021b..bde9994 100644 --- a/api_auth_docker/api.properties +++ b/api_auth_docker/api.properties @@ -20,6 +20,8 @@ action_deriveindex=spender action_derivepubpath=spender action_ln_pay=spender action_ln_newaddr=spender +action_ots_stamp=spender +action_ots_getfile=spender # Admin can do what the spender can do plus: @@ -27,3 +29,4 @@ action_ln_newaddr=spender # Should be called from inside the Swarm: action_conf=internal action_executecallbacks=internal +action_ots_backoffice=internal diff --git a/api_auth_docker/tests.sh b/api_auth_docker/tests.sh index deaf273..25e1285 100644 --- a/api_auth_docker/tests.sh +++ b/api_auth_docker/tests.sh @@ -143,56 +143,68 @@ test_authorization_spender() # getbalance echo -n " Testing getbalance... " rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/getbalance) - [ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 130 - [ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 135 + [ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 430 + [ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 435 # getnewaddress echo -n " Testing getnewaddress... " rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/getnewaddress) - [ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 140 - [ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 145 + [ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 440 + [ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 445 # spend echo -n " Testing spend... " rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/spend) - [ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 150 - [ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 155 + [ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 450 + [ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 455 # addtobatch echo -n " Testing addtobatch... " rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/addtobatch) - [ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 160 - [ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 165 + [ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 460 + [ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 465 # batchspend echo -n " Testing batchspend... " rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/batchspend) - [ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 170 - [ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 175 + [ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 470 + [ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 475 # deriveindex echo -n " Testing deriveindex... " rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/deriveindex) - [ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 180 - [ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 185 + [ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 480 + [ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 485 # derivepubpath echo -n " Testing derivepubpath... " rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/derivepubpath) - [ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 190 - [ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 195 + [ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 490 + [ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 495 # ln_pay echo -n " Testing ln_pay... " rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/ln_pay) - [ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 200 - [ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 205 + [ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 500 + [ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 505 # ln_newaddr echo -n " Testing ln_newaddr... " rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/ln_newaddr) - [ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 210 - [ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 215 + [ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 510 + [ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 515 + + # ots_stamp + echo -n " Testing ots_stamp... " + rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/ots_stamp) + [ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 520 + [ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 525 + + # ots_getfile + echo -n " Testing ots_getfile... " + rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/ots_getfile) + [ ${is_spender} = true ] && [ "${rc}" -eq "403" ] && return 530 + [ ${is_spender} = false ] && [ "${rc}" -ne "403" ] && return 535 return 0 } @@ -216,12 +228,17 @@ test_authorization_internal() # conf echo -n " Testing conf... " rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/conf) - [ "${rc}" -ne "403" ] && return 220 + [ "${rc}" -ne "403" ] && return 920 # executecallbacks echo -n " Testing executecallbacks... " rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/executecallbacks) - [ "${rc}" -ne "403" ] && return 230 + [ "${rc}" -ne "403" ] && return 930 + + # ots_backoffice + echo -n " Testing ots_backoffice... " + rc=$(time -f "%E" curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $token" -k https://localhost/ots_backoffice) + [ "${rc}" -ne "403" ] && return 940 return 0 } diff --git a/cron_docker/README.md b/cron_docker/README.md index 65af613..c5e56bb 100644 --- a/cron_docker/README.md +++ b/cron_docker/README.md @@ -3,7 +3,8 @@ ## Configure your container by modifying `env.properties` file ```properties -PROXY_URL=cyphernode:8888/executecallbacks +TX_CONF_URL=cyphernode:8888/executecallbacks +OTS_URL=cyphernode:8888/ots_backoffice ``` ## Building docker image diff --git a/cron_docker/callbacks_cron b/cron_docker/callbacks_cron index 68b888b..e6a2e20 100644 --- a/cron_docker/callbacks_cron +++ b/cron_docker/callbacks_cron @@ -1,3 +1,4 @@ #!/bin/sh -curl ${PROXY_URL} +curl ${TX_CONF_URL} +curl ${OTS_URL} diff --git a/cron_docker/env.properties b/cron_docker/env.properties index 7c46889..e49eee3 100644 --- a/cron_docker/env.properties +++ b/cron_docker/env.properties @@ -1 +1,2 @@ -PROXY_URL=cyphernode:8888/executecallbacks +TX_CONF_URL=cyphernode:8888/executecallbacks +OTS_URL=cyphernode:8888/ots_backoffice diff --git a/doc/INSTALL-MANUAL-STEPS.md b/doc/INSTALL-MANUAL-STEPS.md index decd9ff..4f376af 100644 --- a/doc/INSTALL-MANUAL-STEPS.md +++ b/doc/INSTALL-MANUAL-STEPS.md @@ -38,6 +38,7 @@ vi proxy_docker/env.properties ```shell vi cron_docker/env.properties vi pycoin_docker/env.properties +vi otsclient_docker/env.properties vi api_auth_docker/env.properties ``` @@ -52,6 +53,7 @@ docker build -t authapi api_auth_docker/. docker build -t proxycronimg cron_docker/. docker build -t btcproxyimg proxy_docker/. docker build -t pycoinimg pycoin_docker/. +docker build -t otsclientimg otsclient_docker/. ``` ## Build images from Satoshi Portal's dockers repo @@ -137,6 +139,7 @@ sudo find ~/btcdata -type d -exec chmod 2775 {} \; ; sudo find ~/btcdata -type f ```shell id="001";h64=$(echo -n "{\"alg\":\"HS256\",\"typ\":\"JWT\"}" | base64);p64=$(echo -n "{\"id\":\"$id\",\"exp\":$((`date +"%s"`+10))}" | base64);k="2df1eeea370eacdc5cf7e96c2d82140d1568079a5d4d87006ec8718a98883b36";s=$(echo -n "$h64.$p64" | openssl dgst -hmac "$k" -sha256 -r | cut -sd ' ' -f1);token="$h64.$p64.$s";curl -H "Authorization: Bearer $token" -k https://localhost/getbestblockhash id="003";h64=$(echo -n "{\"alg\":\"HS256\",\"typ\":\"JWT\"}" | base64);p64=$(echo -n "{\"id\":\"$id\",\"exp\":$((`date +"%s"`+10))}" | base64);k="b9b8d527a1a27af2ad1697db3521f883760c342fc386dbc42c4efbb1a4d5e0af";s=$(echo -n "$h64.$p64" | openssl dgst -hmac "$k" -sha256 -r | cut -sd ' ' -f1);token="$h64.$p64.$s";curl -H "Authorization: Bearer $token" -k https://localhost/getbalance +id="003";h64=$(echo -n "{\"alg\":\"HS256\",\"typ\":\"JWT\"}" | base64);p64=$(echo -n "{\"id\":\"$id\",\"exp\":$((`date +"%s"`+10))}" | base64);k="b9b8d527a1a27af2ad1697db3521f883760c342fc386dbc42c4efbb1a4d5e0af";s=$(echo -n "$h64.$p64" | openssl dgst -hmac "$k" -sha256 -r | cut -sd ' ' -f1);token="$h64.$p64.$s";curl -v -H "Content-Type: application/json" -d '{"hash":"123","callbackUrl":"http://callback"}' -H "Authorization: Bearer $token" -k https://localhost/ots_stamp ``` ```shell diff --git a/docker-compose.yml b/docker-compose.yml index d5a652e..97f10fb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -29,6 +29,8 @@ services: - "~/btcproxydb:/proxy/db" # c-lightning looks for $HOME/.lightning/, and $HOME is set to / in the container - "~/lndata:/.lightning" + # OTS files, shared with otsclient container + - "~/otsfiles:/otsfiles" # deploy: # placement: # constraints: [node.hostname==dev] @@ -59,6 +61,20 @@ services: networks: - cyphernodenet + otsclient: + # otsclient JS + env_file: + - otsclient_docker/env.properties + image: otsclientimg +# deploy: +# placement: +# constraints: [node.hostname==dev] + volumes: + - "~/otsfiles:/otsfiles" + command: $USER /script/startotsclient.sh + networks: + - cyphernodenet + clightningnode: # c-lightning lightning network node image: clnimg diff --git a/otsclient_docker/Dockerfile b/otsclient_docker/Dockerfile new file mode 100644 index 0000000..1ae1779 --- /dev/null +++ b/otsclient_docker/Dockerfile @@ -0,0 +1,27 @@ +FROM node:11.1-alpine + +RUN apk add --update --no-cache \ + git \ + jq \ + su-exec \ + && yarn global add javascript-opentimestamps + +WORKDIR /script + +COPY script/otsclient.sh /script/otsclient.sh +COPY script/requesthandler.sh /script/requesthandler.sh +COPY script/responsetoclient.sh /script/responsetoclient.sh +COPY script/startotsclient.sh /script/startotsclient.sh +COPY script/trace.sh /script/trace.sh + +RUN chmod +x /script/startotsclient.sh /script/requesthandler.sh + +ENTRYPOINT ["su-exec"] + +# docker build -t otsclient-js . +# docker run -it --rm --name otsclient -v /home/debian/otsfiles:/otsfiles otsclient-js `id -u cyphernode`:`id -g cyphernode` ash + +# ots-cli.js stamp -d 1ddfb769eb0b8876bc570e25580e6a53afcf973362ee1ee4b54a807da2e5eed7 +# ots-cli.js verify -d 1ddfb769eb0b8876bc570e25580e6a53afcf973362ee1ee4b54a807da2e5eed7 1ddfb769eb0b8876bc570e25580e6a53afcf973362ee1ee4b54a807da2e5eed7.ots +# ots-cli.js info 1ddfb769eb0b8876bc570e25580e6a53afcf973362ee1ee4b54a807da2e5eed7.ots +# ots-cli.js upgrade 1ddfb769eb0b8876bc570e25580e6a53afcf973362ee1ee4b54a807da2e5eed7.ots diff --git a/otsclient_docker/README.md b/otsclient_docker/README.md new file mode 100644 index 0000000..c90bb4e --- /dev/null +++ b/otsclient_docker/README.md @@ -0,0 +1,24 @@ +# Build image + +```shell +docker build -t otsclientimg . +``` + +# OTS files directory... + +```shell +mkdir -p ~/otsfiles +sudo chown -R cyphernode:debian ~/otsfiles ; sudo chmod g+ws ~/otsfiles +sudo find ~/otsfiles -type d -exec chmod 2775 {} \; ; sudo find ~/otsfiles -type f -exec chmod g+rw {} \; +``` + +# Usefull examples + +See https://github.com/opentimestamps/javascript-opentimestamps + +List SegWit addresses for path 0/24-30 for a pub32: + +```shell +curl -H "Content-Type: application/json" -d '{"pub32":"tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk","path":"0/25-30"}' http://localhost:7777/derive +curl -H "Content-Type: application/json" -d '{"pub32":"vpub5SLqN2bLY4WeZF3kL4VqiWF1itbf3A6oRrq9aPf16AZMVWYCuN9TxpAZwCzVgW94TNzZPNc9XAHD4As6pdnExBtCDGYRmNJrcJ4eV9hNqcv","path":"0/25-30"}' http://localhost:7777/derive +``` diff --git a/otsclient_docker/env.properties b/otsclient_docker/env.properties new file mode 100644 index 0000000..3971c34 --- /dev/null +++ b/otsclient_docker/env.properties @@ -0,0 +1,2 @@ +TRACING=1 +OTSCLIENT_LISTENING_PORT=6666 diff --git a/otsclient_docker/script/otsclient.sh b/otsclient_docker/script/otsclient.sh new file mode 100644 index 0000000..1861b6e --- /dev/null +++ b/otsclient_docker/script/otsclient.sh @@ -0,0 +1,83 @@ +#!/bin/sh + +. ./trace.sh + +stamp() +{ + trace "Entering stamp()..." + + local hash=${1} + trace "[stamp] hash=${hash}" + + local result + local returncode + local data + + trace "[stamp] ots-cli.js stamp -d ${hash}" + result=$(cd /otsfiles && ots-cli.js stamp -d ${hash} 2>&1) + returncode=$? + trace_rc ${returncode} + trace "[stamp] result=${result}" + + # The timestamp proof '1ddfb769eb0b8876bc570e25580e6a53afcf973362ee1ee4b54a807da2e5eed7.ots' has been created! + + data="{\"method\":\"stamp\",\"hash\":\"${hash}\",\"result\":\"" + + trace "[stamp] grepping..." + echo "${result}" | grep "has been created!" > /dev/null + returncode=$? + trace_rc ${returncode} + + if [ "${returncode}" -eq "0" ]; then + # String found + data="${data}success\"}" + else + # String nor found + data="${data}error\",\"error\":\"${result}\"}" + fi + + trace "[stamp] data=${data}" + + echo "${data}" + + return ${returncode} +} + +upgrade() +{ + trace "Entering upgrade()..." + + local hash=${1} + trace "[upgrade] hash=${hash}" + + local result + local returncode + + trace "[upgrade] ots-cli.js upgrade ${hash}.ots" + result=$(cd /otsfiles && ots-cli.js upgrade ${hash}.ots 2>&1) + returncode=$? + trace_rc ${returncode} + trace "[upgrade] result=${result}" + + # Success! Timestamp complete + # Failed! Timestamp not complete + + data="{\"method\":\"upgrade\",\"hash\":\"${hash}\",\"result\":\"" + + trace "[upgrade] grepping..." + echo "${result}" | grep "Success!" > /dev/null + returncode=$? + trace_rc ${returncode} + + if [ "${returncode}" -eq "0" ]; then + data="${data}success\"}" + else + data="${data}error\",\"error\":\"${result}\"}" + fi + + trace "[upgrade] data=${data}" + + echo "${data}" + + return ${returncode} +} diff --git a/otsclient_docker/script/requesthandler.sh b/otsclient_docker/script/requesthandler.sh new file mode 100644 index 0000000..7ad8d08 --- /dev/null +++ b/otsclient_docker/script/requesthandler.sh @@ -0,0 +1,88 @@ +#!/bin/sh +# +# +# +# + +. ./otsclient.sh +. ./responsetoclient.sh +. ./trace.sh + +main() +{ + trace "Entering main()..." + + local step=0 + local cmd + local http_method + local line + local content_length + local response + local returncode + + while read line; do + line=$(echo "${line}" | tr -d '\r\n') + trace "[main] line=${line}" + + if [ "${cmd}" = "" ]; then + # First line! + # Looking for something like: + # GET /cmd/params HTTP/1.1 + # POST / HTTP/1.1 + cmd=$(echo "${line}" | cut -d '/' -f2 | cut -d ' ' -f1) + trace "[main] cmd=${cmd}" + http_method=$(echo "${line}" | cut -d ' ' -f1) + trace "[main] http_method=${http_method}" + if [ "${http_method}" = "GET" ]; then + step=1 + fi + fi + if [ "${line}" = "" ]; then + trace "[main] empty line" + if [ ${step} -eq 1 ]; then + trace "[main] body part finished, disconnecting" + break + else + trace "[main] headers part finished, body incoming" + step=1 + fi + fi + # line=content-length: 406 + case "${line}" in *[cC][oO][nN][tT][eE][nN][tT]-[lL][eE][nN][gG][tT][hH]*) + content_length=$(echo ${line} | cut -d ':' -f2) + trace "[main] content_length=${content_length}"; + ;; + esac + if [ ${step} -eq 1 ]; then + trace "[main] step=${step}" + if [ "${http_method}" = "POST" ]; then + read -n ${content_length} line + trace "[main] line=${line}" + fi + case "${cmd}" in + stamp) + # GET http://192.168.111.152:8080/stamp/1ddfb769eb0b8876bc570e25580e6a53afcf973362ee1ee4b54a807da2e5eed7 + + response=$(stamp $(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)) + response_to_client "${response}" ${?} + break + ;; + upgrade) + # GET http://192.168.111.152:8080/upgrade/1ddfb769eb0b8876bc570e25580e6a53afcf973362ee1ee4b54a807da2e5eed7 + + response=$(upgrade $(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)) + response_to_client "${response}" ${?} + break + ;; + esac + break + fi + done + trace "[main] exiting" + return 0 +} + +export TRACING + +main +exit $? diff --git a/otsclient_docker/script/responsetoclient.sh b/otsclient_docker/script/responsetoclient.sh new file mode 100644 index 0000000..c907e76 --- /dev/null +++ b/otsclient_docker/script/responsetoclient.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +. ./trace.sh + +response_to_client() +{ + trace "Entering response_to_client()..." + + local response=${1} + local returncode=${2} + + ([ -z "${returncode}" ] || [ "${returncode}" -eq "0" ]) && echo -ne "HTTP/1.1 200 OK\r\n" + [ -n "${returncode}" ] && [ "${returncode}" -ne "0" ] && echo -ne "HTTP/1.1 400 Bad Request\r\n" + + echo -e "Content-Type: application/json\r\nContent-Length: ${#response}\r\n\r\n${response}" + + # Small delay needed for the data to be processed correctly by peer + sleep 0.2s +} + +case "${0}" in *responsetoclient.sh) response_to_client $@;; esac diff --git a/otsclient_docker/script/startotsclient.sh b/otsclient_docker/script/startotsclient.sh new file mode 100644 index 0000000..589e0a8 --- /dev/null +++ b/otsclient_docker/script/startotsclient.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +export TRACING +export OTSCLIENT_LISTENING_PORT + +nc -vlkp${OTSCLIENT_LISTENING_PORT} -e ./requesthandler.sh diff --git a/otsclient_docker/script/trace.sh b/otsclient_docker/script/trace.sh new file mode 100644 index 0000000..680f3f2 --- /dev/null +++ b/otsclient_docker/script/trace.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +trace() +{ + if [ -n "${TRACING}" ]; then + echo "$(date -Is) ${1}" 1>&2 + fi +} + +trace_rc() +{ + if [ -n "${TRACING}" ]; then + echo "$(date -Is) Last return code: ${1}" 1>&2 + fi +} diff --git a/proxy_docker/Dockerfile b/proxy_docker/Dockerfile index e49980e..54580ce 100644 --- a/proxy_docker/Dockerfile +++ b/proxy_docker/Dockerfile @@ -12,6 +12,7 @@ COPY app/script/callbacks_job.sh ${HOME}/callbacks_job.sh COPY app/script/blockchainrpc.sh ${HOME}/blockchainrpc.sh COPY app/script/call_lightningd.sh ${HOME}/call_lightningd.sh COPY app/script/bitcoin.sh ${HOME}/bitcoin.sh +COPY app/script/ots.sh ${HOME}/ots.sh COPY app/script/requesthandler.sh ${HOME}/requesthandler.sh COPY app/script/watchrequest.sh ${HOME}/watchrequest.sh COPY app/script/walletoperations.sh ${HOME}/walletoperations.sh diff --git a/proxy_docker/app/data/watching.sql b/proxy_docker/app/data/watching.sql index 290fabf..0717ec4 100644 --- a/proxy_docker/app/data/watching.sql +++ b/proxy_docker/app/data/watching.sql @@ -53,3 +53,13 @@ CREATE TABLE recipient ( inserted_ts INTEGER DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX idx_recipient_address ON recipient (address); + +CREATE TABLE stamp ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + hash TEXT UNIQUE, + callbackUrl TEXT, + requested INTEGER DEFAULT FALSE, + upgraded INTEGER DEFAULT FALSE, + calledback INTEGER DEFAULT FALSE, + inserted_ts INTEGER DEFAULT CURRENT_TIMESTAMP +); diff --git a/proxy_docker/app/script/ots.sh b/proxy_docker/app/script/ots.sh new file mode 100644 index 0000000..e55cf81 --- /dev/null +++ b/proxy_docker/app/script/ots.sh @@ -0,0 +1,203 @@ +#!/bin/sh + +. ./trace.sh + +serve_ots_stamp() +{ + + trace "Entering serve_ots_stamp()..." + + local request=${1} + local hash=$(echo "${request}" | jq ".hash" | tr -d '"') + trace "[serve_ots_stamp] hash=${hash}" + local callbackUrl=$(echo "${request}" | jq ".callbackUrl" | tr -d '"') + trace "[serve_ots_stamp] callbackUrl=${callbackUrl}" + + local result + local returncode + local errorstring + + # Already requested? + local requested + requested=$(sql "SELECT requested FROM stamp WHERE hash='${hash}'") + if [ -n "${requested}" ]; then + # Hash exists in DB... + trace "[serve_ots_stamp] Hash already exists in DB." + + if [ "${requested}" -eq "1" ]; then + # Stamp already requested + trace "[serve_ots_stamp] Stamp already requested" + errorstring="Duplicate stamping request, hash already exists in DB and been OTS requested" + returncode=1 + else + errorstring=$(request_ots_stamp "${hash}") + returncode=$? + fi + else + sql "INSERT OR IGNORE INTO stamp (hash, callbackUrl) VALUES (\"${hash}\", \"${callbackUrl}\")" + returncode=$? + trace_rc ${returncode} + if [ "${returncode}" -eq "0" ]; then + errorstring=$(request_ots_stamp "${hash}") + returncode=$? + trace_rc ${returncode} + else + trace "[serve_ots_stamp] Stamp request could not be inserted in DB" + errorstring="Stamp request could not be inserted in DB, please retry later" + returncode=1 + fi + fi + + if [ "${returncode}" -eq "0" ]; then + result="{\"method\":\"ots_stamp\",\"hash\":\"${hash}\",\"result\":\"success\"" + else + result="{\"method\":\"ots_stamp\",\"hash\":\"${hash}\",\"result\":\"error\",\"error\":\"${errorstring}\"" + fi + + trace "[serve_ots_stamp] result=${result}" + + # Output response to stdout before exiting with return code + echo "${result}" + + return ${returncode} +} + +request_ots_stamp() +{ + # Request the OTS server to stamp + + local hash=${1} + local returncode + local result + local errorstring + + trace "[request_ots_stamp] Stamping..." + result=$(curl -s ${OTSCLIENT_CONTAINER}/stamp/${hash}) + returncode=$? + trace_rc ${returncode} + trace "[request_ots_stamp] Stamping result=${result}" + + if [ "${returncode}" -eq 0 ]; then + # jq -e will have a return code of 1 if the supplied tag is null. + errorstring=$(echo "${result}" | tr '\r\n' ' ' | jq -e ".error" | tr -d '"') + if [ "$?" -eq "0" ]; then + # Error tag not null, so there's an error + + # If the error message is "Already exists" + trace "[request_ots_stamp] grepping 'already exists'..." + echo "${result}" | grep "already exists" > /dev/null + returncode=$? + trace_rc ${returncode} + + if [ "${returncode}" -eq "0" ]; then + # "already exists" found, let's try updating DB again + trace "[request_ots_stamp] was already requested to the OTS server... let's update the DB, looks like it didn't work on first try" + sql "UPDATE stamp SET requested=1 WHERE hash='${hash}'" + errorstring="Duplicate stamping request, hash already exists in DB and been OTS requested" + returncode=1 + else + # If OTS CLIENT responded with an error, it is not down, it just can't stamp it. ABORT. + trace "[request_ots_stamp] Stamping error: ${errorstring}" + sql "DELETE FROM stamp WHERE hash='${hash}'" + returncode=1 + fi + else + trace "[request_ots_stamp] Stamping request sent successfully!" + sql "UPDATE stamp SET requested=1 WHERE hash='${hash}'" + errorstring="" + returncode=0 + fi + else + trace "[request_ots_stamp] Stamping error, will retry later: ${errorstring}" + errorstring="" + returncode=0 + fi + + echo "${errorstring}" + return ${returncode} +} + +serve_ots_backoffice() +{ + # What we want to do here: + # ======================== + # Re-request the unrequested calls to ots_stamp + # Upgrade requested calls to ots_stamp that have not been called back yet + # Call back newly upgraded stamps + + trace "Entering serve_ots_backoffice()..." + + local result + local returncode + + # Let's fetch all the incomplete stamping request + local callbacks=$(sql 'SELECT hash, callbackUrl, requested, upgraded FROM stamp WHERE NOT calledback') + trace "[serve_ots_backoffice] callbacks=${callbacks}" + + local url + local hash + local requested + local upgraded + local IFS=$'\n' + for row in ${callbacks} + do + trace "[serve_ots_backoffice] row=${row}" + hash=$(echo "${row}" | cut -d '|' -f1) + trace "[serve_ots_backoffice] hash=${hash}" + requested=$(echo "${row}" | cut -d '|' -f3) + trace "[serve_ots_backoffice] requested=${requested}" + upgraded=$(echo "${row}" | cut -d '|' -f4) + trace "[serve_ots_backoffice] upgraded=${upgraded}" + + if [ "${requested}" -ne "1" ]; then + # Re-request the unrequested calls to ots_stamp + request_ots_stamp "${hash}" + returncode=$? + else + if [ "${upgraded}" -ne "1" ]; then + # Upgrade requested calls to ots_stamp that have not been called back yet + trace "[serve_ots_backoffice] curl -s ${OTSCLIENT_CONTAINER}/upgrade/${hash}" + result=$(curl -s ${OTSCLIENT_CONTAINER}/upgrade/${hash}) + returncode=$? + trace_rc ${returncode} + trace "[serve_ots_backoffice] result=${result}" + if [ "${returncode}" -eq 0 ]; then + trace "[serve_ots_backoffice] just upgraded!" + sql "UPDATE stamp SET upgraded=1 WHERE hash=\"${hash}\"" + trace_rc $? + + upgraded=1 + fi + fi + if [ "${upgraded}" -eq "1" ]; then + trace "[serve_ots_backoffice] upgraded! Let's send the OTS file to callback..." + url=$(echo "${row}" | cut -d '|' -f2) + trace "[serve_ots_backoffice] url=${url}" + + # Call back newly upgraded stamps + curl -H "X-Forwarded-Proto: https" ${url} + returncode=$? + trace_rc ${returncode} + + if [ "${returncode}" -eq "0" ]; then + sql "UPDATE stamp SET calledback=1 WHERE hash=\"${hash}\"" + trace_rc $? + fi + fi + fi + done +} + +serve_ots_getfile() +{ + trace "Entering serve_ots_getfile()..." + + local hash=${1} + trace "[serve_ots_getfile] hash=${hash}" + + file_response_to_client "/otsfiles/" "${hash}.ots" + returncode=$? + trace_rc ${returncode} + + return ${returncode} +} diff --git a/proxy_docker/app/script/requesthandler.sh b/proxy_docker/app/script/requesthandler.sh index 1605f32..433ffba 100644 --- a/proxy_docker/app/script/requesthandler.sh +++ b/proxy_docker/app/script/requesthandler.sh @@ -17,216 +17,238 @@ . ./walletoperations.sh . ./bitcoin.sh . ./call_lightningd.sh +. ./ots.sh main() { - trace "Entering main()..." + trace "Entering main()..." - local step=0 - local cmd - local http_method - local line - local content_length - local response - local returncode + local step=0 + local cmd + local http_method + local line + local content_length + local response + local returncode - while read line; do - line=$(echo "${line}" | tr -d '\r\n') - trace "[main] line=${line}" + while read line; do + line=$(echo "${line}" | tr -d '\r\n') + trace "[main] line=${line}" - if [ "${cmd}" = "" ]; then - # First line! - # Looking for something like: - # GET /cmd/params HTTP/1.1 - # POST / HTTP/1.1 - cmd=$(echo "${line}" | cut -d '/' -f2 | cut -d ' ' -f1) - trace "[main] cmd=${cmd}" - http_method=$(echo "${line}" | cut -d ' ' -f1) - trace "[main] http_method=${http_method}" - if [ "${http_method}" = "GET" ]; then - step=1 - fi - fi - if [ "${line}" = "" ]; then - trace "[main] empty line" - if [ ${step} -eq 1 ]; then - trace "[main] body part finished, disconnecting" - break - else - trace "[main] headers part finished, body incoming" - step=1 - fi - fi - # line=content-length: 406 - case "${line}" in *[cC][oO][nN][tT][eE][nN][tT]-[lL][eE][nN][gG][tT][hH]*) - content_length=$(echo ${line} | cut -d ':' -f2) - trace "[main] content_length=${content_length}"; - ;; - esac - if [ ${step} -eq 1 ]; then - trace "[main] step=${step}" - if [ "${http_method}" = "POST" ]; then - read -n ${content_length} line - trace "[main] line=${line}" - fi - case "${cmd}" in - watch) - # POST http://192.168.111.152:8080/watch - # BODY {"address":"2N8DcqzfkYi8CkYzvNNS5amoq3SbAcQNXKp","unconfirmedCallbackURL":"192.168.111.233:1111/callback0conf","confirmedCallbackURL":"192.168.111.233:1111/callback1conf"} + if [ "${cmd}" = "" ]; then + # First line! + # Looking for something like: + # GET /cmd/params HTTP/1.1 + # POST / HTTP/1.1 + cmd=$(echo "${line}" | cut -d '/' -f2 | cut -d ' ' -f1) + trace "[main] cmd=${cmd}" + http_method=$(echo "${line}" | cut -d ' ' -f1) + trace "[main] http_method=${http_method}" + if [ "${http_method}" = "GET" ]; then + step=1 + fi + fi + if [ "${line}" = "" ]; then + trace "[main] empty line" + if [ ${step} -eq 1 ]; then + trace "[main] body part finished, disconnecting" + break + else + trace "[main] headers part finished, body incoming" + step=1 + fi + fi + # line=content-length: 406 + case "${line}" in *[cC][oO][nN][tT][eE][nN][tT]-[lL][eE][nN][gG][tT][hH]*) + content_length=$(echo ${line} | cut -d ':' -f2) + trace "[main] content_length=${content_length}"; + ;; + esac + if [ ${step} -eq 1 ]; then + trace "[main] step=${step}" + if [ "${http_method}" = "POST" ]; then + read -n ${content_length} line + trace "[main] line=${line}" + fi + case "${cmd}" in + watch) + # POST http://192.168.111.152:8080/watch + # BODY {"address":"2N8DcqzfkYi8CkYzvNNS5amoq3SbAcQNXKp","unconfirmedCallbackURL":"192.168.111.233:1111/callback0conf","confirmedCallbackURL":"192.168.111.233:1111/callback1conf"} - response=$(watchrequest "${line}") - response_to_client "${response}" ${?} - break - ;; - unwatch) - # curl (GET) 192.168.111.152:8080/unwatch/2N8DcqzfkYi8CkYzvNNS5amoq3SbAcQNXKp + response=$(watchrequest "${line}") + response_to_client "${response}" ${?} + break + ;; + unwatch) + # curl (GET) 192.168.111.152:8080/unwatch/2N8DcqzfkYi8CkYzvNNS5amoq3SbAcQNXKp - response=$(unwatchrequest "${line}") - response_to_client "${response}" ${?} - break - ;; - getactivewatches) - # curl (GET) 192.168.111.152:8080/getactivewatches + response=$(unwatchrequest "${line}") + response_to_client "${response}" ${?} + break + ;; + getactivewatches) + # curl (GET) 192.168.111.152:8080/getactivewatches - response=$(getactivewatches) - response_to_client "${response}" ${?} - break - ;; - conf) - # curl (GET) 192.168.111.152:8080/conf/b081ca7724386f549cf0c16f71db6affeb52ff7a0d9b606fb2e5c43faffd3387 + response=$(getactivewatches) + response_to_client "${response}" ${?} + break + ;; + conf) + # curl (GET) 192.168.111.152:8080/conf/b081ca7724386f549cf0c16f71db6affeb52ff7a0d9b606fb2e5c43faffd3387 - response=$(confirmation_request "${line}") - response_to_client "${response}" ${?} - break - ;; - getbestblockhash) - # curl (GET) http://192.168.111.152:8080/getbestblockhash + response=$(confirmation_request "${line}") + response_to_client "${response}" ${?} + break + ;; + getbestblockhash) + # curl (GET) http://192.168.111.152:8080/getbestblockhash - response=$(get_best_block_hash) - response_to_client "${response}" ${?} - break - ;; - getblockinfo) - # curl (GET) http://192.168.111.152:8080/getblockinfo/000000006f82a384c208ecfa04d05beea02d420f3f398ddda5c7f900de5718ea + response=$(get_best_block_hash) + response_to_client "${response}" ${?} + break + ;; + getblockinfo) + # curl (GET) http://192.168.111.152:8080/getblockinfo/000000006f82a384c208ecfa04d05beea02d420f3f398ddda5c7f900de5718ea - response=$(get_block_info $(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)) - response_to_client "${response}" ${?} - break - ;; - gettransaction) - # curl (GET) http://192.168.111.152:8080/gettransaction/af867c86000da76df7ddb1054b273ca9e034e8c89d049b5b2795f9f590f67648 + response=$(get_block_info $(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)) + response_to_client "${response}" ${?} + break + ;; + gettransaction) + # curl (GET) http://192.168.111.152:8080/gettransaction/af867c86000da76df7ddb1054b273ca9e034e8c89d049b5b2795f9f590f67648 - response=$(get_rawtransaction $(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)) - response_to_client "${response}" ${?} - break - ;; - getbestblockinfo) - # curl (GET) http://192.168.111.152:8080/getbestblockinfo + response=$(get_rawtransaction $(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)) + response_to_client "${response}" ${?} + break + ;; + getbestblockinfo) + # curl (GET) http://192.168.111.152:8080/getbestblockinfo - response=$(get_best_block_info) - response_to_client "${response}" ${?} - break - ;; - executecallbacks) - # curl (GET) http://192.168.111.152:8080/executecallbacks + response=$(get_best_block_info) + response_to_client "${response}" ${?} + break + ;; + executecallbacks) + # curl (GET) http://192.168.111.152:8080/executecallbacks - manage_not_imported - manage_missed_conf - response=$(do_callbacks) - response_to_client "${response}" ${?} - break - ;; - getbalance) - # curl (GET) http://192.168.111.152:8080/getbalance + manage_not_imported + manage_missed_conf + response=$(do_callbacks) + response_to_client "${response}" ${?} + break + ;; + getbalance) + # curl (GET) http://192.168.111.152:8080/getbalance - response=$(getbalance) - response_to_client "${response}" ${?} - break - ;; - getnewaddress) - # curl (GET) http://192.168.111.152:8080/getnewaddress + response=$(getbalance) + response_to_client "${response}" ${?} + break + ;; + getnewaddress) + # curl (GET) http://192.168.111.152:8080/getnewaddress - response=$(getnewaddress) - response_to_client "${response}" ${?} - break - ;; - spend) - # POST http://192.168.111.152:8080/spend - # BODY {"address":"2N8DcqzfkYi8CkYzvNNS5amoq3SbAcQNXKp","amount":0.00233} + response=$(getnewaddress) + response_to_client "${response}" ${?} + break + ;; + spend) + # POST http://192.168.111.152:8080/spend + # BODY {"address":"2N8DcqzfkYi8CkYzvNNS5amoq3SbAcQNXKp","amount":0.00233} - response=$(spend "${line}") - response_to_client "${response}" ${?} - break - ;; - addtobatch) - # POST http://192.168.111.152:8080/addtobatch - # BODY {"address":"2N8DcqzfkYi8CkYzvNNS5amoq3SbAcQNXKp","amount":0.00233} + response=$(spend "${line}") + response_to_client "${response}" ${?} + break + ;; + addtobatch) + # POST http://192.168.111.152:8080/addtobatch + # BODY {"address":"2N8DcqzfkYi8CkYzvNNS5amoq3SbAcQNXKp","amount":0.00233} - response=$(addtobatching $(echo "${line}" | jq ".address" | tr -d '"') $(echo "${line}" | jq ".amount")) - response_to_client "${response}" ${?} - break - ;; - batchspend) - # GET http://192.168.111.152:8080/batchspend + response=$(addtobatching $(echo "${line}" | jq ".address" | tr -d '"') $(echo "${line}" | jq ".amount")) + response_to_client "${response}" ${?} + break + ;; + batchspend) + # GET http://192.168.111.152:8080/batchspend - response=$(batchspend "${line}") - response_to_client "${response}" ${?} - break - ;; - deriveindex) - # curl GET http://192.168.111.152:8080/deriveindex/25-30 - # curl GET http://192.168.111.152:8080/deriveindex/34 + response=$(batchspend "${line}") + response_to_client "${response}" ${?} + break + ;; + deriveindex) + # curl GET http://192.168.111.152:8080/deriveindex/25-30 + # curl GET http://192.168.111.152:8080/deriveindex/34 - response=$(deriveindex $(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)) - response_to_client "${response}" ${?} - break - ;; - derivepubpath) - # POST http://192.168.111.152:8080/derivepubpath - # BODY {"pub32":"tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk","path":"0/25-30"} - # BODY {"pub32":"upub5GtUcgGed1aGH4HKQ3vMYrsmLXwmHhS1AeX33ZvDgZiyvkGhNTvGd2TA5Lr4v239Fzjj4ZY48t6wTtXUy2yRgapf37QHgt6KWEZ6bgsCLpb","path":"0/25-30"} - # BODY {"pub32":"vpub5SLqN2bLY4WeZF3kL4VqiWF1itbf3A6oRrq9aPf16AZMVWYCuN9TxpAZwCzVgW94TNzZPNc9XAHD4As6pdnExBtCDGYRmNJrcJ4eV9hNqcv","path":"0/25-30"} + response=$(deriveindex $(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3)) + response_to_client "${response}" ${?} + break + ;; + derivepubpath) + # POST http://192.168.111.152:8080/derivepubpath + # BODY {"pub32":"tpubD6NzVbkrYhZ4YR3QK2tyfMMvBghAvqtNaNK1LTyDWcRHLcMUm3ZN2cGm5BS3MhCRCeCkXQkTXXjiJgqxpqXK7PeUSp86DTTgkLpcjMtpKWk","path":"0/25-30"} + # BODY {"pub32":"upub5GtUcgGed1aGH4HKQ3vMYrsmLXwmHhS1AeX33ZvDgZiyvkGhNTvGd2TA5Lr4v239Fzjj4ZY48t6wTtXUy2yRgapf37QHgt6KWEZ6bgsCLpb","path":"0/25-30"} + # BODY {"pub32":"vpub5SLqN2bLY4WeZF3kL4VqiWF1itbf3A6oRrq9aPf16AZMVWYCuN9TxpAZwCzVgW94TNzZPNc9XAHD4As6pdnExBtCDGYRmNJrcJ4eV9hNqcv","path":"0/25-30"} - response=$(send_to_pycoin "${line}") - response_to_client "${response}" ${?} - break - ;; - ln_getinfo) - # GET http://192.168.111.152:8080/ln_getinfo + response=$(send_to_pycoin "${line}") + response_to_client "${response}" ${?} + break + ;; + ln_getinfo) + # GET http://192.168.111.152:8080/ln_getinfo - response=$(ln_getinfo) - response_to_client "${response}" ${?} - break - ;; - ln_create_invoice) - # POST http://192.168.111.152:8080/ln_create_invoice - # BODY {"msatoshi":"10000","label":"koNCcrSvhX3dmyFhW","description":"Bylls order #10649","expiry":"900"} + response=$(ln_getinfo) + response_to_client "${response}" ${?} + break + ;; + ln_create_invoice) + # POST http://192.168.111.152:8080/ln_create_invoice + # BODY {"msatoshi":"10000","label":"koNCcrSvhX3dmyFhW","description":"Bylls order #10649","expiry":"900"} - response=$(ln_create_invoice "${line}") - response_to_client "${response}" ${?} - break - ;; - ln_pay) - # POST http://192.168.111.152:8080/ln_pay - # BODY {"bolt11":"lntb1pdca82tpp5gv8mn5jqlj6xztpnt4r472zcyrwf3y2c3cvm4uzg2gqcnj90f83qdp2gf5hgcm0d9hzqnm4w3kx2apqdaexgetjyq3nwvpcxgcqp2g3d86wwdfvyxcz7kce7d3n26d2rw3wf5tzpm2m5fl2z3mm8msa3xk8nv2y32gmzlhwjved980mcmkgq83u9wafq9n4w28amnmwzujgqpmapcr3","expected_msatoshi":"10000","expected_description":"Bitcoin Outlet order #7082"} + response=$(ln_create_invoice "${line}") + response_to_client "${response}" ${?} + break + ;; + ln_pay) + # POST http://192.168.111.152:8080/ln_pay + # BODY {"bolt11":"lntb1pdca82tpp5gv8mn5jqlj6xztpnt4r472zcyrwf3y2c3cvm4uzg2gqcnj90f83qdp2gf5hgcm0d9hzqnm4w3kx2apqdaexgetjyq3nwvpcxgcqp2g3d86wwdfvyxcz7kce7d3n26d2rw3wf5tzpm2m5fl2z3mm8msa3xk8nv2y32gmzlhwjved980mcmkgq83u9wafq9n4w28amnmwzujgqpmapcr3","expected_msatoshi":"10000","expected_description":"Bitcoin Outlet order #7082"} - response=$(ln_pay "${line}") - response_to_client "${response}" ${?} - break - ;; - ln_newaddr) - # GET http://192.168.111.152:8080/ln_newaddr + response=$(ln_pay "${line}") + response_to_client "${response}" ${?} + break + ;; + ln_newaddr) + # GET http://192.168.111.152:8080/ln_newaddr - response=$(ln_newaddr) - response_to_client "${response}" ${?} - break - ;; - esac - break - fi - done - trace "[main] exiting" - return 0 + response=$(ln_newaddr) + response_to_client "${response}" ${?} + break + ;; + ots_stamp) + # POST http://192.168.111.152:8080/ots_stamp + # BODY {"hash":"1ddfb769eb0b8876bc570e25580e6a53afcf973362ee1ee4b54a807da2e5eed7","callbackUrl":"192.168.111.233:1111/callbackUrl"} + + response=$(serve_ots_stamp "${line}") + response_to_client "${response}" ${?} + break + ;; + ots_backoffice) + # curl (GET) http://192.168.111.152:8080/ots_upgradeandcallback + + response=$(serve_ots_backoffice) + response_to_client "${response}" ${?} + break + ;; + ots_getfile) + # curl (GET) http://192.168.111.152:8080/ots_getfile/1ddfb769eb0b8876bc570e25580e6a53afcf973362ee1ee4b54a807da2e5eed7 + + serve_ots_getfile $(echo "${line}" | cut -d ' ' -f2 | cut -d '/' -f3) + break + ;; + esac + break + fi + done + trace "[main] exiting" + return 0 } export NODE_RPC_URL=$BTC_NODE_RPC_URL diff --git a/proxy_docker/app/script/responsetoclient.sh b/proxy_docker/app/script/responsetoclient.sh index 8204395..53f95ec 100644 --- a/proxy_docker/app/script/responsetoclient.sh +++ b/proxy_docker/app/script/responsetoclient.sh @@ -18,4 +18,23 @@ response_to_client() sleep 0.2s } +file_response_to_client() +{ + trace "Entering bin_response_to_client()..." + + local path=${1} + local filename=${2} + local pathfile="${path}${filename}" + local returncode + + [ -r "${pathfile}" ] \ + && echo -ne "HTTP/1.1 200 OK\r\nContent-Disposition: inline; filename=\"${filename}\"\r\nContent-Length: $(stat -c'%s' ${pathfile})\r\n\r\n" \ + && cat ${pathfile} + + [ ! -r "${pathfile}" ] && echo -ne "HTTP/1.1 404 Not Found\r\n" + + # Small delay needed for the data to be processed correctly by peer + sleep 0.2s +} + case "${0}" in *responsetoclient.sh) response_to_client $@;; esac diff --git a/proxy_docker/app/script/watchrequest.sh b/proxy_docker/app/script/watchrequest.sh index e056d8c..9846d80 100644 --- a/proxy_docker/app/script/watchrequest.sh +++ b/proxy_docker/app/script/watchrequest.sh @@ -7,69 +7,68 @@ watchrequest() { - trace "Entering watchrequest()..." + trace "Entering watchrequest()..." - local returncode - local request=${1} - local address=$(echo "${request}" | jq ".address" | tr -d '"') - local cb0conf_url=$(echo "${request}" | jq ".unconfirmedCallbackURL" | tr -d '"') - local cb1conf_url=$(echo "${request}" | jq ".confirmedCallbackURL" | tr -d '"') - local imported - local inserted - local id_inserted - local result - trace "[watchrequest] Watch request on address (${address}), cb 0-conf (${cb0conf_url}), cb 1-conf (${cb1conf_url})" + local returncode + local request=${1} + local address=$(echo "${request}" | jq ".address" | tr -d '"') + local cb0conf_url=$(echo "${request}" | jq ".unconfirmedCallbackURL" | tr -d '"') + local cb1conf_url=$(echo "${request}" | jq ".confirmedCallbackURL" | tr -d '"') + local imported + local inserted + local id_inserted + local result + trace "[watchrequest] Watch request on address (${address}), cb 0-conf (${cb0conf_url}), cb 1-conf (${cb1conf_url})" - result=$(importaddress_rpc "${address}") - returncode=$? - trace_rc ${returncode} - if [ "${returncode}" -eq 0 ]; then - imported=1 - else - imported=0 - fi + result=$(importaddress_rpc "${address}") + returncode=$? + trace_rc ${returncode} + if [ "${returncode}" -eq 0 ]; then + imported=1 + else + imported=0 + fi -# sql "INSERT OR IGNORE INTO watching (address, watching, callback0conf, callback1conf, imported) VALUES (\"${address}\", 1, \"${cb0conf_url}\", \"${cb1conf_url}\", ${imported})" - sql "INSERT OR IGNORE INTO watching (address, watching, callback0conf, callback1conf, imported) VALUES (\"${address}\", 1, \"${cb0conf_url}\", \"${cb1conf_url}\", ${imported})" - returncode=$? - trace_rc ${returncode} - if [ "${returncode}" -eq 0 ]; then - inserted=1 - id_inserted=$(sql "SELECT id FROM watching WHERE address='${address}'") - trace "[watchrequest] id_inserted: ${id_inserted}" - else - inserted=0 - fi + sql "INSERT OR IGNORE INTO watching (address, watching, callback0conf, callback1conf, imported) VALUES (\"${address}\", 1, \"${cb0conf_url}\", \"${cb1conf_url}\", ${imported})" + returncode=$? + trace_rc ${returncode} + if [ "${returncode}" -eq 0 ]; then + inserted=1 + id_inserted=$(sql "SELECT id FROM watching WHERE address='${address}'") + trace "[watchrequest] id_inserted: ${id_inserted}" + else + inserted=0 + fi - local fees2blocks - local fees6blocks - local fees36blocks - local fees144blocks - fees2blocks=$(getestimatesmartfee 2) - trace_rc $? - fees6blocks=$(getestimatesmartfee 6) - trace_rc $? - fees36blocks=$(getestimatesmartfee 36) - trace_rc $? - fees144blocks=$(getestimatesmartfee 144) - trace_rc $? + local fees2blocks + local fees6blocks + local fees36blocks + local fees144blocks + fees2blocks=$(getestimatesmartfee 2) + trace_rc $? + fees6blocks=$(getestimatesmartfee 6) + trace_rc $? + fees36blocks=$(getestimatesmartfee 36) + trace_rc $? + fees144blocks=$(getestimatesmartfee 144) + trace_rc $? - local data="{\"id\":\"${id_inserted}\", - \"event\":\"watch\", - \"imported\":\"${imported}\", - \"inserted\":\"${inserted}\", - \"address\":\"${address}\", - \"unconfirmedCallbackURL\":\"${cb0conf_url}\", - \"confirmedCallbackURL\":\"${cb1conf_url}\", - \"estimatesmartfee2blocks\":\"${fees2blocks}\", - \"estimatesmartfee6blocks\":\"${fees6blocks}\", - \"estimatesmartfee36blocks\":\"${fees36blocks}\", - \"estimatesmartfee144blocks\":\"${fees144blocks}\"}" - trace "[watchrequest] responding=${data}" + local data="{\"id\":\"${id_inserted}\", + \"event\":\"watch\", + \"imported\":\"${imported}\", + \"inserted\":\"${inserted}\", + \"address\":\"${address}\", + \"unconfirmedCallbackURL\":\"${cb0conf_url}\", + \"confirmedCallbackURL\":\"${cb1conf_url}\", + \"estimatesmartfee2blocks\":\"${fees2blocks}\", + \"estimatesmartfee6blocks\":\"${fees6blocks}\", + \"estimatesmartfee36blocks\":\"${fees36blocks}\", + \"estimatesmartfee144blocks\":\"${fees144blocks}\"}" + trace "[watchrequest] responding=${data}" - echo "${data}" + echo "${data}" - return ${returncode} + return ${returncode} } case "${0}" in *watchrequest.sh) watchrequest $@;; esac diff --git a/proxy_docker/env.properties b/proxy_docker/env.properties index 9a1f8d5..6de427e 100644 --- a/proxy_docker/env.properties +++ b/proxy_docker/env.properties @@ -12,7 +12,8 @@ DB_FILE=/proxy/db/proxydb # Pycoin container PYCOIN_CONTAINER=pycoinnode:7777 # OTS container -OTS_CONTAINER=otsnode:6666 +OTSCLIENT_CONTAINER=otsclient:6666 +OTS_FILES=/otsfiles DERIVATION_PUB32=upub5GtUcgGed1aGH4HKQ3vMYrsmLXwmHhS1AeX33ZvDgZiyvkGhNTvGd2TA5Lr4v239Fzjj4ZY48t6wTtXUy2yRgapf37QHgt6KWEZ6bgsCLpb DERIVATION_PATH=0/n