mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-04-04 15:55:23 +00:00 
			
		
		
		
	fix: designers; test: designers, precompile (#59)
* test: dasigners test * test: genesis * fix: abci; test: abci * test: types * test: keeper test * test: util * test: dasigners precompile * chore: remove log
This commit is contained in:
		
							parent
							
								
									500e66733d
								
							
						
					
					
						commit
						04ce67f6a9
					
				| @ -9,6 +9,7 @@ import ( | ||||
| 	"time" | ||||
| 
 | ||||
| 	sdkmath "cosmossdk.io/math" | ||||
| 	dasignerskeeper "github.com/0glabs/0g-chain/x/dasigners/v1/keeper" | ||||
| 	tmdb "github.com/cometbft/cometbft-db" | ||||
| 	abci "github.com/cometbft/cometbft/abci/types" | ||||
| 	"github.com/cometbft/cometbft/libs/log" | ||||
| @ -55,7 +56,7 @@ var ( | ||||
| 	defaultInitialHeight int64 = 1 | ||||
| ) | ||||
| 
 | ||||
| const TestChainId = "kavatest_2221-1" | ||||
| const TestChainId = "zgchain_8888-1" | ||||
| 
 | ||||
| // TestApp is a simple wrapper around an App. It exposes internal keepers for use in integration tests.
 | ||||
| // This file also contains test helpers. Ideally they would be in separate package.
 | ||||
| @ -115,6 +116,7 @@ func (tApp TestApp) GetCommitteeKeeper() committeekeeper.Keeper     { return tAp | ||||
| func (tApp TestApp) GetEvmutilKeeper() evmutilkeeper.Keeper         { return tApp.evmutilKeeper } | ||||
| func (tApp TestApp) GetEvmKeeper() *evmkeeper.Keeper                { return tApp.evmKeeper } | ||||
| func (tApp TestApp) GetFeeMarketKeeper() feemarketkeeper.Keeper     { return tApp.feeMarketKeeper } | ||||
| func (tApp TestApp) GetDASignersKeeper() dasignerskeeper.Keeper     { return tApp.dasignersKeeper } | ||||
| func (tApp TestApp) GetPrecisebankKeeper() precisebankkeeper.Keeper { return tApp.precisebankKeeper } | ||||
| 
 | ||||
| func (tApp TestApp) GetKVStoreKey(key string) *storetypes.KVStoreKey { | ||||
|  | ||||
							
								
								
									
										375
									
								
								precompiles/dasigners/dasigners_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										375
									
								
								precompiles/dasigners/dasigners_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,375 @@ | ||||
| package dasigners_test | ||||
| 
 | ||||
| import ( | ||||
| 	"math/big" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/0glabs/0g-chain/crypto/bn254util" | ||||
| 	dasignersprecompile "github.com/0glabs/0g-chain/precompiles/dasigners" | ||||
| 	"github.com/0glabs/0g-chain/precompiles/testutil" | ||||
| 	"github.com/0glabs/0g-chain/x/dasigners/v1" | ||||
| 	"github.com/0glabs/0g-chain/x/dasigners/v1/keeper" | ||||
| 	dasignerskeeper "github.com/0glabs/0g-chain/x/dasigners/v1/keeper" | ||||
| 	"github.com/0glabs/0g-chain/x/dasigners/v1/types" | ||||
| 	abci "github.com/cometbft/cometbft/abci/types" | ||||
| 	"github.com/consensys/gnark-crypto/ecc/bn254" | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 	"github.com/ethereum/go-ethereum/accounts/abi" | ||||
| 	"github.com/ethereum/go-ethereum/common" | ||||
| 	evmtypes "github.com/evmos/ethermint/x/evm/types" | ||||
| 	"github.com/stretchr/testify/suite" | ||||
| 
 | ||||
| 	"cosmossdk.io/math" | ||||
| 	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" | ||||
| 	"github.com/ethereum/go-ethereum/core/vm" | ||||
| 	"github.com/evmos/ethermint/crypto/ethsecp256k1" | ||||
| ) | ||||
| 
 | ||||
| type DASignersTestSuite struct { | ||||
| 	testutil.PrecompileTestSuite | ||||
| 
 | ||||
| 	abi             abi.ABI | ||||
| 	addr            common.Address | ||||
| 	dasigners       *dasignersprecompile.DASignersPrecompile | ||||
| 	dasignerskeeper dasignerskeeper.Keeper | ||||
| 	signerOne       *testutil.TestSigner | ||||
| 	signerTwo       *testutil.TestSigner | ||||
| } | ||||
| 
 | ||||
| func (suite *DASignersTestSuite) AddDelegation(from string, to string, amount math.Int) { | ||||
| 	accAddr, err := sdk.AccAddressFromHexUnsafe(from) | ||||
| 	suite.Require().NoError(err) | ||||
| 	valAddr, err := sdk.ValAddressFromHex(to) | ||||
| 	suite.Require().NoError(err) | ||||
| 	validator, found := suite.StakingKeeper.GetValidator(suite.Ctx, valAddr) | ||||
| 	if !found { | ||||
| 		consPriv, err := ethsecp256k1.GenerateKey() | ||||
| 		suite.Require().NoError(err) | ||||
| 		newValidator, err := stakingtypes.NewValidator(valAddr, consPriv.PubKey(), stakingtypes.Description{}) | ||||
| 		suite.Require().NoError(err) | ||||
| 		validator = newValidator | ||||
| 	} | ||||
| 	validator.Tokens = validator.Tokens.Add(amount) | ||||
| 	validator.DelegatorShares = validator.DelegatorShares.Add(amount.ToLegacyDec()) | ||||
| 	suite.StakingKeeper.SetValidator(suite.Ctx, validator) | ||||
| 	bonded := suite.dasignerskeeper.GetDelegatorBonded(suite.Ctx, accAddr) | ||||
| 	suite.StakingKeeper.SetDelegation(suite.Ctx, stakingtypes.Delegation{ | ||||
| 		DelegatorAddress: accAddr.String(), | ||||
| 		ValidatorAddress: valAddr.String(), | ||||
| 		Shares:           bonded.Add(amount).ToLegacyDec(), | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func (suite *DASignersTestSuite) SetupTest() { | ||||
| 	suite.PrecompileTestSuite.SetupTest() | ||||
| 
 | ||||
| 	suite.dasignerskeeper = suite.App.GetDASignersKeeper() | ||||
| 
 | ||||
| 	suite.addr = common.HexToAddress(dasignersprecompile.PrecompileAddress) | ||||
| 
 | ||||
| 	precompiles := suite.EvmKeeper.GetPrecompiles() | ||||
| 	precompile, ok := precompiles[suite.addr] | ||||
| 	suite.Assert().EqualValues(ok, true) | ||||
| 	suite.dasigners = precompile.(*dasignersprecompile.DASignersPrecompile) | ||||
| 
 | ||||
| 	suite.signerOne = testutil.GenSigner() | ||||
| 	suite.signerTwo = testutil.GenSigner() | ||||
| 	abi, err := abi.JSON(strings.NewReader(dasignersprecompile.DASignersABI)) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	suite.abi = abi | ||||
| } | ||||
| 
 | ||||
| func (suite *DASignersTestSuite) runTx(input []byte, signer *testutil.TestSigner, gas uint64) ([]byte, error) { | ||||
| 	contract := vm.NewPrecompile(vm.AccountRef(signer.Addr), vm.AccountRef(suite.addr), big.NewInt(0), gas) | ||||
| 	contract.Input = input | ||||
| 
 | ||||
| 	msgEthereumTx := evmtypes.NewTx(suite.EvmKeeper.ChainID(), 0, &suite.addr, big.NewInt(0), gas, big.NewInt(0), big.NewInt(0), big.NewInt(0), input, nil) | ||||
| 	msgEthereumTx.From = signer.HexAddr | ||||
| 	err := msgEthereumTx.Sign(suite.EthSigner, signer.Signer) | ||||
| 	suite.Assert().NoError(err, "failed to sign Ethereum message") | ||||
| 
 | ||||
| 	proposerAddress := suite.Ctx.BlockHeader().ProposerAddress | ||||
| 	cfg, err := suite.EvmKeeper.EVMConfig(suite.Ctx, proposerAddress, suite.EvmKeeper.ChainID()) | ||||
| 	suite.Assert().NoError(err, "failed to instantiate EVM config") | ||||
| 
 | ||||
| 	msg, err := msgEthereumTx.AsMessage(suite.EthSigner, big.NewInt(0)) | ||||
| 	suite.Assert().NoError(err, "failed to instantiate Ethereum message") | ||||
| 
 | ||||
| 	evm := suite.EvmKeeper.NewEVM(suite.Ctx, msg, cfg, nil, suite.Statedb) | ||||
| 	precompiles := suite.EvmKeeper.GetPrecompiles() | ||||
| 	evm.WithPrecompiles(precompiles, []common.Address{suite.addr}) | ||||
| 
 | ||||
| 	return suite.dasigners.Run(evm, contract, false) | ||||
| } | ||||
| 
 | ||||
| func (suite *DASignersTestSuite) registerSigner(testSigner *testutil.TestSigner, sk *big.Int) *types.Signer { | ||||
| 	pkG1 := new(bn254.G1Affine).ScalarMultiplication(bn254util.GetG1Generator(), sk) | ||||
| 	pkG2 := new(bn254.G2Affine).ScalarMultiplication(bn254util.GetG2Generator(), sk) | ||||
| 	hash := types.PubkeyRegistrationHash(testSigner.Addr, big.NewInt(8888)) | ||||
| 	signature := new(bn254.G1Affine).ScalarMultiplication(hash, sk) | ||||
| 	signer := &types.Signer{ | ||||
| 		Account:  testSigner.HexAddr, | ||||
| 		Socket:   "0.0.0.0:1234", | ||||
| 		PubkeyG1: bn254util.SerializeG1(pkG1), | ||||
| 		PubkeyG2: bn254util.SerializeG2(pkG2), | ||||
| 	} | ||||
| 
 | ||||
| 	input, err := suite.abi.Pack( | ||||
| 		"registerSigner", | ||||
| 		dasignersprecompile.NewIDASignersSignerDetail(signer), | ||||
| 		dasignersprecompile.NewBN254G1Point(bn254util.SerializeG1(signature)), | ||||
| 	) | ||||
| 	suite.Assert().NoError(err) | ||||
| 
 | ||||
| 	oldLogs := suite.Statedb.Logs() | ||||
| 	_, err = suite.runTx(input, testSigner, 10000000) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	logs := suite.Statedb.Logs() | ||||
| 	suite.Assert().EqualValues(len(logs), len(oldLogs)+2) | ||||
| 
 | ||||
| 	_, err = suite.abi.Unpack("SocketUpdated", logs[len(logs)-1].Data) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	_, err = suite.abi.Unpack("NewSigner", logs[len(logs)-2].Data) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	return signer | ||||
| } | ||||
| 
 | ||||
| func (suite *DASignersTestSuite) updateSocket(testSigner *testutil.TestSigner, signer *types.Signer) { | ||||
| 	input, err := suite.abi.Pack( | ||||
| 		"updateSocket", | ||||
| 		"0.0.0.0:2345", | ||||
| 	) | ||||
| 	suite.Assert().NoError(err) | ||||
| 
 | ||||
| 	oldLogs := suite.Statedb.Logs() | ||||
| 	_, err = suite.runTx(input, testSigner, 10000000) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	logs := suite.Statedb.Logs() | ||||
| 	suite.Assert().EqualValues(len(logs), len(oldLogs)+1) | ||||
| 
 | ||||
| 	_, err = suite.abi.Unpack("SocketUpdated", logs[len(logs)-1].Data) | ||||
| 	suite.Assert().NoError(err) | ||||
| 
 | ||||
| 	signer.Socket = "0.0.0.0:2345" | ||||
| } | ||||
| 
 | ||||
| func (suite *DASignersTestSuite) registerEpoch(testSigner *testutil.TestSigner, sk *big.Int) { | ||||
| 	hash := types.EpochRegistrationHash(common.HexToAddress(testSigner.HexAddr), 1, big.NewInt(8888)) | ||||
| 	signature := new(bn254.G1Affine).ScalarMultiplication(hash, sk) | ||||
| 
 | ||||
| 	input, err := suite.abi.Pack( | ||||
| 		"registerNextEpoch", | ||||
| 		dasignersprecompile.NewBN254G1Point(bn254util.SerializeG1(signature)), | ||||
| 	) | ||||
| 	suite.Assert().NoError(err) | ||||
| 
 | ||||
| 	_, err = suite.runTx(input, testSigner, 10000000) | ||||
| 	suite.Assert().NoError(err) | ||||
| } | ||||
| 
 | ||||
| func (suite *DASignersTestSuite) queryEpochNumber(testSigner *testutil.TestSigner) { | ||||
| 	input, err := suite.abi.Pack( | ||||
| 		"epochNumber", | ||||
| 	) | ||||
| 	suite.Assert().NoError(err) | ||||
| 
 | ||||
| 	bz, err := suite.runTx(input, testSigner, 10000000) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	out, err := suite.abi.Methods["epochNumber"].Outputs.Unpack(bz) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	suite.Assert().EqualValues(out[0], big.NewInt(1)) | ||||
| } | ||||
| 
 | ||||
| func (suite *DASignersTestSuite) queryQuorumCount(testSigner *testutil.TestSigner) { | ||||
| 	input, err := suite.abi.Pack( | ||||
| 		"quorumCount", | ||||
| 		big.NewInt(1), | ||||
| 	) | ||||
| 	suite.Assert().NoError(err) | ||||
| 
 | ||||
| 	bz, err := suite.runTx(input, testSigner, 10000000) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	out, err := suite.abi.Methods["quorumCount"].Outputs.Unpack(bz) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	suite.Assert().EqualValues(out[0], big.NewInt(1)) | ||||
| } | ||||
| 
 | ||||
| func (suite *DASignersTestSuite) queryGetSigner(testSigner *testutil.TestSigner, answer []*types.Signer) { | ||||
| 	input, err := suite.abi.Pack( | ||||
| 		"getSigner", | ||||
| 		[]common.Address{suite.signerOne.Addr, suite.signerTwo.Addr}, | ||||
| 	) | ||||
| 	suite.Assert().NoError(err) | ||||
| 
 | ||||
| 	bz, err := suite.runTx(input, testSigner, 10000000) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	out, err := suite.abi.Methods["getSigner"].Outputs.Unpack(bz) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	res := make([]dasignersprecompile.IDASignersSignerDetail, 0) | ||||
| 	for _, s := range answer { | ||||
| 		res = append(res, dasignersprecompile.NewIDASignersSignerDetail(s)) | ||||
| 	} | ||||
| 	suite.Assert().EqualValues(out[0], res) | ||||
| } | ||||
| 
 | ||||
| func (suite *DASignersTestSuite) queryIsSigner(testSigner *testutil.TestSigner) { | ||||
| 	input, err := suite.abi.Pack( | ||||
| 		"isSigner", | ||||
| 		suite.signerOne.Addr, | ||||
| 	) | ||||
| 	suite.Assert().NoError(err) | ||||
| 
 | ||||
| 	bz, err := suite.runTx(input, testSigner, 10000000) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	out, err := suite.abi.Methods["isSigner"].Outputs.Unpack(bz) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	suite.Assert().EqualValues(out[0], true) | ||||
| } | ||||
| 
 | ||||
| func (suite *DASignersTestSuite) queryRegisteredEpoch(testSigner *testutil.TestSigner, account common.Address, epoch *big.Int) bool { | ||||
| 	input, err := suite.abi.Pack( | ||||
| 		"registeredEpoch", | ||||
| 		account, | ||||
| 		epoch, | ||||
| 	) | ||||
| 	suite.Assert().NoError(err) | ||||
| 
 | ||||
| 	bz, err := suite.runTx(input, testSigner, 10000000) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	out, err := suite.abi.Methods["registeredEpoch"].Outputs.Unpack(bz) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	return out[0].(bool) | ||||
| } | ||||
| 
 | ||||
| func (suite *DASignersTestSuite) queryGetQuorum(testSigner *testutil.TestSigner) []common.Address { | ||||
| 	input, err := suite.abi.Pack( | ||||
| 		"getQuorum", | ||||
| 		big.NewInt(1), | ||||
| 		big.NewInt(0), | ||||
| 	) | ||||
| 	suite.Assert().NoError(err) | ||||
| 
 | ||||
| 	bz, err := suite.runTx(input, testSigner, 10000000) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	out, err := suite.abi.Methods["getQuorum"].Outputs.Unpack(bz) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	return out[0].([]common.Address) | ||||
| } | ||||
| 
 | ||||
| func (suite *DASignersTestSuite) queryGetQuorumRow(testSigner *testutil.TestSigner, row uint32) common.Address { | ||||
| 	input, err := suite.abi.Pack( | ||||
| 		"getQuorumRow", | ||||
| 		big.NewInt(1), | ||||
| 		big.NewInt(0), | ||||
| 		row, | ||||
| 	) | ||||
| 	suite.Assert().NoError(err) | ||||
| 
 | ||||
| 	bz, err := suite.runTx(input, testSigner, 10000000) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	out, err := suite.abi.Methods["getQuorumRow"].Outputs.Unpack(bz) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	return out[0].(common.Address) | ||||
| } | ||||
| 
 | ||||
| func (suite *DASignersTestSuite) queryGetAggPkG1(testSigner *testutil.TestSigner, bitmap []byte) struct { | ||||
| 	AggPkG1 dasignersprecompile.BN254G1Point | ||||
| 	Total   *big.Int | ||||
| 	Hit     *big.Int | ||||
| } { | ||||
| 	input, err := suite.abi.Pack( | ||||
| 		"getAggPkG1", | ||||
| 		big.NewInt(1), | ||||
| 		big.NewInt(0), | ||||
| 		bitmap, | ||||
| 	) | ||||
| 	suite.Assert().NoError(err) | ||||
| 
 | ||||
| 	bz, err := suite.runTx(input, testSigner, 10000000) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	out, err := suite.abi.Methods["getAggPkG1"].Outputs.Unpack(bz) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	return struct { | ||||
| 		AggPkG1 dasignersprecompile.BN254G1Point | ||||
| 		Total   *big.Int | ||||
| 		Hit     *big.Int | ||||
| 	}{ | ||||
| 		AggPkG1: out[0].(dasignersprecompile.BN254G1Point), | ||||
| 		Total:   out[1].(*big.Int), | ||||
| 		Hit:     out[2].(*big.Int), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (suite *DASignersTestSuite) Test_DASigners() { | ||||
| 	// suite.App.InitializeFromGenesisStates()
 | ||||
| 	dasigners.InitGenesis(suite.Ctx, suite.dasignerskeeper, *types.DefaultGenesisState()) | ||||
| 	// add delegation
 | ||||
| 	params := suite.dasignerskeeper.GetParams(suite.Ctx) | ||||
| 	suite.AddDelegation(suite.signerOne.HexAddr, suite.signerOne.HexAddr, keeper.BondedConversionRate.Mul(sdk.NewIntFromUint64(params.TokensPerVote))) | ||||
| 	suite.AddDelegation(suite.signerTwo.HexAddr, suite.signerOne.HexAddr, keeper.BondedConversionRate.Mul(sdk.NewIntFromUint64(params.TokensPerVote)).Mul(sdk.NewIntFromUint64(2))) | ||||
| 	// tx test
 | ||||
| 	signer1 := suite.registerSigner(suite.signerOne, big.NewInt(1)) | ||||
| 	signer2 := suite.registerSigner(suite.signerTwo, big.NewInt(11)) | ||||
| 	suite.updateSocket(suite.signerOne, signer1) | ||||
| 	suite.updateSocket(suite.signerTwo, signer2) | ||||
| 	suite.registerEpoch(suite.signerOne, big.NewInt(1)) | ||||
| 	suite.registerEpoch(suite.signerTwo, big.NewInt(11)) | ||||
| 	// move to next epoch
 | ||||
| 	suite.Ctx = suite.Ctx.WithBlockHeight(int64(params.EpochBlocks) * 1) | ||||
| 	suite.dasignerskeeper.BeginBlock(suite.Ctx, abci.RequestBeginBlock{}) | ||||
| 	// query test
 | ||||
| 	suite.queryEpochNumber(suite.signerOne) | ||||
| 	suite.queryQuorumCount(suite.signerOne) | ||||
| 	suite.queryGetSigner(suite.signerOne, []*types.Signer{signer1, signer2}) | ||||
| 	suite.queryIsSigner(suite.signerOne) | ||||
| 	suite.Assert().EqualValues(suite.queryRegisteredEpoch(suite.signerOne, suite.signerOne.Addr, big.NewInt(1)), true) | ||||
| 	suite.Assert().EqualValues(suite.queryRegisteredEpoch(suite.signerOne, suite.signerTwo.Addr, big.NewInt(1)), true) | ||||
| 	suite.Assert().EqualValues(suite.queryRegisteredEpoch(suite.signerOne, suite.signerOne.Addr, big.NewInt(2)), false) | ||||
| 	suite.Assert().EqualValues(suite.queryRegisteredEpoch(suite.signerOne, suite.signerTwo.Addr, big.NewInt(0)), false) | ||||
| 
 | ||||
| 	quorum := suite.queryGetQuorum(suite.signerOne) | ||||
| 	suite.Assert().EqualValues(len(quorum), params.EncodedSlices) | ||||
| 	cnt := map[common.Address]int{suite.signerOne.Addr: 0, suite.signerTwo.Addr: 0} | ||||
| 	onePos := len(quorum) | ||||
| 	twoPos := len(quorum) | ||||
| 	for i, v := range quorum { | ||||
| 		suite.Assert().EqualValues(suite.queryGetQuorumRow(suite.signerOne, uint32(i)), v) | ||||
| 		cnt[v] += 1 | ||||
| 		if v == suite.signerOne.Addr { | ||||
| 			onePos = min(onePos, i) | ||||
| 		} else { | ||||
| 			twoPos = min(twoPos, i) | ||||
| 		} | ||||
| 	} | ||||
| 	suite.Assert().EqualValues(cnt[suite.signerOne.Addr], len(quorum)/3) | ||||
| 	suite.Assert().EqualValues(cnt[suite.signerTwo.Addr], len(quorum)*2/3) | ||||
| 
 | ||||
| 	bitMap := make([]byte, len(quorum)/8) | ||||
| 	bitMap[onePos/8] |= 1 << (onePos % 8) | ||||
| 	suite.Assert().EqualValues(suite.queryGetAggPkG1(suite.signerOne, bitMap), struct { | ||||
| 		AggPkG1 dasignersprecompile.BN254G1Point | ||||
| 		Total   *big.Int | ||||
| 		Hit     *big.Int | ||||
| 	}{ | ||||
| 		AggPkG1: dasignersprecompile.NewBN254G1Point(bn254util.SerializeG1(new(bn254.G1Affine).ScalarMultiplication(bn254util.GetG1Generator(), big.NewInt(1)))), | ||||
| 		Total:   big.NewInt(int64(len(quorum))), | ||||
| 		Hit:     big.NewInt(int64(len(quorum) / 3)), | ||||
| 	}) | ||||
| 
 | ||||
| 	bitMap[twoPos/8] |= 1 << (twoPos % 8) | ||||
| 	suite.Assert().EqualValues(suite.queryGetAggPkG1(suite.signerOne, bitMap), struct { | ||||
| 		AggPkG1 dasignersprecompile.BN254G1Point | ||||
| 		Total   *big.Int | ||||
| 		Hit     *big.Int | ||||
| 	}{ | ||||
| 		AggPkG1: dasignersprecompile.NewBN254G1Point(bn254util.SerializeG1(new(bn254.G1Affine).ScalarMultiplication(bn254util.GetG1Generator(), big.NewInt(1+11)))), | ||||
| 		Total:   big.NewInt(int64(len(quorum))), | ||||
| 		Hit:     big.NewInt(int64(len(quorum))), | ||||
| 	}) | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| func TestKeeperSuite(t *testing.T) { | ||||
| 	suite.Run(t, new(DASignersTestSuite)) | ||||
| } | ||||
							
								
								
									
										88
									
								
								precompiles/testutil/suite.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								precompiles/testutil/suite.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,88 @@ | ||||
| package testutil | ||||
| 
 | ||||
| import ( | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/0glabs/0g-chain/app" | ||||
| 	"github.com/0glabs/0g-chain/chaincfg" | ||||
| 	dasignersprecompile "github.com/0glabs/0g-chain/precompiles/dasigners" | ||||
| 	"github.com/0glabs/0g-chain/x/bep3/types" | ||||
| 	"github.com/cosmos/cosmos-sdk/crypto/keyring" | ||||
| 	"github.com/ethereum/go-ethereum/common" | ||||
| 	"github.com/ethereum/go-ethereum/crypto" | ||||
| 	emtests "github.com/evmos/ethermint/tests" | ||||
| 	evmkeeper "github.com/evmos/ethermint/x/evm/keeper" | ||||
| 	"github.com/evmos/ethermint/x/evm/statedb" | ||||
| 	"github.com/stretchr/testify/suite" | ||||
| 
 | ||||
| 	cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 	stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" | ||||
| 	ethtypes "github.com/ethereum/go-ethereum/core/types" | ||||
| 	"github.com/evmos/ethermint/crypto/ethsecp256k1" | ||||
| 
 | ||||
| 	tmproto "github.com/cometbft/cometbft/proto/tendermint/types" | ||||
| 	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" | ||||
| ) | ||||
| 
 | ||||
| type PrecompileTestSuite struct { | ||||
| 	suite.Suite | ||||
| 
 | ||||
| 	StakingKeeper *stakingkeeper.Keeper | ||||
| 	App           app.TestApp | ||||
| 	Ctx           sdk.Context | ||||
| 	QueryClient   types.QueryClient | ||||
| 	Addresses     []sdk.AccAddress | ||||
| 
 | ||||
| 	EvmKeeper *evmkeeper.Keeper | ||||
| 	EthSigner ethtypes.Signer | ||||
| 	Statedb   *statedb.StateDB | ||||
| } | ||||
| 
 | ||||
| type TestSigner struct { | ||||
| 	Addr    common.Address | ||||
| 	HexAddr string | ||||
| 	PrivKey cryptotypes.PrivKey | ||||
| 	Signer  keyring.Signer | ||||
| } | ||||
| 
 | ||||
| func GenSigner() *TestSigner { | ||||
| 	var s TestSigner | ||||
| 	addr, priv := emtests.NewAddrKey() | ||||
| 	s.PrivKey = priv | ||||
| 	s.Addr = addr | ||||
| 	s.HexAddr = dasignersprecompile.ToLowerHexWithoutPrefix(s.Addr) | ||||
| 	s.Signer = emtests.NewSigner(priv) | ||||
| 	return &s | ||||
| } | ||||
| 
 | ||||
| func (suite *PrecompileTestSuite) SetupTest() { | ||||
| 	chaincfg.SetSDKConfig() | ||||
| 	suite.App = app.NewTestApp() | ||||
| 	suite.App.InitializeFromGenesisStates() | ||||
| 	suite.StakingKeeper = suite.App.GetStakingKeeper() | ||||
| 
 | ||||
| 	// make block header
 | ||||
| 	privkey, _ := ethsecp256k1.GenerateKey() | ||||
| 	consAddress := sdk.ConsAddress(privkey.PubKey().Address()) | ||||
| 	key, err := privkey.ToECDSA() | ||||
| 	suite.Assert().NoError(err) | ||||
| 	hexAddr := strings.ToLower(crypto.PubkeyToAddress(key.PublicKey).Hex()[2:]) | ||||
| 	valAddr, err := sdk.ValAddressFromHex(hexAddr) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	suite.Ctx = suite.App.NewContext(true, tmproto.Header{Height: 1, ChainID: app.TestChainId, ProposerAddress: consAddress}) | ||||
| 	newValidator, err := stakingtypes.NewValidator(valAddr, privkey.PubKey(), stakingtypes.Description{}) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	err = suite.StakingKeeper.SetValidatorByConsAddr(suite.Ctx, newValidator) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	suite.StakingKeeper.SetValidator(suite.Ctx, newValidator) | ||||
| 
 | ||||
| 	_, accAddresses := app.GeneratePrivKeyAddressPairs(10) | ||||
| 	suite.Addresses = accAddresses | ||||
| 
 | ||||
| 	suite.EvmKeeper = suite.App.GetEvmKeeper() | ||||
| 
 | ||||
| 	suite.EthSigner = ethtypes.LatestSignerForChainID(suite.EvmKeeper.ChainID()) | ||||
| 
 | ||||
| 	suite.Statedb = statedb.New(suite.Ctx, suite.EvmKeeper, statedb.NewEmptyTxConfig(common.BytesToHash(suite.Ctx.HeaderHash().Bytes()))) | ||||
| } | ||||
| @ -39,7 +39,7 @@ func ExportGenesis(ctx sdk.Context, keeper keeper.Keeper) *types.GenesisState { | ||||
| 		return false | ||||
| 	}) | ||||
| 	epochQuorums := make([]*types.Quorums, 0) | ||||
| 	for i := 0; i < int(epochNumber); i += 1 { | ||||
| 	for i := 0; i <= int(epochNumber); i += 1 { | ||||
| 		quorumCnt, err := keeper.GetQuorumCount(ctx, uint64(i)) | ||||
| 		if err != nil { | ||||
| 			panic("historical quorums not found") | ||||
|  | ||||
							
								
								
									
										155
									
								
								x/dasigners/v1/genesis_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								x/dasigners/v1/genesis_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,155 @@ | ||||
| package dasigners_test | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/suite" | ||||
| 
 | ||||
| 	tmproto "github.com/cometbft/cometbft/proto/tendermint/types" | ||||
| 
 | ||||
| 	"github.com/0glabs/0g-chain/app" | ||||
| 	"github.com/0glabs/0g-chain/x/dasigners/v1" | ||||
| 	"github.com/0glabs/0g-chain/x/dasigners/v1/testutil" | ||||
| 	"github.com/0glabs/0g-chain/x/dasigners/v1/types" | ||||
| ) | ||||
| 
 | ||||
| type GenesisTestSuite struct { | ||||
| 	testutil.Suite | ||||
| } | ||||
| 
 | ||||
| func (suite *GenesisTestSuite) TestInitGenesis() { | ||||
| 	// Most genesis validation tests are located in the types directory. The 'invalid' test cases are
 | ||||
| 	// randomly selected subset of those tests.
 | ||||
| 	testCases := []struct { | ||||
| 		name       string | ||||
| 		genState   *types.GenesisState | ||||
| 		expectPass bool | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name:       "normal", | ||||
| 			genState:   types.DefaultGenesisState(), | ||||
| 			expectPass: true, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "normal-more-epochs", | ||||
| 			genState: types.NewGenesisState(types.Params{ | ||||
| 				TokensPerVote:     10, | ||||
| 				MaxVotesPerSigner: 1024, | ||||
| 				MaxQuorums:        10, | ||||
| 				EpochBlocks:       5760, | ||||
| 				EncodedSlices:     1, | ||||
| 			}, 0, []*types.Signer{{ | ||||
| 				Account:  "0000000000000000000000000000000000000001", | ||||
| 				Socket:   "0.0.0.0:1234", | ||||
| 				PubkeyG1: make([]byte, 64), | ||||
| 				PubkeyG2: make([]byte, 128), | ||||
| 			}}, []*types.Quorums{{ | ||||
| 				Quorums: []*types.Quorum{{Signers: []string{"0000000000000000000000000000000000000001"}}}, | ||||
| 			}}), | ||||
| 			expectPass: true, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "invalid account format", | ||||
| 			genState: types.NewGenesisState(types.Params{ | ||||
| 				TokensPerVote:     10, | ||||
| 				MaxVotesPerSigner: 1024, | ||||
| 				MaxQuorums:        10, | ||||
| 				EpochBlocks:       5760, | ||||
| 				EncodedSlices:     1, | ||||
| 			}, 0, []*types.Signer{{ | ||||
| 				Account:  "0x0000000000000000000000000000000000000001", | ||||
| 				Socket:   "0.0.0.0:1234", | ||||
| 				PubkeyG1: make([]byte, 64), | ||||
| 				PubkeyG2: make([]byte, 128), | ||||
| 			}}, []*types.Quorums{{ | ||||
| 				Quorums: []*types.Quorum{{Signers: []string{"0x0000000000000000000000000000000000000001"}}}, | ||||
| 			}}), | ||||
| 			expectPass: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "invalid pubkeyG1 format", | ||||
| 			genState: types.NewGenesisState(types.Params{ | ||||
| 				TokensPerVote:     10, | ||||
| 				MaxVotesPerSigner: 1024, | ||||
| 				MaxQuorums:        10, | ||||
| 				EpochBlocks:       5760, | ||||
| 				EncodedSlices:     1, | ||||
| 			}, 0, []*types.Signer{{ | ||||
| 				Account:  "0000000000000000000000000000000000000001", | ||||
| 				Socket:   "0.0.0.0:1234", | ||||
| 				PubkeyG1: make([]byte, 63), | ||||
| 				PubkeyG2: make([]byte, 128), | ||||
| 			}}, []*types.Quorums{{ | ||||
| 				Quorums: []*types.Quorum{{Signers: []string{"0000000000000000000000000000000000000001"}}}, | ||||
| 			}}), | ||||
| 			expectPass: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "invalid pubkeyG2 format", | ||||
| 			genState: types.NewGenesisState(types.Params{ | ||||
| 				TokensPerVote:     10, | ||||
| 				MaxVotesPerSigner: 1024, | ||||
| 				MaxQuorums:        10, | ||||
| 				EpochBlocks:       5760, | ||||
| 				EncodedSlices:     1, | ||||
| 			}, 0, []*types.Signer{{ | ||||
| 				Account:  "0000000000000000000000000000000000000001", | ||||
| 				Socket:   "0.0.0.0:1234", | ||||
| 				PubkeyG1: make([]byte, 64), | ||||
| 				PubkeyG2: make([]byte, 129), | ||||
| 			}}, []*types.Quorums{{ | ||||
| 				Quorums: []*types.Quorum{{Signers: []string{"0000000000000000000000000000000000000001"}}}, | ||||
| 			}}), | ||||
| 			expectPass: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "history missing", | ||||
| 			genState: types.NewGenesisState(types.Params{ | ||||
| 				TokensPerVote:     10, | ||||
| 				MaxVotesPerSigner: 1024, | ||||
| 				MaxQuorums:        10, | ||||
| 				EpochBlocks:       5760, | ||||
| 				EncodedSlices:     1, | ||||
| 			}, 0, []*types.Signer{{ | ||||
| 				Account:  "0000000000000000000000000000000000000001", | ||||
| 				Socket:   "0.0.0.0:1234", | ||||
| 				PubkeyG1: make([]byte, 64), | ||||
| 				PubkeyG2: make([]byte, 128), | ||||
| 			}}, []*types.Quorums{}), | ||||
| 			expectPass: false, | ||||
| 		}, | ||||
| 	} | ||||
| 	for _, tc := range testCases { | ||||
| 		suite.Run(tc.name, func() { | ||||
| 			// Setup (note: suite.SetupTest is not run before every suite.Run)
 | ||||
| 			suite.App = app.NewTestApp() | ||||
| 			suite.Keeper = suite.App.GetDASignersKeeper() | ||||
| 			suite.Ctx = suite.App.NewContext(true, tmproto.Header{}) | ||||
| 
 | ||||
| 			// Run
 | ||||
| 			var exportedGenState *types.GenesisState | ||||
| 			run := func() { | ||||
| 				dasigners.InitGenesis(suite.Ctx, suite.Keeper, *tc.genState) | ||||
| 				exportedGenState = dasigners.ExportGenesis(suite.Ctx, suite.Keeper) | ||||
| 			} | ||||
| 			if tc.expectPass { | ||||
| 				suite.Require().NotPanics(run) | ||||
| 			} else { | ||||
| 				suite.Require().Panics(run) | ||||
| 			} | ||||
| 
 | ||||
| 			// Check
 | ||||
| 			if tc.expectPass { | ||||
| 				expectedJson, err := suite.App.AppCodec().MarshalJSON(tc.genState) | ||||
| 				suite.Require().NoError(err) | ||||
| 				actualJson, err := suite.App.AppCodec().MarshalJSON(exportedGenState) | ||||
| 				suite.Require().NoError(err) | ||||
| 				suite.Equal(expectedJson, actualJson) | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestGenesisTestSuite(t *testing.T) { | ||||
| 	suite.Run(t, new(GenesisTestSuite)) | ||||
| } | ||||
| @ -72,7 +72,7 @@ func (k Keeper) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { | ||||
| 	} | ||||
| 	if len(ballots) >= int(params.EncodedSlices) { | ||||
| 		for i := 0; i+int(params.EncodedSlices) <= len(ballots); i += int(params.EncodedSlices) { | ||||
| 			if int(params.MaxQuorums) < len(quorums.Quorums) { | ||||
| 			if int(params.MaxQuorums) <= len(quorums.Quorums) { | ||||
| 				break | ||||
| 			} | ||||
| 			quorum := types.Quorum{ | ||||
| @ -101,10 +101,6 @@ func (k Keeper) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { | ||||
| 			quorum.Signers[i] = ballots[i%n].account | ||||
| 		} | ||||
| 		quorums.Quorums = append(quorums.Quorums, &quorum) | ||||
| 	} else { | ||||
| 		quorums.Quorums = append(quorums.Quorums, &types.Quorum{ | ||||
| 			Signers: make([]string, 0), | ||||
| 		}) | ||||
| 	} | ||||
| 
 | ||||
| 	// save to store
 | ||||
|  | ||||
							
								
								
									
										138
									
								
								x/dasigners/v1/keeper/abci_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								x/dasigners/v1/keeper/abci_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,138 @@ | ||||
| package keeper_test | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/0glabs/0g-chain/x/dasigners/v1" | ||||
| 	"github.com/0glabs/0g-chain/x/dasigners/v1/keeper" | ||||
| 	"github.com/0glabs/0g-chain/x/dasigners/v1/testutil" | ||||
| 	"github.com/0glabs/0g-chain/x/dasigners/v1/types" | ||||
| 	abci "github.com/cometbft/cometbft/abci/types" | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 	"github.com/ethereum/go-ethereum/common" | ||||
| 	"github.com/stretchr/testify/suite" | ||||
| ) | ||||
| 
 | ||||
| type AbciTestSuite struct { | ||||
| 	testutil.Suite | ||||
| } | ||||
| 
 | ||||
| func (suite *AbciTestSuite) TestBeginBlock_NotContinuous() { | ||||
| 	// suite.App.InitializeFromGenesisStates()
 | ||||
| 	dasigners.InitGenesis(suite.Ctx, suite.Keeper, *types.DefaultGenesisState()) | ||||
| 	params := suite.Keeper.GetParams(suite.Ctx) | ||||
| 	suite.Require().Panics(func() { | ||||
| 		suite.Keeper.BeginBlock(suite.Ctx.WithBlockHeight(int64(params.EpochBlocks*2)), abci.RequestBeginBlock{}) | ||||
| 	}, "block height is not continuous") | ||||
| } | ||||
| 
 | ||||
| func (suite *AbciTestSuite) TestBeginBlock_Success() { | ||||
| 	// suite.App.InitializeFromGenesisStates()
 | ||||
| 	dasigners.InitGenesis(suite.Ctx, suite.Keeper, *types.DefaultGenesisState()) | ||||
| 	suite.Keeper.SetParams(suite.Ctx, types.Params{ | ||||
| 		TokensPerVote:     10, | ||||
| 		MaxVotesPerSigner: 200, | ||||
| 		MaxQuorums:        10, | ||||
| 		EpochBlocks:       5760, | ||||
| 		EncodedSlices:     10, | ||||
| 	}) | ||||
| 	params := suite.Keeper.GetParams(suite.Ctx) | ||||
| 	epoch, err := suite.Keeper.GetEpochNumber(suite.Ctx) | ||||
| 	suite.Require().NoError(err) | ||||
| 	cnt, err := suite.Keeper.GetQuorumCount(suite.Ctx, epoch) | ||||
| 	suite.Require().NoError(err) | ||||
| 	suite.Assert().EqualValues(cnt, 0) | ||||
| 	// set signer
 | ||||
| 	suite.Keeper.SetSigner(suite.Ctx, types.Signer{ | ||||
| 		Account:  "0000000000000000000000000000000000000001", | ||||
| 		Socket:   "0.0.0.0:1234", | ||||
| 		PubkeyG1: common.LeftPadBytes([]byte{1}, 32), | ||||
| 		PubkeyG2: common.LeftPadBytes([]byte{2}, 64), | ||||
| 	}) | ||||
| 	suite.Keeper.SetRegistration(suite.Ctx, epoch+1, "0000000000000000000000000000000000000001", common.LeftPadBytes([]byte{1}, 32)) | ||||
| 	suite.Ctx = suite.Ctx.WithBlockHeight(int64(params.EpochBlocks) * int64(epoch+1)) | ||||
| 	suite.Keeper.BeginBlock(suite.Ctx, abci.RequestBeginBlock{}) | ||||
| 	// check quorums
 | ||||
| 	lastEpoch := epoch | ||||
| 	epoch, err = suite.Keeper.GetEpochNumber(suite.Ctx) | ||||
| 	suite.Require().NoError(err) | ||||
| 	suite.Assert().EqualValues(epoch, lastEpoch+1) | ||||
| 	cnt, err = suite.Keeper.GetQuorumCount(suite.Ctx, epoch) | ||||
| 	suite.Require().NoError(err) | ||||
| 	suite.Assert().EqualValues(cnt, 0) | ||||
| 	// set delegation, 1 ballot
 | ||||
| 	suite.AddDelegation("0000000000000000000000000000000000000001", "0000000000000000000000000000000000000001", keeper.BondedConversionRate.Mul(sdk.NewIntFromUint64(params.TokensPerVote))) | ||||
| 	// set signer
 | ||||
| 	suite.Keeper.SetSigner(suite.Ctx, types.Signer{ | ||||
| 		Account:  "0000000000000000000000000000000000000001", | ||||
| 		Socket:   "0.0.0.0:1234", | ||||
| 		PubkeyG1: common.LeftPadBytes([]byte{1}, 32), | ||||
| 		PubkeyG2: common.LeftPadBytes([]byte{2}, 64), | ||||
| 	}) | ||||
| 	suite.Keeper.SetRegistration(suite.Ctx, epoch+1, "0000000000000000000000000000000000000001", common.LeftPadBytes([]byte{1}, 32)) | ||||
| 	suite.Ctx = suite.Ctx.WithBlockHeight(int64(params.EpochBlocks) * int64(epoch+1)) | ||||
| 	suite.Keeper.BeginBlock(suite.Ctx, abci.RequestBeginBlock{}) | ||||
| 	// check quorums
 | ||||
| 	lastEpoch = epoch | ||||
| 	epoch, err = suite.Keeper.GetEpochNumber(suite.Ctx) | ||||
| 	suite.Require().NoError(err) | ||||
| 	suite.Assert().EqualValues(epoch, lastEpoch+1) | ||||
| 	cnt, err = suite.Keeper.GetQuorumCount(suite.Ctx, epoch) | ||||
| 	suite.Require().NoError(err) | ||||
| 	suite.Assert().EqualValues(cnt, 1) | ||||
| 	// set delegation, 10 ballot
 | ||||
| 	suite.AddDelegation( | ||||
| 		"0000000000000000000000000000000000000001", | ||||
| 		"0000000000000000000000000000000000000001", | ||||
| 		keeper.BondedConversionRate.Mul(sdk.NewIntFromUint64(params.TokensPerVote)).Mul(sdk.NewIntFromUint64(9)), | ||||
| 	) | ||||
| 	suite.Keeper.SetRegistration(suite.Ctx, epoch+1, "0000000000000000000000000000000000000001", common.LeftPadBytes([]byte{1}, 32)) | ||||
| 	suite.Ctx = suite.Ctx.WithBlockHeight(int64(params.EpochBlocks) * int64(epoch+1)) | ||||
| 	suite.Keeper.BeginBlock(suite.Ctx, abci.RequestBeginBlock{}) | ||||
| 	// check quorums
 | ||||
| 	lastEpoch = epoch | ||||
| 	epoch, err = suite.Keeper.GetEpochNumber(suite.Ctx) | ||||
| 	suite.Require().NoError(err) | ||||
| 	suite.Assert().EqualValues(epoch, lastEpoch+1) | ||||
| 	cnt, err = suite.Keeper.GetQuorumCount(suite.Ctx, epoch) | ||||
| 	suite.Require().NoError(err) | ||||
| 	suite.Assert().EqualValues(cnt, 1) | ||||
| 	// set delegation, 11 ballot
 | ||||
| 	suite.AddDelegation( | ||||
| 		"0000000000000000000000000000000000000001", | ||||
| 		"0000000000000000000000000000000000000001", | ||||
| 		keeper.BondedConversionRate.Mul(sdk.NewIntFromUint64(params.TokensPerVote)).Mul(sdk.NewIntFromUint64(1)), | ||||
| 	) | ||||
| 	suite.Keeper.SetRegistration(suite.Ctx, epoch+1, "0000000000000000000000000000000000000001", common.LeftPadBytes([]byte{1}, 32)) | ||||
| 	suite.Ctx = suite.Ctx.WithBlockHeight(int64(params.EpochBlocks) * int64(epoch+1)) | ||||
| 	suite.Keeper.BeginBlock(suite.Ctx, abci.RequestBeginBlock{}) | ||||
| 	// check quorums
 | ||||
| 	lastEpoch = epoch | ||||
| 	epoch, err = suite.Keeper.GetEpochNumber(suite.Ctx) | ||||
| 	suite.Require().NoError(err) | ||||
| 	suite.Assert().EqualValues(epoch, lastEpoch+1) | ||||
| 	cnt, err = suite.Keeper.GetQuorumCount(suite.Ctx, epoch) | ||||
| 	suite.Require().NoError(err) | ||||
| 	suite.Assert().EqualValues(cnt, 2) | ||||
| 	// set delegation, 200 ballot
 | ||||
| 	suite.AddDelegation( | ||||
| 		"0000000000000000000000000000000000000001", | ||||
| 		"0000000000000000000000000000000000000001", | ||||
| 		keeper.BondedConversionRate.Mul(sdk.NewIntFromUint64(params.TokensPerVote)).Mul(sdk.NewIntFromUint64(200)), | ||||
| 	) | ||||
| 	suite.Keeper.SetRegistration(suite.Ctx, epoch+1, "0000000000000000000000000000000000000001", common.LeftPadBytes([]byte{1}, 32)) | ||||
| 	suite.Ctx = suite.Ctx.WithBlockHeight(int64(params.EpochBlocks) * int64(epoch+1)) | ||||
| 	suite.Keeper.BeginBlock(suite.Ctx, abci.RequestBeginBlock{}) | ||||
| 	// check quorums
 | ||||
| 	lastEpoch = epoch | ||||
| 	epoch, err = suite.Keeper.GetEpochNumber(suite.Ctx) | ||||
| 	suite.Require().NoError(err) | ||||
| 	suite.Assert().EqualValues(epoch, lastEpoch+1) | ||||
| 	cnt, err = suite.Keeper.GetQuorumCount(suite.Ctx, epoch) | ||||
| 	suite.Require().NoError(err) | ||||
| 	suite.Assert().EqualValues(cnt, 10) | ||||
| } | ||||
| 
 | ||||
| func TestAbciSuite(t *testing.T) { | ||||
| 	suite.Run(t, new(AbciTestSuite)) | ||||
| } | ||||
| @ -24,7 +24,7 @@ func (k Keeper) Signer( | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		if !found { | ||||
| 			return nil, nil | ||||
| 			return nil, types.ErrSignerNotFound | ||||
| 		} | ||||
| 		response.Signer[i] = &signer | ||||
| 	} | ||||
|  | ||||
							
								
								
									
										338
									
								
								x/dasigners/v1/keeper/keeper_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										338
									
								
								x/dasigners/v1/keeper/keeper_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,338 @@ | ||||
| package keeper_test | ||||
| 
 | ||||
| import ( | ||||
| 	"encoding/hex" | ||||
| 	"math/big" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/0glabs/0g-chain/crypto/bn254util" | ||||
| 	"github.com/0glabs/0g-chain/x/dasigners/v1" | ||||
| 	"github.com/0glabs/0g-chain/x/dasigners/v1/keeper" | ||||
| 	"github.com/0glabs/0g-chain/x/dasigners/v1/testutil" | ||||
| 	"github.com/0glabs/0g-chain/x/dasigners/v1/types" | ||||
| 	abci "github.com/cometbft/cometbft/abci/types" | ||||
| 	"github.com/consensys/gnark-crypto/ecc/bn254" | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 	"github.com/ethereum/go-ethereum/common" | ||||
| 	"github.com/stretchr/testify/suite" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	signer1 = "9685C4EB29309820CDC62663CC6CC82F3D42E964" | ||||
| 	signer2 = "9685C4EB29309820CDC62663CC6CC82F3D42E965" | ||||
| ) | ||||
| 
 | ||||
| type KeeperTestSuite struct { | ||||
| 	testutil.Suite | ||||
| } | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) testRegisterSignerInvalidSignature() { | ||||
| 	sk := big.NewInt(1) | ||||
| 	pkG1 := new(bn254.G1Affine).ScalarMultiplication(bn254util.GetG1Generator(), sk) | ||||
| 	pkG2 := new(bn254.G2Affine).ScalarMultiplication(bn254util.GetG2Generator(), sk) | ||||
| 	hash := types.PubkeyRegistrationHash(common.HexToAddress(signer1), big.NewInt(8888)) | ||||
| 	signature := new(bn254.G1Affine).ScalarMultiplication(hash, big.NewInt(2)) | ||||
| 	msg := &types.MsgRegisterSigner{ | ||||
| 		Signer: &types.Signer{ | ||||
| 			Account:  signer1, | ||||
| 			Socket:   "0.0.0.0:1234", | ||||
| 			PubkeyG1: bn254util.SerializeG1(pkG1), | ||||
| 			PubkeyG2: bn254util.SerializeG2(pkG2), | ||||
| 		}, | ||||
| 		Signature: bn254util.SerializeG1(signature), | ||||
| 	} | ||||
| 	_, err := suite.Keeper.RegisterSigner(sdk.WrapSDKContext(suite.Ctx), msg) | ||||
| 	suite.Assert().ErrorIs(err, types.ErrInvalidSignature) | ||||
| } | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) testRegisterSignerSuccess() *types.Signer { // resgister signer
 | ||||
| 	sk := big.NewInt(1) | ||||
| 	pkG1 := new(bn254.G1Affine).ScalarMultiplication(bn254util.GetG1Generator(), sk) | ||||
| 	pkG2 := new(bn254.G2Affine).ScalarMultiplication(bn254util.GetG2Generator(), sk) | ||||
| 	hash := types.PubkeyRegistrationHash(common.HexToAddress(signer1), big.NewInt(8888)) | ||||
| 	signature := new(bn254.G1Affine).ScalarMultiplication(hash, sk) | ||||
| 	signer := &types.Signer{ | ||||
| 		Account:  signer1, | ||||
| 		Socket:   "0.0.0.0:1234", | ||||
| 		PubkeyG1: bn254util.SerializeG1(pkG1), | ||||
| 		PubkeyG2: bn254util.SerializeG2(pkG2), | ||||
| 	} | ||||
| 	msg := &types.MsgRegisterSigner{ | ||||
| 		Signer:    signer, | ||||
| 		Signature: bn254util.SerializeG1(signature), | ||||
| 	} | ||||
| 	oldEventNum := len(suite.Ctx.EventManager().Events()) | ||||
| 	_, err := suite.Keeper.RegisterSigner(sdk.WrapSDKContext(suite.Ctx), msg) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	events := suite.Ctx.EventManager().Events() | ||||
| 	suite.Assert().EqualValues(len(events), oldEventNum+1) | ||||
| 	suite.Assert().EqualValues(events[len(events)-1], sdk.NewEvent( | ||||
| 		types.EventTypeUpdateSigner, | ||||
| 		sdk.NewAttribute(types.AttributeKeySigner, signer.Account), | ||||
| 		sdk.NewAttribute(types.AttributeKeySocket, signer.Socket), | ||||
| 		sdk.NewAttribute(types.AttributeKeyPublicKeyG1, hex.EncodeToString(signer.PubkeyG1)), | ||||
| 		sdk.NewAttribute(types.AttributeKeyPublicKeyG2, hex.EncodeToString(signer.PubkeyG2)), | ||||
| 	)) | ||||
| 	return signer | ||||
| } | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) testQuerySigner(signer *types.Signer) { | ||||
| 	response, err := suite.Keeper.Signer(sdk.WrapSDKContext(suite.Ctx), &types.QuerySignerRequest{ | ||||
| 		Accounts: []string{signer1}, | ||||
| 	}) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	suite.Assert().EqualValues(len(response.Signer), 1) | ||||
| 	suite.Assert().EqualValues(response.Signer[0], signer) | ||||
| 	_, err = suite.Keeper.Signer(sdk.WrapSDKContext(suite.Ctx), &types.QuerySignerRequest{ | ||||
| 		Accounts: []string{signer1, signer2}, | ||||
| 	}) | ||||
| 	suite.Assert().ErrorIs(err, types.ErrSignerNotFound) | ||||
| } | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) testUpdateSocket(signer *types.Signer) { | ||||
| 	signer.Socket = "0.0.0.0:2345" | ||||
| 	msg := &types.MsgUpdateSocket{ | ||||
| 		Account: signer2, | ||||
| 		Socket:  signer.Socket, | ||||
| 	} | ||||
| 	_, err := suite.Keeper.UpdateSocket(sdk.WrapSDKContext(suite.Ctx), msg) | ||||
| 	suite.Assert().ErrorIs(err, types.ErrSignerNotFound) | ||||
| 	msg.Account = signer.Account | ||||
| 	oldEventNum := len(suite.Ctx.EventManager().Events()) | ||||
| 	_, err = suite.Keeper.UpdateSocket(sdk.WrapSDKContext(suite.Ctx), msg) | ||||
| 	suite.Assert().NoError(err, types.ErrSignerNotFound) | ||||
| 	events := suite.Ctx.EventManager().Events() | ||||
| 	suite.Assert().EqualValues(len(events), oldEventNum+1) | ||||
| 	suite.Assert().EqualValues(events[len(events)-1], sdk.NewEvent( | ||||
| 		types.EventTypeUpdateSigner, | ||||
| 		sdk.NewAttribute(types.AttributeKeySigner, signer.Account), | ||||
| 		sdk.NewAttribute(types.AttributeKeySocket, signer.Socket), | ||||
| 		sdk.NewAttribute(types.AttributeKeyPublicKeyG1, hex.EncodeToString(signer.PubkeyG1)), | ||||
| 		sdk.NewAttribute(types.AttributeKeyPublicKeyG2, hex.EncodeToString(signer.PubkeyG2)), | ||||
| 	)) | ||||
| } | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) testRegisterEpochInvalidSignature() { | ||||
| 	sk := big.NewInt(2) | ||||
| 	hash := types.EpochRegistrationHash(common.HexToAddress(signer1), 1, big.NewInt(8888)) | ||||
| 	signature := new(bn254.G1Affine).ScalarMultiplication(hash, sk) | ||||
| 	msg := &types.MsgRegisterNextEpoch{ | ||||
| 		Account:   signer1, | ||||
| 		Signature: bn254util.SerializeG1(signature), | ||||
| 	} | ||||
| 	_, err := suite.Keeper.RegisterNextEpoch(sdk.WrapSDKContext(suite.Ctx), msg) | ||||
| 	suite.Assert().ErrorIs(err, types.ErrInvalidSignature) | ||||
| } | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) secondSigner() *types.Signer { | ||||
| 	sk := big.NewInt(11) | ||||
| 	pkG1 := new(bn254.G1Affine).ScalarMultiplication(bn254util.GetG1Generator(), sk) | ||||
| 	pkG2 := new(bn254.G2Affine).ScalarMultiplication(bn254util.GetG2Generator(), sk) | ||||
| 	hash := types.PubkeyRegistrationHash(common.HexToAddress(signer2), big.NewInt(8888)) | ||||
| 	signature := new(bn254.G1Affine).ScalarMultiplication(hash, sk) | ||||
| 	signer := &types.Signer{ | ||||
| 		Account:  signer2, | ||||
| 		Socket:   "0.0.0.0:1234", | ||||
| 		PubkeyG1: bn254util.SerializeG1(pkG1), | ||||
| 		PubkeyG2: bn254util.SerializeG2(pkG2), | ||||
| 	} | ||||
| 	msg := &types.MsgRegisterSigner{ | ||||
| 		Signer:    signer, | ||||
| 		Signature: bn254util.SerializeG1(signature), | ||||
| 	} | ||||
| 	oldEventNum := len(suite.Ctx.EventManager().Events()) | ||||
| 	_, err := suite.Keeper.RegisterSigner(sdk.WrapSDKContext(suite.Ctx), msg) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	events := suite.Ctx.EventManager().Events() | ||||
| 	suite.Assert().EqualValues(len(events), oldEventNum+1) | ||||
| 	suite.Assert().EqualValues(events[len(events)-1], sdk.NewEvent( | ||||
| 		types.EventTypeUpdateSigner, | ||||
| 		sdk.NewAttribute(types.AttributeKeySigner, signer.Account), | ||||
| 		sdk.NewAttribute(types.AttributeKeySocket, signer.Socket), | ||||
| 		sdk.NewAttribute(types.AttributeKeyPublicKeyG1, hex.EncodeToString(signer.PubkeyG1)), | ||||
| 		sdk.NewAttribute(types.AttributeKeyPublicKeyG2, hex.EncodeToString(signer.PubkeyG2)), | ||||
| 	)) | ||||
| 	// register epoch
 | ||||
| 	hash = types.EpochRegistrationHash(common.HexToAddress(signer2), 1, big.NewInt(8888)) | ||||
| 	signature = new(bn254.G1Affine).ScalarMultiplication(hash, sk) | ||||
| 	msg2 := &types.MsgRegisterNextEpoch{ | ||||
| 		Account:   signer2, | ||||
| 		Signature: bn254util.SerializeG1(signature), | ||||
| 	} | ||||
| 	_, err = suite.Keeper.RegisterNextEpoch(sdk.WrapSDKContext(suite.Ctx), msg2) | ||||
| 	suite.Assert().NoError(err, types.ErrSignerNotFound) | ||||
| 	return signer | ||||
| } | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) testRegisterEpochSuccess() { | ||||
| 	sk := big.NewInt(1) | ||||
| 	hash := types.EpochRegistrationHash(common.HexToAddress(signer1), 1, big.NewInt(8888)) | ||||
| 	signature := new(bn254.G1Affine).ScalarMultiplication(hash, sk) | ||||
| 	msg := &types.MsgRegisterNextEpoch{ | ||||
| 		Account:   signer1, | ||||
| 		Signature: bn254util.SerializeG1(signature), | ||||
| 	} | ||||
| 	_, err := suite.Keeper.RegisterNextEpoch(sdk.WrapSDKContext(suite.Ctx), msg) | ||||
| 	suite.Assert().NoError(err, types.ErrSignerNotFound) | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) newEpoch(params types.Params) { | ||||
| 	// 1st ballot of signer1: 1d5df5684184f84a8dbd20b158b6478a6e8eb021b1cf81ac281dd4c7af4370ed30231e1a6a1d76bac5f464f10c7e99afa8df3c4643ca447bfc80f248764ab2ac
 | ||||
| 	// 1st ballot of signer2: 103d29532b47eb7df57049180475d72737f7ab2be4a0f3614aedbb61c8a844a32c76fcbb29b937c56c577121dfd4be8041e2b4acfe2523ae54f0d6f604745b06
 | ||||
| 	// 2nd ballot of signer2: 93a5bb4c22640a155b18e24c0c584f2bc4bdd94ddb786d86ff3c3816d741e67f
 | ||||
| 	// sorted ballots: 2-1, 1-1, 2-2
 | ||||
| 	suite.Ctx = suite.Ctx.WithBlockHeight(int64(params.EpochBlocks) * 1) | ||||
| 	suite.Keeper.BeginBlock(suite.Ctx, abci.RequestBeginBlock{}) | ||||
| } | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) queryEpochNumber() { | ||||
| 	response, err := suite.Keeper.EpochNumber(sdk.WrapSDKContext(suite.Ctx), &types.QueryEpochNumberRequest{}) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	suite.Assert().EqualValues(response.EpochNumber, 1) | ||||
| } | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) queryQuorumCount() { | ||||
| 	response, err := suite.Keeper.QuorumCount(sdk.WrapSDKContext(suite.Ctx), &types.QueryQuorumCountRequest{ | ||||
| 		EpochNumber: 1, | ||||
| 	}) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	suite.Assert().EqualValues(response.QuorumCount, 1) | ||||
| } | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) queryEpochQuorum(params types.Params) { | ||||
| 	_, err := suite.Keeper.EpochQuorum(sdk.WrapSDKContext(suite.Ctx), &types.QueryEpochQuorumRequest{ | ||||
| 		EpochNumber: 1, | ||||
| 		QuorumId:    1, | ||||
| 	}) | ||||
| 	suite.Assert().ErrorIs(err, types.ErrQuorumIdOutOfBound) | ||||
| 	response, err := suite.Keeper.EpochQuorum(sdk.WrapSDKContext(suite.Ctx), &types.QueryEpochQuorumRequest{ | ||||
| 		EpochNumber: 1, | ||||
| 		QuorumId:    0, | ||||
| 	}) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	quorum := make([]string, 0) | ||||
| 	for i := 0; i < int(params.EncodedSlices); i += 1 { | ||||
| 		if i%3 == 1 { | ||||
| 			quorum = append(quorum, strings.ToLower(signer1)) | ||||
| 		} else { | ||||
| 			quorum = append(quorum, strings.ToLower(signer2)) | ||||
| 		} | ||||
| 	} | ||||
| 	suite.Assert().EqualValues(response.Quorum.Signers, quorum) | ||||
| } | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) queryEpochQuorumRow(params types.Params) { | ||||
| 	_, err := suite.Keeper.EpochQuorumRow(sdk.WrapSDKContext(suite.Ctx), &types.QueryEpochQuorumRowRequest{ | ||||
| 		EpochNumber: 1, | ||||
| 		QuorumId:    0, | ||||
| 		RowIndex:    uint32(params.EncodedSlices), | ||||
| 	}) | ||||
| 	suite.Assert().ErrorIs(err, types.ErrRowIndexOutOfBound) | ||||
| 	response, err := suite.Keeper.EpochQuorumRow(sdk.WrapSDKContext(suite.Ctx), &types.QueryEpochQuorumRowRequest{ | ||||
| 		EpochNumber: 1, | ||||
| 		QuorumId:    0, | ||||
| 		RowIndex:    0, | ||||
| 	}) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	suite.Assert().EqualValues(response.Signer, strings.ToLower(signer2)) | ||||
| 	response, err = suite.Keeper.EpochQuorumRow(sdk.WrapSDKContext(suite.Ctx), &types.QueryEpochQuorumRowRequest{ | ||||
| 		EpochNumber: 1, | ||||
| 		QuorumId:    0, | ||||
| 		RowIndex:    1, | ||||
| 	}) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	suite.Assert().EqualValues(response.Signer, strings.ToLower(signer1)) | ||||
| 	response, err = suite.Keeper.EpochQuorumRow(sdk.WrapSDKContext(suite.Ctx), &types.QueryEpochQuorumRowRequest{ | ||||
| 		EpochNumber: 1, | ||||
| 		QuorumId:    0, | ||||
| 		RowIndex:    2, | ||||
| 	}) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	suite.Assert().EqualValues(response.Signer, strings.ToLower(signer2)) | ||||
| } | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) queryAggregatePubkeyG1(params types.Params) { | ||||
| 	quorumBitMap := make([]byte, params.EncodedSlices/8-1) | ||||
| 	_, err := suite.Keeper.AggregatePubkeyG1(sdk.WrapSDKContext(suite.Ctx), &types.QueryAggregatePubkeyG1Request{ | ||||
| 		EpochNumber:  1, | ||||
| 		QuorumId:     0, | ||||
| 		QuorumBitmap: quorumBitMap, | ||||
| 	}) | ||||
| 	suite.Assert().ErrorIs(err, types.ErrQuorumBitmapLengthMismatch) | ||||
| 	quorumBitMap = append(quorumBitMap, byte(0)) | ||||
| 	response, err := suite.Keeper.AggregatePubkeyG1(sdk.WrapSDKContext(suite.Ctx), &types.QueryAggregatePubkeyG1Request{ | ||||
| 		EpochNumber:  1, | ||||
| 		QuorumId:     0, | ||||
| 		QuorumBitmap: quorumBitMap, | ||||
| 	}) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	pkG1 := new(bn254.G1Affine).ScalarMultiplication(bn254util.GetG1Generator(), big.NewInt(0)) | ||||
| 	suite.Assert().EqualValues(response.AggregatePubkeyG1, bn254util.SerializeG1(pkG1)) | ||||
| 	suite.Assert().EqualValues(response.Total, params.EncodedSlices) | ||||
| 	suite.Assert().EqualValues(response.Hit, 0) | ||||
| 
 | ||||
| 	quorumBitMap[0] = byte(1) | ||||
| 	response, err = suite.Keeper.AggregatePubkeyG1(sdk.WrapSDKContext(suite.Ctx), &types.QueryAggregatePubkeyG1Request{ | ||||
| 		EpochNumber:  1, | ||||
| 		QuorumId:     0, | ||||
| 		QuorumBitmap: quorumBitMap, | ||||
| 	}) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	pkG1 = new(bn254.G1Affine).ScalarMultiplication(bn254util.GetG1Generator(), big.NewInt(11)) | ||||
| 	suite.Assert().EqualValues(response.AggregatePubkeyG1, bn254util.SerializeG1(pkG1)) | ||||
| 	suite.Assert().EqualValues(response.Total, params.EncodedSlices) | ||||
| 	suite.Assert().EqualValues(response.Hit, params.EncodedSlices*2/3) | ||||
| 
 | ||||
| 	quorumBitMap[0] = byte(2) | ||||
| 	response, err = suite.Keeper.AggregatePubkeyG1(sdk.WrapSDKContext(suite.Ctx), &types.QueryAggregatePubkeyG1Request{ | ||||
| 		EpochNumber:  1, | ||||
| 		QuorumId:     0, | ||||
| 		QuorumBitmap: quorumBitMap, | ||||
| 	}) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	pkG1 = new(bn254.G1Affine).ScalarMultiplication(bn254util.GetG1Generator(), big.NewInt(1)) | ||||
| 	suite.Assert().EqualValues(response.AggregatePubkeyG1, bn254util.SerializeG1(pkG1)) | ||||
| 	suite.Assert().EqualValues(response.Total, params.EncodedSlices) | ||||
| 	suite.Assert().EqualValues(response.Hit, params.EncodedSlices/3) | ||||
| 
 | ||||
| 	quorumBitMap[0] = byte(3) | ||||
| 	response, err = suite.Keeper.AggregatePubkeyG1(sdk.WrapSDKContext(suite.Ctx), &types.QueryAggregatePubkeyG1Request{ | ||||
| 		EpochNumber:  1, | ||||
| 		QuorumId:     0, | ||||
| 		QuorumBitmap: quorumBitMap, | ||||
| 	}) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	pkG1 = new(bn254.G1Affine).ScalarMultiplication(bn254util.GetG1Generator(), big.NewInt(1+11)) | ||||
| 	suite.Assert().EqualValues(response.AggregatePubkeyG1, bn254util.SerializeG1(pkG1)) | ||||
| 	suite.Assert().EqualValues(response.Total, params.EncodedSlices) | ||||
| 	suite.Assert().EqualValues(response.Hit, params.EncodedSlices) | ||||
| } | ||||
| 
 | ||||
| func (suite *KeeperTestSuite) Test_Keeper() { | ||||
| 	// suite.App.InitializeFromGenesisStates()
 | ||||
| 	dasigners.InitGenesis(suite.Ctx, suite.Keeper, *types.DefaultGenesisState()) | ||||
| 	// add delegation
 | ||||
| 	params := suite.Keeper.GetParams(suite.Ctx) | ||||
| 	suite.AddDelegation(signer1, signer1, keeper.BondedConversionRate.Mul(sdk.NewIntFromUint64(params.TokensPerVote))) | ||||
| 	suite.AddDelegation(signer2, signer1, keeper.BondedConversionRate.Mul(sdk.NewIntFromUint64(params.TokensPerVote)).Mul(sdk.NewIntFromUint64(2))) | ||||
| 	// test
 | ||||
| 	suite.testRegisterSignerInvalidSignature() | ||||
| 	signerOne := suite.testRegisterSignerSuccess() | ||||
| 	suite.testQuerySigner(signerOne) | ||||
| 	suite.testUpdateSocket(signerOne) | ||||
| 	suite.testRegisterEpochInvalidSignature() | ||||
| 	suite.testRegisterEpochSuccess() | ||||
| 	suite.secondSigner() | ||||
| 	suite.newEpoch(params) | ||||
| 	suite.queryEpochNumber() | ||||
| 	suite.queryQuorumCount() | ||||
| 	suite.queryEpochQuorum(params) | ||||
| 	suite.queryEpochQuorumRow(params) | ||||
| 	suite.queryAggregatePubkeyG1(params) | ||||
| } | ||||
| 
 | ||||
| func TestKeeperSuite(t *testing.T) { | ||||
| 	suite.Run(t, new(KeeperTestSuite)) | ||||
| } | ||||
							
								
								
									
										88
									
								
								x/dasigners/v1/testutil/suite.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								x/dasigners/v1/testutil/suite.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,88 @@ | ||||
| package testutil | ||||
| 
 | ||||
| import ( | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"cosmossdk.io/math" | ||||
| 	tmproto "github.com/cometbft/cometbft/proto/tendermint/types" | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 	stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" | ||||
| 	"github.com/ethereum/go-ethereum/crypto" | ||||
| 	"github.com/stretchr/testify/suite" | ||||
| 
 | ||||
| 	"github.com/0glabs/0g-chain/app" | ||||
| 	"github.com/0glabs/0g-chain/chaincfg" | ||||
| 	"github.com/0glabs/0g-chain/x/dasigners/v1/keeper" | ||||
| 	"github.com/0glabs/0g-chain/x/dasigners/v1/types" | ||||
| 	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" | ||||
| 	"github.com/evmos/ethermint/crypto/ethsecp256k1" | ||||
| ) | ||||
| 
 | ||||
| // Suite implements a test suite for the module integration tests
 | ||||
| type Suite struct { | ||||
| 	suite.Suite | ||||
| 
 | ||||
| 	Keeper        keeper.Keeper | ||||
| 	StakingKeeper *stakingkeeper.Keeper | ||||
| 	App           app.TestApp | ||||
| 	Ctx           sdk.Context | ||||
| 	QueryClient   types.QueryClient | ||||
| 	Addresses     []sdk.AccAddress | ||||
| } | ||||
| 
 | ||||
| // SetupTest instantiates a new app, keepers, and sets suite state
 | ||||
| func (suite *Suite) SetupTest() { | ||||
| 	chaincfg.SetSDKConfig() | ||||
| 	suite.App = app.NewTestApp() | ||||
| 	suite.App.InitializeFromGenesisStates() | ||||
| 	suite.Keeper = suite.App.GetDASignersKeeper() | ||||
| 	suite.StakingKeeper = suite.App.GetStakingKeeper() | ||||
| 
 | ||||
| 	// make block header
 | ||||
| 	privkey, _ := ethsecp256k1.GenerateKey() | ||||
| 	consAddress := sdk.ConsAddress(privkey.PubKey().Address()) | ||||
| 	key, err := privkey.ToECDSA() | ||||
| 	suite.Assert().NoError(err) | ||||
| 	hexAddr := strings.ToLower(crypto.PubkeyToAddress(key.PublicKey).Hex()[2:]) | ||||
| 	valAddr, err := sdk.ValAddressFromHex(hexAddr) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	suite.Ctx = suite.App.NewContext(true, tmproto.Header{Height: 1, ChainID: app.TestChainId, ProposerAddress: consAddress}) | ||||
| 	newValidator, err := stakingtypes.NewValidator(valAddr, privkey.PubKey(), stakingtypes.Description{}) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	err = suite.StakingKeeper.SetValidatorByConsAddr(suite.Ctx, newValidator) | ||||
| 	suite.Assert().NoError(err) | ||||
| 	suite.StakingKeeper.SetValidator(suite.Ctx, newValidator) | ||||
| 
 | ||||
| 	_, accAddresses := app.GeneratePrivKeyAddressPairs(10) | ||||
| 	suite.Addresses = accAddresses | ||||
| 
 | ||||
| 	// Set query client
 | ||||
| 	queryHelper := suite.App.NewQueryServerTestHelper(suite.Ctx) | ||||
| 	queryHandler := suite.Keeper | ||||
| 	types.RegisterQueryServer(queryHelper, queryHandler) | ||||
| 	suite.QueryClient = types.NewQueryClient(queryHelper) | ||||
| } | ||||
| 
 | ||||
| func (suite *Suite) AddDelegation(from string, to string, amount math.Int) { | ||||
| 	accAddr, err := sdk.AccAddressFromHexUnsafe(from) | ||||
| 	suite.Require().NoError(err) | ||||
| 	valAddr, err := sdk.ValAddressFromHex(to) | ||||
| 	suite.Require().NoError(err) | ||||
| 	validator, found := suite.StakingKeeper.GetValidator(suite.Ctx, valAddr) | ||||
| 	if !found { | ||||
| 		consPriv, err := ethsecp256k1.GenerateKey() | ||||
| 		suite.Require().NoError(err) | ||||
| 		newValidator, err := stakingtypes.NewValidator(valAddr, consPriv.PubKey(), stakingtypes.Description{}) | ||||
| 		suite.Require().NoError(err) | ||||
| 		validator = newValidator | ||||
| 	} | ||||
| 	validator.Tokens = validator.Tokens.Add(amount) | ||||
| 	validator.DelegatorShares = validator.DelegatorShares.Add(amount.ToLegacyDec()) | ||||
| 	suite.StakingKeeper.SetValidator(suite.Ctx, validator) | ||||
| 	bonded := suite.Keeper.GetDelegatorBonded(suite.Ctx, accAddr) | ||||
| 	suite.StakingKeeper.SetDelegation(suite.Ctx, stakingtypes.Delegation{ | ||||
| 		DelegatorAddress: accAddr.String(), | ||||
| 		ValidatorAddress: valAddr.String(), | ||||
| 		Shares:           bonded.Add(amount).ToLegacyDec(), | ||||
| 	}) | ||||
| } | ||||
							
								
								
									
										25
									
								
								x/dasigners/v1/testutil/types.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								x/dasigners/v1/testutil/types.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | ||||
| package testutil | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 
 | ||||
| 	sdkmath "cosmossdk.io/math" | ||||
| 	"github.com/cosmos/cosmos-sdk/codec" | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 	"github.com/gogo/protobuf/proto" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| 
 | ||||
| // Avoid cluttering test cases with long function names
 | ||||
| func I(in int64) sdkmath.Int                { return sdkmath.NewInt(in) } | ||||
| func D(str string) sdk.Dec                  { return sdk.MustNewDecFromStr(str) } | ||||
| func C(denom string, amount int64) sdk.Coin { return sdk.NewInt64Coin(denom, amount) } | ||||
| func Cs(coins ...sdk.Coin) sdk.Coins        { return sdk.NewCoins(coins...) } | ||||
| 
 | ||||
| func AssertProtoMessageJSON(t *testing.T, cdc codec.Codec, expected proto.Message, actual proto.Message) { | ||||
| 	expectedJson, err := cdc.MarshalJSON(expected) | ||||
| 	assert.NoError(t, err) | ||||
| 	actualJson, err := cdc.MarshalJSON(actual) | ||||
| 	assert.NoError(t, err) | ||||
| 	assert.Equal(t, string(expectedJson), string(actualJson)) | ||||
| } | ||||
							
								
								
									
										22
									
								
								x/dasigners/v1/types/hash_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								x/dasigners/v1/types/hash_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | ||||
| package types_test | ||||
| 
 | ||||
| import ( | ||||
| 	"math/big" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/0glabs/0g-chain/x/dasigners/v1/types" | ||||
| 	"github.com/ethereum/go-ethereum/common" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| 
 | ||||
| func Test_PubkeyRegistrationHash(t *testing.T) { | ||||
| 	hash := types.PubkeyRegistrationHash(common.HexToAddress("0x9685C4EB29309820CDC62663CC6CC82F3D42E964"), big.NewInt(8888)) | ||||
| 	assert.Equal(t, hash.X.String(), "17347288745752564851578145205408924577042674846071448492673629564958667746090") | ||||
| 	assert.Equal(t, hash.Y.String(), "21456041422468658262738002909407073439935597271458862589356790821116767485654") | ||||
| } | ||||
| 
 | ||||
| func Test_EpochRegistrationHash(t *testing.T) { | ||||
| 	hash := types.EpochRegistrationHash(common.HexToAddress("0x9685C4EB29309820CDC62663CC6CC82F3D42E964"), 1, big.NewInt(8888)) | ||||
| 	assert.Equal(t, hash.X.String(), "13283083124528531674735853832182424672122091139683454761857829308708073730285") | ||||
| 	assert.Equal(t, hash.Y.String(), "21773064143788270772276852950775943855438706734263253481317981346601766662828") | ||||
| } | ||||
							
								
								
									
										63
									
								
								x/dasigners/v1/types/msg_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								x/dasigners/v1/types/msg_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,63 @@ | ||||
| package types_test | ||||
| 
 | ||||
| import ( | ||||
| 	"math/big" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/0glabs/0g-chain/crypto/bn254util" | ||||
| 	"github.com/0glabs/0g-chain/x/dasigners/v1/testutil" | ||||
| 	"github.com/0glabs/0g-chain/x/dasigners/v1/types" | ||||
| 	"github.com/consensys/gnark-crypto/ecc/bn254" | ||||
| 	"github.com/ethereum/go-ethereum/common" | ||||
| 	"github.com/stretchr/testify/suite" | ||||
| ) | ||||
| 
 | ||||
| type MsgTestSuite struct { | ||||
| 	testutil.Suite | ||||
| } | ||||
| 
 | ||||
| func (suite *MsgTestSuite) Test_MsgRegisterSigner() { | ||||
| 	sk := big.NewInt(1) | ||||
| 	pkG1 := new(bn254.G1Affine).ScalarMultiplication(bn254util.GetG1Generator(), sk) | ||||
| 	pkG2 := new(bn254.G2Affine).ScalarMultiplication(bn254util.GetG2Generator(), sk) | ||||
| 	hash := types.PubkeyRegistrationHash(common.HexToAddress("0x9685C4EB29309820CDC62663CC6CC82F3D42E964"), big.NewInt(8888)) | ||||
| 	signature := new(bn254.G1Affine).ScalarMultiplication(hash, sk) | ||||
| 	msg := &types.MsgRegisterSigner{ | ||||
| 		Signer: &types.Signer{ | ||||
| 			Account:  "9685C4EB29309820CDC62663CC6CC82F3D42E964", | ||||
| 			Socket:   "0.0.0.0:1234", | ||||
| 			PubkeyG1: bn254util.SerializeG1(pkG1), | ||||
| 			PubkeyG2: bn254util.SerializeG2(pkG2), | ||||
| 		}, | ||||
| 		Signature: bn254util.SerializeG1(signature), | ||||
| 	} | ||||
| 	suite.Assert().EqualValues(len(msg.GetSigners()), 1) | ||||
| 	suite.Assert().EqualValues(msg.GetSigners()[0].String(), "0g1j6zuf6efxzvzpnwxye3ucmxg9u7596ty686hna") | ||||
| 	suite.Assert().NoError(msg.ValidateBasic()) | ||||
| } | ||||
| 
 | ||||
| func (suite *MsgTestSuite) Test_MsgUpdateSocket() { | ||||
| 	msg := &types.MsgUpdateSocket{ | ||||
| 		Account: "9685C4EB29309820CDC62663CC6CC82F3D42E964", | ||||
| 		Socket:  "0.0.0.0:1234", | ||||
| 	} | ||||
| 	suite.Assert().EqualValues(len(msg.GetSigners()), 1) | ||||
| 	suite.Assert().EqualValues(msg.GetSigners()[0].String(), "0g1j6zuf6efxzvzpnwxye3ucmxg9u7596ty686hna") | ||||
| 	suite.Assert().NoError(msg.ValidateBasic()) | ||||
| } | ||||
| 
 | ||||
| func (suite *MsgTestSuite) Test_MsgRegisterNextEpoch() { | ||||
| 	hash := types.EpochRegistrationHash(common.HexToAddress("0x9685C4EB29309820CDC62663CC6CC82F3D42E964"), 1, big.NewInt(8888)) | ||||
| 	signature := new(bn254.G1Affine).ScalarMultiplication(hash, big.NewInt(1)) | ||||
| 	msg := &types.MsgRegisterNextEpoch{ | ||||
| 		Account:   "9685C4EB29309820CDC62663CC6CC82F3D42E964", | ||||
| 		Signature: bn254util.SerializeG1(signature), | ||||
| 	} | ||||
| 	suite.Assert().EqualValues(len(msg.GetSigners()), 1) | ||||
| 	suite.Assert().EqualValues(msg.GetSigners()[0].String(), "0g1j6zuf6efxzvzpnwxye3ucmxg9u7596ty686hna") | ||||
| 	suite.Assert().NoError(msg.ValidateBasic()) | ||||
| } | ||||
| 
 | ||||
| func TestSuite(t *testing.T) { | ||||
| 	suite.Run(t, new(MsgTestSuite)) | ||||
| } | ||||
							
								
								
									
										28
									
								
								x/dasigners/v1/types/signer_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								x/dasigners/v1/types/signer_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | ||||
| package types_test | ||||
| 
 | ||||
| import ( | ||||
| 	"math/big" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/0glabs/0g-chain/crypto/bn254util" | ||||
| 	"github.com/0glabs/0g-chain/x/dasigners/v1/types" | ||||
| 	"github.com/consensys/gnark-crypto/ecc/bn254" | ||||
| 	"github.com/ethereum/go-ethereum/common" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| 
 | ||||
| func Test_ValidateSignature(t *testing.T) { | ||||
| 	sk := big.NewInt(1) | ||||
| 	pkG1 := new(bn254.G1Affine).ScalarMultiplication(bn254util.GetG1Generator(), sk) | ||||
| 	pkG2 := new(bn254.G2Affine).ScalarMultiplication(bn254util.GetG2Generator(), sk) | ||||
| 	signer := types.Signer{ | ||||
| 		Account:  "9685C4EB29309820CDC62663CC6CC82F3D42E964", | ||||
| 		Socket:   "0.0.0.0:1234", | ||||
| 		PubkeyG1: bn254util.SerializeG1(pkG1), | ||||
| 		PubkeyG2: bn254util.SerializeG2(pkG2), | ||||
| 	} | ||||
| 	assert.NoError(t, signer.Validate()) | ||||
| 	hash := types.PubkeyRegistrationHash(common.HexToAddress("0x9685C4EB29309820CDC62663CC6CC82F3D42E964"), big.NewInt(8888)) | ||||
| 	signature := new(bn254.G1Affine).ScalarMultiplication(hash, big.NewInt(1)) | ||||
| 	assert.Equal(t, signer.ValidateSignature(hash, signature), true) | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 MiniFrenchBread
						MiniFrenchBread