Skip to content

Commit

Permalink
Added unit tests for emission balancer actions and adding rows to dat…
Browse files Browse the repository at this point in the history
…aset
  • Loading branch information
kpachhai committed Oct 8, 2024
1 parent 8633d25 commit 7a713e5
Show file tree
Hide file tree
Showing 13 changed files with 1,401 additions and 29 deletions.
134 changes: 134 additions & 0 deletions actions/claim_delegation_stake_rewards_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// Copyright (C) 2024, Nuklai. All rights reserved.
// See the file LICENSE for licensing terms.

package actions

import (
"context"
"testing"

"github.com/ava-labs/avalanchego/ids"
"github.com/nuklai/nuklaivm/emission"
"github.com/nuklai/nuklaivm/storage"
"github.com/stretchr/testify/require"

"github.com/ava-labs/hypersdk/chain/chaintest"
"github.com/ava-labs/hypersdk/codec/codectest"
"github.com/ava-labs/hypersdk/state"
)

func TestClaimDelegationStakeRewardsActionFailure(t *testing.T) {
emission.MockNewEmission(&emission.MockEmission{LastAcceptedBlockHeight: 10, StakeRewards: 20})

actor := codectest.NewRandomAddress()
nodeID := ids.GenerateTestNodeID()

tests := []chaintest.ActionTest{
{
Name: "StakeMissing",
Actor: actor,
Action: &ClaimDelegationStakeRewards{
NodeID: nodeID, // Non-existent stake
},
State: chaintest.NewInMemoryStore(),
ExpectedErr: ErrStakeMissing,
},
{
Name: "StakeNotStarted",
Actor: actor,
Action: &ClaimDelegationStakeRewards{
NodeID: nodeID,
},
State: func() state.Mutable {
store := chaintest.NewInMemoryStore()
// Set stake with end block greater than the current block height
require.NoError(t, storage.SetDelegatorStake(context.Background(), store, actor, nodeID, 25, 50, 1000, actor))
return store
}(),
ExpectedErr: ErrStakeNotStarted,
},
}

for _, tt := range tests {
tt.Run(context.Background(), t)
}
}

func TestClaimDelegationStakeRewardsActionSuccess(t *testing.T) {
emission.MockNewEmission(&emission.MockEmission{LastAcceptedBlockHeight: 51, StakeRewards: 20})

actor := codectest.NewRandomAddress()
nodeID := ids.GenerateTestNodeID()

tests := []chaintest.ActionTest{
{
Name: "ValidClaim",
ActionID: ids.GenerateTestID(),
Actor: actor,
Action: &ClaimDelegationStakeRewards{
NodeID: nodeID,
},
State: func() state.Mutable {
store := chaintest.NewInMemoryStore()
// Set stake with end block less than the current block height
require.NoError(t, storage.SetDelegatorStake(context.Background(), store, actor, nodeID, 25, 50, 1000, actor))
return store
}(),
Assertion: func(ctx context.Context, t *testing.T, store state.Mutable) {
// Check if balance is correctly updated
balance, err := storage.GetAssetAccountBalanceNoController(ctx, store, storage.NAIAddress, actor)
require.NoError(t, err)
require.Equal(t, uint64(20), balance)

// Check if the stake was claimed correctly
exists, _, _, _, rewardAddress, _, _ := storage.GetDelegatorStakeNoController(ctx, store, actor, nodeID)
require.True(t, exists)
require.Equal(t, actor, rewardAddress)
},
ExpectedOutputs: &ClaimDelegationStakeRewardsResult{
StakeStartBlock: 25,
StakeEndBlock: 50,
StakedAmount: 1000,
BalanceBeforeClaim: 0,
BalanceAfterClaim: 20,
DistributedTo: actor,
},
},
}

for _, tt := range tests {
tt.Run(context.Background(), t)
}
}

// BenchmarkClaimDelegationStakeRewards remains unchanged.
func BenchmarkClaimDelegationStakeRewards(b *testing.B) {
require := require.New(b)
actor := codectest.NewRandomAddress()
nodeID := ids.GenerateTestNodeID()

emission.MockNewEmission(&emission.MockEmission{LastAcceptedBlockHeight: 51, StakeRewards: 20})

claimStakeRewardsBenchmark := &chaintest.ActionBenchmark{
Name: "ClaimStakeRewardsBenchmark",
Actor: actor,
Action: &ClaimDelegationStakeRewards{
NodeID: nodeID,
},
CreateState: func() state.Mutable {
store := chaintest.NewInMemoryStore()
// Set stake with end block less than the current block height
require.NoError(storage.SetDelegatorStake(context.Background(), store, actor, nodeID, 25, 50, 1000, actor))
return store
},
Assertion: func(ctx context.Context, b *testing.B, store state.Mutable) {
// Check if balance is correctly updated
balance, err := storage.GetAssetAccountBalanceNoController(ctx, store, storage.NAIAddress, actor)
require.NoError(err)
require.Equal(b, uint64(20), balance)
},
}

ctx := context.Background()
claimStakeRewardsBenchmark.Run(ctx, b)
}
138 changes: 138 additions & 0 deletions actions/claim_validator_stake_rewards_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
// Copyright (C) 2024, Nuklai. All rights reserved.
// See the file LICENSE for licensing terms.

package actions

import (
"context"
"testing"

"github.com/ava-labs/avalanchego/ids"
"github.com/nuklai/nuklaivm/emission"
"github.com/nuklai/nuklaivm/storage"
"github.com/stretchr/testify/require"

"github.com/ava-labs/hypersdk/chain/chaintest"
"github.com/ava-labs/hypersdk/codec/codectest"
"github.com/ava-labs/hypersdk/state"
)

func TestClaimValidatorStakeRewardsActionFailure(t *testing.T) {
emission.MockNewEmission(&emission.MockEmission{LastAcceptedBlockHeight: 10, StakeRewards: 20})

actor := codectest.NewRandomAddress()
nodeID := ids.GenerateTestNodeID()

tests := []chaintest.ActionTest{
{
Name: "StakeMissing",
Actor: actor,
Action: &ClaimValidatorStakeRewards{
NodeID: nodeID, // Non-existent stake
},
State: chaintest.NewInMemoryStore(),
ExpectedErr: ErrStakeMissing,
},
{
Name: "StakeNotStarted",
Actor: actor,
Action: &ClaimValidatorStakeRewards{
NodeID: nodeID,
},
State: func() state.Mutable {
store := chaintest.NewInMemoryStore()
// Set validator stake with end block greater than the current block height
require.NoError(t, storage.SetValidatorStake(context.Background(), store, nodeID, 25, 50, 5000, 10, actor, actor))
return store
}(),
ExpectedErr: ErrStakeNotStarted,
},
}

for _, tt := range tests {
tt.Run(context.Background(), t)
}
}

func TestClaimValidatorStakeRewardsActionSuccess(t *testing.T) {
emission.MockNewEmission(&emission.MockEmission{LastAcceptedBlockHeight: 51, StakeRewards: 20})

actor := codectest.NewRandomAddress()
nodeID := ids.GenerateTestNodeID()

tests := []chaintest.ActionTest{
{
Name: "ValidClaim",
ActionID: ids.GenerateTestID(),
Actor: actor,
Action: &ClaimValidatorStakeRewards{
NodeID: nodeID,
},
State: func() state.Mutable {
store := chaintest.NewInMemoryStore()
// Set validator stake with end block less than the current block height
require.NoError(t, storage.SetValidatorStake(context.Background(), store, nodeID, 25, 50, emission.GetStakingConfig().MinValidatorStake, 10, actor, actor))
// Set the balance for the validator
require.NoError(t, storage.SetAssetAccountBalance(context.Background(), store, storage.NAIAddress, actor, 0))
return store
}(),
Assertion: func(ctx context.Context, t *testing.T, store state.Mutable) {
// Check if balance is correctly updated
balance, err := storage.GetAssetAccountBalanceNoController(ctx, store, storage.NAIAddress, actor)
require.NoError(t, err)
require.Equal(t, uint64(20), balance)

// Check if the stake still exists after claiming rewards
exists, _, _, _, _, rewardAddress, _, _ := storage.GetValidatorStakeNoController(ctx, store, nodeID)
require.True(t, exists)
require.Equal(t, actor, rewardAddress)
},
ExpectedOutputs: &ClaimValidatorStakeRewardsResult{
StakeStartBlock: 25,
StakeEndBlock: 50,
StakedAmount: emission.GetStakingConfig().MinValidatorStake,
DelegationFeeRate: 10,
BalanceBeforeClaim: 0,
BalanceAfterClaim: 20,
DistributedTo: actor,
},
},
}

for _, tt := range tests {
tt.Run(context.Background(), t)
}
}

func BenchmarkClaimValidatorStakeRewards(b *testing.B) {
require := require.New(b)
actor := codectest.NewRandomAddress()
nodeID := ids.GenerateTestNodeID()

emission.MockNewEmission(&emission.MockEmission{LastAcceptedBlockHeight: 51, StakeRewards: 20})

claimValidatorStakeRewardsBenchmark := &chaintest.ActionBenchmark{
Name: "ClaimValidatorStakeRewardsBenchmark",
Actor: actor,
Action: &ClaimValidatorStakeRewards{
NodeID: nodeID,
},
CreateState: func() state.Mutable {
store := chaintest.NewInMemoryStore()
// Set validator stake with end block less than the current block height
require.NoError(storage.SetValidatorStake(context.Background(), store, nodeID, 25, 50, emission.GetStakingConfig().MinValidatorStake, 10, actor, actor))
// Set the balance for the validator
require.NoError(storage.SetAssetAccountBalance(context.Background(), store, storage.NAIAddress, actor, 0))
return store
},
Assertion: func(ctx context.Context, b *testing.B, store state.Mutable) {
// Check if balance is correctly updated after claiming rewards
balance, err := storage.GetAssetAccountBalanceNoController(ctx, store, storage.NAIAddress, actor)
require.NoError(err)
require.Equal(b, uint64(20), balance) // Reward amount set by emission instance
},
}

ctx := context.Background()
claimValidatorStakeRewardsBenchmark.Run(ctx, b)
}
36 changes: 15 additions & 21 deletions actions/complete_contribute_dataset.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,19 @@ func (d *CompleteContributeDataset) Execute(
actor codec.Address,
_ ids.ID,
) (codec.Typed, error) {
// Check if the dataset exists
_, _, _, _, _, _, _, _, marketplaceAssetAddress, _, _, _, _, _, _, owner, err := storage.GetDatasetInfoNoController(ctx, mu, d.DatasetAddress)
if err != nil {
return nil, err
}
if actor != owner {
return nil, ErrWrongOwner
}
// Check if the dataset is already on sale
if marketplaceAssetAddress != codec.EmptyAddress {
return nil, ErrDatasetAlreadyOnSale
}

// Check if the dataset contribution exists
datasetAddress, dataLocation, dataIdentifier, contributor, active, err := storage.GetDatasetContributionInfoNoController(ctx, mu, d.DatasetContributionID)
if err != nil {
Expand All @@ -84,32 +97,12 @@ func (d *CompleteContributeDataset) Execute(
return nil, ErrDatasetContributorMismatch
}

// Check if the dataset exists
_, _, _, _, _, _, _, _, marketplaceAssetAddress, _, _, _, _, _, _, owner, err := storage.GetDatasetInfoNoController(ctx, mu, d.DatasetAddress)
if err != nil {
return nil, err
}
if actor != owner {
return nil, ErrWrongOwner
}

// Check if the dataset is already on sale
if marketplaceAssetAddress != codec.EmptyAddress {
return nil, ErrDatasetAlreadyOnSale
}

// Retrieve the asset info
assetType, name, symbol, _, _, _, totalSupply, _, _, _, _, _, _, err := storage.GetAssetInfoNoController(ctx, mu, d.DatasetAddress)
if err != nil {
return nil, err
}

// Check if the nftAddress already exists
nftAddress := codec.CreateAddress(nconsts.AssetFractionalTokenID, d.DatasetContributionID)
if storage.AssetExists(ctx, mu, nftAddress) {
return nil, ErrNFTAlreadyExists
}

// Minting logic for non-fungible tokens
if _, err := storage.MintAsset(ctx, mu, d.DatasetAddress, d.DatasetContributor, 1); err != nil {
return nil, err
Expand All @@ -122,7 +115,8 @@ func (d *CompleteContributeDataset) Execute(
if err != nil {
return nil, err
}
symbol = utils.CombineWithSuffix(symbol, totalSupply+1, storage.MaxSymbolSize)
nftAddress := codec.CreateAddress(nconsts.AssetFractionalTokenID, d.DatasetContributionID)
symbol = utils.CombineWithSuffix(symbol, totalSupply, storage.MaxSymbolSize)
if err := storage.SetAssetInfo(ctx, mu, nftAddress, assetType, name, symbol, 0, metadataNFT, []byte(d.DatasetAddress.String()), 0, 1, d.DatasetContributor, codec.EmptyAddress, codec.EmptyAddress, codec.EmptyAddress, codec.EmptyAddress); err != nil {
return nil, err
}
Expand Down
Loading

0 comments on commit 7a713e5

Please sign in to comment.