Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: record challenge attestation result #268

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions e2e/core/basesuite.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import (
"time"

"cosmossdk.io/math"
"github.com/bnb-chain/greenfield/sdk/client"
"github.com/bnb-chain/greenfield/sdk/keys"
"github.com/bnb-chain/greenfield/sdk/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/tx"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/stretchr/testify/suite"

"github.com/bnb-chain/greenfield/sdk/client"
"github.com/bnb-chain/greenfield/sdk/keys"
"github.com/bnb-chain/greenfield/sdk/types"
)

type SPKeyManagers struct {
Expand Down
14 changes: 10 additions & 4 deletions e2e/tests/challenge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,13 +208,16 @@ func (s *ChallengeTestSuite) TestNormalAttest() {
queryRes, err := s.Client.ChallengeQueryClient.LatestAttestedChallenges(context.Background(), &challengetypes.QueryLatestAttestedChallengesRequest{})
s.Require().NoError(err)
found := false
for _, challengeId := range queryRes.ChallengeIds {
if challengeId == event.ChallengeId {
result := challengetypes.CHALLENGE_FAILED
for _, challenge := range queryRes.Challenges {
if challenge.Id == event.ChallengeId {
found = true
result = challenge.Result
break
}
}
s.Require().True(found)
s.Require().True(result == challengetypes.CHALLENGE_SUCCEED)
}

func (s *ChallengeTestSuite) TestHeartbeatAttest() {
Expand Down Expand Up @@ -286,13 +289,16 @@ func (s *ChallengeTestSuite) TestHeartbeatAttest() {
queryRes, err := s.Client.ChallengeQueryClient.LatestAttestedChallenges(context.Background(), &challengetypes.QueryLatestAttestedChallengesRequest{})
s.Require().NoError(err)
found = false
for _, challengeId := range queryRes.ChallengeIds {
if challengeId == event.ChallengeId {
result := challengetypes.CHALLENGE_SUCCEED
for _, challenge := range queryRes.Challenges {
if challenge.Id == event.ChallengeId {
found = true
result = challenge.Result
break
}
}
s.Require().True(found)
s.Require().True(result == challengetypes.CHALLENGE_FAILED)
}

func (s *ChallengeTestSuite) TestFailedAttest_ChallengeExpired() {
Expand Down
3 changes: 2 additions & 1 deletion e2e/tests/eip712_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import (
"math"
"testing"

"github.com/stretchr/testify/suite"

"github.com/bnb-chain/greenfield/e2e/core"
storageutils "github.com/bnb-chain/greenfield/testutil/storage"
storagetypes "github.com/bnb-chain/greenfield/x/storage/types"
"github.com/stretchr/testify/suite"
)

type Eip712TestSuite struct {
Expand Down
10 changes: 8 additions & 2 deletions e2e/tests/storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,7 @@ func (s *StorageTestSuite) TestDiscontinueObject_Normal() {
}
}

time.Sleep(200 * time.Millisecond)
events := make([]storagetypes.EventDeleteObject, 0)
for heightBefore <= heightAfter {
blockRes, err := s.TmClient.TmClient.BlockResults(context.Background(), &heightBefore)
Expand Down Expand Up @@ -1107,6 +1108,7 @@ func (s *StorageTestSuite) TestDiscontinueObject_Normal() {
}
}

time.Sleep(200 * time.Millisecond)
events = make([]storagetypes.EventDeleteObject, 0)
for heightBefore <= heightAfter {
blockRes, err := s.TmClient.TmClient.BlockResults(context.Background(), &heightBefore)
Expand Down Expand Up @@ -1140,7 +1142,7 @@ func (s *StorageTestSuite) TestDiscontinueObject_UserDeleted() {
heightBefore := txRes.Height
heightAfter := int64(0)
for {
time.Sleep(500 * time.Millisecond)
time.Sleep(200 * time.Millisecond)
statusRes, err := s.TmClient.TmClient.Status(context.Background())
s.Require().NoError(err)
blockTime := statusRes.SyncInfo.LatestBlockTime.Unix()
Expand All @@ -1155,6 +1157,7 @@ func (s *StorageTestSuite) TestDiscontinueObject_UserDeleted() {
}
}

time.Sleep(200 * time.Millisecond)
events := make([]storagetypes.EventDeleteObject, 0)
for heightBefore <= heightAfter {
blockRes, err := s.TmClient.TmClient.BlockResults(context.Background(), &heightBefore)
Expand Down Expand Up @@ -1211,6 +1214,7 @@ func (s *StorageTestSuite) TestDiscontinueBucket_Normal() {
}
}

time.Sleep(200 * time.Millisecond)
events := make([]storagetypes.EventDeleteBucket, 0)
for heightBefore <= heightAfter {
blockRes, err := s.TmClient.TmClient.BlockResults(context.Background(), &heightBefore)
Expand Down Expand Up @@ -1250,6 +1254,7 @@ func (s *StorageTestSuite) TestDiscontinueBucket_Normal() {
}
}

time.Sleep(200 * time.Millisecond)
events = make([]storagetypes.EventDeleteBucket, 0)
for heightBefore <= heightAfter {
blockRes, err := s.TmClient.TmClient.BlockResults(context.Background(), &heightBefore)
Expand Down Expand Up @@ -1286,7 +1291,7 @@ func (s *StorageTestSuite) TestDiscontinueBucket_UserDeleted() {
heightBefore := txRes.Height
heightAfter := int64(0)
for {
time.Sleep(500 * time.Millisecond)
time.Sleep(200 * time.Millisecond)
statusRes, err := s.TmClient.TmClient.Status(context.Background())
s.Require().NoError(err)
blockTime := statusRes.SyncInfo.LatestBlockTime.Unix()
Expand All @@ -1301,6 +1306,7 @@ func (s *StorageTestSuite) TestDiscontinueBucket_UserDeleted() {
}
}

time.Sleep(200 * time.Millisecond)
events := make([]storagetypes.EventDeleteBucket, 0)
for heightBefore <= heightAfter {
blockRes, err := s.TmClient.TmClient.BlockResults(context.Background(), &heightBefore)
Expand Down
6 changes: 3 additions & 3 deletions proto/greenfield/challenge/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ service Query {
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/greenfield/challenge/params";
}
// Queries the latest attested challenge ids.
// Queries the latest attested challenges.
rpc LatestAttestedChallenges(QueryLatestAttestedChallengesRequest) returns (QueryLatestAttestedChallengesResponse) {
option (google.api.http).get = "/greenfield/challenge/latest_attested_challenge";
option (google.api.http).get = "/greenfield/challenge/latest_attested_challenges";
}
// Queries the inturn challenger.
rpc InturnAttestationSubmitter(QueryInturnAttestationSubmitterRequest) returns (QueryInturnAttestationSubmitterResponse) {
Expand All @@ -45,7 +45,7 @@ message QueryLatestAttestedChallengesRequest {}

// QueryLatestAttestedChallengesResponse is response type for the Query/LatestAttestedChallenges RPC method.
message QueryLatestAttestedChallengesResponse {
repeated uint64 challengeIds = 1;
repeated AttestedChallenge challenges = 1;
}

// QueryInturnAttestationSubmitterRequest is request type for the Query/InturnAttestationSubmitter RPC method.
Expand Down
13 changes: 11 additions & 2 deletions proto/greenfield/challenge/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,23 @@ message Challenge {
uint64 expired_height = 2;
}

// AttestedChallenge records the challenge which are attested.
message AttestedChallenge {
// The id of the challenge.
uint64 id = 1;

// The attestation result of the challenge.
VoteResult result = 2;
}

// AttestedChallengeIds stored fixed number of the latest attested challenge ids.
// To use the storage more efficiently, a circular queue will be constructed using these fields.
message AttestedChallengeIds {
// The fixed number of challenge ids to save.
uint64 size = 1;

// The latest attested challenge ids.
repeated uint64 ids = 2;
// The latest attested challenges.
repeated AttestedChallenge challenges = 2;

// The cursor to retrieve data from the ids field.
int64 cursor = 3;
Expand Down
8 changes: 8 additions & 0 deletions swagger/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@
}
}
},
{
"url": "./tmp-swagger-gen/greenfield/challenge/query.swagger.json",
"operationIds": {
"rename": {
"Params": "ChallengeParams"
}
}
},
{
"url": "./tmp-swagger-gen/greenfield/payment/query.swagger.json",
"operationIds": {
Expand Down
60 changes: 31 additions & 29 deletions x/challenge/keeper/challenge.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,26 +76,28 @@ func (k Keeper) encodeUint64(data uint64) []byte {
return bz
}

// GetAttestChallengeIds gets the challenge id of the latest attestation challenge
func (k Keeper) GetAttestChallengeIds(ctx sdk.Context) []uint64 {
// GetAttestedChallenges gets the latest attested challenges
func (k Keeper) GetAttestedChallenges(ctx sdk.Context) []*types.AttestedChallenge {
store := ctx.KVStore(k.storeKey)
sizeBz := store.Get(types.AttestChallengeIdsSizeKey)
sizeBz := store.Get(types.AttestedChallengesSizeKey)

if sizeBz == nil {
return []uint64{}
return []*types.AttestedChallenge{}
}

size := binary.BigEndian.Uint64(sizeBz)
cursor := binary.BigEndian.Uint64(store.Get(types.AttestChallengeIdsCursorKey))
cursor := binary.BigEndian.Uint64(store.Get(types.AttestedChallengesCursorKey))

result := []uint64{}
result := []*types.AttestedChallenge{}
current := cursor
idsStore := prefix.NewStore(store, types.AttestChallengeIdsPrefix)
challengeStore := prefix.NewStore(store, types.AttestedChallengesPrefix)
for {
current = (current + 1) % size
idBz := idsStore.Get(k.encodeUint64(current))
if idBz != nil {
result = append(result, binary.BigEndian.Uint64(idBz))
challengeBz := challengeStore.Get(k.encodeUint64(current))
if challengeBz != nil {
var challenge types.AttestedChallenge
k.cdc.MustUnmarshal(challengeBz, &challenge)
result = append(result, &challenge)
}
if current == cursor {
break
Expand All @@ -104,54 +106,54 @@ func (k Keeper) GetAttestChallengeIds(ctx sdk.Context) []uint64 {
return result
}

// AppendAttestChallengeId sets the new id of challenge to the store
func (k Keeper) AppendAttestChallengeId(ctx sdk.Context, challengeId uint64) {
// AppendAttestedChallenge sets the new id of challenge to the store
func (k Keeper) AppendAttestedChallenge(ctx sdk.Context, challenge *types.AttestedChallenge) {
toKeep := k.GetParams(ctx).AttestationKeptCount

store := ctx.KVStore(k.storeKey)
sizeBz := store.Get(types.AttestChallengeIdsSizeKey)
sizeBz := store.Get(types.AttestedChallengesSizeKey)

idsStore := prefix.NewStore(store, types.AttestChallengeIdsPrefix)
challengeStore := prefix.NewStore(store, types.AttestedChallengesPrefix)
if sizeBz == nil { // the first time to append
store.Set(types.AttestChallengeIdsSizeKey, k.encodeUint64(toKeep))
k.enqueueAttestChallengeId(store, idsStore, challengeId)
store.Set(types.AttestedChallengesSizeKey, k.encodeUint64(toKeep))
k.enqueueAttestedChallenge(store, challengeStore, challenge)
return
}

size := binary.BigEndian.Uint64(sizeBz)
if size != toKeep { // the parameter changes, which is not frequent
currentIds := k.GetAttestChallengeIds(ctx)
currentChallenges := k.GetAttestedChallenges(ctx)

iterator := storetypes.KVStorePrefixIterator(idsStore, []byte{})
iterator := storetypes.KVStorePrefixIterator(challengeStore, []byte{})
defer iterator.Close()

for ; iterator.Valid(); iterator.Next() {
idsStore.Delete(iterator.Key())
challengeStore.Delete(iterator.Key())
}

store.Set(types.AttestChallengeIdsSizeKey, k.encodeUint64(toKeep))
store.Delete(types.AttestChallengeIdsCursorKey)
store.Set(types.AttestedChallengesSizeKey, k.encodeUint64(toKeep))
store.Delete(types.AttestedChallengesCursorKey)

for _, id := range currentIds {
k.enqueueAttestChallengeId(store, idsStore, id)
for _, c := range currentChallenges {
k.enqueueAttestedChallenge(store, challengeStore, c)
}
}
k.enqueueAttestChallengeId(store, idsStore, challengeId)
k.enqueueAttestedChallenge(store, challengeStore, challenge)
}

func (k Keeper) enqueueAttestChallengeId(store, idsStore storetypes.KVStore, challengeId uint64) {
size := binary.BigEndian.Uint64(store.Get(types.AttestChallengeIdsSizeKey))
cursorBz := store.Get(types.AttestChallengeIdsCursorKey)
func (k Keeper) enqueueAttestedChallenge(store, challengeStore storetypes.KVStore, challenge *types.AttestedChallenge) {
size := binary.BigEndian.Uint64(store.Get(types.AttestedChallengesSizeKey))
cursorBz := store.Get(types.AttestedChallengesCursorKey)
cursor := uint64(0)
if cursorBz != nil {
cursor = binary.BigEndian.Uint64(cursorBz)
cursor = (cursor + 1) % size
}

cursorBz = k.encodeUint64(cursor)
store.Set(types.AttestChallengeIdsCursorKey, cursorBz)
store.Set(types.AttestedChallengesCursorKey, cursorBz)

idsStore.Set(cursorBz, k.encodeUint64(challengeId))
challengeStore.Set(cursorBz, k.cdc.MustMarshal(challenge))
}

// GetChallengeCountCurrentBlock gets the count of challenges
Expand Down
44 changes: 28 additions & 16 deletions x/challenge/keeper/challenge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,41 +28,53 @@ func TestGetChallengeId(t *testing.T) {
require.True(t, keeper.GetChallengeId(ctx) == 100)
}

func TestAttestedChallengeIds(t *testing.T) {
func TestAttestedChallenges(t *testing.T) {
keeper, ctx := makeKeeper(t)
params := types.DefaultParams()
params.AttestationKeptCount = 5
err := keeper.SetParams(ctx, params)
require.NoError(t, err)

keeper.AppendAttestChallengeId(ctx, 1)
keeper.AppendAttestChallengeId(ctx, 2)
keeper.AppendAttestChallengeId(ctx, 3)
require.Equal(t, []uint64{1, 2, 3}, keeper.GetAttestChallengeIds(ctx))
c1 := &types.AttestedChallenge{Id: 1, Result: types.CHALLENGE_FAILED}
c2 := &types.AttestedChallenge{Id: 2, Result: types.CHALLENGE_SUCCEED}
c3 := &types.AttestedChallenge{Id: 3, Result: types.CHALLENGE_FAILED}

keeper.AppendAttestChallengeId(ctx, 4)
keeper.AppendAttestChallengeId(ctx, 5)
keeper.AppendAttestChallengeId(ctx, 6)
require.Equal(t, []uint64{2, 3, 4, 5, 6}, keeper.GetAttestChallengeIds(ctx))
keeper.AppendAttestedChallenge(ctx, c1)
keeper.AppendAttestedChallenge(ctx, c2)
keeper.AppendAttestedChallenge(ctx, c3)
require.Equal(t, []*types.AttestedChallenge{c1, c2, c3}, keeper.GetAttestedChallenges(ctx))

c4 := &types.AttestedChallenge{Id: 4, Result: types.CHALLENGE_FAILED}
c5 := &types.AttestedChallenge{Id: 5, Result: types.CHALLENGE_FAILED}
c6 := &types.AttestedChallenge{Id: 6, Result: types.CHALLENGE_SUCCEED}

keeper.AppendAttestedChallenge(ctx, c4)
keeper.AppendAttestedChallenge(ctx, c5)
keeper.AppendAttestedChallenge(ctx, c6)
require.Equal(t, []*types.AttestedChallenge{c2, c3, c4, c5, c6}, keeper.GetAttestedChallenges(ctx))

params.AttestationKeptCount = 8
err = keeper.SetParams(ctx, params)
require.NoError(t, err)
keeper.AppendAttestChallengeId(ctx, 7)
keeper.AppendAttestChallengeId(ctx, 8)
require.Equal(t, []uint64{2, 3, 4, 5, 6, 7, 8}, keeper.GetAttestChallengeIds(ctx))
c7 := &types.AttestedChallenge{Id: 7, Result: types.CHALLENGE_FAILED}
c8 := &types.AttestedChallenge{Id: 8, Result: types.CHALLENGE_SUCCEED}
keeper.AppendAttestedChallenge(ctx, c7)
keeper.AppendAttestedChallenge(ctx, c8)
require.Equal(t, []*types.AttestedChallenge{c2, c3, c4, c5, c6, c7, c8}, keeper.GetAttestedChallenges(ctx))

params.AttestationKeptCount = 3
err = keeper.SetParams(ctx, params)
require.NoError(t, err)
keeper.AppendAttestChallengeId(ctx, 9)
require.Equal(t, []uint64{7, 8, 9}, keeper.GetAttestChallengeIds(ctx))
c9 := &types.AttestedChallenge{Id: 9, Result: types.CHALLENGE_SUCCEED}
keeper.AppendAttestedChallenge(ctx, c9)
require.Equal(t, []*types.AttestedChallenge{c7, c8, c9}, keeper.GetAttestedChallenges(ctx))

params.AttestationKeptCount = 5
err = keeper.SetParams(ctx, params)
require.NoError(t, err)
keeper.AppendAttestChallengeId(ctx, 10)
require.Equal(t, []uint64{7, 8, 9, 10}, keeper.GetAttestChallengeIds(ctx))
c10 := &types.AttestedChallenge{Id: 10, Result: types.CHALLENGE_SUCCEED}
keeper.AppendAttestedChallenge(ctx, c10)
require.Equal(t, []*types.AttestedChallenge{c7, c8, c9, c10}, keeper.GetAttestedChallenges(ctx))
}

func makeKeeper(t *testing.T) (*keeper.Keeper, sdk.Context) {
Expand Down
4 changes: 2 additions & 2 deletions x/challenge/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ func (k Keeper) LatestAttestedChallenges(goCtx context.Context, req *types.Query

ctx := sdk.UnwrapSDKContext(goCtx)

challengeId := k.GetAttestChallengeIds(ctx)
challenges := k.GetAttestedChallenges(ctx)

return &types.QueryLatestAttestedChallengesResponse{
ChallengeIds: challengeId,
Challenges: challenges,
}, nil
}

Expand Down
Loading