Skip to content
This repository has been archived by the owner on May 13, 2022. It is now read-only.

Commit

Permalink
Remove custom ygs, only yg-basic and yg-pe
Browse files Browse the repository at this point in the history
Refactor yg-basic to inherit from YieldGenerator, remove duplication
add update note to README
  • Loading branch information
AdamISZ committed Sep 9, 2016
1 parent 980c536 commit 1f7252a
Show file tree
Hide file tree
Showing 8 changed files with 27 additions and 1,794 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ Widespread use of JoinMarket could improve bitcoin's fungibility as a commodity.

##Installation

#####A NOTE ON UPDATING
The installation is slightly changed, with the secp256k1 python binding no longer being optional, and libnacl now being installed via pip, not locally. The short version is: do follow the below process, for example the secp256k1 binding must be the latest version else you'll get errors. Of course if you already have libsodium you don't need to re-install it.

#####REQUIRED INSTALLATION DEPENDENCIES

+ You will need python 2.7
Expand Down
4 changes: 1 addition & 3 deletions test/test_regtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@
#for running bots as subprocesses
python_cmd = 'python2'
yg_cmd = 'yield-generator-basic.py'
#yg_cmd = 'yield-generator-mixdepth.py'
#yg_cmd = 'yield-generator-deluxe.py'

#yg_cmd = 'yg-pe.py'

@pytest.mark.parametrize(
"num_ygs, wallet_structures, mean_amt, mixdepth, sending_amt, ygcfs, fails, donate",
Expand Down
4 changes: 2 additions & 2 deletions test/ygrunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@

#for running bots as subprocesses
python_cmd = 'python2'
#yg_cmd = 'yield-generator-basic.py'
yg_cmd = 'yield-generator-mixdepth.py'
yg_cmd = 'yield-generator-basic.py'
#yg_cmd = 'yield-generator-mixdepth.py'
#yg_cmd = 'yield-generator-deluxe.py'

@pytest.mark.parametrize(
Expand Down
16 changes: 7 additions & 9 deletions yg-pe.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,9 @@
log = get_log()

# is a maker for the purposes of generating a yield from held
# bitcoins without ruining privacy for the taker, the taker could easily check
# the history of the utxos this bot sends, so theres not much incentive
# to ruin the privacy for barely any more yield
# sell-side algorithm:
# add up the value of each utxo for each mixing depth,
# announce a relative-fee order of the highest balance
# spent from utxos that try to make the highest balance even higher
# so try to keep coins concentrated in one mixing depth
# bitcoins while maximising the difficulty of spying on activity;
# this is primarily attempted by avoiding reannouncemnt of orders
# after transactions whereever that is possible.
class YieldGeneratorPrivEnhance(YieldGenerator):


Expand Down Expand Up @@ -175,5 +170,8 @@ def on_tx_confirmed(self, cjorder, confirmations, txid):


if __name__ == "__main__":
ygmain(YieldGeneratorPrivEnhance)
ygmain(YieldGeneratorPrivEnhance, txfee=txfee,
cjfee_a=cjfee_a, cjfee_r=cjfee_r,
ordertype=ordertype, nickserv_password=nickserv_password,
minsize=minsize, mix_levels=mix_levels)
print('done')
136 changes: 14 additions & 122 deletions yield-generator-basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,11 @@
import time
from optparse import OptionParser

from joinmarket import Maker, IRCMessageChannel, MessageChannelCollection
from joinmarket import BlockrInterface
from joinmarket import jm_single, get_network, load_program_config
from joinmarket import get_log, calc_cj_fee, debug_dump_object
from joinmarket import Wallet
from joinmarket import Wallet, YieldGenerator, ygmain
from joinmarket import get_irc_mchannels

# data_dir = os.path.dirname(os.path.realpath(__file__))
# sys.path.insert(0, os.path.join(data_dir, 'joinmarket'))

# import blockchaininterface

txfee = 1000
cjfee_a = 200
cjfee_r = '0.002'
Expand All @@ -26,47 +19,19 @@
minsize = 100000
mix_levels = 5


log = get_log()

# is a maker for the purposes of generating a yield from held
# bitcoins without ruining privacy for the taker, the taker could easily check
# the history of the utxos this bot sends, so theres not much incentive
# to ruin the privacy for barely any more yield
# sell-side algorithm:
# add up the value of each utxo for each mixing depth,
# announce a relative-fee order of the highest balance
# spent from utxos that try to make the highest balance even higher
# so try to keep coins concentrated in one mixing depth
class YieldGenerator(Maker):
statement_file = os.path.join('logs', 'yigen-statement.csv')

def __init__(self, msgchan, wallet):
Maker.__init__(self, msgchan, wallet)
self.msgchan.register_channel_callbacks(self.on_welcome,
self.on_set_topic, None, None,
self.on_nick_leave, None)
self.tx_unconfirm_timestamp = {}

def log_statement(self, data):
if get_network() == 'testnet':
return

data = [str(d) for d in data]
self.income_statement = open(self.statement_file, 'a')
self.income_statement.write(','.join(data) + '\n')
self.income_statement.close()

def on_welcome(self):
Maker.on_welcome(self)
if not os.path.isfile(self.statement_file):
self.log_statement(
['timestamp', 'cj amount/satoshi', 'my input count',
'my input value/satoshi', 'cjfee/satoshi', 'earned/satoshi',
'confirm time/min', 'notes'])
# bitcoins, offering from the maximum mixdepth and trying to offer
# the largest amount within the constraints of mixing depth isolation.
# It will often (but not always) reannounce orders after transactions,
# thus is somewhat suboptimal in giving more information to spies.
class YieldGeneratorBasic(YieldGenerator):

timestamp = datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")
self.log_statement([timestamp, '', '', '', '', '', '', 'Connected'])
def __init__(self, msgchan, wallet, offerconfig):
self.txfee, self.cjfee_a, self.cjfee_r, self.ordertype, self.minsize, \
self.mix_levels = offerconfig
super(YieldGeneratorBasic,self).__init__(msgchan, wallet)

def create_my_orders(self):
mix_balance = self.wallet.get_balance_by_mixdepth()
Expand Down Expand Up @@ -160,82 +125,9 @@ def on_tx_confirmed(self, cjorder, confirmations, txid):
confirm_time / 60.0, 2), ''])
return self.on_tx_unconfirmed(cjorder, txid, None)


def main():
global txfee, cjfee_a, cjfee_r, ordertype, nickserv_password, minsize, mix_levels
import sys

parser = OptionParser(usage='usage: %prog [options] [wallet file]')
parser.add_option('-o', '--ordertype', action='store', type='string', dest='ordertype', default=ordertype,
help='type of order; can be either reloffer or absoffer')
parser.add_option('-t', '--txfee', action='store', type='int', dest='txfee', default=txfee,
help='minimum miner fee in satoshis')
parser.add_option('-c', '--cjfee', action='store', type='string', dest='cjfee', default='',
help='requested coinjoin fee in satoshis or proportion')
parser.add_option('-p', '--password', action='store', type='string', dest='password', default=nickserv_password,
help='irc nickserv password')
parser.add_option('-s', '--minsize', action='store', type='int', dest='minsize', default=minsize,
help='minimum coinjoin size in satoshis')
parser.add_option('-m', '--mixlevels', action='store', type='int', dest='mixlevels', default=mix_levels,
help='number of mixdepths to use')
(options, args) = parser.parse_args()
if len(args) < 1:
parser.error('Needs a wallet')
sys.exit(0)
seed = args[0]
ordertype = options.ordertype
txfee = options.txfee
if ordertype == 'reloffer':
if options.cjfee != '':
cjfee_r = options.cjfee
# minimum size is such that you always net profit at least 20% of the miner fee
minsize = max(int(1.2 * txfee / float(cjfee_r)), options.minsize)
elif ordertype == 'absoffer':
if options.cjfee != '':
cjfee_a = int(options.cjfee)
minsize = options.minsize
else:
parser.error('You specified an incorrect order type which can be either reloffer or absoffer')
sys.exit(0)
nickserv_password = options.password
mix_levels = options.mixlevels

load_program_config()
if isinstance(jm_single().bc_interface, BlockrInterface):
c = ('\nYou are running a yield generator by polling the blockr.io '
'website. This is quite bad for privacy. That site is owned by '
'coinbase.com Also your bot will run faster and more efficently, '
'you can be immediately notified of new bitcoin network '
'information so your money will be working for you as hard as '
'possibleLearn how to setup JoinMarket with Bitcoin Core: '
'https://github.com/chris-belcher/joinmarket/wiki/Running'
'-JoinMarket-with-Bitcoin-Core-full-node')
print(c)
ret = raw_input('\nContinue? (y/n):')
if ret[0] != 'y':
return

wallet = Wallet(seed, max_mix_depth=mix_levels)
jm_single().bc_interface.sync_wallet(wallet)

log.debug('starting yield generator')
mcs = [IRCMessageChannel(c, realname='btcint=' + jm_single().config.get(
"BLOCKCHAIN", "blockchain_source"),
password=nickserv_password) for c in get_irc_mchannels()]
mcc = MessageChannelCollection(mcs)
maker = YieldGenerator(mcc, wallet)
try:
log.debug('connecting to message channels')
mcc.run()
except:
log.debug('CRASHING, DUMPING EVERYTHING')
debug_dump_object(wallet, ['addr_cache', 'keys', 'seed'])
debug_dump_object(maker)
debug_dump_object(mcc)
import traceback
log.debug(traceback.format_exc())


if __name__ == "__main__":
main()
ygmain(YieldGeneratorBasic, txfee=txfee, cjfee_a=cjfee_a,
cjfee_r=cjfee_r, ordertype=ordertype,
nickserv_password=nickserv_password,
minsize=minsize, mix_levels=mix_levels)
print('done')
Loading

0 comments on commit 1f7252a

Please sign in to comment.