def create_proposal(blk): signing_lockset = LockSet(len(validators)) for privkey in privkeys: v = VoteBlock(blk.number - 1, 0, blk.hash) v.sign(privkey) signing_lockset.add(v) bp = BlockProposal(height=blk.number, round=0, block=blk, signing_lockset=signing_lockset, round_lockset=None) bp.sign(tester.k0) return bp
def test_blockproposal(): s = tester.state() # block 1 s.mine(n=1) genesis = s.blocks[0] assert genesis.header.number == 0 blk1 = s.blocks[1] assert blk1.header.number == 1 gls = genesis_signing_lockset(genesis, privkeys[0]) bp = BlockProposal(height=1, round=0, block=blk1, signing_lockset=gls, round_lockset=None) assert bp.lockset == gls assert isinstance(bp, Proposal) bp.sign(tester.k0) with pytest.raises(InvalidProposalError): # round >0 needs round_lockset bp = BlockProposal(height=1, round=1, block=blk1, signing_lockset=gls, round_lockset=None) bp.validate_votes(validators, validators[:1]) # block 2 s.mine(n=1) blk2 = s.blocks[2] assert blk2.header.number == 2 ls = LockSet(len(validators)) for privkey in privkeys: v = VoteBlock(height=1, round=0, blockhash=blk1.hash) v.sign(privkey) ls.add(v) bp = BlockProposal(height=2, round=0, block=blk2, signing_lockset=ls, round_lockset=None) assert bp.lockset == ls with pytest.raises(InvalidProposalError): # signature missing bp.validate_votes(validators, validators) with pytest.raises(InvalidProposalError): bp.sign(privkeys[0]) # privkey doesnt match coinbase bp.validate_votes(validators, validators) with pytest.raises(InvalidSignature): # already signed bp.sign(tester.k0) bp.v = 0 # reset sigcheck hack bp.sign(tester.k0) bp.validate_votes(validators, validators) with pytest.raises(InvalidProposalError): # round >0 needs round_lockset bp = BlockProposal(height=2, round=1, block=blk2, signing_lockset=gls, round_lockset=None) # block 2 round 1, timeout in round=0 rls = LockSet(len(validators)) for privkey in privkeys: v = VoteNil(height=2, round=0) v.sign(privkey) rls.add(v) bp = BlockProposal(height=2, round=1, block=blk2, signing_lockset=ls, round_lockset=rls) assert bp.lockset == rls bp.sign(tester.k0) bp.validate_votes(validators, validators) # serialize s = rlp.encode(bp) dbp = rlp.decode(s, BlockProposal) assert dbp.block == blk2 dbp.validate_votes(validators, validators) # check quorumpossible lockset failure rls = LockSet(len(validators)) for i, privkey in enumerate(privkeys): if i < 4: v = VoteBlock(height=2, round=0, blockhash="0" * 32) else: v = VoteNil(height=2, round=0) v.sign(privkey) rls.add(v) assert not rls.has_noquorum assert rls.has_quorum_possible with pytest.raises(InvalidProposalError): # NoQuorum necessary R0 bp = BlockProposal(height=2, round=1, block=blk2, signing_lockset=ls, round_lockset=rls)
def test_blockproposal(): s = tester.state() # block 1 s.mine(n=1) genesis = s.blocks[0] assert genesis.header.number == 0 blk1 = s.blocks[1] assert blk1.header.number == 1 gls = genesis_signing_lockset(genesis, privkeys[0]) bp = BlockProposal(height=1, round=0, block=blk1, signing_lockset=gls, round_lockset=None) assert bp.lockset == gls assert isinstance(bp, Proposal) bp.sign(tester.k0) with pytest.raises(InvalidProposalError): # round >0 needs round_lockset bp = BlockProposal(height=1, round=1, block=blk1, signing_lockset=gls, round_lockset=None) bp.validate_votes(validators, validators[:1]) # block 2 s.mine(n=1) blk2 = s.blocks[2] assert blk2.header.number == 2 ls = LockSet(len(validators)) for privkey in privkeys: v = VoteBlock(height=1, round=0, blockhash=blk1.hash) v.sign(privkey) ls.add(v) bp = BlockProposal(height=2, round=0, block=blk2, signing_lockset=ls, round_lockset=None) assert bp.lockset == ls with pytest.raises(InvalidProposalError): # signature missing bp.validate_votes(validators, validators) with pytest.raises(InvalidProposalError): bp.sign(privkeys[0]) # privkey doesnt match coinbase bp.validate_votes(validators, validators) with pytest.raises(InvalidSignature): # already signed bp.sign(tester.k0) bp.v = 0 # reset sigcheck hack bp.sign(tester.k0) bp.validate_votes(validators, validators) with pytest.raises(InvalidProposalError): # round >0 needs round_lockset bp = BlockProposal(height=2, round=1, block=blk2, signing_lockset=gls, round_lockset=None) # block 2 round 1, timeout in round=0 rls = LockSet(len(validators)) for privkey in privkeys: v = VoteNil(height=2, round=0) v.sign(privkey) rls.add(v) bp = BlockProposal(height=2, round=1, block=blk2, signing_lockset=ls, round_lockset=rls) assert bp.lockset == rls bp.sign(tester.k0) bp.validate_votes(validators, validators) # serialize s = rlp.encode(bp) dbp = rlp.decode(s, BlockProposal) assert dbp.block == blk2 dbp.validate_votes(validators, validators) # check quorumpossible lockset failure rls = LockSet(len(validators)) for i, privkey in enumerate(privkeys): if i < 4: v = VoteBlock(height=2, round=0, blockhash='0' * 32) else: v = VoteNil(height=2, round=0) v.sign(privkey) rls.add(v) assert not rls.has_noquorum assert rls.has_quorum_possible with pytest.raises(InvalidProposalError): # NoQuorum necessary R0 bp = BlockProposal(height=2, round=1, block=blk2, signing_lockset=ls, round_lockset=rls)