nonce.py (3659B)
1 # external imports 2 from hexathon import ( 3 add_0x, 4 strip_0x, 5 ) 6 7 # local imports 8 from chainlib.nonce import NonceOracle as BaseNonceOracle 9 from chainlib.jsonrpc import JSONRPCRequest 10 11 12 def nonce(address, confirmed=False, id_generator=None): 13 """Generate json-rpc query to retrieve next nonce of address from node. 14 15 :param address: Address to retrieve nonce for, in hex 16 :type address: str 17 :param id_generator: json-rpc id generator 18 :type id_generator: chainlib.connection.JSONRPCIdGenerator 19 :rtype: dict 20 :returns: rpc query object 21 """ 22 j = JSONRPCRequest(id_generator) 23 o = j.template() 24 o['method'] = 'eth_getTransactionCount' 25 o['params'].append(address) 26 if confirmed: 27 o['params'].append('latest') 28 else: 29 o['params'].append('pending') 30 return j.finalize(o) 31 32 33 def nonce_confirmed(address, id_generator=None): 34 return nonce(address, confirmed=True, id_generator=id_generator) 35 36 37 class NonceOracle(BaseNonceOracle): 38 """Base class for the nonce parameter helpers. 39 40 :param address: Address to retireve nonce for, in hex 41 :type address: str 42 :param id_generator: json-rpc id generator 43 :type id_generator: chainlib.connection.JSONRPCIdGenerator 44 """ 45 def __init__(self, address, id_generator=None, confirmed=None): 46 self.id_generator = id_generator 47 super(NonceOracle, self).__init__(add_0x(address), confirmed=confirmed) 48 49 50 def get_nonce(self, confirmed=False): 51 """Load initial nonce value. 52 """ 53 raise NotImplementedError('Class must be extended') 54 55 56 def next_nonce(self): 57 """Return next nonce value and advance. 58 59 :rtype: int 60 :returns: Next nonce for address. 61 """ 62 n = self.nonce 63 self.nonce += 1 64 return n 65 66 67 class RPCNonceOracle(NonceOracle): 68 """JSON-RPC only nonce parameter helper. 69 70 :param address: Address to retireve nonce for, in hex 71 :type address: str 72 :param conn: RPC connection 73 :type conn: chainlib.connection.RPCConnection 74 :param id_generator: json-rpc id generator 75 :type id_generator: chainlib.connection.JSONRPCIdGenerator 76 """ 77 def __init__(self, address, conn, id_generator=None, confirmed=False): 78 self.conn = conn 79 super(RPCNonceOracle, self).__init__(address, id_generator=id_generator, confirmed=confirmed) 80 81 82 def get_nonce(self, confirmed=False): 83 """Load and return nonce value from network. 84 85 Note! First call to next_nonce after calling get_nonce will return the same value! 86 87 :rtype: int 88 :returns: Initial nonce 89 """ 90 o = nonce(self.address, confirmed=confirmed, id_generator=self.id_generator) 91 r = self.conn.do(o) 92 n = strip_0x(r) 93 return int(n, 16) 94 95 96 class OverrideNonceOracle(NonceOracle): 97 """Manually set initial nonce value. 98 99 :param address: Address to retireve nonce for, in hex 100 :type address: str 101 :param nonce: Nonce value 102 :type nonce: int 103 :param id_generator: json-rpc id generator (not used) 104 :type id_generator: chainlib.connection.JSONRPCIdGenerator 105 """ 106 def __init__(self, address, nonce, id_generator=None, confirmed=False): 107 self.initial_nonce = nonce 108 self.nonce = self.initial_nonce 109 super(OverrideNonceOracle, self).__init__(address, id_generator=id_generator, confirmed=confirmed) 110 111 112 def get_nonce(self, confirmed=False): 113 """Returns initial nonce value set at object construction. 114 115 :rtype: int 116 :returns: Initial nonce value. 117 """ 118 return self.initial_nonce 119 120 121 DefaultNonceOracle = RPCNonceOracle