Skip to content

Commit

Permalink
Merge pull request #122 from mysteriumnetwork/matic-bindings
Browse files Browse the repository at this point in the history
Matic bindings
  • Loading branch information
vkuznecovas authored Aug 2, 2021
2 parents 96e1475 + 46ea8ff commit 7ca06e9
Show file tree
Hide file tree
Showing 19 changed files with 1,084 additions and 861 deletions.
22 changes: 11 additions & 11 deletions bindings/ChannelImplementation.go

Large diffs are not rendered by default.

74 changes: 63 additions & 11 deletions bindings/HermesImplementation.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion bindings/MystToken.go

Large diffs are not rendered by default.

407 changes: 351 additions & 56 deletions bindings/Registry.go

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions client/bc.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ type BC interface {
GetBeneficiary(registryAddress, identity common.Address) (common.Address, error)
GetLastRegistryNonce(registry common.Address) (*big.Int, error)
GetChannelImplementationByVersion(registryID common.Address, version *big.Int) (common.Address, error)
GetProvidersWithdrawalChannel(hermesAddress common.Address, addressToCheck common.Address, pending bool) (ProviderChannel, error)
SubscribeToWithdrawalPromiseSettledEvent(providerID, hermesID common.Address) (sink chan *bindings.HermesImplementationPromiseSettled, cancel func(), err error)

IsRegisteredAsProvider(hermesAddress, registryAddress, addressToCheck common.Address) (bool, error)
IsRegistered(registryAddress, addressToCheck common.Address) (bool, error)
Expand Down Expand Up @@ -85,6 +87,10 @@ type BC interface {
RewarderUpdateRoot(req RewarderUpdateRoot) (*types.Transaction, error)
RewarderTotalClaimed(rewarderAddress common.Address) (*big.Int, error)
CustodyTransferTokens(req CustodyTokensTransfer) (*types.Transaction, error)

PayAndSettle(psr PayAndSettleRequest) (*types.Transaction, error)
IsChannelOpened(registryID, identity, hermesID common.Address) (bool, error)
FilterPromiseSettledEventByChannelID(from uint64, to *uint64, hermesID common.Address, providerAddresses [][32]byte) ([]bindings.HermesImplementationPromiseSettled, error)
}

// EtherClient interface implements all methods required for a EtherClient to work
Expand Down
159 changes: 150 additions & 9 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,27 @@ func (bc *Blockchain) GetProviderChannel(hermesAddress common.Address, addressTo
return ch, errors.Wrap(err, "could not get provider channel from bc")
}

// GetProviderChannel returns the provider channel
func (bc *Blockchain) GetProvidersWithdrawalChannel(hermesAddress common.Address, addressToCheck common.Address, pending bool) (ProviderChannel, error) {
addressBytes, err := bc.getProviderChannelAddressForWithdrawalBytes(hermesAddress, addressToCheck)
if err != nil {
return ProviderChannel{}, errors.Wrap(err, "could not calculate provider channel address")
}
caller, err := bindings.NewHermesImplementationCaller(hermesAddress, bc.ethClient.Client())
if err != nil {
return ProviderChannel{}, errors.Wrap(err, "could not create hermes caller")
}

ctx, cancel := context.WithTimeout(context.Background(), bc.bcTimeout)
defer cancel()

ch, err := caller.Channels(&bind.CallOpts{
Pending: pending,
Context: ctx,
}, addressBytes)
return ch, errors.Wrap(err, "could not get provider channel from bc")
}

func (bc *Blockchain) getProviderChannelStake(hermesAddress common.Address, addressToCheck common.Address) (*big.Int, error) {
ch, err := bc.GetProviderChannel(hermesAddress, addressToCheck, false)
return ch.Stake, errors.Wrap(err, "could not get provider channel from bc")
Expand Down Expand Up @@ -233,6 +254,19 @@ func (bc *Blockchain) getProviderChannelAddressBytes(hermesAddress, addressToChe
return addressBytes, nil
}

func (bc *Blockchain) getProviderChannelAddressForWithdrawalBytes(hermesAddress, addressToCheck common.Address) ([32]byte, error) {
addressBytes := [32]byte{}

addr, err := crypto.GenerateProviderChannelIDForPayAndSettle(addressToCheck.Hex(), hermesAddress.Hex())
if err != nil {
return addressBytes, errors.Wrap(err, "could not generate channel address")
}

copy(addressBytes[:], crypto.Pad(common.Hex2Bytes(strings.TrimPrefix(addr, "0x")), 32))

return addressBytes, nil
}

// SubscribeToPromiseSettledEvent subscribes to promise settled events
func (bc *Blockchain) SubscribeToPromiseSettledEvent(providerID, hermesID common.Address) (sink chan *bindings.HermesImplementationPromiseSettled, cancel func(), err error) {
addr, err := bc.getProviderChannelAddressBytes(hermesID, providerID)
Expand All @@ -242,6 +276,15 @@ func (bc *Blockchain) SubscribeToPromiseSettledEvent(providerID, hermesID common
return bc.SubscribeToPromiseSettledEventByChannelID(hermesID, [][32]byte{addr})
}

// SubscribeToWithdrawalPromiseSettledEvent subscribes to withdrawal promise settled events
func (bc *Blockchain) SubscribeToWithdrawalPromiseSettledEvent(providerID, hermesID common.Address) (sink chan *bindings.HermesImplementationPromiseSettled, cancel func(), err error) {
addr, err := bc.getProviderChannelAddressForWithdrawalBytes(hermesID, providerID)
if err != nil {
return sink, cancel, errors.Wrap(err, "could not get provider channel address")
}
return bc.SubscribeToPromiseSettledEventByChannelID(hermesID, [][32]byte{addr})
}

// IsRegistered checks wether the given identity is registered or not
func (bc *Blockchain) IsRegistered(registryAddress, addressToCheck common.Address) (bool, error) {
caller, err := bindings.NewRegistryCaller(registryAddress, bc.ethClient.Client())
Expand Down Expand Up @@ -275,6 +318,7 @@ func (bc *Blockchain) GetMystBalance(mystAddress, identity common.Address) (*big
// RegistrationRequest contains all the parameters for the registration request
type RegistrationRequest struct {
WriteRequest
ChainID int64
HermesID common.Address
Stake *big.Int
TransactorFee *big.Int
Expand Down Expand Up @@ -345,6 +389,65 @@ func (bc *Blockchain) RegisterIdentity(rr RegistrationRequest) (*types.Transacti
return tx, err
}

// PayAndSettleRequest allows to pay and settle and exit to l1 via this.
type PayAndSettleRequest struct {
WriteRequest
Beneficiary common.Address
HermesID common.Address
ProviderID common.Address
Promise crypto.Promise
BeneficiarySignature []byte
}

func (psr PayAndSettleRequest) toEstimator(ethClient EthClientGetter) (*bindings.ContractEstimator, error) {
return bindings.NewContractEstimator(psr.HermesID, bindings.HermesImplementationABI, ethClient.Client())
}

func (psr PayAndSettleRequest) toEstimateOps() *bindings.EstimateOpts {
return &bindings.EstimateOpts{
From: psr.Identity,
Method: "payAndSettle",
Params: []interface{}{psr.ProviderID, psr.Promise.Amount, psr.Promise.Fee, ToBytes32(psr.Promise.R), psr.Promise.Signature, psr.Beneficiary, psr.BeneficiarySignature},
}
}

// PayAndSettle registers the given identity on blockchain.
func (bc *Blockchain) PayAndSettle(psr PayAndSettleRequest) (*types.Transaction, error) {
transactor, err := bindings.NewHermesImplementationTransactor(psr.HermesID, bc.ethClient.Client())
if err != nil {
return nil, err
}
parent := context.Background()
ctx, cancel := context.WithTimeout(parent, bc.bcTimeout)
defer cancel()

nonce := psr.Nonce
if nonce == nil {
nonceUint, err := bc.getNonce(psr.Identity)
if err != nil {
return nil, errors.Wrap(err, "could not get nonce")
}
nonce = big.NewInt(0).SetUint64(nonceUint)
}
tx, err := transactor.PayAndSettle(&bind.TransactOpts{
From: psr.Identity,
Signer: psr.Signer,
Context: ctx,
GasLimit: psr.GasLimit,
GasPrice: psr.GasPrice,
Nonce: nonce,
},
psr.ProviderID,
psr.Promise.Amount,
psr.Promise.Fee,
ToBytes32(psr.Promise.R),
psr.Promise.Signature,
psr.Beneficiary,
psr.BeneficiarySignature,
)
return tx, err
}

// TransferRequest contains all the parameters for a transfer request
type TransferRequest struct {
MystAddress common.Address
Expand Down Expand Up @@ -457,7 +560,7 @@ func (r SettleIntoStakeRequest) toEstimateOps() *bindings.EstimateOpts {
r.ProviderID,
r.Promise.Amount,
r.Promise.Fee,
toBytes32(r.Promise.R),
ToBytes32(r.Promise.R),
r.Promise.Signature,
},
}
Expand Down Expand Up @@ -607,7 +710,7 @@ func (r SettleAndRebalanceRequest) toEstimateOps() *bindings.EstimateOpts {
return &bindings.EstimateOpts{
From: r.Identity,
Method: "settlePromise",
Params: []interface{}{r.ProviderID, r.Promise.Amount, r.Promise.Fee, toBytes32(r.Promise.R), r.Promise.Signature},
Params: []interface{}{r.ProviderID, r.Promise.Amount, r.Promise.Fee, ToBytes32(r.Promise.R), r.Promise.Signature},
}
}

Expand Down Expand Up @@ -636,12 +739,12 @@ func (bc *Blockchain) SettleAndRebalance(req SettleAndRebalanceRequest) (*types.
req.ProviderID,
req.Promise.Amount,
req.Promise.Fee,
toBytes32(req.Promise.R),
ToBytes32(req.Promise.R),
req.Promise.Signature,
)
}

func toBytes32(arr []byte) (res [32]byte) {
func ToBytes32(arr []byte) (res [32]byte) {
copy(res[:], arr)
return res
}
Expand Down Expand Up @@ -675,7 +778,7 @@ func (bc *Blockchain) GetProviderChannelByID(acc common.Address, chID []byte) (P
return caller.Channels(&bind.CallOpts{
Pending: false,
Context: ctx,
}, toBytes32(chID))
}, ToBytes32(chID))
}

// ConsumersHermes represents the consumers hermes
Expand Down Expand Up @@ -852,7 +955,7 @@ func (bc *Blockchain) GetHermes(registryID, hermesID common.Address) (Hermes, er
ctx, cancel := context.WithTimeout(context.Background(), bc.bcTimeout)
defer cancel()

status, err := caller.Hermeses(&bind.CallOpts{
status, err := caller.GetHermes(&bind.CallOpts{
Context: ctx,
}, hermesID)
if err != nil {
Expand Down Expand Up @@ -882,6 +985,20 @@ func (bc *Blockchain) GetChannelImplementationByVersion(registryID common.Addres
}, version)
}

func (bc *Blockchain) IsChannelOpened(registryID, identity, hermesID common.Address) (bool, error) {
caller, err := bindings.NewRegistryCaller(registryID, bc.ethClient.Client())
if err != nil {
return false, fmt.Errorf("could not create new registry caller %w", err)
}

ctx, cancel := context.WithTimeout(context.Background(), bc.bcTimeout)
defer cancel()

return caller.IsChannelOpened(&bind.CallOpts{
Context: ctx,
}, identity, hermesID)
}

// SubscribeToPromiseSettledEventByChannelID subscribes to promise settled events
func (bc *Blockchain) SubscribeToPromiseSettledEventByChannelID(hermesID common.Address, providerAddresses [][32]byte) (sink chan *bindings.HermesImplementationPromiseSettled, cancel func(), err error) {
caller, err := bindings.NewHermesImplementationFilterer(hermesID, bc.ethClient.Client())
Expand All @@ -907,6 +1024,30 @@ func (bc *Blockchain) SubscribeToPromiseSettledEventByChannelID(hermesID common.
return sink, sub.Unsubscribe, nil
}

// FilterPromiseSettledEventByChannelID filters promise settled events
func (bc *Blockchain) FilterPromiseSettledEventByChannelID(from uint64, to *uint64, hermesID common.Address, providerAddresses [][32]byte) ([]bindings.HermesImplementationPromiseSettled, error) {
caller, err := bindings.NewHermesImplementationFilterer(hermesID, bc.ethClient.Client())
if err != nil {
return nil, errors.Wrap(err, "could not create hermes caller")
}
ctx, cancel := context.WithTimeout(context.Background(), bc.bcTimeout)
defer cancel()
iter, err := caller.FilterPromiseSettled(&bind.FilterOpts{
Start: from,
End: to,
Context: ctx,
}, providerAddresses, []common.Address{})
if err != nil {
return nil, err
}
res := make([]bindings.HermesImplementationPromiseSettled, 0)
for iter.Next() {
ev := iter.Event
res = append(res, *ev)
}
return res, nil
}

// GetEthBalance gets the current ethereum balance for the address.
func (bc *Blockchain) GetEthBalance(address common.Address) (*big.Int, error) {
ctx, cancel := context.WithTimeout(context.Background(), bc.bcTimeout)
Expand Down Expand Up @@ -1016,7 +1157,7 @@ func (r SettleWithBeneficiaryRequest) toEstimateOps() *bindings.EstimateOpts {
r.ProviderID,
r.Promise.Amount,
r.Promise.Fee,
toBytes32(r.Promise.R),
ToBytes32(r.Promise.R),
r.Promise.Signature,
r.Beneficiary,
r.Signature,
Expand Down Expand Up @@ -1070,7 +1211,7 @@ func (bc *Blockchain) SettleWithBeneficiary(req SettleWithBeneficiaryRequest) (*
req.ProviderID,
req.Promise.Amount,
req.Promise.Fee,
toBytes32(req.Promise.R),
ToBytes32(req.Promise.R),
req.Promise.Signature,
req.Beneficiary,
req.Signature,
Expand Down Expand Up @@ -1130,7 +1271,7 @@ func (bc *Blockchain) RewarderUpdateRoot(req RewarderUpdateRoot) (*types.Transac
GasPrice: req.GasPrice,
Nonce: big.NewInt(0).SetUint64(nonce),
},
toBytes32(req.ClaimRoot),
ToBytes32(req.ClaimRoot),
req.BlockNumber,
req.TotalReward,
)
Expand Down
42 changes: 42 additions & 0 deletions client/multichain_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,15 @@ func (mbc *MultichainBlockchainClient) SuggestGasPrice(chainID int64) (*big.Int,
return bc.SuggestGasPrice()
}

func (mbc *MultichainBlockchainClient) FilterPromiseSettledEventByChannelID(chainID int64, from uint64, to *uint64, hermesID common.Address, providerAddresses [][32]byte) ([]bindings.HermesImplementationPromiseSettled, error) {
bc, err := mbc.getClientByChain(chainID)
if err != nil {
return nil, err
}

return bc.FilterPromiseSettledEventByChannelID(from, to, hermesID, providerAddresses)
}

func (mbc *MultichainBlockchainClient) SubscribeToConsumerChannelBalanceUpdate(chainID int64, mystSCAddress common.Address, channelAddresses []common.Address) (sink chan *bindings.MystTokenTransfer, cancel func(), err error) {
bc, err := mbc.getClientByChain(chainID)
if err != nil {
Expand Down Expand Up @@ -386,6 +395,15 @@ func (mbc *MultichainBlockchainClient) GetChannelImplementationByVersion(chainID
return bc.GetChannelImplementationByVersion(registryID, version)
}

func (mbc *MultichainBlockchainClient) IsChannelOpened(chainID int64, registryID, identity, hermesID common.Address) (bool, error) {
bc, err := mbc.getClientByChain(chainID)
if err != nil {
return false, err
}

return bc.IsChannelOpened(registryID, identity, hermesID)
}

// FilterLogs executes a filter query.
func (mbc *MultichainBlockchainClient) FilterLogs(chainID int64, q ethereum.FilterQuery) ([]types.Log, error) {
bc, err := mbc.getClientByChain(chainID)
Expand Down Expand Up @@ -421,6 +439,14 @@ func (mbc *MultichainBlockchainClient) IsHermesActive(chainID int64, hermesID co
return bc.IsHermesActive(hermesID)
}

func (mbc *MultichainBlockchainClient) PayAndSettle(chainID int64, psr PayAndSettleRequest) (*types.Transaction, error) {
bc, err := mbc.getClientByChain(chainID)
if err != nil {
return nil, err
}
return bc.PayAndSettle(psr)
}

func (mbc *MultichainBlockchainClient) TransactionByHash(chainID int64, hash common.Hash) (*types.Transaction, bool, error) {
bc, err := mbc.getClientByChain(chainID)
if err != nil {
Expand Down Expand Up @@ -469,3 +495,19 @@ func (mbc *MultichainBlockchainClient) CustodyTransferTokens(chainID int64, req
}
return bc.CustodyTransferTokens(req)
}

func (mbc *MultichainBlockchainClient) GetProvidersWithdrawalChannel(chainID int64, hermesAddress common.Address, addressToCheck common.Address, pending bool) (ProviderChannel, error) {
bc, err := mbc.getClientByChain(chainID)
if err != nil {
return ProviderChannel{}, err
}
return bc.GetProvidersWithdrawalChannel(hermesAddress, addressToCheck, pending)
}

func (mbc *MultichainBlockchainClient) SubscribeToWithdrawalPromiseSettledEvent(chainID int64, providerID, hermesID common.Address) (sink chan *bindings.HermesImplementationPromiseSettled, cancel func(), err error) {
bc, err := mbc.getClientByChain(chainID)
if err != nil {
return nil, func() {}, err
}
return bc.SubscribeToWithdrawalPromiseSettledEvent(providerID, hermesID)
}
8 changes: 6 additions & 2 deletions client/nonce_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,17 @@ import (

// NonceTracker keeps track of nonces atomically.
type NonceTracker struct {
client EtherClient
client client
nonces map[common.Address]uint64
nonceLock sync.Mutex
}

type client interface {
PendingNonceAt(ctx context.Context, account common.Address) (uint64, error)
}

// NewNonceTracker returns a new nonce tracker.
func NewNonceTracker(client EtherClient) *NonceTracker {
func NewNonceTracker(client client) *NonceTracker {
return &NonceTracker{
client: client,
nonces: make(map[common.Address]uint64),
Expand Down
Loading

0 comments on commit 7ca06e9

Please sign in to comment.