Commit 4220008c authored by Ralph Pichler's avatar Ralph Pichler Committed by GitHub

swap without bindings (#1471)

parent bfc0e675
......@@ -134,7 +134,6 @@ func InitChequebookService(
chainID,
overlayEthAddress,
chequeSigner,
chequebook.NewSimpleSwapBindings,
)
if err != nil {
return nil, fmt.Errorf("chequebook init: %w", err)
......@@ -153,11 +152,10 @@ func initChequeStoreCashout(
) (chequebook.ChequeStore, chequebook.CashoutService) {
chequeStore := chequebook.NewChequeStore(
stateStore,
swapBackend,
chequebookFactory,
chainID,
overlayEthAddress,
chequebook.NewSimpleSwapBindings,
transactionService,
chequebook.RecoverCheque,
)
......
// Copyright 2020 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package chequebook
import (
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethersphere/sw3-bindings/v3/simpleswapfactory"
)
// SimpleSwapBinding is the interface for the generated go bindings for ERC20SimpleSwap
type SimpleSwapBinding interface {
Balance(*bind.CallOpts) (*big.Int, error)
Issuer(*bind.CallOpts) (common.Address, error)
TotalPaidOut(*bind.CallOpts) (*big.Int, error)
PaidOut(*bind.CallOpts, common.Address) (*big.Int, error)
}
type SimpleSwapBindingFunc = func(common.Address, bind.ContractBackend) (SimpleSwapBinding, error)
// NewSimpleSwapBindings generates the default go bindings
func NewSimpleSwapBindings(address common.Address, backend bind.ContractBackend) (SimpleSwapBinding, error) {
return simpleswapfactory.NewERC20SimpleSwap(address, backend)
}
......@@ -12,7 +12,6 @@ import (
"strings"
"sync"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethersphere/bee/pkg/settlement/swap/erc20"
"github.com/ethersphere/bee/pkg/settlement/swap/transaction"
......@@ -63,12 +62,11 @@ type Service interface {
type service struct {
lock sync.Mutex
backend transaction.Backend
transactionService transaction.Service
address common.Address
chequebookInstance SimpleSwapBinding
ownerAddress common.Address
address common.Address
contract *chequebookContract
ownerAddress common.Address
erc20Service erc20.Service
......@@ -78,17 +76,11 @@ type service struct {
}
// New creates a new chequebook service for the provided chequebook contract.
func New(backend transaction.Backend, transactionService transaction.Service, address, ownerAddress common.Address, store storage.StateStorer, chequeSigner ChequeSigner, erc20Service erc20.Service, simpleSwapBindingFunc SimpleSwapBindingFunc) (Service, error) {
chequebookInstance, err := simpleSwapBindingFunc(address, backend)
if err != nil {
return nil, err
}
func New(transactionService transaction.Service, address, ownerAddress common.Address, store storage.StateStorer, chequeSigner ChequeSigner, erc20Service erc20.Service) (Service, error) {
return &service{
backend: backend,
transactionService: transactionService,
address: address,
chequebookInstance: chequebookInstance,
contract: newChequebookContract(address, transactionService),
ownerAddress: ownerAddress,
erc20Service: erc20Service,
store: store,
......@@ -119,9 +111,7 @@ func (s *service) Deposit(ctx context.Context, amount *big.Int) (hash common.Has
// Balance returns the token balance of the chequebook.
func (s *service) Balance(ctx context.Context) (*big.Int, error) {
return s.chequebookInstance.Balance(&bind.CallOpts{
Context: ctx,
})
return s.contract.Balance(ctx)
}
// AvailableBalance returns the token balance of the chequebook which is not yet used for uncashed cheques.
......@@ -136,9 +126,7 @@ func (s *service) AvailableBalance(ctx context.Context) (*big.Int, error) {
return nil, err
}
totalPaidOut, err := s.chequebookInstance.TotalPaidOut(&bind.CallOpts{
Context: ctx,
})
totalPaidOut, err := s.contract.TotalPaidOut(ctx)
if err != nil {
return nil, err
}
......
......@@ -12,7 +12,6 @@ import (
"strings"
"sync"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethersphere/bee/pkg/crypto"
"github.com/ethersphere/bee/pkg/settlement/swap/transaction"
......@@ -44,14 +43,13 @@ type ChequeStore interface {
}
type chequeStore struct {
lock sync.Mutex
store storage.StateStorer
factory Factory
chaindID int64
simpleSwapBindingFunc SimpleSwapBindingFunc
backend transaction.Backend
beneficiary common.Address // the beneficiary we expect in cheques sent to us
recoverChequeFunc RecoverChequeFunc
lock sync.Mutex
store storage.StateStorer
factory Factory
chaindID int64
transactionService transaction.Service
beneficiary common.Address // the beneficiary we expect in cheques sent to us
recoverChequeFunc RecoverChequeFunc
}
type RecoverChequeFunc func(cheque *SignedCheque, chainID int64) (common.Address, error)
......@@ -59,20 +57,18 @@ type RecoverChequeFunc func(cheque *SignedCheque, chainID int64) (common.Address
// NewChequeStore creates new ChequeStore
func NewChequeStore(
store storage.StateStorer,
backend transaction.Backend,
factory Factory,
chainID int64,
beneficiary common.Address,
simpleSwapBindingFunc SimpleSwapBindingFunc,
transactionService transaction.Service,
recoverChequeFunc RecoverChequeFunc) ChequeStore {
return &chequeStore{
store: store,
factory: factory,
backend: backend,
chaindID: chainID,
simpleSwapBindingFunc: simpleSwapBindingFunc,
beneficiary: beneficiary,
recoverChequeFunc: recoverChequeFunc,
store: store,
factory: factory,
chaindID: chainID,
transactionService: transactionService,
beneficiary: beneficiary,
recoverChequeFunc: recoverChequeFunc,
}
}
......@@ -135,16 +131,10 @@ func (s *chequeStore) ReceiveCheque(ctx context.Context, cheque *SignedCheque) (
}
// blockchain calls below
binding, err := s.simpleSwapBindingFunc(cheque.Chequebook, s.backend)
if err != nil {
return nil, err
}
contract := newChequebookContract(cheque.Chequebook, s.transactionService)
// this does not change for the same chequebook
expectedIssuer, err := binding.Issuer(&bind.CallOpts{
Context: ctx,
})
expectedIssuer, err := contract.Issuer(ctx)
if err != nil {
return nil, err
}
......@@ -161,16 +151,12 @@ func (s *chequeStore) ReceiveCheque(ctx context.Context, cheque *SignedCheque) (
// basic liquidity check
// could be omitted as it is not particularly useful
balance, err := binding.Balance(&bind.CallOpts{
Context: ctx,
})
balance, err := contract.Balance(ctx)
if err != nil {
return nil, err
}
alreadyPaidOut, err := binding.PaidOut(&bind.CallOpts{
Context: ctx,
}, s.beneficiary)
alreadyPaidOut, err := contract.PaidOut(ctx, s.beneficiary)
if err != nil {
return nil, err
}
......
......@@ -10,10 +10,9 @@ import (
"math/big"
"testing"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethersphere/bee/pkg/settlement/swap/chequebook"
"github.com/ethersphere/bee/pkg/settlement/swap/transaction/backendmock"
transactionmock "github.com/ethersphere/bee/pkg/settlement/swap/transaction/mock"
storemock "github.com/ethersphere/bee/pkg/statestore/mock"
)
......@@ -49,29 +48,19 @@ func TestReceiveCheque(t *testing.T) {
chequestore := chequebook.NewChequeStore(
store,
backendmock.New(),
factory,
chainID,
beneficiary,
func(address common.Address, b bind.ContractBackend) (chequebook.SimpleSwapBinding, error) {
if address != chequebookAddress {
t.Fatalf("binding to wrong chequebook. wanted %x, got %x", chequebookAddress, address)
}
return &simpleSwapBindingMock{
issuer: func(*bind.CallOpts) (common.Address, error) {
return issuer, nil
},
balance: func(*bind.CallOpts) (*big.Int, error) {
return cumulativePayout2, nil
},
paidOut: func(o *bind.CallOpts, b common.Address) (*big.Int, error) {
if b != beneficiary {
t.Fatalf("checking for wrong beneficiary. wanted %x, got %x", beneficiary, b)
}
return big.NewInt(0), nil
},
}, nil
},
transactionmock.New(
transactionmock.WithABICallSequence(
transactionmock.ABICall(&chequebookABI, issuer.Hash().Bytes(), "issuer"),
transactionmock.ABICall(&chequebookABI, cumulativePayout2.FillBytes(make([]byte, 32)), "balance"),
transactionmock.ABICall(&chequebookABI, big.NewInt(0).FillBytes(make([]byte, 32)), "paidOut", beneficiary),
transactionmock.ABICall(&chequebookABI, issuer.Hash().Bytes(), "issuer"),
transactionmock.ABICall(&chequebookABI, cumulativePayout2.FillBytes(make([]byte, 32)), "balance"),
transactionmock.ABICall(&chequebookABI, big.NewInt(0).FillBytes(make([]byte, 32)), "paidOut", beneficiary),
),
),
func(c *chequebook.SignedCheque, cid int64) (common.Address, error) {
if cid != chainID {
t.Fatalf("recovery with wrong chain id. wanted %d, got %d", chainID, cid)
......@@ -149,12 +138,12 @@ func TestReceiveChequeInvalidBeneficiary(t *testing.T) {
chequestore := chequebook.NewChequeStore(
store,
backendmock.New(),
&factoryMock{},
chainID,
beneficiary,
transactionmock.New(),
nil,
nil)
)
_, err := chequestore.ReceiveCheque(context.Background(), cheque)
if err == nil {
......@@ -177,7 +166,6 @@ func TestReceiveChequeInvalidAmount(t *testing.T) {
chequestore := chequebook.NewChequeStore(
store,
backendmock.New(),
&factoryMock{
verifyChequebook: func(ctx context.Context, address common.Address) error {
return nil
......@@ -185,19 +173,13 @@ func TestReceiveChequeInvalidAmount(t *testing.T) {
},
chainID,
beneficiary,
func(address common.Address, b bind.ContractBackend) (chequebook.SimpleSwapBinding, error) {
return &simpleSwapBindingMock{
issuer: func(*bind.CallOpts) (common.Address, error) {
return issuer, nil
},
balance: func(*bind.CallOpts) (*big.Int, error) {
return cumulativePayout, nil
},
paidOut: func(o *bind.CallOpts, b common.Address) (*big.Int, error) {
return big.NewInt(0), nil
},
}, nil
},
transactionmock.New(
transactionmock.WithABICallSequence(
transactionmock.ABICall(&chequebookABI, issuer.Hash().Bytes(), "issuer"),
transactionmock.ABICall(&chequebookABI, cumulativePayout.FillBytes(make([]byte, 32)), "balance"),
transactionmock.ABICall(&chequebookABI, big.NewInt(0).FillBytes(make([]byte, 32)), "paidOut", beneficiary),
),
),
func(c *chequebook.SignedCheque, cid int64) (common.Address, error) {
return issuer, nil
})
......@@ -241,7 +223,6 @@ func TestReceiveChequeInvalidChequebook(t *testing.T) {
chequestore := chequebook.NewChequeStore(
store,
backendmock.New(),
&factoryMock{
verifyChequebook: func(ctx context.Context, address common.Address) error {
return chequebook.ErrNotDeployedByFactory
......@@ -249,19 +230,12 @@ func TestReceiveChequeInvalidChequebook(t *testing.T) {
},
chainID,
beneficiary,
func(address common.Address, b bind.ContractBackend) (chequebook.SimpleSwapBinding, error) {
return &simpleSwapBindingMock{
issuer: func(*bind.CallOpts) (common.Address, error) {
return issuer, nil
},
balance: func(*bind.CallOpts) (*big.Int, error) {
return cumulativePayout, nil
},
paidOut: func(o *bind.CallOpts, b common.Address) (*big.Int, error) {
return big.NewInt(0), nil
},
}, nil
},
transactionmock.New(
transactionmock.WithABICallSequence(
transactionmock.ABICall(&chequebookABI, issuer.Bytes(), "issuer"),
transactionmock.ABICall(&chequebookABI, cumulativePayout.FillBytes(make([]byte, 32)), "balance"),
),
),
func(c *chequebook.SignedCheque, cid int64) (common.Address, error) {
return issuer, nil
})
......@@ -290,7 +264,6 @@ func TestReceiveChequeInvalidSignature(t *testing.T) {
chequestore := chequebook.NewChequeStore(
store,
backendmock.New(),
&factoryMock{
verifyChequebook: func(ctx context.Context, address common.Address) error {
return nil
......@@ -298,16 +271,11 @@ func TestReceiveChequeInvalidSignature(t *testing.T) {
},
chainID,
beneficiary,
func(address common.Address, b bind.ContractBackend) (chequebook.SimpleSwapBinding, error) {
return &simpleSwapBindingMock{
issuer: func(*bind.CallOpts) (common.Address, error) {
return issuer, nil
},
balance: func(*bind.CallOpts) (*big.Int, error) {
return cumulativePayout, nil
},
}, nil
},
transactionmock.New(
transactionmock.WithABICallSequence(
transactionmock.ABICall(&chequebookABI, issuer.Hash().Bytes(), "issuer"),
),
),
func(c *chequebook.SignedCheque, cid int64) (common.Address, error) {
return common.Address{}, nil
})
......@@ -336,7 +304,6 @@ func TestReceiveChequeInsufficientBalance(t *testing.T) {
chequestore := chequebook.NewChequeStore(
store,
backendmock.New(),
&factoryMock{
verifyChequebook: func(ctx context.Context, address common.Address) error {
return nil
......@@ -344,19 +311,13 @@ func TestReceiveChequeInsufficientBalance(t *testing.T) {
},
chainID,
beneficiary,
func(address common.Address, b bind.ContractBackend) (chequebook.SimpleSwapBinding, error) {
return &simpleSwapBindingMock{
issuer: func(*bind.CallOpts) (common.Address, error) {
return issuer, nil
},
balance: func(*bind.CallOpts) (*big.Int, error) {
return big.NewInt(0).Sub(cumulativePayout, big.NewInt(1)), nil
},
paidOut: func(o *bind.CallOpts, b common.Address) (*big.Int, error) {
return big.NewInt(0), nil
},
}, nil
},
transactionmock.New(
transactionmock.WithABICallSequence(
transactionmock.ABICall(&chequebookABI, issuer.Hash().Bytes(), "issuer"),
transactionmock.ABICall(&chequebookABI, new(big.Int).Sub(cumulativePayout, big.NewInt(1)).FillBytes(make([]byte, 32)), "balance"),
transactionmock.ABICall(&chequebookABI, big.NewInt(0).FillBytes(make([]byte, 32)), "paidOut", beneficiary),
),
),
func(c *chequebook.SignedCheque, cid int64) (common.Address, error) {
return issuer, nil
})
......@@ -385,7 +346,6 @@ func TestReceiveChequeSufficientBalancePaidOut(t *testing.T) {
chequestore := chequebook.NewChequeStore(
store,
backendmock.New(),
&factoryMock{
verifyChequebook: func(ctx context.Context, address common.Address) error {
return nil
......@@ -393,19 +353,13 @@ func TestReceiveChequeSufficientBalancePaidOut(t *testing.T) {
},
chainID,
beneficiary,
func(address common.Address, b bind.ContractBackend) (chequebook.SimpleSwapBinding, error) {
return &simpleSwapBindingMock{
issuer: func(*bind.CallOpts) (common.Address, error) {
return issuer, nil
},
balance: func(*bind.CallOpts) (*big.Int, error) {
return big.NewInt(0).Sub(cumulativePayout, big.NewInt(100)), nil
},
paidOut: func(o *bind.CallOpts, b common.Address) (*big.Int, error) {
return big.NewInt(100), nil
},
}, nil
},
transactionmock.New(
transactionmock.WithABICallSequence(
transactionmock.ABICall(&chequebookABI, issuer.Hash().Bytes(), "issuer"),
transactionmock.ABICall(&chequebookABI, new(big.Int).Sub(cumulativePayout, big.NewInt(100)).FillBytes(make([]byte, 32)), "balance"),
transactionmock.ABICall(&chequebookABI, big.NewInt(0).FillBytes(make([]byte, 32)), "paidOut", beneficiary),
),
),
func(c *chequebook.SignedCheque, cid int64) (common.Address, error) {
return issuer, nil
})
......
......@@ -8,34 +8,10 @@ import (
"context"
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethersphere/bee/pkg/settlement/swap/chequebook"
)
type simpleSwapBindingMock struct {
balance func(*bind.CallOpts) (*big.Int, error)
issuer func(*bind.CallOpts) (common.Address, error)
totalPaidOut func(o *bind.CallOpts) (*big.Int, error)
paidOut func(*bind.CallOpts, common.Address) (*big.Int, error)
}
func (m *simpleSwapBindingMock) Balance(o *bind.CallOpts) (*big.Int, error) {
return m.balance(o)
}
func (m *simpleSwapBindingMock) Issuer(o *bind.CallOpts) (common.Address, error) {
return m.issuer(o)
}
func (m *simpleSwapBindingMock) TotalPaidOut(o *bind.CallOpts) (*big.Int, error) {
return m.totalPaidOut(o)
}
func (m *simpleSwapBindingMock) PaidOut(o *bind.CallOpts, c common.Address) (*big.Int, error) {
return m.paidOut(o, c)
}
type chequeSignerMock struct {
sign func(cheque *chequebook.Cheque) ([]byte, error)
}
......
// Copyright 2020 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package chequebook
import (
"context"
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethersphere/bee/pkg/settlement/swap/transaction"
)
type chequebookContract struct {
address common.Address
transactionService transaction.Service
}
func newChequebookContract(address common.Address, transactionService transaction.Service) *chequebookContract {
return &chequebookContract{
address: address,
transactionService: transactionService,
}
}
func (c *chequebookContract) Issuer(ctx context.Context) (common.Address, error) {
callData, err := chequebookABI.Pack("issuer")
if err != nil {
return common.Address{}, err
}
output, err := c.transactionService.Call(ctx, &transaction.TxRequest{
To: &c.address,
Data: callData,
})
if err != nil {
return common.Address{}, err
}
results, err := chequebookABI.Unpack("issuer", output)
if err != nil {
return common.Address{}, err
}
return *abi.ConvertType(results[0], new(common.Address)).(*common.Address), nil
}
// Balance returns the token balance of the chequebook.
func (c *chequebookContract) Balance(ctx context.Context) (*big.Int, error) {
callData, err := chequebookABI.Pack("balance")
if err != nil {
return nil, err
}
output, err := c.transactionService.Call(ctx, &transaction.TxRequest{
To: &c.address,
Data: callData,
})
if err != nil {
return nil, err
}
results, err := chequebookABI.Unpack("balance", output)
if err != nil {
return nil, err
}
return abi.ConvertType(results[0], new(big.Int)).(*big.Int), nil
}
func (c *chequebookContract) PaidOut(ctx context.Context, address common.Address) (*big.Int, error) {
callData, err := chequebookABI.Pack("paidOut", address)
if err != nil {
return nil, err
}
output, err := c.transactionService.Call(ctx, &transaction.TxRequest{
To: &c.address,
Data: callData,
})
if err != nil {
return nil, err
}
results, err := chequebookABI.Unpack("paidOut", output)
if err != nil {
return nil, err
}
return abi.ConvertType(results[0], new(big.Int)).(*big.Int), nil
}
func (c *chequebookContract) TotalPaidOut(ctx context.Context) (*big.Int, error) {
callData, err := chequebookABI.Pack("totalPaidOut")
if err != nil {
return nil, err
}
output, err := c.transactionService.Call(ctx, &transaction.TxRequest{
To: &c.address,
Data: callData,
})
if err != nil {
return nil, err
}
results, err := chequebookABI.Unpack("totalPaidOut", output)
if err != nil {
return nil, err
}
return abi.ConvertType(results[0], new(big.Int)).(*big.Int), nil
}
......@@ -102,7 +102,6 @@ func Init(
chainId int64,
overlayEthAddress common.Address,
chequeSigner ChequeSigner,
simpleSwapBindingFunc SimpleSwapBindingFunc,
) (chequebookService Service, err error) {
// verify that the supplied factory is valid
err = chequebookFactory.VerifyBytecode(ctx)
......@@ -167,7 +166,7 @@ func Init(
return nil, err
}
chequebookService, err = New(swapBackend, transactionService, chequebookAddress, overlayEthAddress, stateStore, chequeSigner, erc20Service, simpleSwapBindingFunc)
chequebookService, err = New(transactionService, chequebookAddress, overlayEthAddress, stateStore, chequeSigner, erc20Service)
if err != nil {
return nil, err
}
......@@ -188,7 +187,7 @@ func Init(
logger.Info("successfully deposited to chequebook")
}
} else {
chequebookService, err = New(swapBackend, transactionService, chequebookAddress, overlayEthAddress, stateStore, chequeSigner, erc20Service, simpleSwapBindingFunc)
chequebookService, err = New(transactionService, chequebookAddress, overlayEthAddress, stateStore, chequeSigner, erc20Service)
if err != nil {
return nil, err
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment