Skip to content

Commit 214fd27

Browse files
authored
Merge pull request WebOfTrust#860 from SmithSamuelM/fix_del_ddos
Some clean up refactoring to use fleshed out OnIoDupSuber methods for pdes escrow
2 parents dd6e9f7 + 9e06c8f commit 214fd27

File tree

6 files changed

+387
-11
lines changed

6 files changed

+387
-11
lines changed

Diff for: src/keri/core/eventing.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -3380,7 +3380,7 @@ def escrowPDEvent(self, serder, *, sigers=None, wigers=None,
33803380

33813381
logger.debug(f"Kever state: Escrowed partially delegated event=\n"
33823382
f"{serder.ked}\n.")
3383-
return self.db.pdes.add(keys=snKey(serder.preb, serder.sn), val=serder.saidb)
3383+
return self.db.pdes.addOn(keys=serder.pre, on=serder.sn, val=serder.said)
33843384

33853385

33863386
def state(self):
@@ -5976,7 +5976,7 @@ def processEscrowPartialDels(self):
59765976
except Exception as ex: # log diagnostics errors etc
59775977
# error other than waiting on sigs or seal so remove from escrow
59785978
# removes one event escrow at key val
5979-
self.db.pdes.rem(keys=snKey(epre, esn), val=edig) # event idx escrow
5979+
self.db.pdes.remOn(keys=epre, on=esn, val=edig) # event idx escrow
59805980
self.db.udes.rem(keys=dgkey) # remove source seal escrow if any
59815981
if logger.isEnabledFor(logging.DEBUG):
59825982
logger.exception("Kevery unescrowed: %s", ex.args[0])
@@ -5988,7 +5988,7 @@ def processEscrowPartialDels(self):
59885988
# duplicitous so we process remaining escrows in spite of found
59895989
# valid event escrow.
59905990
# removes one event escrow at key val
5991-
self.db.pdes.rem(keys=snKey(epre, esn), val=edig) # event idx escrow
5991+
self.db.pdes.remOn(keys=epre, on=esn, val=edig) # event idx escrow
59925992
self.db.udes.rem(keys=dgkey) # remove source seal escrow if any
59935993
logger.info("Kevery unescrow succeeded in valid event: "
59945994
"event=%s", eserder.said)

Diff for: src/keri/db/dbing.py

+173-1
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,65 @@ def delTopVal(self, db, top=b''):
662662

663663
# For subdbs the use keys with trailing part the is monotonically
664664
# ordinal number serialized as 32 hex bytes
665+
666+
# used in OnSuberBase
667+
def putOnVal(self, db, key, on=0, val=b'', *, sep=b'.'):
668+
"""Write serialized bytes val to location at onkey consisting of
669+
key + sep + serialized on in db.
670+
Does not overwrite.
671+
672+
Returns:
673+
result (bool): True if successful write i.e onkey not already in db
674+
False otherwise
675+
676+
Parameters:
677+
db (lmdbsubdb): named sub db of lmdb
678+
key (bytes): key within sub db's keyspace plus trailing part on
679+
on (int): ordinal number at which write
680+
val (bytes): to be written at onkey
681+
sep (bytes): separator character for split
682+
"""
683+
with self.env.begin(db=db, write=True, buffers=True) as txn:
684+
if key: # not empty
685+
onkey = onKey(key, on, sep=sep) # start replay at this enty 0 is earliest
686+
else:
687+
onkey = key
688+
try:
689+
return (txn.put(onkey, val, overwrite=False))
690+
except lmdb.BadValsizeError as ex:
691+
raise KeyError(f"Key: `{onkey}` is either empty, too big (for lmdb),"
692+
" or wrong DUPFIXED size. ref) lmdb.BadValsizeError")
693+
694+
# used in OnSuberBase
695+
def setOnVal(self, db, key, on=0, val=b'', *, sep=b'.'):
696+
"""
697+
Write serialized bytes val to location at onkey consisting of
698+
key + sep + serialized on in db.
699+
Overwrites pre-existing value at onkey if any.
700+
701+
Returns:
702+
result (bool): True if successful write i.e onkey not already in db
703+
False otherwise
704+
705+
Parameters:
706+
db (lmdbsubdb): named sub db of lmdb
707+
key (bytes): key within sub db's keyspace plus trailing part on
708+
on (int): ordinal number at which write
709+
val (bytes): to be written at onkey
710+
sep (bytes): separator character for split
711+
"""
712+
with self.env.begin(db=db, write=True, buffers=True) as txn:
713+
if key: # not empty
714+
onkey = onKey(key, on, sep=sep) # start replay at this enty 0 is earliest
715+
else:
716+
onkey = key
717+
try:
718+
return (txn.put(onkey, val))
719+
except lmdb.BadValsizeError as ex:
720+
raise KeyError(f"Key: `{onkey}` is either empty, too big (for lmdb),"
721+
" or wrong DUPFIXED size. ref) lmdb.BadValsizeError")
722+
723+
665724
# used in OnSuberBase
666725
def appendOnVal(self, db, key, val, *, sep=b'.'):
667726
"""
@@ -721,6 +780,35 @@ def appendOnVal(self, db, key, val, *, sep=b'.'):
721780
raise ValueError(f"Failed appending {val=} at {key=}.")
722781
return on
723782

783+
784+
# used in OnSuberBase
785+
def getOnVal(self, db, key, on=0, *, sep=b'.'):
786+
"""Gets value at onkey consisting of key + sep + serialized on in db.
787+
788+
Returns:
789+
val (bytes | memoryview): entry at onkey consisting of key + sep +
790+
serialized on in db.
791+
None if no entry at key
792+
793+
Parameters:
794+
db (lmdbsubdb): named sub db of lmdb
795+
key (bytes): key within sub db's keyspace plus trailing part on
796+
on (int): ordinal number at which to retrieve
797+
sep (bytes): separator character for split
798+
799+
"""
800+
with self.env.begin(db=db, write=False, buffers=True) as txn:
801+
if key: # not empty
802+
onkey = onKey(key, on, sep=sep) # start replay at this enty 0 is earliest
803+
else:
804+
onkey = key
805+
try:
806+
return(txn.get(onkey))
807+
except lmdb.BadValsizeError as ex:
808+
raise KeyError(f"Key: `{onkey}` is either empty, too big (for lmdb),"
809+
" or wrong DUPFIXED size. ref) lmdb.BadValsizeError")
810+
811+
724812
# used in OnSuberBase
725813
def delOnVal(self, db, key, on=0, *, sep=b'.'):
726814
"""
@@ -1713,6 +1801,34 @@ def getTopIoDupItemIter(self, db, top=b''):
17131801
# this is so we do the proem add and strip here not in some higher level class
17141802
# like suber
17151803

1804+
def addOnIoDupVal(self, db, key, on=0, val=b'', sep=b'.'):
1805+
"""
1806+
Add val bytes as dup at onkey consisting of key + sep + serialized on in db.
1807+
Adds to existing values at key if any
1808+
Returns True if written else False if dup val already exists
1809+
1810+
Duplicates are inserted in lexocographic order not insertion order.
1811+
Lmdb does not insert a duplicate unless it is a unique value for that
1812+
key.
1813+
1814+
Does inclusion test to dectect of duplicate already exists
1815+
Uses a python set for the duplicate inclusion test. Set inclusion scales
1816+
with O(1) whereas list inclusion scales with O(n).
1817+
1818+
Returns:
1819+
result (bool): True if duplicate val added at onkey idempotent
1820+
False if duplicate val preexists at onkey
1821+
1822+
Parameters:
1823+
db is opened named sub db with dupsort=True
1824+
key (bytes): key within sub db's keyspace plus trailing part on
1825+
val (bytes): serialized value to add at onkey as dup
1826+
sep (bytes): separator character for split
1827+
"""
1828+
onkey = onKey(key, on, sep=sep)
1829+
return (self.addIoDupVal(db, key=onkey, val=val))
1830+
1831+
17161832
# used in OnIoDupSuber
17171833
def appendOnIoDupVal(self, db, key, val, *, sep=b'.'):
17181834
"""
@@ -1742,10 +1858,66 @@ def appendOnIoDupVal(self, db, key, val, *, sep=b'.'):
17421858
return (self.appendOnVal(db=db, key=key, val=val, sep=sep))
17431859

17441860

1861+
def delOnIoDupVals(self, db, key, on=0, sep=b'.'):
1862+
"""Deletes all dup iovals at onkey consisting of key + sep + serialized
1863+
on in db.
1864+
1865+
Assumes DB opened with dupsort=True
1866+
1867+
Duplicates are inserted in lexocographic order not insertion order.
1868+
Lmdb does not insert a duplicate unless it is a unique value for that
1869+
key.
1870+
1871+
Does inclusion test to dectect of duplicate already exists
1872+
Uses a python set for the duplicate inclusion test. Set inclusion scales
1873+
with O(1) whereas list inclusion scales with O(n).
1874+
1875+
Returns:
1876+
result (bool): True if onkey present so all dups at onkey deleted
1877+
False if onkey not present
1878+
1879+
Parameters:
1880+
db is opened named sub db with dupsort=True
1881+
key (bytes): key within sub db's keyspace plus trailing part on
1882+
sep (bytes): separator character for split
1883+
"""
1884+
onkey = onKey(key, on, sep=sep)
1885+
return (self.delIoDupVals(db, key=onkey))
1886+
1887+
1888+
def delOnIoDupVal(self, db, key, on=0, val=b'', sep=b'.'):
1889+
"""Deletes dup ioval at key onkey consisting of key + sep + serialized
1890+
on in db.
1891+
Returns True if deleted else False if dup val not present
1892+
Assumes DB opened with dupsort=True
1893+
1894+
Duplicates are inserted in lexocographic order not insertion order.
1895+
Lmdb does not insert a duplicate unless it is a unique value for that
1896+
key.
1897+
1898+
Does inclusion test to dectect of duplicate already exists
1899+
Uses a python set for the duplicate inclusion test. Set inclusion scales
1900+
with O(1) whereas list inclusion scales with O(n).
1901+
1902+
Returns:
1903+
result (bool): True if duplicate val found and deleted
1904+
False if duplicate val does not exist at onkey
1905+
1906+
Parameters:
1907+
db is opened named sub db with dupsort=True
1908+
key (bytes): key within sub db's keyspace plus trailing part on
1909+
val (bytes): serialized dup value to del at onkey
1910+
sep (bytes): separator character for split
1911+
"""
1912+
onkey = onKey(key, on, sep=sep)
1913+
return (self.delIoDupVal(db, key=onkey, val=val))
1914+
1915+
1916+
17451917
# used in OnIoDupSuber
17461918
def getOnIoDupValIter(self, db, key=b'', on=0, *, sep=b'.'):
17471919
"""
1748-
Returns iterator of triples (key, on, val), at each key over all ordinal
1920+
Returns iterator of val at each key over all ordinal
17491921
numbered keys with same key + sep + on in db. Values are sorted by
17501922
onKey(key, on) where on is ordinal number int and key is prefix sans on.
17511923
Values duplicates are sorted internally by hidden prefixed insertion order

0 commit comments

Comments
 (0)