Skip to content

Commit

Permalink
Refactored actions to use codec.address
Browse files Browse the repository at this point in the history
  • Loading branch information
kpachhai committed Oct 7, 2024
1 parent 4ccdfbe commit 20312c0
Show file tree
Hide file tree
Showing 49 changed files with 819 additions and 1,089 deletions.
21 changes: 6 additions & 15 deletions actions/burn_asset_ft.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func (*BurnAssetFT) GetTypeID() uint8 {

func (b *BurnAssetFT) StateKeys(actor codec.Address) state.Keys {
return state.Keys{
string(storage.AssetInfoKey(b.AssetAddress)): state.Read | state.Write,
string(storage.AssetInfoKey(b.AssetAddress)): state.Read | state.Write,
string(storage.AssetAccountBalanceKey(b.AssetAddress, actor)): state.Read | state.Write,
}
}
Expand All @@ -63,24 +63,15 @@ func (b *BurnAssetFT) Execute(
return nil, ErrAssetTypeInvalid
}

// Check that actor does not burn move than what they currently have
balance, err := storage.GetAssetAccountBalanceNoController(ctx, mu, b.AssetAddress, actor)
if err != nil {
return nil, err
}
if balance < b.Value {
return nil, ErrInsufficientAssetBalance
}

// Burning logic for fungible tokens
newBalance, err := storage.BurnAsset(ctx, mu, b.AssetAddress, actor, b.Value)
if err != nil {
return nil, err
}

return &BurnAssetFTResult{
OldBalance: newBalance + b.Value,
NewBalance: newBalance,
OldBalance: newBalance + b.Value,
NewBalance: newBalance,
}, nil
}

Expand All @@ -106,16 +97,16 @@ var (
)

type BurnAssetFTResult struct {
OldBalance uint64 `serialize:"true" json:"old_balance"`
NewBalance uint64 `serialize:"true" json:"new_balance"`
OldBalance uint64 `serialize:"true" json:"old_balance"`
NewBalance uint64 `serialize:"true" json:"new_balance"`
}

func (*BurnAssetFTResult) GetTypeID() uint8 {
return nconsts.BurnAssetFTID
}

func (*BurnAssetFTResult) Size() int {
return consts.Uint64Len*2
return consts.Uint64Len * 2
}

func (r *BurnAssetFTResult) Marshal(p *codec.Packer) {
Expand Down
19 changes: 14 additions & 5 deletions actions/claim_delegation_stake_rewards.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"errors"

"github.com/ava-labs/avalanchego/ids"
smath "github.com/ava-labs/avalanchego/utils/math"
"github.com/nuklai/nuklaivm/emission"
"github.com/nuklai/nuklaivm/storage"

Expand Down Expand Up @@ -35,8 +36,8 @@ func (*ClaimDelegationStakeRewards) GetTypeID() uint8 {

func (c *ClaimDelegationStakeRewards) StateKeys(actor codec.Address) state.Keys {
return state.Keys{
string(storage.BalanceKey(actor, ids.Empty)): state.All,
string(storage.DelegatorStakeKey(actor, c.NodeID)): state.Read,
string(storage.DelegatorStakeKey(actor, c.NodeID)): state.Read,
string(storage.AssetAccountBalanceKey(storage.NAIAddress, actor)): state.All,
}
}

Expand Down Expand Up @@ -74,17 +75,25 @@ func (c *ClaimDelegationStakeRewards) Execute(
return nil, err
}

balance, err := storage.AddBalance(ctx, mu, rewardAddress, ids.Empty, rewardAmount, true)
// Get the reward
balance, err := storage.GetAssetAccountBalanceNoController(ctx, mu, storage.NAIAddress, rewardAddress)
if err != nil {
return nil, err
}
newBalance, err := smath.Add(balance, rewardAmount)
if err != nil {
return nil, err
}
if err = storage.SetAssetAccountBalance(ctx, mu, storage.NAIAddress, rewardAddress, newBalance); err != nil {
return nil, err
}

return &ClaimDelegationStakeRewardsResult{
StakeStartBlock: stakeStartBlock,
StakeEndBlock: stakeEndBlock,
StakedAmount: stakedAmount,
BalanceBeforeClaim: balance - rewardAmount,
BalanceAfterClaim: balance,
BalanceBeforeClaim: balance,
BalanceAfterClaim: newBalance,
DistributedTo: rewardAddress,
}, nil
}
Expand Down
96 changes: 32 additions & 64 deletions actions/claim_marketplace_payment.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"strconv"

"github.com/ava-labs/avalanchego/ids"
smath "github.com/ava-labs/avalanchego/utils/math"
"github.com/nuklai/nuklaivm/emission"
"github.com/nuklai/nuklaivm/storage"
"github.com/nuklai/nuklaivm/utils"
Expand All @@ -33,14 +34,12 @@ var (
)

type ClaimMarketplacePayment struct {
// DatasetID ID
DatasetID ids.ID `json:"dataset_id"`

// Marketplace ID(This is also the asset ID in the marketplace that represents the dataset)
MarketplaceAssetID ids.ID `json:"marketplace_asset_id"`
// Marketplace asset address that represents the dataset subscription in the
// marketplace
MarketplaceAssetAddress codec.Address `serialize:"true" json:"marketplace_asset_address"`

// Asset to use for the payment
AssetForPayment ids.ID `json:"asset_for_payment"`
PaymentAssetAddress codec.Address `serialize:"true" json:"payment_asset_address"`
}

func (*ClaimMarketplacePayment) GetTypeID() uint8 {
Expand All @@ -49,10 +48,8 @@ func (*ClaimMarketplacePayment) GetTypeID() uint8 {

func (c *ClaimMarketplacePayment) StateKeys(actor codec.Address) state.Keys {
return state.Keys{
string(storage.DatasetInfoKey(c.DatasetID)): state.Read,
string(storage.AssetInfoKey(c.MarketplaceAssetID)): state.Read | state.Write,
string(storage.AssetInfoKey(c.AssetForPayment)): state.Read,
string(storage.BalanceKey(actor, c.AssetForPayment)): state.Allocate | state.Write,
string(storage.AssetInfoKey(c.MarketplaceAssetAddress)): state.Read | state.Write,
string(storage.AssetAccountBalanceKey(c.PaymentAssetAddress, actor)): state.All,
}
}

Expand All @@ -64,43 +61,31 @@ func (c *ClaimMarketplacePayment) Execute(
actor codec.Address,
_ ids.ID,
) (codec.Typed, error) {
// Check if the dataset exists
exists, _, _, _, _, _, _, _, _, _, baseAsset, _, _, _, _, _, owner, err := storage.GetDatasetInfoNoController(ctx, mu, c.DatasetID)
// Check for the asset
assetType, name, symbol, decimals, metadata, uri, totalSupply, maxSupply, owner, mintActor, pauseUnpauseActor, freezeUnfreezeActor, enableDisableKYCAccountActor, err := storage.GetAssetInfoNoController(ctx, mu, c.MarketplaceAssetAddress)
if err != nil {
return nil, err
}
if !exists {
return nil, ErrDatasetNotFound
// Ensure the asset is a marketplace token
if assetType != nconsts.AssetMarketplaceTokenID {
return nil, ErrOutputWrongAssetType
}

// Check if the user is the owner of the dataset
// Only the onwer can claim the payment
// Check if the user is the owner of the asset
// Only the owner can claim the payment
if owner != actor {
return nil, ErrWrongOwner
}

// Ensure assetForPayment is supported
if c.AssetForPayment != baseAsset {
return nil, ErrBaseAssetNotSupported
}

// Check if the marketplace asset exists
exists, assetType, name, symbol, decimals, metadata, uri, totalSupply, maxSupply, admin, mintActor, pauseUnpauseActor, freezeUnfreezeActor, enableDisableKYCAccountActor, err := storage.GetAssetInfoNoController(ctx, mu, c.MarketplaceAssetID)
// Convert the metdata to a map
metadataMap, err := utils.BytesToMap(metadata)
if err != nil {
return nil, err
}
if !exists {
return nil, ErrAssetMissing
}
if assetType != nconsts.AssetMarketplaceTokenID {
return nil, ErrOutputWrongAssetType
// Ensure paymentAssetAddress is supported
if metadataMap["paymentAssetAddress"] != c.PaymentAssetAddress.String() {
return nil, ErrPaymentAssetNotSupported
}

// Unmarshal the metadata JSON into a map
metadataMap, err := utils.BytesToMap(metadata)
if err != nil {
return nil, err
}
// Parse existing values from the metadata
paymentRemaining, err := strconv.ParseUint(metadataMap["paymentRemaining"], 10, 64)
if err != nil {
Expand All @@ -120,19 +105,7 @@ func (c *ClaimMarketplacePayment) Execute(

// Store the initial total before updating
initialTotal := paymentRemaining + paymentClaimed
// Parse the value of 1 in the base unit according to the number of decimals
decimalsToUse := uint8(nconsts.Decimals)
if c.AssetForPayment != ids.Empty {
exists, _, _, _, decimals, _, _, _, _, _, _, _, _, _, err = storage.GetAssetInfoNoController(ctx, mu, c.AssetForPayment)
if err != nil {
return nil, err
}
if !exists {
return nil, ErrAssetNotFound
}
decimalsToUse = decimals
}
baseValueOfOneUnit, _ := utils.ParseBalance("1", decimalsToUse)
baseValueOfOneUnit, _ := utils.ParseBalance("1", decimals)
// Get the current block height
currentBlockHeight := emission.GetEmission().GetLastAcceptedBlockHeight()
// Calculate the number of blocks the subscription has been active
Expand Down Expand Up @@ -169,13 +142,21 @@ func (c *ClaimMarketplacePayment) Execute(
}

// Update the asset with the updated metadata
if err := storage.SetAssetInfo(ctx, mu, c.MarketplaceAssetID, assetType, name, symbol, decimals, updatedMetadata, uri, totalSupply, maxSupply, admin, mintActor, pauseUnpauseActor, freezeUnfreezeActor, enableDisableKYCAccountActor); err != nil {
if err := storage.SetAssetInfo(ctx, mu, c.MarketplaceAssetAddress, assetType, name, symbol, decimals, updatedMetadata, uri, totalSupply, maxSupply, owner, mintActor, pauseUnpauseActor, freezeUnfreezeActor, enableDisableKYCAccountActor); err != nil {
return nil, err
}

// TODO: Distribute the rewards to all the users who contributed to the dataset
// This only distributes the rewards to the owner of the dataset
if _, err := storage.AddBalance(ctx, mu, actor, c.AssetForPayment, totalAccumulatedReward, true); err != nil {
balance, err := storage.GetAssetAccountBalanceNoController(ctx, mu, c.PaymentAssetAddress, actor)
if err != nil {
return nil, err
}
newBalance, err := smath.Add(balance, totalAccumulatedReward)
if err != nil {
return nil, err
}
if err = storage.SetAssetAccountBalance(ctx, mu, c.PaymentAssetAddress, actor, newBalance); err != nil {
return nil, err
}

Expand All @@ -197,23 +178,10 @@ func (*ClaimMarketplacePayment) ValidRange(chain.Rules) (int64, int64) {
return -1, -1
}

var _ chain.Marshaler = (*ClaimMarketplacePayment)(nil)

func (*ClaimMarketplacePayment) Size() int {
return ids.IDLen * 3
}

func (c *ClaimMarketplacePayment) Marshal(p *codec.Packer) {
p.PackID(c.DatasetID)
p.PackID(c.MarketplaceAssetID)
p.PackID(c.AssetForPayment)
}

func UnmarshalClaimMarketplacePayment(p *codec.Packer) (chain.Action, error) {
var claimPaymentResult ClaimMarketplacePayment
p.UnpackID(true, &claimPaymentResult.DatasetID)
p.UnpackID(true, &claimPaymentResult.MarketplaceAssetID)
p.UnpackID(false, &claimPaymentResult.AssetForPayment)
p.UnpackAddress(&claimPaymentResult.MarketplaceAssetAddress)
p.UnpackAddress(&claimPaymentResult.PaymentAssetAddress)
return &claimPaymentResult, p.Err()
}

Expand Down
38 changes: 19 additions & 19 deletions actions/claim_marketplace_payment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ func TestClaimMarketplacePaymentAction(t *testing.T) {
Name: "DatasetNotFound",
Actor: addr,
Action: &ClaimMarketplacePayment{
DatasetID: datasetID, // Non-existent dataset ID
MarketplaceAssetID: marketplaceAssetID,
AssetForPayment: baseAssetID,
DatasetID: datasetID, // Non-existent dataset ID
MarketplaceAssetAddress: marketplaceAssetID,
PaymentAssetAddress: baseAssetID,
},
State: chaintest.NewInMemoryStore(),
ExpectedErr: ErrDatasetNotFound,
Expand All @@ -45,9 +45,9 @@ func TestClaimMarketplacePaymentAction(t *testing.T) {
Name: "WrongOwner",
Actor: codectest.NewRandomAddress(), // Not the owner of the dataset
Action: &ClaimMarketplacePayment{
DatasetID: datasetID,
MarketplaceAssetID: marketplaceAssetID,
AssetForPayment: baseAssetID,
DatasetID: datasetID,
MarketplaceAssetAddress: marketplaceAssetID,
PaymentAssetAddress: baseAssetID,
},
State: func() state.Mutable {
store := chaintest.NewInMemoryStore()
Expand All @@ -61,25 +61,25 @@ func TestClaimMarketplacePaymentAction(t *testing.T) {
Name: "AssetNotSupported",
Actor: addr,
Action: &ClaimMarketplacePayment{
DatasetID: datasetID,
MarketplaceAssetID: marketplaceAssetID,
AssetForPayment: ids.GenerateTestID(), // Non-existent base asset ID
DatasetID: datasetID,
MarketplaceAssetAddress: marketplaceAssetID,
PaymentAssetAddress: ids.GenerateTestID(), // Non-existent base asset ID
},
State: func() state.Mutable {
store := chaintest.NewInMemoryStore()
// Set the dataset with the correct owner
require.NoError(t, storage.SetDatasetInfo(context.Background(), store, datasetID, []byte("Dataset Name"), []byte("Description"), []byte("Science"), []byte("MIT"), []byte("MIT"), []byte("http://license-url.com"), []byte("Metadata"), false, ids.Empty, ids.Empty, 0, 100, 0, 100, 100, addr))
return store
}(),
ExpectedErr: ErrBaseAssetNotSupported,
ExpectedErr: ErrPaymentAssetNotSupported,
},
{
Name: "NoPaymentRemaining",
Actor: addr,
Action: &ClaimMarketplacePayment{
DatasetID: datasetID,
MarketplaceAssetID: marketplaceAssetID,
AssetForPayment: baseAssetID,
DatasetID: datasetID,
MarketplaceAssetAddress: marketplaceAssetID,
PaymentAssetAddress: baseAssetID,
},
State: func() state.Mutable {
store := chaintest.NewInMemoryStore()
Expand All @@ -103,9 +103,9 @@ func TestClaimMarketplacePaymentAction(t *testing.T) {
ActionID: marketplaceAssetID,
Actor: addr,
Action: &ClaimMarketplacePayment{
DatasetID: datasetID,
MarketplaceAssetID: marketplaceAssetID,
AssetForPayment: baseAssetID,
DatasetID: datasetID,
MarketplaceAssetAddress: marketplaceAssetID,
PaymentAssetAddress: baseAssetID,
},
State: func() state.Mutable {
store := chaintest.NewInMemoryStore()
Expand Down Expand Up @@ -167,9 +167,9 @@ func BenchmarkClaimMarketplacePayment(b *testing.B) {
Name: "ClaimMarketplacePaymentBenchmark",
Actor: actor,
Action: &ClaimMarketplacePayment{
DatasetID: datasetID,
MarketplaceAssetID: marketplaceAssetID,
AssetForPayment: baseAssetID,
DatasetID: datasetID,
MarketplaceAssetAddress: marketplaceAssetID,
PaymentAssetAddress: baseAssetID,
},
CreateState: func() state.Mutable {
store := chaintest.NewInMemoryStore()
Expand Down
Loading

0 comments on commit 20312c0

Please sign in to comment.