github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/integration/governance/helpers.go (about) 1 // +build integration 2 3 package governance 4 5 import ( 6 "context" 7 "fmt" 8 "math/big" 9 "net" 10 "testing" 11 12 "github.com/hyperledger/burrow/acm" 13 "github.com/hyperledger/burrow/acm/validator" 14 "github.com/hyperledger/burrow/config" 15 "github.com/hyperledger/burrow/core" 16 "github.com/hyperledger/burrow/crypto" 17 "github.com/hyperledger/burrow/execution/exec" 18 "github.com/hyperledger/burrow/genesis" 19 "github.com/hyperledger/burrow/integration" 20 "github.com/hyperledger/burrow/integration/rpctest" 21 "github.com/hyperledger/burrow/logging/logconfig" 22 "github.com/hyperledger/burrow/rpc/rpcquery" 23 "github.com/hyperledger/burrow/rpc/rpctransact" 24 "github.com/hyperledger/burrow/txs" 25 "github.com/hyperledger/burrow/txs/payload" 26 "github.com/stretchr/testify/require" 27 "github.com/tendermint/tendermint/p2p" 28 ) 29 30 func newConfig(genesisDoc *genesis.GenesisDoc, account *acm.PrivateAccount, 31 keysAccounts ...*acm.PrivateAccount) (conf *config.BurrowConfig, err error) { 32 33 // FIXME: some combination of cleanup and shutdown seems to make tests fail on CI 34 // testConfig, cleanup := integration.NewTestConfig(genesisDoc) 35 testConfig, _ := integration.NewTestConfig(genesisDoc) 36 // defer cleanup() 37 38 // comment to see all logging 39 testConfig.Logging = logconfig.New().Root(func(sink *logconfig.SinkConfig) *logconfig.SinkConfig { 40 return sink.SetTransform(logconfig.FilterTransform(logconfig.IncludeWhenAllMatch, 41 "total_validator")).SetOutput(logconfig.StdoutOutput()) 42 }) 43 44 // Try and grab a free port - this is not foolproof since there is race between other concurrent tests after we close 45 // the listener and start the node 46 l, err := net.Listen("tcp", "localhost:0") 47 if err != nil { 48 return nil, err 49 } 50 host, port, err := net.SplitHostPort(l.Addr().String()) 51 if err != nil { 52 return nil, err 53 } 54 testConfig.Tendermint.ListenHost = host 55 testConfig.Tendermint.ListenPort = port 56 57 err = l.Close() 58 if err != nil { 59 return nil, err 60 } 61 62 return testConfig, nil 63 } 64 65 func newKernelAndBoot(conf *config.BurrowConfig, account *acm.PrivateAccount, 66 keysAccounts ...*acm.PrivateAccount) (kernel *core.Kernel, err error) { 67 68 kernel, err = integration.TestKernel(account, keysAccounts, conf) 69 if err != nil { 70 return nil, err 71 } 72 73 return kernel, kernel.Boot() 74 } 75 76 func signTx(t *testing.T, tx payload.Payload, chainID string, from acm.AddressableSigner) (txEnv *txs.Envelope) { 77 txEnv = txs.Enclose(chainID, tx) 78 require.NoError(t, txEnv.Sign(from)) 79 return 80 } 81 82 func getValidators(t testing.TB, qcli rpcquery.QueryClient) map[crypto.Address]*validator.Validator { 83 vs, err := qcli.GetValidatorSet(context.Background(), &rpcquery.GetValidatorSetParam{}) 84 require.NoError(t, err) 85 vals := make(map[crypto.Address]*validator.Validator, len(vs.Set)) 86 for _, v := range vs.Set { 87 vals[v.PublicKey.GetAddress()] = v 88 } 89 return vals 90 } 91 92 func getValidatorSet(t testing.TB, qcli rpcquery.QueryClient) *validator.Set { 93 vs, err := qcli.GetValidatorSet(context.Background(), &rpcquery.GetValidatorSetParam{}) 94 require.NoError(t, err) 95 // Include the genesis validator and compare the sets 96 return validator.UnpersistSet(vs.Set) 97 } 98 99 func getAccount(t testing.TB, qcli rpcquery.QueryClient, address crypto.Address) *acm.Account { 100 acc, err := qcli.GetAccount(context.Background(), &rpcquery.GetAccountParam{ 101 Address: address, 102 }) 103 require.NoError(t, err) 104 return acc 105 } 106 107 func account(i int) *acm.PrivateAccount { 108 return rpctest.PrivateAccounts[i] 109 } 110 111 func payloadSync(cli rpctransact.TransactClient, tx payload.Payload) (*exec.TxExecution, error) { 112 return cli.BroadcastTxSync(context.Background(), &rpctransact.TxEnvelopeParam{ 113 Payload: tx.Any(), 114 }) 115 } 116 117 func assertValidatorsEqual(t testing.TB, expected, actual *validator.Set) { 118 require.NoError(t, expected.Equal(actual), "validator sets should be equal\nExpected: %v\n\nActual: %v\n", 119 expected, actual) 120 } 121 122 func changePower(vs *validator.Set, i int, power uint64) { 123 vs.ChangePower(account(i).GetPublicKey(), new(big.Int).SetUint64(power)) 124 } 125 126 func connectKernels(k1, k2 *core.Kernel) error { 127 k1Address, err := k1.Node.NodeInfo().NetAddress() 128 if err != nil { 129 return fmt.Errorf("could not get kernel address: %v", err) 130 } 131 k2Address, err := k2.Node.NodeInfo().NetAddress() 132 if err != nil { 133 return fmt.Errorf("could not get kernel address: %v", err) 134 } 135 fmt.Printf("Connecting %v -> %v\n", k1Address, k2Address) 136 err = k1.Node.Switch().DialPeerWithAddress(k2Address) 137 if err != nil { 138 switch e := err.(type) { 139 case p2p.ErrRejected: 140 return fmt.Errorf("connection between test kernels was rejected: %v", e) 141 default: 142 return fmt.Errorf("could not connect test kernels: %v", err) 143 } 144 } 145 return nil 146 } 147 148 func connectAllKernels(ks []*core.Kernel) error { 149 source := ks[0] 150 for _, dest := range ks[1:] { 151 err := connectKernels(source, dest) 152 if err != nil { 153 return err 154 } 155 } 156 return nil 157 } 158 159 func getMaxFlow(t testing.TB, qcli rpcquery.QueryClient) uint64 { 160 vs, err := qcli.GetValidatorSet(context.Background(), &rpcquery.GetValidatorSetParam{}) 161 require.NoError(t, err) 162 set := validator.UnpersistSet(vs.Set) 163 totalPower := set.TotalPower() 164 maxFlow := new(big.Int) 165 return maxFlow.Sub(maxFlow.Div(totalPower, big.NewInt(3)), big.NewInt(1)).Uint64() 166 } 167 168 func setSequence(t testing.TB, qcli rpcquery.QueryClient, tx payload.Payload) { 169 for _, input := range tx.GetInputs() { 170 ca, err := qcli.GetAccount(context.Background(), &rpcquery.GetAccountParam{Address: input.Address}) 171 require.NoError(t, err) 172 input.Sequence = ca.Sequence + 1 173 } 174 } 175 176 func localSignAndBroadcastSync(t testing.TB, tcli rpctransact.TransactClient, chainID string, 177 signer acm.AddressableSigner, tx payload.Payload) (*exec.TxExecution, error) { 178 txEnv := txs.Enclose(chainID, tx) 179 err := txEnv.Sign(signer) 180 require.NoError(t, err) 181 182 return tcli.BroadcastTxSync(context.Background(), &rpctransact.TxEnvelopeParam{Envelope: txEnv}) 183 }