Skip to content
This repository has been archived by the owner on Aug 2, 2021. It is now read-only.

swap: unify variable types, pt. 2 #2082

Merged
merged 10 commits into from
Jan 30, 2020
8 changes: 5 additions & 3 deletions contracts/swap/swap.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
contract "github.com/ethersphere/go-sw3/contracts-v0-2-0/erc20simpleswap"
"github.com/ethersphere/swarm/uint256"
)

var (
Expand All @@ -50,7 +51,7 @@ type Contract interface {
// Deposit sends a raw transaction to the chequebook, triggering the fallback—depositing amount
Deposit(auth *bind.TransactOpts, amout *big.Int) (*types.Receipt, error)
// CashChequeBeneficiaryStart sends the transaction to cash a cheque as the beneficiary
CashChequeBeneficiaryStart(opts *bind.TransactOpts, beneficiary common.Address, cumulativePayout *big.Int, ownerSig []byte) (*types.Transaction, error)
CashChequeBeneficiaryStart(opts *bind.TransactOpts, beneficiary common.Address, cumulativePayout *uint256.Uint256, ownerSig []byte) (*types.Transaction, error)
// CashChequeBeneficiaryResult processes the receipt from a CashChequeBeneficiary transaction
CashChequeBeneficiaryResult(receipt *types.Receipt) *CashChequeResult
// LiquidBalance returns the LiquidBalance (total balance in ERC20-token - total hard deposits in ERC20-token) of the chequebook
Expand Down Expand Up @@ -143,8 +144,9 @@ func (s simpleContract) Deposit(auth *bind.TransactOpts, amount *big.Int) (*type
}

// CashChequeBeneficiaryStart sends the transaction to cash a cheque as the beneficiary
func (s simpleContract) CashChequeBeneficiaryStart(opts *bind.TransactOpts, beneficiary common.Address, cumulativePayout *big.Int, ownerSig []byte) (*types.Transaction, error) {
tx, err := s.instance.CashChequeBeneficiary(opts, beneficiary, cumulativePayout, ownerSig)
func (s simpleContract) CashChequeBeneficiaryStart(opts *bind.TransactOpts, beneficiary common.Address, cumulativePayout *uint256.Uint256, ownerSig []byte) (*types.Transaction, error) {
payout := cumulativePayout.Value()
tx, err := s.instance.CashChequeBeneficiary(opts, beneficiary, &payout, ownerSig)
if err != nil {
return nil, err
}
Expand Down
41 changes: 28 additions & 13 deletions swap/cashout.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/metrics"
contract "github.com/ethersphere/swarm/contracts/swap"
"github.com/ethersphere/swarm/uint256"
)

// CashChequeBeneficiaryTransactionCost is the expected gas cost of a CashChequeBeneficiary transaction
Expand Down Expand Up @@ -66,8 +67,7 @@ func (c *CashoutProcessor) cashCheque(ctx context.Context, request *CashoutReque
return err
}

cumulativePayout := cheque.CumulativePayout.Value()
tx, err := otherSwap.CashChequeBeneficiaryStart(opts, request.Destination, &cumulativePayout, cheque.Signature)
tx, err := otherSwap.CashChequeBeneficiaryStart(opts, request.Destination, cheque.CumulativePayout, cheque.Signature)
if err != nil {
return err
}
Expand All @@ -80,30 +80,45 @@ func (c *CashoutProcessor) cashCheque(ctx context.Context, request *CashoutReque
}

// estimatePayout estimates the payout for a given cheque as well as the transaction cost
func (c *CashoutProcessor) estimatePayout(ctx context.Context, cheque *Cheque) (expectedPayout uint64, transactionCosts uint64, err error) {
func (c *CashoutProcessor) estimatePayout(ctx context.Context, cheque *Cheque) (expectedPayout *uint256.Uint256, transactionCosts *uint256.Uint256, err error) {
otherSwap, err := contract.InstanceAt(cheque.Contract, c.backend)
if err != nil {
return 0, 0, err
return nil, nil, err
}

paidOut, err := otherSwap.PaidOut(&bind.CallOpts{Context: ctx}, cheque.Beneficiary)
po, err := otherSwap.PaidOut(&bind.CallOpts{Context: ctx}, cheque.Beneficiary)
if err != nil {
return 0, 0, err
return nil, nil, err
}

gasPrice, err := c.backend.SuggestGasPrice(ctx)
paidOut, err := uint256.New().Set(*po)
if err != nil {
return 0, 0, err
return nil, nil, err
}

transactionCosts = gasPrice.Uint64() * CashChequeBeneficiaryTransactionCost
gp, err := c.backend.SuggestGasPrice(ctx)
if err != nil {
return nil, nil, err
}

gasPrice, err := uint256.New().Set(*gp)
if err != nil {
return nil, nil, err
}

cumulativePayout := cheque.CumulativePayout.Value()
if paidOut.Cmp(&cumulativePayout) > 0 {
return 0, transactionCosts, nil
transactionCosts, err = uint256.New().Mul(gasPrice, uint256.FromUint64(CashChequeBeneficiaryTransactionCost))
if err != nil {
return nil, nil, err
}

if paidOut.Cmp(cheque.CumulativePayout) > 0 {
return uint256.New(), transactionCosts, nil
}

expectedPayout = (&cumulativePayout).Uint64() - paidOut.Uint64()
expectedPayout, err = uint256.New().Sub(cheque.CumulativePayout, paidOut)
if err != nil {
return nil, nil, err
}

return expectedPayout, transactionCosts, nil
}
Expand Down
25 changes: 14 additions & 11 deletions swap/cashout_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package swap

import (
"context"
"math/big"
"testing"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
Expand All @@ -37,7 +36,7 @@ func TestContractIntegration(t *testing.T) {
reset := setupContractTest()
defer reset()

payout := big.NewInt(42)
payout := uint256.FromUint64(42)

chequebook, err := testDeployWithPrivateKey(context.Background(), backend, ownerKey, ownerAddress, payout)
if err != nil {
Expand Down Expand Up @@ -85,13 +84,17 @@ func TestContractIntegration(t *testing.T) {
log.Debug("cheques result", "result", result)

// create a cheque that will bounce
bouncingCheque, err := newSignedTestCheque(chequebook.ContractParams().ContractAddress, beneficiaryAddress, payout.Add(payout, big.NewInt(int64(10000*RetrieveRequestPrice))), ownerKey)
_, err = payout.Add(payout, uint256.FromUint64(10000*RetrieveRequestPrice))
if err != nil {
t.Fatal(err)
}

cumulativePayout := bouncingCheque.CumulativePayout.Value()
tx, err = chequebook.CashChequeBeneficiaryStart(opts, beneficiaryAddress, &cumulativePayout, bouncingCheque.Signature)
bouncingCheque, err := newSignedTestCheque(chequebook.ContractParams().ContractAddress, beneficiaryAddress, payout, ownerKey)
if err != nil {
t.Fatal(err)
}

tx, err = chequebook.CashChequeBeneficiaryStart(opts, beneficiaryAddress, bouncingCheque.CumulativePayout, bouncingCheque.Signature)
if err != nil {
t.Fatal(err)
}
Expand All @@ -118,7 +121,7 @@ func TestCashCheque(t *testing.T) {
defer reset()

cashoutProcessor := newCashoutProcessor(backend, ownerKey)
payout := big.NewInt(42)
payout := uint256.FromUint64(42)

chequebook, err := testDeployWithPrivateKey(context.Background(), backend, ownerKey, ownerAddress, payout)
if err != nil {
Expand Down Expand Up @@ -156,7 +159,7 @@ func TestEstimatePayout(t *testing.T) {
defer reset()

cashoutProcessor := newCashoutProcessor(backend, ownerKey)
payout := big.NewInt(42)
payout := uint256.FromUint64(42)

chequebook, err := testDeployWithPrivateKey(context.Background(), backend, ownerKey, ownerAddress, payout)
if err != nil {
Expand All @@ -173,12 +176,12 @@ func TestEstimatePayout(t *testing.T) {
t.Fatal(err)
}

if expectedPayout != payout.Uint64() {
t.Fatalf("unexpected expectedPayout: got %d, wanted: %d", expectedPayout, payout.Uint64())
if !expectedPayout.Equals(payout) {
t.Fatalf("unexpected expectedPayout: got %v, wanted: %v", expectedPayout, payout)
}

// the gas price in the simulated backend is 1 therefore the total transactionCost should be 50000 * 1 = 50000
if transactionCost != CashChequeBeneficiaryTransactionCost {
t.Fatalf("unexpected transactionCost: got %d, wanted: %d", transactionCost, 0)
if !transactionCost.Equals(uint256.FromUint64(CashChequeBeneficiaryTransactionCost)) {
t.Fatalf("unexpected transaction cost: got %v, wanted: %d", transactionCost, 0)
}
}
14 changes: 8 additions & 6 deletions swap/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,14 +177,15 @@ func newTestCheque() *Cheque {
return cheque
}

func newSignedTestCheque(testChequeContract common.Address, beneficiaryAddress common.Address, cumulativePayout *big.Int, signingKey *ecdsa.PrivateKey) (*Cheque, error) {
func newSignedTestCheque(testChequeContract common.Address, beneficiaryAddress common.Address, cumulativePayout *uint256.Uint256, signingKey *ecdsa.PrivateKey) (*Cheque, error) {
cp := cumulativePayout.Value()
cheque := &Cheque{
ChequeParams: ChequeParams{
Contract: testChequeContract,
CumulativePayout: uint256.FromUint64(cumulativePayout.Uint64()),
CumulativePayout: cumulativePayout,
Beneficiary: beneficiaryAddress,
},
Honey: cumulativePayout.Uint64(),
Honey: (&cp).Uint64(),
}

sig, err := cheque.Sign(signingKey)
Expand Down Expand Up @@ -263,7 +264,7 @@ func setupContractTest() func() {
}

// deploy for testing (needs simulated backend commit)
func testDeployWithPrivateKey(ctx context.Context, backend cswap.Backend, privateKey *ecdsa.PrivateKey, ownerAddress common.Address, depositAmount *big.Int) (cswap.Contract, error) {
func testDeployWithPrivateKey(ctx context.Context, backend cswap.Backend, privateKey *ecdsa.PrivateKey, ownerAddress common.Address, depositAmount *uint256.Uint256) (cswap.Contract, error) {
opts := bind.NewKeyedTransactor(privateKey)
opts.Context = ctx

Expand Down Expand Up @@ -293,7 +294,8 @@ func testDeployWithPrivateKey(ctx context.Context, backend cswap.Backend, privat
return nil, err
}

tx, err := token.Mint(bind.NewKeyedTransactor(ownerKey), contract.ContractParams().ContractAddress, depositAmount)
deposit := depositAmount.Value()
tx, err := token.Mint(bind.NewKeyedTransactor(ownerKey), contract.ContractParams().ContractAddress, &deposit)
if err != nil {
return nil, err
}
Expand All @@ -311,7 +313,7 @@ func testDeployWithPrivateKey(ctx context.Context, backend cswap.Backend, privat
}

// deploy for testing (needs simulated backend commit)
func testDeploy(ctx context.Context, swap *Swap, depositAmount *big.Int) (err error) {
func testDeploy(ctx context.Context, swap *Swap, depositAmount *uint256.Uint256) (err error) {
swap.contract, err = testDeployWithPrivateKey(ctx, swap.backend, swap.owner.privateKey, swap.owner.address, depositAmount)
return err
}
Expand Down
17 changes: 8 additions & 9 deletions swap/protocol_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"context"
"fmt"
"io/ioutil"
"math/big"
"os"
"path/filepath"
"reflect"
Expand Down Expand Up @@ -51,7 +50,7 @@ type swapTester struct {
}

// creates a new protocol tester for swap with a deployed chequebook
func newSwapTester(t *testing.T, backend *swapTestBackend, depositAmount *big.Int) (*swapTester, func(), error) {
func newSwapTester(t *testing.T, backend *swapTestBackend, depositAmount *uint256.Uint256) (*swapTester, func(), error) {
swap, clean := newTestSwap(t, ownerKey, backend)

err := testDeploy(context.Background(), swap, depositAmount)
Expand Down Expand Up @@ -136,7 +135,7 @@ func correctSwapHandshakeMsg(swap *Swap) *HandshakeMsg {
// TestHandshake tests the correct handshake scenario
func TestHandshake(t *testing.T) {
// setup the protocolTester, which will allow protocol testing by sending messages
protocolTester, clean, err := newSwapTester(t, nil, big.NewInt(0))
protocolTester, clean, err := newSwapTester(t, nil, uint256.FromUint64(0))
defer clean()
if err != nil {
t.Fatal(err)
Expand All @@ -154,7 +153,7 @@ func TestHandshake(t *testing.T) {
// TestHandshakeInvalidChainID tests that a handshake with the wrong chain id is rejected
func TestHandshakeInvalidChainID(t *testing.T) {
// setup the protocolTester, which will allow protocol testing by sending messages
protocolTester, clean, err := newSwapTester(t, nil, big.NewInt(0))
protocolTester, clean, err := newSwapTester(t, nil, uint256.FromUint64(0))
defer clean()
if err != nil {
t.Fatal(err)
Expand All @@ -176,7 +175,7 @@ func TestHandshakeInvalidChainID(t *testing.T) {
// TestHandshakeEmptyContract tests that a handshake with an empty contract address is rejected
func TestHandshakeEmptyContract(t *testing.T) {
// setup the protocolTester, which will allow protocol testing by sending messages
protocolTester, clean, err := newSwapTester(t, nil, big.NewInt(0))
protocolTester, clean, err := newSwapTester(t, nil, uint256.FromUint64(0))
defer clean()
if err != nil {
t.Fatal(err)
Expand All @@ -198,7 +197,7 @@ func TestHandshakeEmptyContract(t *testing.T) {
// TestHandshakeInvalidContract tests that a handshake with an address that's not a valid chequebook
func TestHandshakeInvalidContract(t *testing.T) {
// setup the protocolTester, which will allow protocol testing by sending messages
protocolTester, clean, err := newSwapTester(t, nil, big.NewInt(0))
protocolTester, clean, err := newSwapTester(t, nil, uint256.FromUint64(0))
defer clean()
if err != nil {
t.Fatal(err)
Expand All @@ -224,7 +223,7 @@ func TestHandshakeInvalidContract(t *testing.T) {
func TestEmitCheque(t *testing.T) {
testBackend := newTestBackend(t)

protocolTester, clean, err := newSwapTester(t, testBackend, big.NewInt(0))
protocolTester, clean, err := newSwapTester(t, testBackend, uint256.FromUint64(0))
defer clean()
if err != nil {
t.Fatal(err)
Expand All @@ -249,7 +248,7 @@ func TestEmitCheque(t *testing.T) {
balance := uint256.FromUint64(100001)
balanceValue := balance.Value()

if err := testDeploy(context.Background(), debitorSwap, &balanceValue); err != nil {
if err := testDeploy(context.Background(), debitorSwap, balance); err != nil {
t.Fatal(err)
}

Expand Down Expand Up @@ -334,7 +333,7 @@ func TestEmitCheque(t *testing.T) {
func TestTriggerPaymentThreshold(t *testing.T) {
testBackend := newTestBackend(t)
log.Debug("create test swap")
protocolTester, clean, err := newSwapTester(t, testBackend, big.NewInt(int64(DefaultPaymentThreshold)*2))
protocolTester, clean, err := newSwapTester(t, testBackend, uint256.FromUint64(DefaultPaymentThreshold*2))
defer clean()
if err != nil {
t.Fatal(err)
Expand Down
2 changes: 1 addition & 1 deletion swap/simulations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ func newSimServiceMap(params *swapSimulationParams) map[string]simulation.Servic
ts.spec.Hook = protocols.NewAccounting(balance)
ts.swap = balance
// deploy the accounting to the `SimulatedBackend`
err = testDeploy(context.Background(), balance, big.NewInt(100000*int64(RetrieveRequestPrice)))
err = testDeploy(context.Background(), balance, uint256.FromUint64(100000*RetrieveRequestPrice))
if err != nil {
return nil, nil, err
}
Expand Down
6 changes: 2 additions & 4 deletions swap/swap.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,16 +438,14 @@ func (s *Swap) handleEmitChequeMsg(ctx context.Context, p *Peer, msg *EmitCheque
return protocols.Break(err)
}

payout := uint256.FromUint64(expectedPayout)
costs := uint256.FromUint64(transactionCosts)
costsMultiplier := uint256.FromUint64(2)
costThreshold, err := uint256.New().Mul(costs, costsMultiplier)
costThreshold, err := uint256.New().Mul(transactionCosts, costsMultiplier)
if err != nil {
return err
}

// do a payout transaction if we get 2 times the gas costs
if payout.Cmp(costThreshold) == 1 {
if expectedPayout.Cmp(costThreshold) == 1 {
go defaultCashCheque(s, cheque)
}

Expand Down
Loading