mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-11-10 10:05:18 +00:00
test: dasigners precompile
Some checks are pending
Continuous Integration (Commit) / lint (push) Waiting to run
Some checks are pending
Continuous Integration (Commit) / lint (push) Waiting to run
This commit is contained in:
parent
88359d2e3c
commit
831e257507
377
precompiles/dasigners/dasigners_test.go
Normal file
377
precompiles/dasigners/dasigners_test.go
Normal file
@ -0,0 +1,377 @@
|
||||
package dasigners_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"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)
|
||||
fmt.Printf("%v\n", out[0])
|
||||
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))
|
||||
}
|
Loading…
Reference in New Issue
Block a user