Handle duplicate tx attempts
This commit is contained in:
parent
c22fafad53
commit
95930ef7de
@ -42,7 +42,6 @@ class StatusEnum(enum.IntEnum):
|
|||||||
"""
|
"""
|
||||||
PENDING = 0
|
PENDING = 0
|
||||||
"""Transaction has been added but no processing has been performed"""
|
"""Transaction has been added but no processing has been performed"""
|
||||||
|
|
||||||
SENDFAIL = StatusBits.DEFERRED | StatusBits.LOCAL_ERROR
|
SENDFAIL = StatusBits.DEFERRED | StatusBits.LOCAL_ERROR
|
||||||
"""Temporary error occurred when sending transaction to node"""
|
"""Temporary error occurred when sending transaction to node"""
|
||||||
RETRY = StatusBits.QUEUED | StatusBits.DEFERRED
|
RETRY = StatusBits.QUEUED | StatusBits.DEFERRED
|
||||||
|
@ -29,3 +29,8 @@ class BackendIntegrityError(ChainQueueException):
|
|||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class DuplicateTxError(ChainQueueException):
|
||||||
|
"""Backend already knows transaction
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
@ -6,7 +6,9 @@ import logging
|
|||||||
# local imports
|
# local imports
|
||||||
from chainqueue.cache import CacheTx
|
from chainqueue.cache import CacheTx
|
||||||
from chainqueue.entry import QueueEntry
|
from chainqueue.entry import QueueEntry
|
||||||
from chainqueue.error import NotLocalTxError
|
from chainqueue.error import (
|
||||||
|
NotLocalTxError,
|
||||||
|
)
|
||||||
|
|
||||||
logg = logging.getLogger(__name__)
|
logg = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -53,8 +55,8 @@ class Store:
|
|||||||
n = self.counter.next()
|
n = self.counter.next()
|
||||||
t = datetime.datetime.now().timestamp()
|
t = datetime.datetime.now().timestamp()
|
||||||
s = to_key(t, n, k)
|
s = to_key(t, n, k)
|
||||||
self.state_store.put(s, v)
|
|
||||||
self.index_store.put(k, s)
|
self.index_store.put(k, s)
|
||||||
|
self.state_store.put(s, v)
|
||||||
if self.cache != None:
|
if self.cache != None:
|
||||||
self.cache.put(self.chain_spec, tx)
|
self.cache.put(self.chain_spec, tx)
|
||||||
return (s, k,)
|
return (s, k,)
|
||||||
|
@ -5,6 +5,9 @@ import logging
|
|||||||
# external imports
|
# external imports
|
||||||
from leveldir.hex import HexDir
|
from leveldir.hex import HexDir
|
||||||
|
|
||||||
|
# local imports
|
||||||
|
from chainqueue.error import DuplicateTxError
|
||||||
|
|
||||||
logg = logging.getLogger(__name__)
|
logg = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -15,9 +18,20 @@ class IndexStore(HexDir):
|
|||||||
self.store = HexDir(root_path, digest_bytes)
|
self.store = HexDir(root_path, digest_bytes)
|
||||||
|
|
||||||
|
|
||||||
|
def __exists(self, k):
|
||||||
|
existing = None
|
||||||
|
try:
|
||||||
|
existing = self.get(k)
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
return existing != None
|
||||||
|
|
||||||
|
|
||||||
def put(self, k, v):
|
def put(self, k, v):
|
||||||
kb = bytes.fromhex(k)
|
kb = bytes.fromhex(k)
|
||||||
vb = v.encode('utf-8')
|
vb = v.encode('utf-8')
|
||||||
|
if self.__exists(k):
|
||||||
|
raise DuplicateTxError(k)
|
||||||
self.store.add(kb, vb)
|
self.store.add(kb, vb)
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ from chainqueue.store.fs import (
|
|||||||
IndexStore,
|
IndexStore,
|
||||||
CounterStore,
|
CounterStore,
|
||||||
)
|
)
|
||||||
|
from chainqueue.error import DuplicateTxError
|
||||||
|
|
||||||
|
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
@ -48,5 +49,14 @@ class TestStoreImplementations(unittest.TestCase):
|
|||||||
self.assertEqual(v, 2)
|
self.assertEqual(v, 2)
|
||||||
|
|
||||||
|
|
||||||
|
def test_duplicate(self):
|
||||||
|
store = IndexStore(self.path)
|
||||||
|
hx = os.urandom(32).hex()
|
||||||
|
data = 'foo_bar_baz'
|
||||||
|
store.put(hx, data)
|
||||||
|
with self.assertRaises(DuplicateTxError):
|
||||||
|
store.put(hx, data)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Loading…
Reference in New Issue
Block a user