mirror of
https://github.com/aljazceru/plugins.git
synced 2025-12-23 16:14:20 +01:00
sauron: add Tor proxy support
Signed-off-by: Antoine Poinsot <darosior@protonmail.com>
This commit is contained in:
committed by
Christian Decker
parent
04662336fa
commit
bd1459ab4e
@@ -23,3 +23,12 @@ Here is a fully reptilian example running against [blockstream.info](https://blo
|
|||||||
```
|
```
|
||||||
lightningd --mainnet --disable-plugin bcli --plugin $PWD/sauron.py --sauron-api-endpoint https://blockstream.info/api/
|
lightningd --mainnet --disable-plugin bcli --plugin $PWD/sauron.py --sauron-api-endpoint https://blockstream.info/api/
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can use also proxy your requests through [Tor](https://www.torproject.org/) by
|
||||||
|
specifying a SOCKS proxy to use with the `--sauron-tor-proxy` startup option, in
|
||||||
|
the form `address:port`.
|
||||||
|
|
||||||
|
Hidden services are also supported :
|
||||||
|
```
|
||||||
|
lightningd --testnet --disable-plugin bcli --plugin $PWD/sauron.py --sauron-tor-proxy localhost:9050 --sauron-api-endpoint http://explorerzydxu5ecjrkwceayqybizmpjjznk5izmitf2modhcusuqlid.onion/testnet/api/
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
pyln-client>=0.7.3
|
pyln-client>=0.7.3
|
||||||
requests>=2.0.0
|
requests>=2.23.0
|
||||||
|
requests[socks]>=2.23.0
|
||||||
|
|||||||
@@ -6,20 +6,40 @@ from art import sauron_eye
|
|||||||
from pyln.client import Plugin
|
from pyln.client import Plugin
|
||||||
|
|
||||||
|
|
||||||
plugin = Plugin()
|
plugin = Plugin(dynamic=False)
|
||||||
|
plugin.sauron_socks_proxies = None
|
||||||
|
|
||||||
|
|
||||||
class SauronError(Exception):
|
class SauronError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def fetch(url):
|
||||||
|
"""Fetch this {url}, maybe through a pre-defined proxy."""
|
||||||
|
# FIXME: Maybe try to be smart and renew circuit to broadcast different
|
||||||
|
# transactions ? Hint: lightningd will agressively send us the same
|
||||||
|
# transaction a certain amount of times.
|
||||||
|
session = requests.session()
|
||||||
|
session.proxies = plugin.sauron_socks_proxies
|
||||||
|
return session.get(url)
|
||||||
|
|
||||||
|
|
||||||
@plugin.init()
|
@plugin.init()
|
||||||
def init(plugin, options, configuration, **kwargs):
|
def init(plugin, options, configuration, **kwargs):
|
||||||
plugin.api_endpoint = options.get("sauron-api-endpoint")
|
plugin.api_endpoint = options["sauron-api-endpoint"]
|
||||||
if not plugin.api_endpoint:
|
if not plugin.api_endpoint:
|
||||||
raise SauronError("You need to specify the sauron-api-endpoint option.")
|
raise SauronError("You need to specify the sauron-api-endpoint option.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
if options["sauron-tor-proxy"]:
|
||||||
|
address, port = options["sauron-tor-proxy"].split(":")
|
||||||
|
socks5_proxy = "socks5h://{}:{}".format(address, port)
|
||||||
|
plugin.sauron_socks_proxies = {
|
||||||
|
"http": socks5_proxy,
|
||||||
|
"https": socks5_proxy,
|
||||||
|
}
|
||||||
|
plugin.log("Using proxy {} for requests".format(socks5_proxy))
|
||||||
|
|
||||||
plugin.log("Sauron plugin initialized")
|
plugin.log("Sauron plugin initialized")
|
||||||
plugin.log(sauron_eye)
|
plugin.log(sauron_eye)
|
||||||
|
|
||||||
@@ -37,14 +57,14 @@ def getchaininfo(plugin, **kwargs):
|
|||||||
"regtest"
|
"regtest"
|
||||||
}
|
}
|
||||||
|
|
||||||
genesis_req = requests.get(blockhash_url)
|
genesis_req = fetch(blockhash_url)
|
||||||
if not genesis_req.status_code == 200:
|
if not genesis_req.status_code == 200:
|
||||||
raise SauronError("Endpoint at {} returned {} ({}) when trying to "
|
raise SauronError("Endpoint at {} returned {} ({}) when trying to "
|
||||||
"get genesis block hash."
|
"get genesis block hash."
|
||||||
.format(blockhash_url, genesis_req.status_code,
|
.format(blockhash_url, genesis_req.status_code,
|
||||||
genesis_req.text))
|
genesis_req.text))
|
||||||
|
|
||||||
blockcount_req = requests.get(blockcount_url)
|
blockcount_req = fetch(blockcount_url)
|
||||||
if not blockcount_req.status_code == 200:
|
if not blockcount_req.status_code == 200:
|
||||||
raise SauronError("Endpoint at {} returned {} ({}) when trying to "
|
raise SauronError("Endpoint at {} returned {} ({}) when trying to "
|
||||||
"get blockcount.".format(blockcount_url,
|
"get blockcount.".format(blockcount_url,
|
||||||
@@ -67,9 +87,9 @@ def getchaininfo(plugin, **kwargs):
|
|||||||
def getrawblock(plugin, height, **kwargs):
|
def getrawblock(plugin, height, **kwargs):
|
||||||
blockhash_url = "{}/block-height/{}".format(plugin.api_endpoint, height)
|
blockhash_url = "{}/block-height/{}".format(plugin.api_endpoint, height)
|
||||||
|
|
||||||
blockhash_req = requests.get(blockhash_url)
|
blockhash_req = fetch(blockhash_url)
|
||||||
block_req = requests.get("{}/block/{}/raw".format(plugin.api_endpoint,
|
block_req = fetch("{}/block/{}/raw".format(plugin.api_endpoint,
|
||||||
blockhash_req.text))
|
blockhash_req.text))
|
||||||
if blockhash_req.status_code != 200 or block_req.status_code != 200:
|
if blockhash_req.status_code != 200 or block_req.status_code != 200:
|
||||||
return {
|
return {
|
||||||
"blockhash": None,
|
"blockhash": None,
|
||||||
@@ -104,13 +124,13 @@ def getutxout(plugin, txid, vout, **kwargs):
|
|||||||
gettx_url = "{}/tx/{}".format(plugin.api_endpoint, txid)
|
gettx_url = "{}/tx/{}".format(plugin.api_endpoint, txid)
|
||||||
status_url = "{}/tx/{}/outspend/{}".format(plugin.api_endpoint, txid, vout)
|
status_url = "{}/tx/{}/outspend/{}".format(plugin.api_endpoint, txid, vout)
|
||||||
|
|
||||||
gettx_req = requests.get(gettx_url)
|
gettx_req = fetch(gettx_url)
|
||||||
if not gettx_req.status_code == 200:
|
if not gettx_req.status_code == 200:
|
||||||
raise SauronError("Endpoint at {} returned {} ({}) when trying to "
|
raise SauronError("Endpoint at {} returned {} ({}) when trying to "
|
||||||
"get transaction.".format(gettx_url,
|
"get transaction.".format(gettx_url,
|
||||||
gettx_req.status_code,
|
gettx_req.status_code,
|
||||||
gettx_req.text))
|
gettx_req.text))
|
||||||
status_req = requests.get(status_url)
|
status_req = fetch(status_url)
|
||||||
if not status_req.status_code == 200:
|
if not status_req.status_code == 200:
|
||||||
raise SauronError("Endpoint at {} returned {} ({}) when trying to "
|
raise SauronError("Endpoint at {} returned {} ({}) when trying to "
|
||||||
"get utxo status.".format(status_url,
|
"get utxo status.".format(status_url,
|
||||||
@@ -134,7 +154,7 @@ def getutxout(plugin, txid, vout, **kwargs):
|
|||||||
def getfeerate(plugin, **kwargs):
|
def getfeerate(plugin, **kwargs):
|
||||||
feerate_url = "{}/fee-estimates".format(plugin.api_endpoint)
|
feerate_url = "{}/fee-estimates".format(plugin.api_endpoint)
|
||||||
|
|
||||||
feerate_req = requests.get(feerate_url)
|
feerate_req = fetch(feerate_url)
|
||||||
assert feerate_req.status_code == 200
|
assert feerate_req.status_code == 200
|
||||||
feerates = feerate_req.json()
|
feerates = feerate_req.json()
|
||||||
# It renders sat/vB, we want sat/kVB, so multiply everything by 10**3
|
# It renders sat/vB, we want sat/kVB, so multiply everything by 10**3
|
||||||
@@ -161,4 +181,13 @@ plugin.add_option(
|
|||||||
"The URL of the esplora instance to hit (including '/api')."
|
"The URL of the esplora instance to hit (including '/api')."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
plugin.add_option(
|
||||||
|
"sauron-tor-proxy",
|
||||||
|
"",
|
||||||
|
"Tor's SocksPort address in the form address:port, don't specify the"
|
||||||
|
" protocol. If you didn't modify your torrc you want to put"
|
||||||
|
"'localhost:9050' here."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
plugin.run()
|
plugin.run()
|
||||||
|
|||||||
Reference in New Issue
Block a user