This repository has been archived by the owner on Jun 13, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
153 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import abc | ||
|
||
|
||
class DbInterface(abc.ABC): | ||
|
||
@abc.abstractmethod | ||
def get_history(self, uid): | ||
return NotImplemented | ||
|
||
@abc.abstractmethod | ||
def save_history(self, uid, history): | ||
return NotImplemented |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from .db_interface import DbInterface | ||
|
||
|
||
class MemoryDb(DbInterface): | ||
|
||
def __init__(self): | ||
self.uid = {} | ||
|
||
def get_history(self, uid): | ||
return self.uid.get(uid) | ||
|
||
def save_history(self, uid, history): | ||
self.uid[uid] = history |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,6 @@ | ||
class RequestFailedException(Exception): | ||
"""request failed without success http status""" | ||
|
||
|
||
class TxHistoryNotFoundException(Exception): | ||
"""tx history is not found for specific block number""" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import rlp | ||
from rlp.sedes import big_endian_int, binary, CountableList | ||
|
||
from .exceptions import TxHistoryNotFoundException | ||
|
||
|
||
class History(rlp.Serializable): | ||
EMPTY_TX = b'\x00' * 32 | ||
|
||
fields = [ | ||
('latest_tx_blk_num', big_endian_int), | ||
('tx_history', CountableList(binary)), | ||
('proofs', CountableList(binary)), | ||
('blk_num', CountableList(big_endian_int)) | ||
] | ||
|
||
def __init__(self, deposit_tx_blk_num, tx, proof): | ||
self.latest_tx_blk_num = deposit_tx_blk_num | ||
self.tx_history = [tx] | ||
self.proofs = [proof] | ||
self.blk_num = [deposit_tx_blk_num] | ||
|
||
def update_tx_history(self, blk_num, tx, proof): | ||
if blk_num not in self.blk_num: | ||
if tx != self.EMPTY_TX: | ||
self.latest_tx_blk_num = max(self.latest_tx_blk_num, blk_num) | ||
self.tx_history.append(tx) | ||
self.proofs.append(proof) | ||
self.blk_num.append(blk_num) | ||
|
||
def get_data_by_block(self, blk_num): | ||
try: | ||
idx = self.blk_num.index(blk_num) | ||
except ValueError: | ||
raise TxHistoryNotFoundException('tx history not found') | ||
return self.tx_history[idx], self.proofs[idx] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import pytest | ||
|
||
from plasma_cash.client.db.memory_db import MemoryDb | ||
|
||
|
||
class TestMemoryDb(object): | ||
@pytest.fixture(scope='function') | ||
def db(self): | ||
return MemoryDb() | ||
|
||
def test_save_and_get_history(self, db): | ||
DUMMY_HISTORY = 'dummy history' | ||
DUMMY_UID = 1 | ||
db.save_history(DUMMY_UID, DUMMY_HISTORY) | ||
assert db.get_history(DUMMY_UID) == DUMMY_HISTORY | ||
|
||
def test_history_not_found(self, db): | ||
DUMMY_UID = 1 | ||
assert db.get_history(DUMMY_UID) is None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import pytest | ||
|
||
from plasma_cash.client.exceptions import TxHistoryNotFoundException | ||
from plasma_cash.client.history import History | ||
|
||
|
||
class TestHistory(object): | ||
DUMMY_DEPOSIT_BLK_NUM = 1 | ||
DUMMY_TX1 = 'dummy tx1' | ||
DUMMY_PROOF1 = 'dummy proof1' | ||
|
||
@pytest.fixture(scope='function') | ||
def history(self): | ||
return History(self.DUMMY_DEPOSIT_BLK_NUM, self.DUMMY_TX1, self.DUMMY_PROOF1) | ||
|
||
def test_constructor(self): | ||
history = History(self.DUMMY_DEPOSIT_BLK_NUM, self.DUMMY_TX1, self.DUMMY_PROOF1) | ||
assert history.latest_tx_blk_num == self.DUMMY_DEPOSIT_BLK_NUM | ||
assert history.tx_history == [self.DUMMY_TX1] | ||
assert history.proofs == [self.DUMMY_PROOF1] | ||
assert history.blk_num == [self.DUMMY_DEPOSIT_BLK_NUM] | ||
|
||
def test_update_history(self, history): | ||
DUMMY_BLK_NUM = 2 | ||
DUMMY_TX2 = 'dummy tx2' | ||
DUMMY_PROOF2 = 'dummy proof2' | ||
history.update_tx_history(DUMMY_BLK_NUM, DUMMY_TX2, DUMMY_PROOF2) | ||
assert history.latest_tx_blk_num == 2 | ||
assert history.tx_history == [self.DUMMY_TX1, DUMMY_TX2] | ||
assert history.proofs == [self.DUMMY_PROOF1, DUMMY_PROOF2] | ||
assert history.blk_num == [1, 2] | ||
|
||
def test_update_empty_history(self, history): | ||
DUMMY_BLK_NUM = 2 | ||
EMPTY_TX = b'\x00' * 32 | ||
NON_INCLUSIVE_PROOF = 'non inclusion proof' | ||
history.update_tx_history(DUMMY_BLK_NUM, EMPTY_TX, NON_INCLUSIVE_PROOF) | ||
assert history.latest_tx_blk_num == 1 | ||
assert history.tx_history == [self.DUMMY_TX1, EMPTY_TX] | ||
assert history.proofs == [self.DUMMY_PROOF1, NON_INCLUSIVE_PROOF] | ||
assert history.blk_num == [1, 2] | ||
|
||
def test_update_history_with_wrong_order(self, history): | ||
DUMMY_BLK_NUM = 3 | ||
DUMMY_TX3 = 'dummy tx3' | ||
DUMMY_PROOF3 = 'dummy proof3' | ||
history.update_tx_history(DUMMY_BLK_NUM, DUMMY_TX3, DUMMY_PROOF3) | ||
assert history.tx_history == [self.DUMMY_TX1, DUMMY_TX3] | ||
assert history.proofs == [self.DUMMY_PROOF1, DUMMY_PROOF3] | ||
assert history.blk_num == [1, 3] | ||
|
||
DUMMY_BLK_NUM = 2 | ||
DUMMY_TX2 = 'dummy tx2' | ||
DUMMY_PROOF2 = 'dummy proof2' | ||
history.update_tx_history(DUMMY_BLK_NUM, DUMMY_TX2, DUMMY_PROOF2) | ||
assert history.tx_history == [self.DUMMY_TX1, DUMMY_TX3, DUMMY_TX2] | ||
assert history.proofs == [self.DUMMY_PROOF1, DUMMY_PROOF3, DUMMY_PROOF2] | ||
assert history.blk_num == [1, 3, 2] | ||
|
||
def test_get_data_by_block(self, history): | ||
DUMMY_BLK_NUM = 1 | ||
tx, proof = history.get_data_by_block(DUMMY_BLK_NUM) | ||
assert tx == history.tx_history[0] | ||
assert proof == history.proofs[0] | ||
|
||
def test_get_data_by_block_failed(self, history): | ||
DUMMY_BLK_NUM = 2 | ||
with pytest.raises(TxHistoryNotFoundException): | ||
history.get_data_by_block(DUMMY_BLK_NUM) |