No duplicate vote inserts with mongodb (#1258)

* prevent duplicate vote inserts
This commit is contained in:
Rodolphe Marques 2017-03-22 14:25:16 +01:00 committed by GitHub
parent 9987041ac0
commit 10d83c2ab9
4 changed files with 27 additions and 19 deletions

View File

@ -100,4 +100,5 @@ def create_votes_secondary_index(conn, dbname):
ASCENDING),
('node_pubkey',
ASCENDING)],
name='block_and_voter')
name='block_and_voter',
unique=True)

View File

@ -212,6 +212,7 @@ def test_get_owned_ids(signed_create_tx, user_pk):
def test_get_votes_by_block_id(signed_create_tx, structurally_valid_vote):
from bigchaindb.common.crypto import generate_key_pair
from bigchaindb.backend import connect, query
from bigchaindb.models import Block
conn = connect()
@ -219,10 +220,14 @@ def test_get_votes_by_block_id(signed_create_tx, structurally_valid_vote):
# create and insert a block
block = Block(transactions=[signed_create_tx])
conn.db.bigchain.insert_one(block.to_dict())
# create and insert some votes
structurally_valid_vote['vote']['voting_for_block'] = block.id
conn.db.votes.insert_one(structurally_valid_vote)
# create a second vote under a different key
_, pk = generate_key_pair()
structurally_valid_vote['vote']['voting_for_block'] = block.id
structurally_valid_vote['node_pubkey'] = pk
structurally_valid_vote.pop('_id')
conn.db.votes.insert_one(structurally_valid_vote)
@ -325,6 +330,19 @@ def test_write_vote(structurally_valid_vote):
assert vote_db == structurally_valid_vote
def test_duplicate_vote_raises_duplicate_key(structurally_valid_vote):
from bigchaindb.backend import connect, query
from bigchaindb.backend.exceptions import DuplicateKeyError
conn = connect()
# write a vote
query.write_vote(conn, structurally_valid_vote)
# write the same vote a second time
with pytest.raises(DuplicateKeyError):
query.write_vote(conn, structurally_valid_vote)
def test_get_genesis_block(genesis_block):
from bigchaindb.backend import connect, query
conn = connect()

View File

@ -446,23 +446,6 @@ class TestBigchainApi(object):
b.write_vote(b.vote(block_3.id, b.get_last_voted_block().id, True))
assert b.get_last_voted_block().id == block_3.id
def test_no_vote_written_if_block_already_has_vote(self, b, genesis_block):
from bigchaindb.models import Block
block_1 = dummy_block()
b.write_block(block_1)
b.write_vote(b.vote(block_1.id, genesis_block.id, True))
retrieved_block_1 = b.get_block(block_1.id)
retrieved_block_1 = Block.from_dict(retrieved_block_1)
# try to vote again on the retrieved block, should do nothing
b.write_vote(b.vote(retrieved_block_1.id, genesis_block.id, True))
retrieved_block_2 = b.get_block(block_1.id)
retrieved_block_2 = Block.from_dict(retrieved_block_2)
assert retrieved_block_1 == retrieved_block_2
@pytest.mark.usefixtures('inputs')
def test_assign_transaction_one_node(self, b, user_pk, user_sk):
from bigchaindb.backend import query

View File

@ -27,6 +27,8 @@ def test_get_votes_endpoint(b, client):
@pytest.mark.bdb
@pytest.mark.usefixtures('inputs')
def test_get_votes_endpoint_multiple_votes(b, client):
from bigchaindb.common.crypto import generate_key_pair
tx = Transaction.create([b.me], [([b.me], 1)])
tx = tx.sign([b.me_private])
@ -37,8 +39,12 @@ def test_get_votes_endpoint_multiple_votes(b, client):
vote_valid = b.vote(block.id, last_block, True)
b.write_vote(vote_valid)
# vote the block valid
# vote the block invalid
# a note can only vote once so we need a new node_pubkey for the second
# vote
_, pk = generate_key_pair()
vote_invalid = b.vote(block.id, last_block, False)
vote_invalid['node_pubkey'] = pk
b.write_vote(vote_invalid)
res = client.get(VOTES_ENDPOINT + '?block_id=' + block.id)