refactor check duplicates to staking_verifier (#2898)

pull/2902/head
Ganesha Upadhyaya 5 years ago committed by GitHub
parent ab9f3f8e0b
commit 6bc602194c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 65
      core/staking_verifier.go
  2. 213
      core/staking_verifier_test.go
  3. 58
      core/state_transition.go
  4. 7
      core/tx_pool.go
  5. 24
      core/tx_pool_test.go
  6. 23
      test/chain/reward/main.go

@ -23,6 +23,46 @@ var (
errBlockNumMissing = errors.New("no block number was provided") errBlockNumMissing = errors.New("no block number was provided")
) )
func checkDuplicateFields(
bc ChainContext, state vm.StateDB,
validator common.Address, identity string, blsKeys []shard.BLSPublicKey,
) error {
addrs, err := bc.ReadValidatorList()
if err != nil {
return err
}
checkIdentity := identity != ""
checkBlsKeys := len(blsKeys) != 0
blsKeyMap := map[shard.BLSPublicKey]struct{}{}
for _, key := range blsKeys {
blsKeyMap[key] = struct{}{}
}
for _, addr := range addrs {
if !bytes.Equal(validator.Bytes(), addr.Bytes()) {
wrapper, err := state.ValidatorWrapperCopy(addr)
if err != nil {
return err
}
if checkIdentity && wrapper.Identity == identity {
return errors.Wrapf(errDupIdentity, "duplicate identity %s", identity)
}
if checkBlsKeys {
for _, existingKey := range wrapper.SlotPubKeys {
if _, ok := blsKeyMap[existingKey]; ok {
return errors.Wrapf(errDupBlsKey, "duplicate bls key %x", existingKey)
}
}
}
}
}
return nil
}
// TODO: add unit tests to check staking msg verification // TODO: add unit tests to check staking msg verification
// VerifyAndCreateValidatorFromMsg verifies the create validator message using // VerifyAndCreateValidatorFromMsg verifies the create validator message using
@ -31,12 +71,14 @@ var (
// //
// Note that this function never updates the stateDB, it only reads from stateDB. // Note that this function never updates the stateDB, it only reads from stateDB.
func VerifyAndCreateValidatorFromMsg( func VerifyAndCreateValidatorFromMsg(
stateDB vm.StateDB, epoch *big.Int, blockNum *big.Int, msg *staking.CreateValidator, stateDB vm.StateDB, chainContext ChainContext, epoch *big.Int, blockNum *big.Int, msg *staking.CreateValidator,
) (*staking.ValidatorWrapper, error) { ) (*staking.ValidatorWrapper, error) {
if stateDB == nil { if stateDB == nil {
return nil, errStateDBIsMissing return nil, errStateDBIsMissing
} }
if chainContext == nil {
return nil, errChainContextMissing
}
if epoch == nil { if epoch == nil {
return nil, errEpochMissing return nil, errEpochMissing
} }
@ -51,6 +93,13 @@ func VerifyAndCreateValidatorFromMsg(
errValidatorExist, common2.MustAddressToBech32(msg.ValidatorAddress), errValidatorExist, common2.MustAddressToBech32(msg.ValidatorAddress),
) )
} }
if err := checkDuplicateFields(
chainContext, stateDB,
msg.ValidatorAddress,
msg.Identity,
msg.SlotPubKeys); err != nil {
return nil, err
}
if !CanTransfer(stateDB, msg.ValidatorAddress, msg.Amount) { if !CanTransfer(stateDB, msg.ValidatorAddress, msg.Amount) {
return nil, errInsufficientBalanceForStake return nil, errInsufficientBalanceForStake
} }
@ -82,7 +131,6 @@ func VerifyAndEditValidatorFromMsg(
stateDB vm.StateDB, chainContext ChainContext, stateDB vm.StateDB, chainContext ChainContext,
epoch, blockNum *big.Int, msg *staking.EditValidator, epoch, blockNum *big.Int, msg *staking.EditValidator,
) (*staking.ValidatorWrapper, error) { ) (*staking.ValidatorWrapper, error) {
if stateDB == nil { if stateDB == nil {
return nil, errStateDBIsMissing return nil, errStateDBIsMissing
} }
@ -95,6 +143,17 @@ func VerifyAndEditValidatorFromMsg(
if !stateDB.IsValidator(msg.ValidatorAddress) { if !stateDB.IsValidator(msg.ValidatorAddress) {
return nil, errValidatorNotExist return nil, errValidatorNotExist
} }
newBlsKeys := []shard.BLSPublicKey{}
if msg.SlotKeyToAdd != nil {
newBlsKeys = append(newBlsKeys, *msg.SlotKeyToAdd)
}
if err := checkDuplicateFields(
chainContext, stateDB,
msg.ValidatorAddress,
msg.Identity,
newBlsKeys); err != nil {
return nil, err
}
wrapper, err := stateDB.ValidatorWrapperCopy(msg.ValidatorAddress) wrapper, err := stateDB.ValidatorWrapperCopy(msg.ValidatorAddress)
if err != nil { if err != nil {
return nil, err return nil, err

@ -6,11 +6,17 @@ import (
"testing" "testing"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/bls/ffi/go/bls"
blockfactory "github.com/harmony-one/harmony/block/factory"
"github.com/harmony-one/harmony/core/state" "github.com/harmony-one/harmony/core/state"
"github.com/harmony-one/harmony/core/vm"
"github.com/harmony-one/harmony/crypto/hash" "github.com/harmony-one/harmony/crypto/hash"
chain2 "github.com/harmony-one/harmony/internal/chain"
common2 "github.com/harmony-one/harmony/internal/common" common2 "github.com/harmony-one/harmony/internal/common"
"github.com/harmony-one/harmony/internal/params"
"github.com/harmony-one/harmony/numeric" "github.com/harmony-one/harmony/numeric"
"github.com/harmony-one/harmony/shard" "github.com/harmony-one/harmony/shard"
staking "github.com/harmony-one/harmony/staking/types" staking "github.com/harmony-one/harmony/staking/types"
@ -23,6 +29,25 @@ var (
twelveK = new(big.Int).Mul(big.NewInt(12000), big.NewInt(1e18)) twelveK = new(big.Int).Mul(big.NewInt(12000), big.NewInt(1e18))
) )
func createChain(database *ethdb.MemDatabase) *BlockChain {
key, _ := crypto.GenerateKey()
gspec := Genesis{
Config: params.TestChainConfig,
Factory: blockfactory.ForTest,
Alloc: GenesisAlloc{
crypto.PubkeyToAddress(key.PublicKey): {
Balance: big.NewInt(8e18),
},
},
GasLimit: 1e18,
ShardID: 0,
}
genesis := gspec.MustCommit(database)
_ = genesis
chain, _ := NewBlockChain(database, nil, gspec.Config, chain2.Engine, vm.Config{}, nil)
return chain
}
func generateBLSKeySigPair() (shard.BLSPublicKey, shard.BLSSignature) { func generateBLSKeySigPair() (shard.BLSPublicKey, shard.BLSSignature) {
p := &bls.PublicKey{} p := &bls.PublicKey{}
p.DeserializeHexStr(testBLSPubKey) p.DeserializeHexStr(testBLSPubKey)
@ -75,11 +100,13 @@ func createValidator() *staking.CreateValidator {
// Test CV1: create validator // Test CV1: create validator
func TestCV1(t *testing.T) { func TestCV1(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err != nil { ); err != nil {
t.Error("expected", nil, "got", err) t.Error("expected", nil, "got", err)
} }
@ -87,18 +114,20 @@ func TestCV1(t *testing.T) {
// Test CV3: validator already exists // Test CV3: validator already exists
func TestCV3(t *testing.T) { func TestCV3(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err != nil { ); err != nil {
t.Error("expected", nil, "got", err) t.Error("expected", nil, "got", err)
} }
statedb.SetValidatorFlag(msg.ValidatorAddress) statedb.SetValidatorFlag(msg.ValidatorAddress)
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); !strings.Contains(err.Error(), errValidatorExist.Error()) { ); !strings.Contains(err.Error(), errValidatorExist.Error()) {
t.Error("expected", errValidatorExist, "got", err) t.Error("expected", errValidatorExist, "got", err)
} }
@ -106,13 +135,15 @@ func TestCV3(t *testing.T) {
// Test CV9: name == 140 characters // Test CV9: name == 140 characters
func TestCV9(t *testing.T) { func TestCV9(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
// name length: 140 characters // name length: 140 characters
msg.Name = "Helloiwfhwifbwfbcerghveugbviuscbhwiefbcusidbcifwefhgciwefherhbfiwuehfciwiuebfcuyiewfhwieufwiweifhcwefhwefhwidsffevjnononwondqmeofniowfndjowe" msg.Name = "Helloiwfhwifbwfbcerghveugbviuscbhwiefbcusidbcifwefhgciwefherhbfiwuehfciwiuebfcuyiewfhwieufwiweifhcwefhwefhwidsffevjnononwondqmeofniowfndjowe"
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err != nil { ); err != nil {
t.Error("expected", nil, "got", err) t.Error("expected", nil, "got", err)
} }
@ -120,13 +151,15 @@ func TestCV9(t *testing.T) {
// Test CV10: identity == 140 characters // Test CV10: identity == 140 characters
func TestCV10(t *testing.T) { func TestCV10(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
// identity length: 140 characters // identity length: 140 characters
msg.Identity = "Helloiwfhwifbwfbcerghveugbviuscbhwiefbcusidbcifwefhgciwefherhbfiwuehfciwiuebfcuyiewfhwieufwiweifhcwefhwefhwidsffevjnononwondqmeofniowfndjowe" msg.Identity = "Helloiwfhwifbwfbcerghveugbviuscbhwiefbcusidbcifwefhgciwefherhbfiwuehfciwiuebfcuyiewfhwieufwiweifhcwefhwefhwidsffevjnononwondqmeofniowfndjowe"
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err != nil { ); err != nil {
t.Error("expected", nil, "got", err) t.Error("expected", nil, "got", err)
} }
@ -134,13 +167,15 @@ func TestCV10(t *testing.T) {
// Test CV11: website == 140 characters // Test CV11: website == 140 characters
func TestCV11(t *testing.T) { func TestCV11(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
// website length: 140 characters // website length: 140 characters
msg.Website = "Helloiwfhwifbwfbcerghveugbviuscbhwiefbcusidbcifwefhgciwefherhbfiwuehfciwiuebfcuyiewfhwieufwiweifhcwefhwefhwidsffevjnononwondqmeofniowfndjowe" msg.Website = "Helloiwfhwifbwfbcerghveugbviuscbhwiefbcusidbcifwefhgciwefherhbfiwuehfciwiuebfcuyiewfhwieufwiweifhcwefhwefhwidsffevjnononwondqmeofniowfndjowe"
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err != nil { ); err != nil {
t.Error("expected", nil, "got", err) t.Error("expected", nil, "got", err)
} }
@ -148,13 +183,15 @@ func TestCV11(t *testing.T) {
// Test CV12: security == 140 characters // Test CV12: security == 140 characters
func TestCV12(t *testing.T) { func TestCV12(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
// security contact length: 140 characters // security contact length: 140 characters
msg.SecurityContact = "Helloiwfhwifbwfbcerghveugbviuscbhwiefbcusidbcifwefhgciwefherhbfiwuehfciwiuebfcuyiewfhwieufwiweifhcwefhwefhwidsffevjnononwondqmeofniowfndjowe" msg.SecurityContact = "Helloiwfhwifbwfbcerghveugbviuscbhwiefbcusidbcifwefhgciwefherhbfiwuehfciwiuebfcuyiewfhwieufwiweifhcwefhwefhwidsffevjnononwondqmeofniowfndjowe"
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err != nil { ); err != nil {
t.Error("expected", nil, "got", err) t.Error("expected", nil, "got", err)
} }
@ -162,13 +199,15 @@ func TestCV12(t *testing.T) {
// Test CV13: details == 280 characters // Test CV13: details == 280 characters
func TestCV13(t *testing.T) { func TestCV13(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
// details length: 280 characters // details length: 280 characters
msg.Details = "HelloiwfhwifbwfbcerghveugbviuscbhwiefbcusidbcifwefhgciwefherhbfiwuehfciwiuebfcuyiewfhwieufwiweifhcwefhwefhwidsffevjnononwondqmeofniowfndjoweHlloiwfhwifbwfbcerghveugbviuscbhwiefbcusidbcifwefhgciwefherhbfiwuehfciwiuedbfcuyiewfhwieufwiweifhcwefhwefhwidsffevjnononwondqmeofniowfndjowe" msg.Details = "HelloiwfhwifbwfbcerghveugbviuscbhwiefbcusidbcifwefhgciwefherhbfiwuehfciwiuebfcuyiewfhwieufwiweifhcwefhwefhwidsffevjnononwondqmeofniowfndjoweHlloiwfhwifbwfbcerghveugbviuscbhwiefbcusidbcifwefhgciwefherhbfiwuehfciwiuedbfcuyiewfhwieufwiweifhcwefhwefhwidsffevjnononwondqmeofniowfndjowe"
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err != nil { ); err != nil {
t.Error("expected", nil, "got", err) t.Error("expected", nil, "got", err)
} }
@ -176,14 +215,16 @@ func TestCV13(t *testing.T) {
// Test CV14: commission rate <= max rate & max change rate <= max rate // Test CV14: commission rate <= max rate & max change rate <= max rate
func TestCV14(t *testing.T) { func TestCV14(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
// commission rate == max rate && max change rate == max rate // commission rate == max rate && max change rate == max rate
msg.CommissionRates.Rate, _ = numeric.NewDecFromStr("0.5") msg.CommissionRates.Rate, _ = numeric.NewDecFromStr("0.5")
msg.CommissionRates.MaxChangeRate, _ = numeric.NewDecFromStr("0.5") msg.CommissionRates.MaxChangeRate, _ = numeric.NewDecFromStr("0.5")
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err != nil { ); err != nil {
t.Error("expected", nil, "got", err) t.Error("expected", nil, "got", err)
} }
@ -191,13 +232,15 @@ func TestCV14(t *testing.T) {
// Test CV15: commission rate > max rate // Test CV15: commission rate > max rate
func TestCV15(t *testing.T) { func TestCV15(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
// commission rate: 0.6 > max rate: 0.5 // commission rate: 0.6 > max rate: 0.5
msg.CommissionRates.Rate, _ = numeric.NewDecFromStr("0.6") msg.CommissionRates.Rate, _ = numeric.NewDecFromStr("0.6")
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err == nil { ); err == nil {
t.Error("expected", "commission rate and change rate can not be larger than max commission rate", "got", nil) t.Error("expected", "commission rate and change rate can not be larger than max commission rate", "got", nil)
} }
@ -205,13 +248,15 @@ func TestCV15(t *testing.T) {
// Test CV16: max change rate > max rate // Test CV16: max change rate > max rate
func TestCV16(t *testing.T) { func TestCV16(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
// max change rate: 0.6 > max rate: 0.5 // max change rate: 0.6 > max rate: 0.5
msg.CommissionRates.MaxChangeRate, _ = numeric.NewDecFromStr("0.6") msg.CommissionRates.MaxChangeRate, _ = numeric.NewDecFromStr("0.6")
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err == nil { ); err == nil {
t.Error("expected", "commission rate and change rate can not be larger than max commission rate", "got", nil) t.Error("expected", "commission rate and change rate can not be larger than max commission rate", "got", nil)
} }
@ -219,13 +264,15 @@ func TestCV16(t *testing.T) {
// Test CV17: max rate == 1 // Test CV17: max rate == 1
func TestCV17(t *testing.T) { func TestCV17(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
// max rate == 1 // max rate == 1
msg.CommissionRates.MaxRate, _ = numeric.NewDecFromStr("1") msg.CommissionRates.MaxRate, _ = numeric.NewDecFromStr("1")
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err != nil { ); err != nil {
t.Error("expected", nil, "got", err) t.Error("expected", nil, "got", err)
} }
@ -233,7 +280,9 @@ func TestCV17(t *testing.T) {
// Test CV18: max rate == 1 && max change rate == 1 && commission rate == 0 // Test CV18: max rate == 1 && max change rate == 1 && commission rate == 0
func TestCV18(t *testing.T) { func TestCV18(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
// max rate == 1 && max change rate == 1 && commission rate == 0 // max rate == 1 && max change rate == 1 && commission rate == 0
@ -241,7 +290,7 @@ func TestCV18(t *testing.T) {
msg.CommissionRates.MaxChangeRate, _ = numeric.NewDecFromStr("1") msg.CommissionRates.MaxChangeRate, _ = numeric.NewDecFromStr("1")
msg.CommissionRates.Rate, _ = numeric.NewDecFromStr("1") msg.CommissionRates.Rate, _ = numeric.NewDecFromStr("1")
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err != nil { ); err != nil {
t.Error("expected", nil, "got", err) t.Error("expected", nil, "got", err)
} }
@ -249,13 +298,15 @@ func TestCV18(t *testing.T) {
// Test CV19: commission rate == 0 // Test CV19: commission rate == 0
func TestCV19(t *testing.T) { func TestCV19(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
// commission rate == 0 // commission rate == 0
msg.CommissionRates.Rate, _ = numeric.NewDecFromStr("0") msg.CommissionRates.Rate, _ = numeric.NewDecFromStr("0")
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err != nil { ); err != nil {
t.Error("expected", nil, "got", err) t.Error("expected", nil, "got", err)
} }
@ -263,13 +314,15 @@ func TestCV19(t *testing.T) {
// Test CV20: max change rate == 0 // Test CV20: max change rate == 0
func TestCV20(t *testing.T) { func TestCV20(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
// commission rate == 0 // commission rate == 0
msg.CommissionRates.MaxChangeRate, _ = numeric.NewDecFromStr("0") msg.CommissionRates.MaxChangeRate, _ = numeric.NewDecFromStr("0")
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err != nil { ); err != nil {
t.Error("expected", nil, "got", err) t.Error("expected", nil, "got", err)
} }
@ -277,7 +330,9 @@ func TestCV20(t *testing.T) {
// Test CV21: max change rate == 0 & max rate == 0 & commission rate == 0 // Test CV21: max change rate == 0 & max rate == 0 & commission rate == 0
func TestCV21(t *testing.T) { func TestCV21(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
// max change rate == 0 & max rate == 0 & commission rate == 0 // max change rate == 0 & max rate == 0 & commission rate == 0
@ -285,7 +340,7 @@ func TestCV21(t *testing.T) {
msg.CommissionRates.MaxChangeRate, _ = numeric.NewDecFromStr("0") msg.CommissionRates.MaxChangeRate, _ = numeric.NewDecFromStr("0")
msg.CommissionRates.Rate, _ = numeric.NewDecFromStr("0") msg.CommissionRates.Rate, _ = numeric.NewDecFromStr("0")
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err != nil { ); err != nil {
t.Error("expected", nil, "got", err) t.Error("expected", nil, "got", err)
} }
@ -293,14 +348,16 @@ func TestCV21(t *testing.T) {
// Test CV22: max change rate == 1 & max rate == 1 // Test CV22: max change rate == 1 & max rate == 1
func TestCV22(t *testing.T) { func TestCV22(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
// max change rate == 1 & max rate == 1 // max change rate == 1 & max rate == 1
msg.CommissionRates.MaxRate, _ = numeric.NewDecFromStr("1") msg.CommissionRates.MaxRate, _ = numeric.NewDecFromStr("1")
msg.CommissionRates.MaxChangeRate, _ = numeric.NewDecFromStr("1") msg.CommissionRates.MaxChangeRate, _ = numeric.NewDecFromStr("1")
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err != nil { ); err != nil {
t.Error("expected", nil, "got", err) t.Error("expected", nil, "got", err)
} }
@ -308,13 +365,15 @@ func TestCV22(t *testing.T) {
// Test CV23: commission rate < 0 // Test CV23: commission rate < 0
func TestCV23(t *testing.T) { func TestCV23(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
// commission rate < 0 // commission rate < 0
msg.CommissionRates.Rate, _ = numeric.NewDecFromStr("-0.1") msg.CommissionRates.Rate, _ = numeric.NewDecFromStr("-0.1")
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err == nil { ); err == nil {
t.Error("expected", "rate:-0.100000000000000000: commission rate, change rate and max rate should be within 0-100 percent", "got", nil) t.Error("expected", "rate:-0.100000000000000000: commission rate, change rate and max rate should be within 0-100 percent", "got", nil)
} }
@ -322,13 +381,15 @@ func TestCV23(t *testing.T) {
// Test CV24: max rate < 0 // Test CV24: max rate < 0
func TestCV24(t *testing.T) { func TestCV24(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
// max rate < 0 // max rate < 0
msg.CommissionRates.MaxRate, _ = numeric.NewDecFromStr("-0.001") msg.CommissionRates.MaxRate, _ = numeric.NewDecFromStr("-0.001")
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err == nil { ); err == nil {
t.Error("expected", "rate:-0.001000000000000000: commission rate, change rate and max rate should be within 0-100 percent", "got", nil) t.Error("expected", "rate:-0.001000000000000000: commission rate, change rate and max rate should be within 0-100 percent", "got", nil)
} }
@ -336,13 +397,15 @@ func TestCV24(t *testing.T) {
// Test CV25: max change rate < 0 // Test CV25: max change rate < 0
func TestCV25(t *testing.T) { func TestCV25(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
// max rate < 0 // max rate < 0
msg.CommissionRates.MaxChangeRate, _ = numeric.NewDecFromStr("-0.001") msg.CommissionRates.MaxChangeRate, _ = numeric.NewDecFromStr("-0.001")
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err == nil { ); err == nil {
t.Error("expected", "rate:-0.001000000000000000: commission rate, change rate and max rate should be within 0-100 percent", "got", nil) t.Error("expected", "rate:-0.001000000000000000: commission rate, change rate and max rate should be within 0-100 percent", "got", nil)
} }
@ -350,13 +413,15 @@ func TestCV25(t *testing.T) {
// Test CV26: commission rate > 1 // Test CV26: commission rate > 1
func TestCV26(t *testing.T) { func TestCV26(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
// commission rate > 1 // commission rate > 1
msg.CommissionRates.Rate, _ = numeric.NewDecFromStr("1.01") msg.CommissionRates.Rate, _ = numeric.NewDecFromStr("1.01")
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err == nil { ); err == nil {
t.Error("expected", "rate:1.01000000000000000: commission rate, change rate and max rate should be within 0-100 percent", "got", nil) t.Error("expected", "rate:1.01000000000000000: commission rate, change rate and max rate should be within 0-100 percent", "got", nil)
} }
@ -364,13 +429,15 @@ func TestCV26(t *testing.T) {
// Test CV27: max rate > 1 // Test CV27: max rate > 1
func TestCV27(t *testing.T) { func TestCV27(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
// max rate > 1 // max rate > 1
msg.CommissionRates.MaxRate, _ = numeric.NewDecFromStr("1.01") msg.CommissionRates.MaxRate, _ = numeric.NewDecFromStr("1.01")
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err == nil { ); err == nil {
t.Error("expected", "rate:1.01000000000000000: commission rate, change rate and max rate should be within 0-100 percent", "got", nil) t.Error("expected", "rate:1.01000000000000000: commission rate, change rate and max rate should be within 0-100 percent", "got", nil)
} }
@ -378,13 +445,15 @@ func TestCV27(t *testing.T) {
// Test CV28: max change rate > 1 // Test CV28: max change rate > 1
func TestCV28(t *testing.T) { func TestCV28(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
// max change rate > 1 // max change rate > 1
msg.CommissionRates.MaxChangeRate, _ = numeric.NewDecFromStr("1.01") msg.CommissionRates.MaxChangeRate, _ = numeric.NewDecFromStr("1.01")
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err == nil { ); err == nil {
t.Error("expected", "rate:1.01000000000000000: commission rate, change rate and max rate should be within 0-100 percent", "got", nil) t.Error("expected", "rate:1.01000000000000000: commission rate, change rate and max rate should be within 0-100 percent", "got", nil)
} }
@ -392,14 +461,16 @@ func TestCV28(t *testing.T) {
// Test CV29: amount > MinSelfDelegation // Test CV29: amount > MinSelfDelegation
func TestCV29(t *testing.T) { func TestCV29(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, twelveK) statedb.AddBalance(msg.ValidatorAddress, twelveK)
// amount > MinSelfDelegation // amount > MinSelfDelegation
msg.Amount = twelveK msg.Amount = twelveK
msg.MinSelfDelegation = tenK msg.MinSelfDelegation = tenK
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err != nil { ); err != nil {
t.Error("expected", nil, "got", err) t.Error("expected", nil, "got", err)
} }
@ -407,14 +478,16 @@ func TestCV29(t *testing.T) {
// Test CV30: amount == MinSelfDelegation // Test CV30: amount == MinSelfDelegation
func TestCV30(t *testing.T) { func TestCV30(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
// amount > MinSelfDelegation // amount > MinSelfDelegation
msg.Amount = tenK msg.Amount = tenK
msg.MinSelfDelegation = tenK msg.MinSelfDelegation = tenK
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err != nil { ); err != nil {
t.Error("expected", nil, "got", err) t.Error("expected", nil, "got", err)
} }
@ -422,14 +495,16 @@ func TestCV30(t *testing.T) {
// Test CV31: amount < MinSelfDelegation // Test CV31: amount < MinSelfDelegation
func TestCV31(t *testing.T) { func TestCV31(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
// amount > MinSelfDelegation // amount > MinSelfDelegation
msg.Amount = twelveK msg.Amount = twelveK
msg.MinSelfDelegation = tenK msg.MinSelfDelegation = tenK
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err == nil { ); err == nil {
t.Error("expected", "min_self_delegation 5000000000000000000, after delegation amount 4000000000000000000: self delegation can not be less than min_self_delegation", "got", nil) t.Error("expected", "min_self_delegation 5000000000000000000, after delegation amount 4000000000000000000: self delegation can not be less than min_self_delegation", "got", nil)
} }
@ -437,14 +512,16 @@ func TestCV31(t *testing.T) {
// Test CV32: MaxTotalDelegation < MinSelfDelegation // Test CV32: MaxTotalDelegation < MinSelfDelegation
func TestCV32(t *testing.T) { func TestCV32(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
// MaxTotalDelegation < MinSelfDelegation // MaxTotalDelegation < MinSelfDelegation
msg.MaxTotalDelegation = tenK msg.MaxTotalDelegation = tenK
msg.MinSelfDelegation = twelveK msg.MinSelfDelegation = twelveK
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err == nil { ); err == nil {
t.Error("expected", "max_total_delegation can not be less than min_self_delegation", "got", nil) t.Error("expected", "max_total_delegation can not be less than min_self_delegation", "got", nil)
} }
@ -452,13 +529,15 @@ func TestCV32(t *testing.T) {
// Test CV33: MinSelfDelegation < 1 ONE // Test CV33: MinSelfDelegation < 1 ONE
func TestCV33(t *testing.T) { func TestCV33(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
// MinSelfDelegation < 10,000 ONE // MinSelfDelegation < 10,000 ONE
msg.MinSelfDelegation = big.NewInt(1e18) msg.MinSelfDelegation = big.NewInt(1e18)
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err == nil { ); err == nil {
t.Error("expected", "delegation-given 1000000000000000000: min_self_delegation has to be greater than 10,000 ONE", "got", nil) t.Error("expected", "delegation-given 1000000000000000000: min_self_delegation has to be greater than 10,000 ONE", "got", nil)
} }
@ -466,13 +545,15 @@ func TestCV33(t *testing.T) {
// Test CV34: MinSelfDelegation not specified // Test CV34: MinSelfDelegation not specified
func TestCV34(t *testing.T) { func TestCV34(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
// MinSelfDelegation not specified // MinSelfDelegation not specified
msg.MinSelfDelegation = nil msg.MinSelfDelegation = nil
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err == nil { ); err == nil {
t.Error("expected", "MinSelfDelegation can not be nil", "got", nil) t.Error("expected", "MinSelfDelegation can not be nil", "got", nil)
} }
@ -480,13 +561,15 @@ func TestCV34(t *testing.T) {
// Test CV35: MinSelfDelegation < 0 // Test CV35: MinSelfDelegation < 0
func TestCV35(t *testing.T) { func TestCV35(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
// MinSelfDelegation < 0 // MinSelfDelegation < 0
msg.MinSelfDelegation = big.NewInt(-1) msg.MinSelfDelegation = big.NewInt(-1)
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err == nil { ); err == nil {
t.Error("expected", "delegation-given -1: min_self_delegation has to be greater than 1 ONE", "got", nil) t.Error("expected", "delegation-given -1: min_self_delegation has to be greater than 1 ONE", "got", nil)
} }
@ -494,14 +577,16 @@ func TestCV35(t *testing.T) {
// Test CV36: amount > MaxTotalDelegation // Test CV36: amount > MaxTotalDelegation
func TestCV36(t *testing.T) { func TestCV36(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
// amount > MaxTotalDelegation // amount > MaxTotalDelegation
msg.Amount = big.NewInt(4e18) msg.Amount = big.NewInt(4e18)
msg.MaxTotalDelegation = big.NewInt(3e18) msg.MaxTotalDelegation = big.NewInt(3e18)
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err == nil { ); err == nil {
t.Error("expected", "total delegation can not be bigger than max_total_delegation", "got", nil) t.Error("expected", "total delegation can not be bigger than max_total_delegation", "got", nil)
} }
@ -509,13 +594,15 @@ func TestCV36(t *testing.T) {
// Test CV39: MaxTotalDelegation < 0 // Test CV39: MaxTotalDelegation < 0
func TestCV39(t *testing.T) { func TestCV39(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) database := ethdb.NewMemDatabase()
statedb, _ := state.New(common.Hash{}, state.NewDatabase(database))
chain := createChain(database)
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK) statedb.AddBalance(msg.ValidatorAddress, tenK)
// MaxTotalDelegation < 0 // MaxTotalDelegation < 0
msg.MaxTotalDelegation = big.NewInt(-1) msg.MaxTotalDelegation = big.NewInt(-1)
if _, err := VerifyAndCreateValidatorFromMsg( if _, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, chain, postStakingEpoch, big.NewInt(0), msg,
); err == nil { ); err == nil {
t.Error("expected", "max_total_delegation can not be less than min_self_delegation", "got", nil) t.Error("expected", "max_total_delegation can not be less than min_self_delegation", "got", nil)
} }

@ -17,12 +17,9 @@
package core package core
import ( import (
"bytes"
"math" "math"
"math/big" "math/big"
"github.com/harmony-one/harmony/shard"
staking2 "github.com/harmony-one/harmony/staking" staking2 "github.com/harmony-one/harmony/staking"
"github.com/harmony-one/harmony/staking/network" "github.com/harmony-one/harmony/staking/network"
@ -389,54 +386,11 @@ func (st *StateTransition) StakingTransitionDb() (usedGas uint64, err error) {
return st.gasUsed(), err return st.gasUsed(), err
} }
func (st *StateTransition) checkDuplicateFields(validator common.Address, identity string, blsKeys []shard.BLSPublicKey) error {
addrs, err := st.bc.ReadValidatorList()
if err != nil {
return err
}
checkIdentity := identity != ""
checkBlsKeys := len(blsKeys) != 0
blsKeyMap := map[shard.BLSPublicKey]struct{}{}
for _, key := range blsKeys {
blsKeyMap[key] = struct{}{}
}
for _, addr := range addrs {
if !bytes.Equal(validator.Bytes(), addr.Bytes()) {
wrapper, err := st.state.ValidatorWrapperCopy(addr)
if err != nil {
return err
}
if checkIdentity && wrapper.Identity == identity {
return errors.Wrapf(errDupIdentity, "duplicate identity %s", identity)
}
if checkBlsKeys {
for _, existingKey := range wrapper.SlotPubKeys {
if _, ok := blsKeyMap[existingKey]; ok {
return errors.Wrapf(errDupBlsKey, "duplicate bls key %x", existingKey)
}
}
}
}
}
return nil
}
func (st *StateTransition) verifyAndApplyCreateValidatorTx( func (st *StateTransition) verifyAndApplyCreateValidatorTx(
createValidator *staking.CreateValidator, blockNum *big.Int, createValidator *staking.CreateValidator, blockNum *big.Int,
) error { ) error {
if err := st.checkDuplicateFields(
createValidator.ValidatorAddress,
createValidator.Identity,
createValidator.SlotPubKeys); err != nil {
return err
}
wrapper, err := VerifyAndCreateValidatorFromMsg( wrapper, err := VerifyAndCreateValidatorFromMsg(
st.state, st.evm.EpochNumber, blockNum, createValidator, st.state, st.bc, st.evm.EpochNumber, blockNum, createValidator,
) )
if err != nil { if err != nil {
return err return err
@ -452,16 +406,6 @@ func (st *StateTransition) verifyAndApplyCreateValidatorTx(
func (st *StateTransition) verifyAndApplyEditValidatorTx( func (st *StateTransition) verifyAndApplyEditValidatorTx(
editValidator *staking.EditValidator, blockNum *big.Int, editValidator *staking.EditValidator, blockNum *big.Int,
) error { ) error {
newBlsKeys := []shard.BLSPublicKey{}
if editValidator.SlotKeyToAdd != nil {
newBlsKeys = append(newBlsKeys, *editValidator.SlotKeyToAdd)
}
if err := st.checkDuplicateFields(
editValidator.ValidatorAddress,
editValidator.Identity,
newBlsKeys); err != nil {
return err
}
wrapper, err := VerifyAndEditValidatorFromMsg( wrapper, err := VerifyAndEditValidatorFromMsg(
st.state, st.bc, st.evm.EpochNumber, blockNum, editValidator, st.state, st.bc, st.evm.EpochNumber, blockNum, editValidator,
) )

@ -762,8 +762,11 @@ func (pool *TxPool) validateStakingTx(tx *staking.StakingTransaction) error {
if shard.Schedule.IsLastBlock(currentBlockNumber.Uint64()) { if shard.Schedule.IsLastBlock(currentBlockNumber.Uint64()) {
pendingEpoch = new(big.Int).Add(pendingEpoch, big.NewInt(1)) pendingEpoch = new(big.Int).Add(pendingEpoch, big.NewInt(1))
} }
chainContext, ok := pool.chain.(ChainContext)
_, err = VerifyAndCreateValidatorFromMsg(pool.currentState, pendingEpoch, pendingBlockNumber, stkMsg) if !ok {
chainContext = nil // might use testing blockchain, set to nil for verifier to handle.
}
_, err = VerifyAndCreateValidatorFromMsg(pool.currentState, chainContext, pendingEpoch, pendingBlockNumber, stkMsg)
return err return err
case staking.DirectiveEditValidator: case staking.DirectiveEditValidator:
msg, err := staking.RLPDecodeStakeMsg(tx.Data(), staking.DirectiveEditValidator) msg, err := staking.RLPDecodeStakeMsg(tx.Data(), staking.DirectiveEditValidator)

@ -35,7 +35,9 @@ import (
"github.com/harmony-one/harmony/common/denominations" "github.com/harmony-one/harmony/common/denominations"
"github.com/harmony-one/harmony/core/state" "github.com/harmony-one/harmony/core/state"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/core/vm"
"github.com/harmony-one/harmony/crypto/hash" "github.com/harmony-one/harmony/crypto/hash"
chain2 "github.com/harmony-one/harmony/internal/chain"
"github.com/harmony-one/harmony/internal/params" "github.com/harmony-one/harmony/internal/params"
"github.com/harmony-one/harmony/numeric" "github.com/harmony-one/harmony/numeric"
"github.com/harmony-one/harmony/shard" "github.com/harmony-one/harmony/shard"
@ -136,6 +138,26 @@ func pricedTransaction(shardID uint32, nonce uint64, gaslimit uint64, gasprice *
return signedTx return signedTx
} }
func createBlockChain() *BlockChain {
key, _ := crypto.GenerateKey()
gspec := Genesis{
Config: params.TestChainConfig,
Factory: blockfactory.ForTest,
Alloc: GenesisAlloc{
crypto.PubkeyToAddress(key.PublicKey): {
Balance: big.NewInt(8e18),
},
},
GasLimit: 1e18,
ShardID: 0,
}
database := ethdb.NewMemDatabase()
genesis := gspec.MustCommit(database)
_ = genesis
blockchain, _ := NewBlockChain(database, nil, gspec.Config, chain2.Engine, vm.Config{}, nil)
return blockchain
}
func setupTxPool() (*TxPool, *ecdsa.PrivateKey) { func setupTxPool() (*TxPool, *ecdsa.PrivateKey) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
blockchain := &testBlockChain{statedb, 1e18, new(event.Feed)} blockchain := &testBlockChain{statedb, 1e18, new(event.Feed)}
@ -301,6 +323,7 @@ func TestCreateValidatorTransaction(t *testing.T) {
t.Parallel() t.Parallel()
pool, _ := setupTxPool() pool, _ := setupTxPool()
pool.chain = createBlockChain()
defer pool.Stop() defer pool.Stop()
fromKey, _ := crypto.GenerateKey() fromKey, _ := crypto.GenerateKey()
@ -328,6 +351,7 @@ func TestMixedTransactions(t *testing.T) {
t.Parallel() t.Parallel()
pool, _ := setupTxPool() pool, _ := setupTxPool()
pool.chain = createBlockChain()
defer pool.Stop() defer pool.Stop()
fromKey, _ := crypto.GenerateKey() fromKey, _ := crypto.GenerateKey()

@ -6,14 +6,19 @@ import (
"math/rand" "math/rand"
"time" "time"
blockfactory "github.com/harmony-one/harmony/block/factory"
"github.com/harmony-one/harmony/internal/params"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
common2 "github.com/ethereum/go-ethereum/common" common2 "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core"
"github.com/harmony-one/harmony/core/state" "github.com/harmony-one/harmony/core/state"
"github.com/harmony-one/harmony/core/vm"
"github.com/harmony-one/harmony/crypto/hash" "github.com/harmony-one/harmony/crypto/hash"
"github.com/harmony-one/harmony/internal/chain"
"github.com/harmony-one/harmony/internal/common" "github.com/harmony-one/harmony/internal/common"
"github.com/harmony-one/harmony/numeric" "github.com/harmony-one/harmony/numeric"
"github.com/harmony-one/harmony/shard" "github.com/harmony-one/harmony/shard"
@ -83,11 +88,27 @@ func createValidator() *staking.CreateValidator {
} }
func main() { func main() {
key, _ := crypto.GenerateKey()
gspec := core.Genesis{
Config: params.TestChainConfig,
Factory: blockfactory.ForTest,
Alloc: core.GenesisAlloc{
crypto.PubkeyToAddress(key.PublicKey): {
Balance: big.NewInt(8000000000000000000),
},
},
GasLimit: 1e18,
ShardID: 0,
}
database := ethdb.NewMemDatabase()
genesis := gspec.MustCommit(database)
_ = genesis
bc, _ := core.NewBlockChain(database, nil, gspec.Config, chain.Engine, vm.Config{}, nil)
statedb, _ := state.New(common2.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) statedb, _ := state.New(common2.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
msg := createValidator() msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, new(big.Int).Mul(big.NewInt(5e18), big.NewInt(2000))) statedb.AddBalance(msg.ValidatorAddress, new(big.Int).Mul(big.NewInt(5e18), big.NewInt(2000)))
validator, err := core.VerifyAndCreateValidatorFromMsg( validator, err := core.VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg, statedb, bc, postStakingEpoch, big.NewInt(0), msg,
) )
if err != nil { if err != nil {
fmt.Print(err) fmt.Print(err)

Loading…
Cancel
Save