Skip to content

Commit

Permalink
cr fix
Browse files Browse the repository at this point in the history
  • Loading branch information
igorcrevar committed Feb 29, 2024
1 parent 3bdb0ef commit eba9e3f
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 12 deletions.
51 changes: 40 additions & 11 deletions e2e-polybft/e2e/consensus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -825,22 +825,35 @@ func TestE2E_Deploy_Nested_Contract(t *testing.T) {
}

func TestE2E_TestValidatorSetPrecompile(t *testing.T) {
var (
premineBalance = ethgo.Ether(2e6) // 2M native tokens (so that we have enough balance to fund new validator)
stakeAmount = ethgo.Ether(500)
)

admin, err := wallet.GenerateKey()
require.NoError(t, err)

validatorAddrs := []types.Address(nil)
adminAddr := types.Address(admin.Address())
dummyKey, err := wallet.GenerateKey()
require.NoError(t, err)

// start cluster with 'validatorSize' validators
cluster := framework.NewTestCluster(t, 4,
framework.WithBladeAdmin(adminAddr.String()),
framework.WithSecretsCallback(func(addrs []types.Address, _ *framework.TestClusterConfig) {
validatorAddrs = addrs
}))
framework.WithBladeAdmin(admin.Address().String()),
framework.WithSecretsCallback(func(addresses []types.Address, config *framework.TestClusterConfig) {
for _, a := range addresses {
config.Premine = append(config.Premine, fmt.Sprintf("%s:%s", a, premineBalance))
config.StakeAmounts = append(config.StakeAmounts, stakeAmount)
}

config.Premine = append(config.Premine, fmt.Sprintf("%s:%s", dummyKey.Address(), premineBalance))
}),
)

defer cluster.Stop()

cluster.WaitForReady(t)

validatorKeys := make([]*wallet.Key, len(validatorAddrs))
validatorKeys := make([]*wallet.Key, len(cluster.Servers))

for i, s := range cluster.Servers {
voterAcc, err := validatorHelper.GetAccountFromDir(s.DataDir())
Expand Down Expand Up @@ -880,20 +893,33 @@ func TestE2E_TestValidatorSetPrecompile(t *testing.T) {
sendIncTx := func(validatorID int) {
t.Helper()

isValidator := validatorID >= 0 && validatorID < len(validatorKeys)
incFn := contractsapi.TestValidatorSetPrecompile.Abi.GetMethod("inc")

incFnBytes, err := incFn.Encode([]interface{}{})
require.NoError(t, err)

var key *wallet.Key
if isValidator {
key = validatorKeys[validatorID]
} else {
key = dummyKey
}

txn := &ethgo.Transaction{
From: ethgo.Address(validatorAddrs[validatorID]),
From: key.Address(),
To: &validatorSetPrecompileTestAddr,
Input: incFnBytes,
}

receipt, err = txRelayer.SendTransaction(txn, validatorKeys[validatorID])
require.NoError(t, err)
require.Equal(t, uint64(types.ReceiptSuccess), receipt.Status)
receipt, err = txRelayer.SendTransaction(txn, key)

if isValidator {
require.NoError(t, err)
require.Equal(t, uint64(types.ReceiptSuccess), receipt.Status)
} else {
require.ErrorContains(t, err, "unable to apply transaction even for the highest gas limit")
}
}

require.False(t, hasQuorum())
Expand All @@ -907,6 +933,9 @@ func TestE2E_TestValidatorSetPrecompile(t *testing.T) {
sendIncTx(1)
require.False(t, hasQuorum())

sendIncTx(-1) // non validator
require.False(t, hasQuorum())

sendIncTx(3)
require.True(t, hasQuorum())
}
9 changes: 8 additions & 1 deletion state/runtime/precompiled/validator_set_precompile.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,17 @@ var (
errValidatorSetPrecompileNotEnabled = errors.New("validator set precompile is not enabled")
)

// ValidatorSetPrecompileBackend is an interface defining the contract for a precompile backend
// responsible for retrieving validators (current account set) for a specific block number
type ValidatorSetPrecompileBackend interface {
GetValidatorsForBlock(blockNumber uint64) (validator.AccountSet, error)
}

// validatorSetPrecompile is a concrete implementation of the contract interface.
// The struct implements two functionalities through the `run` method:
// - isValidator(address addr) bool: Returns true if addr is the address of a validator.
// - hasQuorum(address[] addrs) bool: Returns true if the array of validators is sufficient to constitute a quorum
// It encapsulates a backend that provides the functionality to retrieve validators for a specific block number
type validatorSetPrecompile struct {
backend ValidatorSetPrecompileBackend
}
Expand All @@ -34,7 +41,7 @@ func (c *validatorSetPrecompile) gas(input []byte, _ *chain.ForksInTime) uint64
// Run runs the precompiled contract with the given input.
// There are two functions:
// isValidator(address addr) bool
// hasConsensus(address[] addrs) bool
// hasQuorum(address[] addrs) bool
// Input must be ABI encoded: address or (address[])
// Output could be an error or ABI encoded "bool" value
func (c *validatorSetPrecompile) run(input []byte, caller types.Address, host runtime.Host) ([]byte, error) {
Expand Down

0 comments on commit eba9e3f

Please sign in to comment.