diff --git a/bigchaindb/core.py b/bigchaindb/core.py index af265d09..95cccfc7 100644 --- a/bigchaindb/core.py +++ b/bigchaindb/core.py @@ -1,6 +1,7 @@ import random import math import collections +from copy import deepcopy from itertools import compress import rethinkdb as r @@ -130,6 +131,9 @@ class Bigchain(object): # I am the only node assignee = self.me + # We copy the transaction here to not add `assignee` to the transaction + # dictionary passed to this method (as it would update by reference). + signed_transaction = deepcopy(signed_transaction) # update the transaction signed_transaction.update({'assignee': assignee}) @@ -151,7 +155,7 @@ class Bigchain(object): Returns: A dict with the transaction details if the transaction was found. Will add the transaction status to payload ('valid', 'undecided', - or 'backlog'). If no transaction with that `txid` was found it + or 'backlog'). If no transaction with that `txid` was found it returns `None` """ diff --git a/tests/test_core.py b/tests/test_core.py index 91dc9ef5..2650ff37 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -95,3 +95,14 @@ def test_transaction_exists(monkeypatch, items, exists): RqlQuery, 'run', lambda x, y: namedtuple('response', 'items')(items)) bigchain = Bigchain(public_key='pubkey', private_key='privkey') assert bigchain.transaction_exists('txid') is exists + + +def test_write_transaction_no_sideffects(b): + from rethinkdb.errors import ReqlOpFailedError + transaction = {'id': 'abc'} + expected = {'id': 'abc'} + with pytest.raises(ReqlOpFailedError): + b.write_transaction(transaction) + assert transaction == expected + with pytest.raises(KeyError): + transaction['assignee']