예제 #1
0
def sign_deploy(private_key: str, term: str, phlo_price: int, phlo_limit: int,
                valid_after_block_number: int, timestamp: int,
                sig_algorithm: str) -> None:
    pri = PrivateKey.from_hex(private_key)
    signed_deploy = create_deploy_data(pri, term, phlo_price, phlo_limit,
                                       valid_after_block_number, timestamp)
    click.echo(signed_deploy.sig.hex())
예제 #2
0
def test_slash_GHOST_disobeyed(command_line_options: CommandLineOptions, random_generator: Random, docker_client: DockerClient) -> None:
    """
    Slash a validator who doesn't follow GHOST.

    1. bootstrap proposes a valid block B1
    2. v2 proposes a valid block B2
    3. v1 proposes a valid block B3
    4. v1 proposes an invalid block B4 whose parent is B1 and send it to v2
    5. v2 records invalid block B4 (InvalidParents)
    6. v2 proposes a new block B5 which slashes v1
    """
    with three_nodes_network_with_node_client(command_line_options, random_generator, docker_client) as  (context, bootstrap_node , validator1, validator2, client):

        contract = '/opt/docker/examples/tut-hello.rho'

        bootstrap_node.deploy(contract, BONDED_VALIDATOR_KEY_1)
        blockhash1 = bootstrap_node.propose()

        wait_for_node_sees_block(context, validator1, blockhash1)
        wait_for_node_sees_block(context, validator2, blockhash1)

        validator2.deploy(contract, BONDED_VALIDATOR_KEY_2)
        blockhash2 = validator2.propose()

        wait_for_node_sees_block(context, validator1, blockhash2)
        wait_for_node_sees_block(context, bootstrap_node, blockhash2)

        validator1.deploy(contract, BONDED_VALIDATOR_KEY_3)
        blockhash3 = validator1.propose()

        wait_for_node_sees_block(context, validator2, blockhash3)
        wait_for_node_sees_block(context, bootstrap_node, blockhash3)

        block_info1 = validator1.get_block(blockhash1)
        block_info3 = validator1.get_block(blockhash3)
        block_msg3 = client.block_request(block_info3.blockInfo.blockHash, validator1)

        invalid_block =  BlockMessage()
        invalid_block.CopyFrom(block_msg3)
        invalid_block.header.ClearField("parentsHashList")  # pylint: disable=maybe-no-member
        invalid_block.body.state.blockNumber = 2  # pylint: disable=maybe-no-member
        invalid_block.header.parentsHashList.append(bytes.fromhex(block_info1.blockInfo.blockHash))  # pylint: disable=maybe-no-member
        invalid_block.header.timestamp = int(time.time()*1000)  # pylint: disable=maybe-no-member
        deploy_data = create_deploy_data(BONDED_VALIDATOR_KEY_2, Path("../rholang/examples/tut-hello.rho").read_text(), 1, 1000000)
        invalid_block.body.deploys[0].deploy.CopyFrom(deploy_data)  # pylint: disable=maybe-no-member
        invalid_block_hash = gen_block_hash_from_block(invalid_block)
        invalid_block.sig = BONDED_VALIDATOR_KEY_1.sign_block_hash(invalid_block_hash)
        invalid_block.blockHash = invalid_block_hash
        client.send_block(invalid_block, validator2)

        record_invalid = re.compile("Recording invalid block {}... for InvalidParents".format(invalid_block_hash.hex()[:10]))
        wait_for_log_match(context, validator2, record_invalid)

        validator2.deploy(contract, BONDED_VALIDATOR_KEY_1)
        slashed_blockhash = validator2.propose()
        slashed_block_info = validator2.get_block(slashed_blockhash)
        bonds_validators = {b.validator: b.stake for b in slashed_block_info.blockInfo.bonds}

        assert bonds_validators[BONDED_VALIDATOR_KEY_1.get_public_key().to_hex()] == 0
예제 #3
0
def test_client_deploy(key: PrivateKey, terms: str, phlo_price: int,
                       phlo_limit: int, valid_after_block_no: int,
                       timestamp_millis: int) -> None:
    class DummyDeploySerivce(DeployServiceServicer):
        def doDeploy(self, request: DeployDataProto,
                     context: grpc.ServicerContext) -> DeployResponse:
            return DeployResponse(result=request.sig.hex())

    with deploy_service(DummyDeploySerivce()) as (server, port), \
            RClient(TEST_HOST, port) as client:
        ret = client.deploy(key, terms, phlo_price, phlo_limit,
                            valid_after_block_no, timestamp_millis)
        assert verify_deploy_data(
            key.get_public_key(), bytes.fromhex(ret),
            create_deploy_data(key, terms, phlo_price, phlo_limit,
                               valid_after_block_no, timestamp_millis))
예제 #4
0
def test_slash_invalid_validator_approve_evil_block(command_line_options: CommandLineOptions, random_generator: Random, docker_client: DockerClient) -> None:
    """Slash a validator who doesn't slash invalid block

    1.v1 proposes valid block
    2.v1 creates another block with invalid parent block hash and sends it to v2
    3.v2 creates block using v1's second block as parent hash (i.e. no slashing, another invalid block) and sends it to v3
    4.v3 records invalid block (InvalidTransaction) from v2
    5.v3 proposes block which slashes both v1 and v2
    """
    with three_nodes_network_with_node_client(command_line_options, random_generator, docker_client) as  (context, validator3 , validator1, validator2, client):

        genesis_block = validator3.get_blocks(2)[0]

        contract = '/opt/docker/examples/tut-hello.rho'

        validator1.deploy(contract, BONDED_VALIDATOR_KEY_1)
        blockhash = validator1.propose()

        wait_for_node_sees_block(context, validator3, blockhash)
        wait_for_node_sees_block(context, validator2, blockhash)

        block_info = validator1.get_block(blockhash)

        block_msg = client.block_request(block_info.blockInfo.blockHash, validator1)

        evil_block_hash = generate_block_hash()

        # invalid block from validator1
        invalid_block = BlockMessage()
        invalid_block.CopyFrom(block_msg)
        invalid_block.seqNum = block_msg.seqNum + 1
        invalid_block.body.state.blockNumber = block_msg.body.state.blockNumber + 1  # pylint: disable=maybe-no-member
        invalid_block.blockHash = evil_block_hash
        invalid_block.header.timestamp = int(time.time()*1000)  # pylint: disable=maybe-no-member
        invalid_block.sig = BONDED_VALIDATOR_KEY_1.sign_block_hash(evil_block_hash)
        invalid_block.header.ClearField("parentsHashList")  # pylint: disable=maybe-no-member
        invalid_block.header.parentsHashList.append(bytes.fromhex(genesis_block.blockInfo.blockHash))  # pylint: disable=maybe-no-member
        invalid_block.ClearField("justifications")
        invalid_block.justifications.extend([  # pylint: disable=maybe-no-member
            Justification(validator=BONDED_VALIDATOR_KEY_1.get_public_key().to_bytes(), latestBlockHash=block_msg.blockHash),
            Justification(validator=BONDED_VALIDATOR_KEY_2.get_public_key().to_bytes(), latestBlockHash=bytes.fromhex(genesis_block.blockInfo.blockHash)),
            Justification(validator=BOOTSTRAP_NODE_KEY.get_public_key().to_bytes(), latestBlockHash=bytes.fromhex(genesis_block.blockInfo.blockHash)),
        ])
        client.send_block(invalid_block, validator2)

        wait_for_node_sees_block(context, validator2, evil_block_hash.hex())

        # block which is created by validator2 but not slashing validator1
        block_not_slash_invalid_block = BlockMessage()
        block_not_slash_invalid_block.CopyFrom(block_msg)
        block_not_slash_invalid_block.seqNum = 1
        block_not_slash_invalid_block.body.state.blockNumber = 1  # pylint: disable=maybe-no-member
        block_not_slash_invalid_block.sender = BONDED_VALIDATOR_KEY_2.get_public_key().to_bytes()
        block_not_slash_invalid_block.ClearField("justifications")
        block_not_slash_invalid_block.justifications.extend([  # pylint: disable=maybe-no-member
            Justification(validator=BONDED_VALIDATOR_KEY_1.get_public_key().to_bytes(), latestBlockHash=evil_block_hash),
            Justification(validator=BONDED_VALIDATOR_KEY_2.get_public_key().to_bytes(), latestBlockHash=bytes.fromhex(genesis_block.blockInfo.blockHash)),
            Justification(validator=BOOTSTRAP_NODE_KEY.get_public_key().to_bytes(), latestBlockHash=bytes.fromhex(genesis_block.blockInfo.blockHash)),
        ])
        deploy_data = create_deploy_data(BONDED_VALIDATOR_KEY_2, Path("../rholang/examples/tut-hello.rho").read_text(), 1, 1000000)
        block_not_slash_invalid_block.body.deploys[0].deploy.CopyFrom(deploy_data)  # pylint: disable=maybe-no-member
        block_not_slash_invalid_block.header.ClearField("parentsHashList")  # pylint: disable=maybe-no-member
        block_not_slash_invalid_block.header.parentsHashList.append(bytes.fromhex(genesis_block.blockInfo.blockHash))  # pylint: disable=maybe-no-member
        block_not_slash_invalid_block.header.timestamp = int(time.time()*1000)  # pylint: disable=maybe-no-member
        invalid_block_hash = gen_block_hash_from_block(block_not_slash_invalid_block)
        block_not_slash_invalid_block.sig = BONDED_VALIDATOR_KEY_2.sign_block_hash(invalid_block_hash)
        block_not_slash_invalid_block.blockHash = invalid_block_hash

        client.send_block(block_not_slash_invalid_block, validator3)

        # Because validator2 doesn't slash validator1's block while validator3 slash validator1's block,
        # hence there are some comm events lack of in validator3 which cause an invalid transaction
        record_invalid = re.compile("Recording invalid block {}... for InvalidTransaction".format(invalid_block_hash.hex()[:10]))
        wait_for_log_match(context, validator3, record_invalid)


        validator3.deploy(contract, BOOTSTRAP_NODE_KEY)
        slashed_blockhash = validator3.propose()
        slashed_block_info = validator3.get_block(slashed_blockhash)
        bonds_validators = {b.validator: b.stake for b in slashed_block_info.blockInfo.bonds}

        assert bonds_validators[BONDED_VALIDATOR_KEY_1.get_public_key().to_hex()] == 0
        assert bonds_validators[BONDED_VALIDATOR_KEY_2.get_public_key().to_hex()] == 0
예제 #5
0
import time

from rchain.crypto import PrivateKey, PublicKey
from rchain.util import create_deploy_data, verify_deploy_data

private_key = PrivateKey.generate()
public_key = private_key.get_public_key()

contract = "@0!(2)"

deploy_data = create_deploy_data(key=private_key,
                                 term=contract, phlo_price=1,
                                 phlo_limit=100000,
                                 valid_after_block_no=10,
                                 timestamp_millis=int(time.time() * 1000))

assert verify_deploy_data(public_key, deploy_data.sig, deploy_data)