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

New actions integration tests #32

Closed
wants to merge 84 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
c1f3e6d
integration tests for staking
najlachamseddine Apr 6, 2024
12a816f
tests for staking
najlachamseddine Apr 7, 2024
0ac3470
Merge branch 'dev' into new-actions-integration-tests
najlachamseddine Apr 9, 2024
06046f5
delete 2d file and current test file keep only staking test (for debu…
najlachamseddine Apr 10, 2024
bb5963d
delete unit tests second file
najlachamseddine Apr 10, 2024
df29b23
use It
najlachamseddine Apr 10, 2024
dfdcd11
set parallelism to 5
najlachamseddine Apr 11, 2024
33790e7
remove sleep time
najlachamseddine Apr 11, 2024
63c40a8
change factories for nodes
najlachamseddine Apr 11, 2024
9e88267
transfer to node address
najlachamseddine Apr 11, 2024
99de97a
test balance
najlachamseddine Apr 11, 2024
b6acd99
transfer and register
najlachamseddine Apr 12, 2024
45a47cc
transfer and register
najlachamseddine Apr 12, 2024
70cd8ce
transfer and register
najlachamseddine Apr 12, 2024
49364d3
add print
najlachamseddine Apr 12, 2024
fad8a0a
add print
najlachamseddine Apr 12, 2024
5e9b959
uncomment tokenvm tests
najlachamseddine Apr 12, 2024
fc585d8
emission instances
najlachamseddine Apr 16, 2024
52fca7f
transfer works and register is called
najlachamseddine Apr 17, 2024
305eb67
add import function
najlachamseddine Apr 17, 2024
eff65cd
clean code
najlachamseddine Apr 17, 2024
4d53839
create interface to be able to mock emission
najlachamseddine Apr 18, 2024
6dff2aa
register validator stake and get staked validators tests pass
najlachamseddine Apr 18, 2024
7458851
height
najlachamseddine Apr 18, 2024
0a48b16
delegate user stake
najlachamseddine Apr 19, 2024
ad9f85c
user delegate claim
najlachamseddine Apr 22, 2024
2630622
test same block is accepted
najlachamseddine Apr 22, 2024
8a8b8c9
clean up
najlachamseddine Apr 22, 2024
1184790
set initial code int tests
najlachamseddine Apr 22, 2024
9d90a25
update
najlachamseddine Apr 23, 2024
b2e3aa4
deactivated initial integration tests for now
najlachamseddine Apr 23, 2024
f3c7058
Merge branch 'dev' into new-actions-integration-tests
najlachamseddine Apr 23, 2024
77a2752
add gossiper
najlachamseddine Apr 24, 2024
2d3129c
no need for gossiping (the current vm is the proposer/builder)
najlachamseddine Apr 24, 2024
7840f97
no need to delegatorsLastClaim to be public
najlachamseddine Apr 24, 2024
876da14
add staked validators test
najlachamseddine Apr 24, 2024
a7f84d7
fund node 0
najlachamseddine Apr 27, 2024
8ad0c98
register validator stake node 0
najlachamseddine Apr 27, 2024
48e2d7b
delegate user stake to node 0
najlachamseddine Apr 28, 2024
ccca0bf
user delegate passes
najlachamseddine Apr 28, 2024
d5079d7
delegate user passes (unstable test)
najlachamseddine Apr 29, 2024
3322320
delegate user passes (unstable test)
najlachamseddine Apr 29, 2024
ce5e475
passes
najlachamseddine Apr 29, 2024
7506eb4
should pass till before claim delegation reward
najlachamseddine Apr 29, 2024
c04bd5e
By -> It
najlachamseddine Apr 29, 2024
9cb51fa
merge dev
najlachamseddine Apr 30, 2024
2490422
update tests with start/end block
najlachamseddine Apr 30, 2024
2126c8e
update tests with start/end block
najlachamseddine Apr 30, 2024
64763e0
claim user reward
najlachamseddine May 1, 2024
edb54ed
undelegate stake user
najlachamseddine May 1, 2024
28ae444
Made rewardamount to be equal to 0
kpachhai May 1, 2024
f533cc6
claim validator rewards
najlachamseddine May 1, 2024
86cdea4
Merge branch 'new-actions-integration-tests' of github.com:Nuklai/nuk…
najlachamseddine May 1, 2024
21625ee
claim validator stake reward
najlachamseddine May 1, 2024
44149d7
withdraw validator
najlachamseddine May 2, 2024
9902cec
desc
najlachamseddine May 3, 2024
7382b51
merge dev
najlachamseddine May 3, 2024
1e967db
withdraw stake
najlachamseddine May 3, 2024
83686e5
reward not required
najlachamseddine May 3, 2024
1d6443b
FIt -> It
najlachamseddine May 3, 2024
c568b59
int test
najlachamseddine May 3, 2024
6a26217
integration tests
najlachamseddine May 7, 2024
bbe3fae
add TODO
najlachamseddine May 7, 2024
0c4e2f3
remove println
najlachamseddine May 7, 2024
d61bc74
rename file
najlachamseddine May 7, 2024
56d21fd
restore integration tests file
najlachamseddine May 7, 2024
aad1945
put integration tests in one file
najlachamseddine May 7, 2024
84d536d
remove println
najlachamseddine May 7, 2024
cc72208
fmt
najlachamseddine May 7, 2024
6ac613b
space
najlachamseddine May 7, 2024
5d5800d
space
najlachamseddine May 7, 2024
6065476
println
najlachamseddine May 7, 2024
46c73da
update manual
najlachamseddine May 8, 2024
56e5316
integration tests pass in one file
najlachamseddine May 8, 2024
7abfae9
integration tests pass in one file
najlachamseddine May 8, 2024
9768e47
remove old file
najlachamseddine May 8, 2024
c66d1f4
update
najlachamseddine May 8, 2024
a9e0362
e2e tests should pass
najlachamseddine May 8, 2024
dc03de1
linter
najlachamseddine May 9, 2024
93ae68a
linter e2e
najlachamseddine May 9, 2024
1b21f33
rename file from manual to mock
najlachamseddine May 13, 2024
57dbc2c
merge main
najlachamseddine May 13, 2024
f775941
lint
najlachamseddine May 13, 2024
dd9bc05
fix lint: golangci-lint run --fix
najlachamseddine May 13, 2024
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
2 changes: 1 addition & 1 deletion cmd/nuklai-cli/cmd/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ var registerValidatorStakeCmd = &cobra.Command{

if autoRegister {
hutils.Outf("{{yellow}}Loading private key for %s{{/}}\n", nodeNumber)
validatorSignerKey, err := loadPrivateKey("bls", fmt.Sprintf("/tmp/nuklaivm/nodes/%s-bls/signer.key", nodeNumber))
validatorSignerKey, err := LoadPrivateKey("bls", fmt.Sprintf("/tmp/nuklaivm/nodes/%s-bls/signer.key", nodeNumber))
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/nuklai-cli/cmd/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func generatePrivateKey(k string) (*cli.PrivateKey, error) {
}
}

func loadPrivateKey(k string, path string) (*cli.PrivateKey, error) {
func LoadPrivateKey(k string, path string) (*cli.PrivateKey, error) {
switch k {
case ed25519Key:
p, err := hutils.LoadBytes(path, ed25519.PrivateKeyLen)
Expand Down Expand Up @@ -187,7 +187,7 @@ var importKeyCmd = &cobra.Command{
return checkKeyType(args[0])
},
RunE: func(_ *cobra.Command, args []string) error {
priv, err := loadPrivateKey(args[0], args[1])
priv, err := LoadPrivateKey(args[0], args[1])
if err != nil {
return err
}
Expand Down
32 changes: 19 additions & 13 deletions controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ type Controller struct {

metaDB database.Database

emission *emission.Emission // Emission Balancer for NuklaiVM
emission emission.Tracker // Emission Balancer for NuklaiVM
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wanna get your thought process on why we chose to have this not be a pointer like previously. Any specific reason?

Copy link
Contributor Author

@najlachamseddine najlachamseddine May 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tracker is an interface, then a pointer var _ Tracker = (*Emission)(nil) as defined in emission/emission.go

The creation tracker = emission.NewEmission(c, c.inner, c.genesis.EmissionBalancer.TotalSupply, c.genesis.EmissionBalancer.MaxSupply, emissionAddr) of the emission instance hasn't changed and it is still returning a pointer *Emission

}

func New() *vm.VM {
Expand Down Expand Up @@ -123,13 +123,23 @@ func (c *Controller) Initialize(

// Create builder and gossiper
var (
build builder.Builder
gossip gossiper.Gossiper
build builder.Builder
gossip gossiper.Gossiper
tracker emission.Tracker
)

// Initialize emission balancer
emissionAddr, err := codec.ParseAddressBech32(nconsts.HRP, c.genesis.EmissionBalancer.EmissionAddress)
if err != nil {
return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err
}

if c.config.TestMode {
c.inner.Logger().Info("running build and gossip in test mode")
build = builder.NewManual(inner)
gossip = gossiper.NewManual(inner)
tracker = emission.NewManual(c, c.inner, c.genesis.EmissionBalancer.TotalSupply, c.genesis.EmissionBalancer.MaxSupply, emissionAddr)
c.emission = tracker
} else {
build = builder.NewTime(inner)
gcfg := gossiper.DefaultProposerConfig()
Expand All @@ -142,15 +152,10 @@ func (c *Controller) Initialize(
if err != nil {
return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err
}
tracker = emission.NewEmission(c, c.inner, c.genesis.EmissionBalancer.TotalSupply, c.genesis.EmissionBalancer.MaxSupply, emissionAddr)
c.emission = tracker
}

// Initialize emission balancer
emissionAddr, err := codec.ParseAddressBech32(nconsts.HRP, c.genesis.EmissionBalancer.EmissionAddress)
if err != nil {
return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err
}
c.emission = emission.New(c, c.inner, c.genesis.EmissionBalancer.TotalSupply, c.genesis.EmissionBalancer.MaxSupply, emissionAddr)

return c.config, c.genesis, build, gossip, blockDB, stateDB, apis, nconsts.ActionRegistry, nconsts.AuthRegistry, auth.Engines(), nil
}

Expand Down Expand Up @@ -255,22 +260,23 @@ func (c *Controller) Accepted(ctx context.Context, blk *chain.StatelessBlock) er
}
}

emissionAccount, totalSupply, maxSupply, _, _ := c.emission.GetInfo()
// Distribute fees
if totalFee > 0 {
c.emission.DistributeFees(totalFee)
emissionAddress, err := codec.AddressBech32(nconsts.HRP, c.emission.EmissionAccount.Address)
emissionAddress, err := codec.AddressBech32(nconsts.HRP, emissionAccount.Address)
if err != nil {
return err // This should never happen
}
c.inner.Logger().Info("distributed fees to Emission and Validators", zap.Uint64("current block height", c.inner.LastAcceptedBlock().Height()), zap.Uint64("total fee", totalFee), zap.Uint64("total supply", c.emission.TotalSupply), zap.Uint64("max supply", c.emission.MaxSupply), zap.Uint64("rewards per epock", c.emission.GetRewardsPerEpoch()), zap.String("emission address", emissionAddress), zap.Uint64("emission address unclaimed balance", c.emission.EmissionAccount.UnclaimedBalance))
c.inner.Logger().Info("distributed fees to Emission and Validators", zap.Uint64("current block height", c.inner.LastAcceptedBlock().Height()), zap.Uint64("total fee", totalFee), zap.Uint64("total supply", totalSupply), zap.Uint64("max supply", maxSupply), zap.Uint64("rewards per epock", c.emission.GetRewardsPerEpoch()), zap.String("emission address", emissionAddress), zap.Uint64("emission address unclaimed balance", emissionAccount.UnclaimedBalance))
c.metrics.feesDistributed.Add(float64(totalFee))
}

// Mint new NAI if needed
mintNewNAI := c.emission.MintNewNAI()
if mintNewNAI > 0 {
c.emission.AddToTotalSupply(mintNewNAI)
c.inner.Logger().Info("minted new NAI", zap.Uint64("current block height", c.inner.LastAcceptedBlock().Height()), zap.Uint64("newly minted NAI", mintNewNAI), zap.Uint64("total supply", c.emission.TotalSupply), zap.Uint64("max supply", c.emission.MaxSupply))
c.inner.Logger().Info("minted new NAI", zap.Uint64("current block height", c.inner.LastAcceptedBlock().Height()), zap.Uint64("newly minted NAI", mintNewNAI), zap.Uint64("total supply", totalSupply), zap.Uint64("max supply", maxSupply))
}

return batch.Write()
Expand Down
3 changes: 2 additions & 1 deletion controller/resolutions.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ func (c *Controller) GetLoanFromState(
}

func (c *Controller) GetEmissionInfo() (uint64, uint64, uint64, uint64, uint64, emission.EmissionAccount, emission.EpochTracker, error) {
return c.emission.GetLastAcceptedBlockHeight(), c.emission.TotalSupply, c.emission.MaxSupply, c.emission.TotalStaked, c.emission.GetRewardsPerEpoch(), c.emission.EmissionAccount, c.emission.EpochTracker, nil
emissionAccount, totalSupply, maxSupply, totalStaked, epochTracker := c.emission.GetInfo()
return c.emission.GetLastAcceptedBlockHeight(), totalSupply, maxSupply, totalStaked, c.emission.GetRewardsPerEpoch(), emissionAccount, epochTracker, nil
}

func (c *Controller) GetValidators(ctx context.Context, staked bool) ([]*emission.Validator, error) {
Expand Down
59 changes: 12 additions & 47 deletions emission/emission.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,37 +15,7 @@ import (
"github.com/nuklai/nuklaivm/storage"
)

var (
emission *Emission
once sync.Once
)

type Validator struct {
IsActive bool `json:"isActive"` // Indicates if the validator is currently active
NodeID ids.NodeID `json:"nodeID"` // Node ID of the validator
PublicKey []byte `json:"publicKey"` // Public key of the validator
StakedAmount uint64 `json:"stakedAmount"` // Total amount staked by the validator
UnclaimedStakedReward uint64 `json:"stakedReward"` // Total rewards accumulated by the validator
DelegationFeeRate float64 `json:"delegationFeeRate"` // Fee rate for delegations
DelegatedAmount uint64 `json:"delegatedAmount"` // Total amount delegated to the validator
UnclaimedDelegatedReward uint64 `json:"unclaimedDelegatedReward"` // Total rewards accumulated by the delegators

delegatorsLastClaim map[codec.Address]uint64 // Map of delegator addresses to their last claim block height
epochRewards map[uint64]uint64 // Rewards per epoch
stakeStartBlock uint64 // Start block of the stake
stakeEndBlock uint64 // End block of the stake
}

type EmissionAccount struct {
Address codec.Address `json:"address"`
UnclaimedBalance uint64 `json:"unclaimedBalance"`
}

type EpochTracker struct {
BaseAPR float64 `json:"baseAPR"` // Base APR to use
BaseValidators uint64 `json:"baseValidators"` // Base number of validators to use
EpochLength uint64 `json:"epochLength"` // Number of blocks per reward epoch
}
var _ Tracker = (*Emission)(nil)

type Emission struct {
c Controller
Expand All @@ -65,7 +35,7 @@ type Emission struct {

// New initializes the Emission struct with initial parameters and sets up the validators heap
// and indices map.
func New(c Controller, vm NuklaiVM, totalSupply, maxSupply uint64, emissionAddress codec.Address) *Emission {
func NewEmission(c Controller, vm NuklaiVM, totalSupply, maxSupply uint64, emissionAddress codec.Address) *Emission {
once.Do(func() {
c.Logger().Info("Initializing emission with max supply and rewards per block settings")

Expand All @@ -91,12 +61,7 @@ func New(c Controller, vm NuklaiVM, totalSupply, maxSupply uint64, emissionAddre
},
}
})
return emission
}

// GetEmission returns the singleton instance of Emission
func GetEmission() *Emission {
return emission
return emission.(*Emission)
}

// AddToTotalSupply increases the total supply of NAI by a specified amount, ensuring it
Expand Down Expand Up @@ -527,15 +492,6 @@ func (e *Emission) DistributeFees(fee uint64) {
}
}

func distributeValidatorRewards(totalValidatorReward uint64, delegationFeeRate float64, delegatedAmount uint64) (uint64, uint64) {
delegationRewards := uint64(0)
if delegatedAmount > 0 {
delegationRewards = uint64(float64(totalValidatorReward) * delegationFeeRate)
}
validatorRewards := totalValidatorReward - delegationRewards
return validatorRewards, delegationRewards
}

// GetStakedValidator retrieves the details of a specific validator by their NodeID.
func (e *Emission) GetStakedValidator(nodeID ids.NodeID) []*Validator {
e.c.Logger().Info("fetching staked validator")
Expand Down Expand Up @@ -591,3 +547,12 @@ func (e *Emission) GetLastAcceptedBlockHeight() uint64 {
e.c.Logger().Info("fetching last accepted block height")
return e.nuklaivm.LastAcceptedBlock().Height()
}

func (e *Emission) GetEmissionValidators() map[ids.NodeID]*Validator {
e.c.Logger().Info("fetching emission validators")
return e.validators
}

func (e *Emission) GetInfo() (emissionAccount EmissionAccount, totalSupply uint64, maxSupply uint64, totalStaked uint64, epochTracker EpochTracker) {
return e.EmissionAccount, e.TotalSupply, e.MaxSupply, e.TotalStaked, e.EpochTracker
}
49 changes: 49 additions & 0 deletions emission/helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package emission

import (
"sync"

"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/hypersdk/codec"
)

var (
once sync.Once
emission Tracker
)

type Validator struct {
IsActive bool `json:"isActive"` // Indicates if the validator is currently active
NodeID ids.NodeID `json:"nodeID"` // Node ID of the validator
PublicKey []byte `json:"publicKey"` // Public key of the validator
StakedAmount uint64 `json:"stakedAmount"` // Total amount staked by the validator
UnclaimedStakedReward uint64 `json:"stakedReward"` // Total rewards accumulated by the validator
DelegationFeeRate float64 `json:"delegationFeeRate"` // Fee rate for delegations
DelegatedAmount uint64 `json:"delegatedAmount"` // Total amount delegated to the validator
UnclaimedDelegatedReward uint64 `json:"delegatedReward"` // Total rewards accumulated by the delegators

delegatorsLastClaim map[codec.Address]uint64 // Map of delegator addresses to their last claim block height
epochRewards map[uint64]uint64 // Rewards per epoch
stakeStartBlock uint64 // Start block of the stake
stakeEndBlock uint64 // End block of the stake
}

type EmissionAccount struct {
Address codec.Address `json:"address"`
UnclaimedBalance uint64 `json:"unclaimedBalance"`
}

type EpochTracker struct {
BaseAPR float64 `json:"baseAPR"` // Base APR to use
BaseValidators uint64 `json:"baseValidators"` // Base number of validators to use
EpochLength uint64 `json:"epochLength"` // Number of blocks per reward epoch
}

func distributeValidatorRewards(totalValidatorReward uint64, delegationFeeRate float64, delegatedAmount uint64) (uint64, uint64) {
delegationRewards := uint64(0)
if delegatedAmount > 0 {
delegationRewards = uint64(float64(totalValidatorReward) * delegationFeeRate)
}
validatorRewards := totalValidatorReward - delegationRewards
return validatorRewards, delegationRewards
}
Loading
Loading