Typo fix
[stratum-mining.git] / mining / interfaces.py
1 '''This module contains classes used by pool core to interact with the rest of the pool.
2    Default implementation do almost nothing, you probably want to override these classes
3    and customize references to interface instances in your launcher.
4    (see launcher_demo.tac for an example).
5 ''' 
6 from stratum import settings
7 import time
8 from twisted.internet import reactor, defer
9 from lib.util import b58encode
10
11 import stratum.logger
12 log = stratum.logger.get_logger('interfaces')
13
14 import DBInterface
15 dbi = DBInterface.DBInterface()
16 dbi.init_main()
17
18 class WorkerManagerInterface(object):
19     def __init__(self):
20         # Fire deferred when manager is ready
21         self.on_load = defer.Deferred()
22         self.on_load.callback(True)
23         
24     def authorize(self, worker_name, worker_password):
25         # Important NOTE: This is called on EVERY submitted share. So you'll need caching!!!
26         return dbi.check_password(worker_name,worker_password)
27
28
29 class ShareLimiterInterface(object):
30     '''Implement difficulty adjustments here'''
31     
32     def submit(self, connection_ref, job_id, current_difficulty, timestamp, worker_name):
33         '''connection - weak reference to Protocol instance
34            current_difficulty - difficulty of the connection
35            timestamp - submission time of current share
36            
37            - raise SubmitException for stop processing this request
38            - call mining.set_difficulty on connection to adjust the difficulty'''
39         return dbi.update_worker_diff(worker_name,settings.POOL_TARGET)
40  
41 class ShareManagerInterface(object):
42     def __init__(self):
43         # Fire deferred when manager is ready
44         self.on_load = defer.Deferred()
45         self.on_load.callback(True)
46         self.block_height = 0
47         self.prev_hash = 0
48
49     def on_network_block(self, prevhash, block_height):
50         '''Prints when there's new block coming from the network (possibly new round)'''
51         self.block_height = block_height
52         self.prev_hash = b58encode(int(prevhash,16))
53         pass
54     
55     def on_submit_share(self, worker_name, block_header, block_hash, difficulty, timestamp, is_valid, ip, invalid_reason, share_diff ):
56         log.info("%s (%s) %s %s" % (block_hash, share_diff, 'valid' if is_valid else 'INVALID', worker_name))
57         dbi.queue_share([worker_name,block_header,block_hash,difficulty,timestamp,is_valid, ip, self.block_height, self.prev_hash, 
58                 invalid_reason, share_diff ])
59  
60     def on_submit_block(self, is_accepted, worker_name, block_header, block_hash, timestamp, ip, share_diff ):
61         log.info("Block %s %s" % (block_hash, 'ACCEPTED' if is_accepted else 'REJECTED'))
62         dbi.found_block([worker_name,block_header,block_hash,-1,timestamp,is_accepted,ip,self.block_height, self.prev_hash, share_diff ])
63     
64 class TimestamperInterface(object):
65     '''This is the only source for current time in the application.
66     Override this for generating unix timestamp in different way.'''
67     def time(self):
68         return time.time()
69
70 class PredictableTimestamperInterface(TimestamperInterface):
71     '''Predictable timestamper may be useful for unit testing.'''
72     start_time = 1345678900 # Some day in year 2012
73     delta = 0
74     
75     def time(self):
76         self.delta += 1
77         return self.start_time + self.delta
78         
79 class Interfaces(object):
80     worker_manager = None
81     share_manager = None
82     share_limiter = None
83     timestamper = None
84     template_registry = None
85     
86     @classmethod
87     def set_worker_manager(cls, manager):
88         cls.worker_manager = manager    
89     
90     @classmethod        
91     def set_share_manager(cls, manager):
92         cls.share_manager = manager
93
94     @classmethod        
95     def set_share_limiter(cls, limiter):
96         cls.share_limiter = limiter
97     
98     @classmethod
99     def set_timestamper(cls, manager):
100         cls.timestamper = manager
101         
102     @classmethod
103     def set_template_registry(cls, registry):
104         dbi.set_bitcoinrpc(registry.bitcoin_rpc)
105         cls.template_registry = registry