Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to pre-deploy the validator smart contract in a new QBFT network without configuring transition #1543

Closed
LeoHLee opened this issue Oct 24, 2022 · 3 comments · Fixed by #1570

Comments

@LeoHLee
Copy link

LeoHLee commented Oct 24, 2022

System information

Geth version: quorum 22.7.0
OS & Version: Windows/Linux/OSX

Expected behaviour

I mocked the example contract to generate a storage layout for the validator contract, and have inserted it into the "alloc" section of genesis file. Validators should have been authorized to seal blocks after I set validatorcontractaddress, according to the doc.

Actual behaviour

A blank list is returned when calling istanbul.getValidators(), even after I have got expected validator list with web3 http API.

My genesis block

{
	"nonce": "0x0",
	"gasLimit": "0xf7b760",
	"gasUsed": "0x0",
	"number": "0x0",
	"difficulty": "0x1",
	"coinbase": "0x0000000000000000000000000000000000000000",
	"mixHash": "0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365",
	"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
	"config": {
		"chainId": 114514,
		"homesteadBlock": 0,
		"eip150Block": 0,
		"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
		"eip155Block": 0,
		"eip158Block": 0,
		"byzantiumBlock": 0,
		"constantinopleBlock": 0,
		"isQuorum": true,
		"maxCodeSizeConfig": [
			{
				"block": 0,
				"size": 64
			}
		],
		"txnSizeLimit": 64,
		"qbft": {
			"policy": 0,
			"epoch": 30000,
			"ceil2Nby3Block": 0,
			"testQBFTBlock": 0,
			"blockperiodseconds": 5,
			"emptyblockperiodseconds": 60,
			"validatorcontractaddress": "0x0000000000000000000000000000000001919810"
		}
	},
	"alloc": {
		"0x0000000000000000000000000000000001919810": {
			"comment": "validator smart contract",
			"balance": "0x00",
			"code": "0x608060405234801561001057600080fd5b506004361061005d577c0100000000000000000000000000000000000000000000000000000000600035046340a141ff81146100625780634d238c8e14610077578063b7ab4db51461008a575b600080fd5b610075610070366004610377565b6100a8565b005b610075610085366004610377565b610247565b610092610315565b60405161009f91906103a7565b60405180910390f35b600054600160a060020a031633146100bf57600080fd5b6001546000805b8281101561019557811561014757600181815481106100e7576100e76103f4565b600091825260209091200154600160a060020a031660016101088184610452565b81548110610118576101186103f4565b9060005260206000200160006101000a815481600160a060020a030219169083600160a060020a031602179055505b83600160a060020a031660018281548110610164576101646103f4565b600091825260209091200154600160a060020a03160361018357600191505b8061018d8161046b565b9150506100c6565b5080156101e15760018054806101ad576101ad610484565b6000828152602090208101600019908101805473ffffffffffffffffffffffffffffffffffffffff19169055019055505050565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f546869732076616c696461746f72206973206e6f7420696e206c697374000000604482015260640160405180910390fd5b600054600160a060020a0316331461025e57600080fd5b60005b6001548110156102b85781600160a060020a031660018281548110610288576102886103f4565b600091825260209091200154600160a060020a0316036102a6575050565b806102b08161046b565b915050610261565b506001805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6018054600160a060020a03831673ffffffffffffffffffffffffffffffffffffffff1990911617905550565b6060600180548060200260200160405190810160405280929190818152602001828054801561036d57602002820191906000526020600020905b8154600160a060020a0316815260019091019060200180831161034f575b5050505050905090565b60006020828403121561038957600080fd5b8135600160a060020a03811681146103a057600080fd5b9392505050565b6020808252825182820181905260009190848201906040850190845b818110156103e8578351600160a060020a0316835292840192918401916001016103c3565b50909695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561046557610465610423565b92915050565b60006001820161047d5761047d610423565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220b6c842fefcee5e9bbd2592ab69d92b9ceb000c75d96d1eb94ea9087f457c145a64736f6c63430008110033",
			"version": "0x01",
			"storage": {
				"0000000000000000000000000000000000000000000000000000000000000000": "000000000000000000000000767c4a8ef57a81de497d919748e35aa75b9a1eeb",
				"0000000000000000000000000000000000000000000000000000000000000001": "0000000000000000000000000000000000000000000000000000000000000005",
				"b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6": "000000000000000000000000db5c58264ad1dd9fad06d95704c2b5b8b1f37626",
				"b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7": "00000000000000000000000062b6ba881ffb920294845d3b71a7a4c259d605b5",
				"b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf8": "0000000000000000000000005b7413bce2cc405436b0d2eebc0ac92566d6c324",
				"b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf9": "000000000000000000000000284ba98cc36b5e5be74445f8d8bfac3d95725d6f",
				"b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfa": "0000000000000000000000002081fc57f6fe03cfa484da347d65f30401d60710"
			}
		}
	},
	"extraData": "0xe5a00000000000000000000000000000000000000000000000000000000000000000c0c080c0",
	"timestamp": "0x6356586c"
}

My validator contract code

pragma solidity ^0.8.7;
//SPDX-License-Identifier: GPL

interface ValidatorSmartContractInterface {
    function getValidators() external view returns (address[] memory);
}

contract SingleAdminValidatorListImpl is ValidatorSmartContractInterface {
    address admin;
    address[] validators;

    function getValidators() external view returns (address[] memory) {
        return validators;
    }

    modifier requireAdmin() {
        require(msg.sender == admin);
        _;
    }

    function addValidator(address newValidator) external requireAdmin {
        for (uint i = 0; i < validators.length; i ++) {
            if(validators[i] == newValidator)
                return;
        }
        validators.push(newValidator);
    }

    function removeValidator(address badValidator) external requireAdmin {
        uint len = validators.length;
        bool deleted = false;
        for (uint i = 0; i < len; i ++) {
            if (deleted) validators[i - 1] = validators[i];
            if (validators[i] == badValidator) deleted = true;
        }
        if (deleted) validators.pop();
        else revert("This validator is not in list");
    }
}

What I have noticed

At around line 370 of quorum/consensus/istanbul/backend/engine.go, I found a line:

if sb.config.ValidatorContract != (common.Address{}) && sb.config.GetValidatorSelectionMode(big.NewInt(0)) == params.ContractMode

The GetValidatorSelectionMode function is implemented in quorum/consensus/istanbul/config.go

func (c Config) GetValidatorSelectionMode(blockNumber *big.Int) string {
	mode := params.BlockHeaderMode
	c.getTransitionValue(blockNumber, func(transition params.Transition) {
		if transition.ValidatorSelectionMode != "" {
			mode = transition.ValidatorSelectionMode
		}
	})
	return mode
}

So it seems that with no transition, GetValidatorSelectionMode always returns BlockHeaderMode, which disabling contract mode, even if I have set validatorcontractaddress.

@baptiste-b-pegasys
Copy link
Contributor

Hello,
thank you for raising this.
Have you tried with the latest version?
Might be fixed by #1530

@LeoHLee
Copy link
Author

LeoHLee commented Oct 24, 2022

Hello, thank you for raising this. Have you tried with the latest version? Might be fixed by #1530

I have just tried the lastest version 22.7.2 and the problem is not solved. Pre-deployed validator contract still cannot take effect, unless I add a transition entry to genesis, like this

{
  ...
  "config": {
    ...
    "qbft": {
      "policy": 0,
      "epoch": 30000,
      "ceil2Nby3Block": 0,
      "testQBFTBlock": 0,
      "blockperiodseconds": 5,
      "emptyblockperiodseconds": 60,
      "validatorcontractaddress": "0x0000000000000000000000000000000001919810"
    },
    "transitions": [
      {
        "block": 0,
        "validatorselectionmode": "contract"
      }
    ]
  }
}

@baptiste-b-pegasys
Copy link
Contributor

You are right, this is mandatory in this version: in term of usability, we need to improve that.
Also, while this mode is mandatory and it's not possible to have the extra data with filled list and the smart contract filled at the genesis block because of a check up at the initialization, it's not consistent too.
Thank you for raising this, should leave this ticket open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants