Skip to content

Commit

Permalink
Merge pull request #2934 from 0chain/feature/ct-auth-crash-and-reward
Browse files Browse the repository at this point in the history
Conductor test - authorizer node recovery
  • Loading branch information
dabasov committed Nov 10, 2023
2 parents b5f04c9 + 9d7d898 commit 406f9cd
Show file tree
Hide file tree
Showing 18 changed files with 198 additions and 406 deletions.
3 changes: 3 additions & 0 deletions code/go/0chain.net/conductor/conductor/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,9 @@ func (r *Runner) ConfigureTestCase(configurator cases.TestCaseConfigurator) erro
case *cases.RoundHasFinalized:
state.RoundHasFinalizedConfig = cfg

case *cases.RoundRandomSeed:
state.RoundRandomSeed = cfg

default:
log.Panicf("unknown test case name: %s", configurator.Name())
}
Expand Down
1 change: 1 addition & 0 deletions code/go/0chain.net/conductor/conductrpc/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ type State struct {
FBRequestor *cases.FBRequestor
MissingLFBTicket *cases.MissingLFBTickets
RoundHasFinalizedConfig *cases.RoundHasFinalized
RoundRandomSeed *cases.RoundRandomSeed

LockNotarizationAndSendNextRoundVRF *config.LockNotarizationAndSendNextRoundVRF

Expand Down
42 changes: 42 additions & 0 deletions code/go/0chain.net/conductor/config/cases/round_random_seed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package cases

import (
"0chain.net/conductor/cases"
"github.com/mitchellh/mapstructure"
)

type (
// RoundRandomSeed represents TestCaseConfigurator implementation.
RoundRandomSeed struct {
RandomSeed int64 `json:"random_seed" yaml:"random_seed" mapstructure:"random_seed"`
}
)

const (
RoundRandomSeedName = "round random seed"
)

var (
// Ensure RoundRandomSeed implements TestCaseConfigurator.
_ TestCaseConfigurator = (*RoundRandomSeed)(nil)
)

// NewRoundRandomSeed creates initialised RoundRandomSeed.
func NewRoundRandomSeed() *RoundRandomSeed {
return &RoundRandomSeed{}
}

// TestCase implements TestCaseConfigurator interface.
func (n *RoundRandomSeed) TestCase() cases.TestCase {
return cases.NewRoundHasFinalized()
}

// Name implements TestCaseConfigurator interface.
func (n *RoundRandomSeed) Name() string {
return RoundRandomSeedName
}

// Decode implements MapDecoder interface.
func (n *RoundRandomSeed) Decode(val interface{}) error {
return mapstructure.Decode(val, n)
}
10 changes: 10 additions & 0 deletions code/go/0chain.net/conductor/config/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,16 @@ func init() {
return ex.ConfigureTestCase(cfg)
})

register("round_random_seed", func(name string,
ex Executor, val interface{}, tm time.Duration) (err error) {
cfg := cases.NewRoundRandomSeed()
if err := cfg.Decode(val); err != nil {
return err
}

return ex.ConfigureTestCase(cfg)
})

register("make_test_case_check", func(name string, ex Executor, val interface{}, tm time.Duration) (err error) {
cfg := &TestCaseCheck{}
if err := cfg.Decode(val); err != nil {
Expand Down
3 changes: 3 additions & 0 deletions code/go/0chain.net/smartcontract/dbs/event/stakepool.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ func (edb *EventDb) rewardUpdate(spus []dbs.StakePoolReward, round int64) error
}
}()

logging.Logger.Debug("reward provider", zap.Any("rewards", rewards))

if len(rewards.rewards) > 0 || len(rewards.totalRewards) > 0 {
if err := edb.rewardProviders(rewards.rewards, rewards.totalRewards, round); err != nil {
return fmt.Errorf("could not rewards providers: %v", err)
Expand All @@ -146,6 +148,7 @@ func (edb *EventDb) rewardUpdate(spus []dbs.StakePoolReward, round int64) error
}

if len(rewards.delegatePools) > 0 {
logging.Logger.Debug("reward provider pools", zap.Any("rewards", rewards))
if err := edb.rewardProviderDelegates(rewards.delegatePools, round); err != nil {
return fmt.Errorf("could not rewards delegate pool: %v", err)
}
Expand Down
15 changes: 12 additions & 3 deletions code/go/0chain.net/smartcontract/zcnsc/mint.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"math"
"math/rand"
"sort"

cstate "0chain.net/chaincore/chain/state"
"0chain.net/chaincore/state"
Expand All @@ -19,7 +20,7 @@ import (
)

// Mint inputData - is a MintPayload
func (zcn *ZCNSmartContract) Mint(trans *transaction.Transaction, inputData []byte, ctx cstate.StateContextI) (resp string, err error) {
func (zcn *ZCNSmartContract) mint(trans *transaction.Transaction, inputData []byte, randomSeed int64, ctx cstate.StateContextI) (resp string, err error) {
const (
code = "failed to mint"
)
Expand Down Expand Up @@ -171,8 +172,16 @@ func (zcn *ZCNSmartContract) Mint(trans *transaction.Transaction, inputData []by
Signers: signers,
})

rand.Seed(ctx.GetBlock().GetRoundRandomSeed())
sig := payload.Signatures[rand.Intn(len(payload.Signatures))]
// sort the signatures
sortedSigs := make([]*AuthorizerSignature, len(payload.Signatures))
copy(sortedSigs, payload.Signatures)
sort.Slice(sortedSigs, func(i, j int) bool {
return sortedSigs[i].ID < sortedSigs[j].ID
})

rd := rand.New(rand.NewSource(randomSeed))
sig := sortedSigs[rd.Intn(len(payload.Signatures))]
logging.Logger.Debug("mint reward", zap.String("authorizer", sig.ID), zap.Int64("seed", randomSeed))

sp, err := zcn.getStakePool(sig.ID, ctx)
if err != nil {
Expand Down
16 changes: 16 additions & 0 deletions code/go/0chain.net/smartcontract/zcnsc/mint_integration_tests.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//go:build integration_tests
// +build integration_tests

package zcnsc

import (
cstate "0chain.net/chaincore/chain/state"
"0chain.net/chaincore/transaction"
crpc "0chain.net/conductor/conductrpc"
"github.com/0chain/common/core/logging"
)

func (zcn *ZCNSmartContract) Mint(trans *transaction.Transaction, inputData []byte, ctx cstate.StateContextI) (resp string, err error) {
logging.Logger.Debug("mint from CT")
return zcn.mint(trans, inputData, crpc.Client().State().RoundRandomSeed.RandomSeed, ctx)
}
13 changes: 13 additions & 0 deletions code/go/0chain.net/smartcontract/zcnsc/mint_main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//go:build !integration_tests
// +build !integration_tests

package zcnsc

import (
cstate "0chain.net/chaincore/chain/state"
"0chain.net/chaincore/transaction"
)

func (zcn *ZCNSmartContract) Mint(trans *transaction.Transaction, inputData []byte, ctx cstate.StateContextI) (resp string, err error) {
return zcn.mint(trans, inputData, ctx.GetBlock().GetRoundRandomSeed(), ctx)
}
12 changes: 10 additions & 2 deletions code/go/0chain.net/smartcontract/zcnsc/mint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package zcnsc_test

import (
"math/rand"
"sort"
"testing"
"time"

Expand Down Expand Up @@ -166,8 +167,15 @@ func Test_MaxFeeMint(t *testing.T) {
mintsMap[m.ToClientID] = mm[i]
}

rand.Seed(ctx.GetBlock().GetRoundRandomSeed())
sig := payload.Signatures[rand.Intn(len(payload.Signatures))]
// sort the signatures
sortedSigs := make([]*AuthorizerSignature, len(payload.Signatures))
copy(sortedSigs, payload.Signatures)
sort.Slice(sortedSigs, func(i, j int) bool {
return sortedSigs[i].ID < sortedSigs[j].ID
})

rd := rand.New(rand.NewSource(ctx.GetBlock().GetRoundRandomSeed()))
sig := sortedSigs[rd.Intn(len(payload.Signatures))]

stakePool := NewStakePool()
err = ctx.GetTrieNode(stakepool.StakePoolKey(spenum.Authorizer, sig.ID), stakePool)
Expand Down
4 changes: 2 additions & 2 deletions docker.local/bin/conductor/mint_zcn.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#!/bin/bash
# burn zcn in 0chain network
burn_zcn_output=$(./zwalletcli/zwallet bridge-burn-eth --amount 1 --wallet wallet.json)
burn_zcn_output=$(./zwalletcli/zwallet bridge-burn-eth --amount 10000000000 --wallet wallet.json)

tx=$(echo $burn_zcn_output | sed -n 's/.*burn \[OK\]: \(.*\)/\1/p')

# get authorizers signatures
./zwalletcli/zwallet bridge-mint-zcn --wallet wallet.json
./zwalletcli/zwallet bridge-mint-zcn --burn-txn-hash $tx --wallet wallet.json
2 changes: 1 addition & 1 deletion docker.local/bin/conductor/patch-0box-tests.sh
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
sed -i "s/ipv4_address: 198.18.0.98/ipv4_address: 198.18.0.95/" docker.local/docker-compose-ct.yml
sed -i "s/AWS_ACCESS_KEY_ID=key_id/AWS_ACCESS_KEY_ID=$1/" docker.local/docker-compose-ct.yml
sed -i "s/AWS_SECRET_ACCESS_KEY=secret_key/AWS_SECRET_ACCESS_KEY=$2/" docker.local/docker-compose-ct.yml
sed -i "s,block_worker: .*$,block_worker: $3," docker.local/config/0box.yaml
sed -i "s,block_worker: .*$,block_worker: $3," docker.local/config/0box.yaml
3 changes: 3 additions & 0 deletions docker.local/bin/conductor/patch-authorizer-tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

sed -i "s|ethereum_node_url:\ .*|ethereum_node_url: $1|" config/config.yaml
14 changes: 10 additions & 4 deletions docker.local/bin/conductor/register_authorizer.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,14 @@ printf '{"client_id":"1746b06bb09f55ee01b33b5e2e055d6cc7a900cb57c0a3a5eaabb8a0e7

./zwalletcli/zwallet send --tokens 10 --desc 'to auth 2' --to_client_id 47c534abb2bcb33e9944aee9a0df0e0adc4c0b659b9499aa656920975c38a80a
./zwalletcli/zwallet send --tokens 10 --desc 'to auth 3' --to_client_id 7f2097074f678d08146e5585d6965b04307939fee0457ea18c4242bff197c65a
./zwalletcli/zwallet send --tokens 10 --desc 'to auth 3' --to_client_id d5b9204835a6ea8ba93a0b4f14ce38bc72dec5165465416f0a3b9f66f988e1ab

./zwalletcli/zwallet auth-register --url http://198.18.0.131:3031 --client_key 7b630ba670dac2f22d43c2399b70eff378689a53ee03ea20957bb7e73df016200fea410ba5102558b0c39617e5afd2c1843b161a1dedec15e1ab40543a78a518 --client_id 1746b06bb09f55ee01b33b5e2e055d6cc7a900cb57c0a3a5eaabb8a0e7745802 --min_stake 2 --max_stake 10 --num_delegates 5 --service_charge 0.0 --wallet wallet.json
./zwalletcli/zwallet auth-register --url http://198.18.0.132:3032 --client_key 326759d10f6f6534e28852eed3347c3b27ec6fb4e549b689cf033d9cbee463223f4bd2e17405e738f8c42f58232e1f37b6f8cbb75b242566aab486efcd19700d --client_id 47c534abb2bcb33e9944aee9a0df0e0adc4c0b659b9499aa656920975c38a80a --min_stake 2 --max_stake 10 --num_delegates 5 --service_charge 0.0 --wallet wallet.json
./zwalletcli/zwallet auth-register --url http://198.18.0.133:3033 --client_key 5cd52e8da7d6814edfd9e3ede49eee4b3e45292daed3341bd551c477f0cbe41f12dafd37f381777609775429e796e1640ceddeeb30fff23caca84d76672a96a0 --client_id 7f2097074f678d08146e5585d6965b04307939fee0457ea18c4242bff197c65a --min_stake 2 --max_stake 10 --num_delegates 5 --service_charge 0.0 --wallet wallet.json
./zwalletcli/zwallet auth-register --url http://198.18.0.134:3034 --client_key 0db96df65ad705ca3b3139b02071bfb611523c53c5ab4693cff08588a3ba5e067e4890144650ea0b0428dbd4de3ce5da6874a8822cf2838549ea5cc26f89ea1b --client_id d5b9204835a6ea8ba93a0b4f14ce38bc72dec5165465416f0a3b9f66f988e1ab --min_stake 2 --max_stake 10 --num_delegates 5 --service_charge 0.0 --wallet wallet.json
./zwalletcli/zwallet auth-register --url http://198.18.0.131:3031 --client_key 7b630ba670dac2f22d43c2399b70eff378689a53ee03ea20957bb7e73df016200fea410ba5102558b0c39617e5afd2c1843b161a1dedec15e1ab40543a78a518 --client_id 1746b06bb09f55ee01b33b5e2e055d6cc7a900cb57c0a3a5eaabb8a0e7745802 --min_stake 2 --max_stake 10 --num_delegates 5 --service_charge 0.1 --wallet wallet.json
./zwalletcli/zwallet auth-register --url http://198.18.0.132:3032 --client_key 326759d10f6f6534e28852eed3347c3b27ec6fb4e549b689cf033d9cbee463223f4bd2e17405e738f8c42f58232e1f37b6f8cbb75b242566aab486efcd19700d --client_id 47c534abb2bcb33e9944aee9a0df0e0adc4c0b659b9499aa656920975c38a80a --min_stake 2 --max_stake 10 --num_delegates 5 --service_charge 0.1 --wallet wallet.json
./zwalletcli/zwallet auth-register --url http://198.18.0.133:3033 --client_key 5cd52e8da7d6814edfd9e3ede49eee4b3e45292daed3341bd551c477f0cbe41f12dafd37f381777609775429e796e1640ceddeeb30fff23caca84d76672a96a0 --client_id 7f2097074f678d08146e5585d6965b04307939fee0457ea18c4242bff197c65a --min_stake 2 --max_stake 10 --num_delegates 5 --service_charge 0.1 --wallet wallet.json
./zwalletcli/zwallet auth-register --url http://198.18.0.134:3034 --client_key 0db96df65ad705ca3b3139b02071bfb611523c53c5ab4693cff08588a3ba5e067e4890144650ea0b0428dbd4de3ce5da6874a8822cf2838549ea5cc26f89ea1b --client_id d5b9204835a6ea8ba93a0b4f14ce38bc72dec5165465416f0a3b9f66f988e1ab --min_stake 2 --max_stake 10 --num_delegates 5 --service_charge 0.1 --wallet wallet.json

./zboxcli/zbox sp-lock --authorizer_id 1746b06bb09f55ee01b33b5e2e055d6cc7a900cb57c0a3a5eaabb8a0e7745802 --tokens 5 --wallet wallet.json
./zboxcli/zbox sp-lock --authorizer_id 47c534abb2bcb33e9944aee9a0df0e0adc4c0b659b9499aa656920975c38a80a --tokens 5 --wallet wallet.json
./zboxcli/zbox sp-lock --authorizer_id 7f2097074f678d08146e5585d6965b04307939fee0457ea18c4242bff197c65a --tokens 5 --wallet wallet.json
./zboxcli/zbox sp-lock --authorizer_id d5b9204835a6ea8ba93a0b4f14ce38bc72dec5165465416f0a3b9f66f988e1ab --tokens 5 --wallet wallet.json
4 changes: 2 additions & 2 deletions docker.local/config/conductor.config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ nodes:
- name: "authorizer-4"
id: d5b9204835a6ea8ba93a0b4f14ce38bc72dec5165465416f0a3b9f66f988e1ab
work_dir: "../token_bridge_authserver/docker.local/auth4"
env: AUTHORIZER=4,ETH_MNEMONIC=prize tennis people canoe tongue reform main ghost jelly prefer swear nurse,ETH_UNLOCKPASSWORD="L9gwnf#Gm)bpZLP7",ETH_ADDRESS=0xD21073e6DC7E65aABc8763b9B34AAd9Eb4c8cE65,ETH_PK=0x8f86829881c924854a3ed32e986cb64bde652eb7431cc693a38d20da90319a88
env: AUTHORIZER=4,ETH_MNEMONIC=prize tennis people canoe tongue reform main ghost jelly prefer swear nurse,ETH_UNLOCKPASSWORD="12345678",ETH_BRIDGE_ADDRESS=0x7700D773022b19622095118Fadf46f7B9448Be9b
start_command: "docker-compose -p auth4 -f ../build.authorizer-integration-tests/b0docker-compose.yml up"
stop_command: "docker-compose -p auth4 -f ../build.authorizer-integration-tests/b0docker-compose.yml down"

Expand All @@ -258,7 +258,7 @@ nodes:
env: "" # no ENV needed
start_command: "../0dns/docker.local/bin/start-no-daemon.sh" # not demonized instance
stop_command: "../0dns/docker.local/bin/stop-no-daemon.sh" # not demonized instance

- name: "0box"
id: "0box"
work_dir: "../0box/"
Expand Down
67 changes: 67 additions & 0 deletions docker.local/config/conductor.node-recovery-3.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
enable:
- "Node Recovery"
- "Client Operation"

# sets of test cases
sets:
- name: "Node Recovery"
tests:
- "Authorizer Recovery - Authorizer should be able to sign tickets and gain rewards after it is recovered"

tests:
- name: "Authorizer Recovery - Authorizer should be able to sign tickets and gain rewards after it is recovered"
flow:
- set_monitor: "sharder-1"
- cleanup_bc: {}
- command:
name: "cleanup_0dns"
- start: ['sharder-1', 'sharder-2', 'miner-1', 'miner-2', 'miner-3', 'miner-4']
- wait_round:
round: 15 # just wait the BC starts
- start: ['0dns']
- sleep: "20s"
- start: ['0box']
- sleep: "20s"
- wait_round:
shift: 50
- command:
name: "register_authorizer"
- wait_add:
authorizers: ['authorizer-1','authorizer-2','authorizer-3','authorizer-4']
start: true
- wait_round:
shift: 200
- sync_latest_aggregates:
authorizers:
- "d5b9204835a6ea8ba93a0b4f14ce38bc72dec5165465416f0a3b9f66f988e1ab"
required: true
- round_random_seed:
random_seed: 54
- command:
name: "mint_zcn"
- check_aggregate_value_change:
provider_type: authorizer
provider_id: d5b9204835a6ea8ba93a0b4f14ce38bc72dec5165465416f0a3b9f66f988e1ab
key: total_rewards
monotonicity: increase
timeout: "2m"
- stop: ['authorizer-4']
- wait_round:
shift: 100
- wait_add:
authorizers: [ 'authorizer-4' ]
start: true
- sync_latest_aggregates:
authorizers:
- "d5b9204835a6ea8ba93a0b4f14ce38bc72dec5165465416f0a3b9f66f988e1ab"
required: true
- round_random_seed:
random_seed: 54
- command:
name: "mint_zcn"
- check_aggregate_value_change:
provider_type: authorizer
provider_id: d5b9204835a6ea8ba93a0b4f14ce38bc72dec5165465416f0a3b9f66f988e1ab
key: total_rewards
monotonicity: increase
timeout: "2m"
Loading

0 comments on commit 406f9cd

Please sign in to comment.