Skip to content

Commit

Permalink
Merge pull request #64 from gateway-fm/feat/coreAccountMethods
Browse files Browse the repository at this point in the history
feat: core liquidation listeners
  • Loading branch information
asolovov authored May 3, 2024
2 parents 7f9088b + b170aa5 commit d7f1c6d
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 2 deletions.
4 changes: 2 additions & 2 deletions contracts/core/contract.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions events/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,14 @@ type IEvents interface {
// ListenPoolCreated is used to listen to all 'PoolCreated' Core contract events and return them as models.PoolCreated
// struct and return errors on ErrChan chanel
ListenPoolCreated() (*PoolCreatedSubscription, error)

// ListenVaultLiquidationsCore is used to listen to all 'VaultLiquidations' Core contract events and return them as models.CoreVaultLiquidation
// struct and return errors on ErrChan chanel
ListenVaultLiquidationsCore() (*VaultLiquidationsCoreSubscription, error)

// ListenLiquidationsCore is used to listen to all 'Liquidations' Core contract events and return them as models.CoreLiquidation
// struct and return errors on ErrChan chanel
ListenLiquidationsCore() (*LiquidationsCoreSubscription, error)
}

// Events implements IEvents interface
Expand Down
86 changes: 86 additions & 0 deletions events/liauidationsCore.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package events

import (
"context"
"math/big"

"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/event"

"github.com/gateway-fm/perpsv3-Go/contracts/core"
"github.com/gateway-fm/perpsv3-Go/errors"
"github.com/gateway-fm/perpsv3-Go/models"
"github.com/gateway-fm/perpsv3-Go/pkg/logger"
)

// LiquidationsCoreSubscription is a struct for listening to all 'LiquidationsCore' contract events and return them as models.Account struct
type LiquidationsCoreSubscription struct {
*basicSubscription
NewAccountChan chan *models.CoreLiquidation
contractEventChan chan *core.CoreLiquidation
}

func (e *Events) ListenLiquidationsCore() (*LiquidationsCoreSubscription, error) {
liquidationChan := make(chan *core.CoreLiquidation)

liquidationSub, err := e.core.WatchLiquidation(nil, liquidationChan, nil, nil, nil)
if err != nil {
logger.Log().WithField("layer", "Events-LiquidationsCore").Errorf("error watch liquidation: %v", err.Error())
return nil, errors.GetEventListenErr(err, "LiquidationsCore")
}

liquidationsSub := newLiquidationsCoreSubscription(liquidationSub, liquidationChan)

go liquidationsSub.listen(e.rpcClient)

return liquidationsSub, nil
}

// newLiquidationsCoreSubscription is used to get new LiquidationsCoreSubscription instance
func newLiquidationsCoreSubscription(
eventSub event.Subscription,
liquidation chan *core.CoreLiquidation,
) *LiquidationsCoreSubscription {
return &LiquidationsCoreSubscription{
basicSubscription: newBasicSubscription(eventSub),
NewAccountChan: make(chan *models.CoreLiquidation),
contractEventChan: liquidation,
}
}

// listen is used to run events listen goroutine
func (s *LiquidationsCoreSubscription) listen(rpcClient *ethclient.Client) {
defer func() {
close(s.NewAccountChan)
close(s.contractEventChan)
}()

for {
select {
case <-s.stop:
return
case err := <-s.eventSub.Err():
if err != nil {
logger.Log().WithField("layer", "Events-LiquidationsCore").Errorf(
"error listening liquidation info: %v", err.Error(),
)
s.ErrChan <- err
}
return
case liquidation := <-s.contractEventChan:
block, err := rpcClient.HeaderByNumber(context.Background(), big.NewInt(int64(liquidation.Raw.BlockNumber)))
time := uint64(0)
if err != nil {
logger.Log().WithField("layer", "Events-LiquidationsCore").Warningf(
"error fetching block number %v: %v; liquidation event time set to 0 ",
liquidation.Raw.BlockNumber, err.Error(),
)
s.ErrChan <- err
} else {
time = block.Time
}

s.NewAccountChan <- models.GetCoreLiquidationFromEvent(liquidation, time)
}
}
}
86 changes: 86 additions & 0 deletions events/vaultLiquidationsCore.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package events

import (
"context"
"math/big"

"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/event"

"github.com/gateway-fm/perpsv3-Go/contracts/core"
"github.com/gateway-fm/perpsv3-Go/errors"
"github.com/gateway-fm/perpsv3-Go/models"
"github.com/gateway-fm/perpsv3-Go/pkg/logger"
)

// VaultLiquidationsCoreSubscription is a struct for listening to all 'VaultLiquidationsCore' contract events and return them as models.Account struct
type VaultLiquidationsCoreSubscription struct {
*basicSubscription
NewAccountChan chan *models.CoreVaultLiquidation
contractEventChan chan *core.CoreVaultLiquidation
}

func (e *Events) ListenVaultLiquidationsCore() (*VaultLiquidationsCoreSubscription, error) {
liquidationChan := make(chan *core.CoreVaultLiquidation)

liquidationSub, err := e.core.WatchVaultLiquidation(nil, liquidationChan, nil, nil)
if err != nil {
logger.Log().WithField("layer", "Events-VaultLiquidationsCore").Errorf("error watch liquidation: %v", err.Error())
return nil, errors.GetEventListenErr(err, "VaultLiquidationsCore")
}

liquidationsSub := newVaultLiquidationsCoreSubscription(liquidationSub, liquidationChan)

go liquidationsSub.listen(e.rpcClient)

return liquidationsSub, nil
}

// newVaultLiquidationsCoreSubscription is used to get new VaultLiquidationsCoreSubscription instance
func newVaultLiquidationsCoreSubscription(
eventSub event.Subscription,
liquidation chan *core.CoreVaultLiquidation,
) *VaultLiquidationsCoreSubscription {
return &VaultLiquidationsCoreSubscription{
basicSubscription: newBasicSubscription(eventSub),
NewAccountChan: make(chan *models.CoreVaultLiquidation),
contractEventChan: liquidation,
}
}

// listen is used to run events listen goroutine
func (s *VaultLiquidationsCoreSubscription) listen(rpcClient *ethclient.Client) {
defer func() {
close(s.NewAccountChan)
close(s.contractEventChan)
}()

for {
select {
case <-s.stop:
return
case err := <-s.eventSub.Err():
if err != nil {
logger.Log().WithField("layer", "Events-VaultLiquidationsCore").Errorf(
"error listening liquidation info: %v", err.Error(),
)
s.ErrChan <- err
}
return
case liquidation := <-s.contractEventChan:
block, err := rpcClient.HeaderByNumber(context.Background(), big.NewInt(int64(liquidation.Raw.BlockNumber)))
time := uint64(0)
if err != nil {
logger.Log().WithField("layer", "Events-VaultLiquidationsCore").Warningf(
"error fetching block number %v: %v; liquidation event time set to 0 ",
liquidation.Raw.BlockNumber, err.Error(),
)
s.ErrChan <- err
} else {
time = block.Time
}

s.NewAccountChan <- models.GetCoreVaultLiquidationFromEvent(liquidation, time)
}
}
}
16 changes: 16 additions & 0 deletions perpsv3.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,14 @@ type IPerpsv3 interface {
// struct and return errors on ErrChan chanel
ListenPoolCreated() (*events.PoolCreatedSubscription, error)

// ListenVaultLiquidationsCore is used to listen to all 'VaultLiquidations' Core contract events and return them as models.CoreVaultLiquidation
// struct and return errors on ErrChan chanel
ListenVaultLiquidationsCore() (*events.VaultLiquidationsCoreSubscription, error)

// ListenLiquidationsCore is used to listen to all 'Liquidations' Core contract events and return them as models.CoreLiquidation
// struct and return errors on ErrChan chanel
ListenLiquidationsCore() (*events.LiquidationsCoreSubscription, error)

// GetPosition is used to get position data struct from latest block with given params
// Function can return contract error if market ID is invalid
GetPosition(accountID *big.Int, marketID *big.Int) (*models.Position, error)
Expand Down Expand Up @@ -511,6 +519,14 @@ func (p *Perpsv3) ListenPoolCreated() (*events.PoolCreatedSubscription, error) {
return p.events.ListenPoolCreated()
}

func (p *Perpsv3) ListenVaultLiquidationsCore() (*events.VaultLiquidationsCoreSubscription, error) {
return p.events.ListenVaultLiquidationsCore()
}

func (p *Perpsv3) ListenLiquidationsCore() (*events.LiquidationsCoreSubscription, error) {
return p.events.ListenLiquidationsCore()
}

func (p *Perpsv3) GetPosition(accountID *big.Int, marketID *big.Int) (*models.Position, error) {
return p.service.GetPosition(accountID, marketID)
}
Expand Down

0 comments on commit d7f1c6d

Please sign in to comment.