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

Commit

Permalink
swap, uint256: unify variable types, pt. 1 (#2063)
Browse files Browse the repository at this point in the history
swap, uint256: add uint256 package and type, refactor Cheque cumulative payout field into uint256 type
  • Loading branch information
mortelli authored Jan 15, 2020
1 parent e7e98cf commit 0bc6bef
Show file tree
Hide file tree
Showing 13 changed files with 466 additions and 91 deletions.
29 changes: 18 additions & 11 deletions swap/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package swap
import (
"encoding/json"
"fmt"
"math/big"

"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/rpc"
contract "github.com/ethersphere/swarm/contracts/swap"
"github.com/ethersphere/swarm/state"
"github.com/ethersphere/swarm/uint256"
)

// APIs is a node.Service interface method
Expand All @@ -23,7 +25,7 @@ func (s *Swap) APIs() []rpc.API {
}

type swapAPI interface {
AvailableBalance() (uint64, error)
AvailableBalance() (*uint256.Uint256, error)
PeerBalance(peer enode.ID) (int64, error)
Balances() (map[enode.ID]int64, error)
PeerCheques(peer enode.ID) (PeerCheques, error)
Expand Down Expand Up @@ -52,22 +54,22 @@ func NewAPI(s *Swap) *API {
}

// AvailableBalance returns the total balance of the chequebook against which new cheques can be written
func (s *Swap) AvailableBalance() (uint64, error) {
func (s *Swap) AvailableBalance() (*uint256.Uint256, error) {
// get the LiquidBalance of the chequebook
liquidBalance, err := s.contract.LiquidBalance(nil)
contractLiquidBalance, err := s.contract.LiquidBalance(nil)
if err != nil {
return 0, err
return nil, err
}

// get all cheques
cheques, err := s.Cheques()
if err != nil {
return 0, err
return nil, err
}

// Compute the total worth of cheques sent and how much of of this is cashed
var sentChequesWorth uint64
var cashedChequesWorth uint64
sentChequesWorth := new(big.Int)
cashedChequesWorth := new(big.Int)
for _, peerCheques := range cheques {
var sentCheque *Cheque
if peerCheques.PendingCheque != nil {
Expand All @@ -77,14 +79,19 @@ func (s *Swap) AvailableBalance() (uint64, error) {
} else {
continue
}
sentChequesWorth += sentCheque.ChequeParams.CumulativePayout
cumulativePayout := sentCheque.ChequeParams.CumulativePayout.Value()
sentChequesWorth.Add(sentChequesWorth, &cumulativePayout)
paidOut, err := s.contract.PaidOut(nil, sentCheque.ChequeParams.Beneficiary)
if err != nil {
return 0, err
return nil, err
}
cashedChequesWorth += paidOut.Uint64()
cashedChequesWorth.Add(cashedChequesWorth, paidOut)
}
return liquidBalance.Uint64() + cashedChequesWorth - sentChequesWorth, nil

totalChequesWorth := new(big.Int).Sub(cashedChequesWorth, sentChequesWorth)
tentativeLiquidBalance := new(big.Int).Add(contractLiquidBalance, totalChequesWorth)

return uint256.New().Set(*tentativeLiquidBalance)
}

// PeerBalance returns the balance for a given peer
Expand Down
9 changes: 5 additions & 4 deletions swap/cashout.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package swap
import (
"context"
"crypto/ecdsa"
"math/big"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -67,7 +66,8 @@ func (c *CashoutProcessor) cashCheque(ctx context.Context, request *CashoutReque
return err
}

tx, err := otherSwap.CashChequeBeneficiaryStart(opts, request.Destination, big.NewInt(int64(cheque.CumulativePayout)), cheque.Signature)
cumulativePayout := cheque.CumulativePayout.Value()
tx, err := otherSwap.CashChequeBeneficiaryStart(opts, request.Destination, &cumulativePayout, cheque.Signature)
if err != nil {
return err
}
Expand Down Expand Up @@ -98,11 +98,12 @@ func (c *CashoutProcessor) estimatePayout(ctx context.Context, cheque *Cheque) (

transactionCosts = gasPrice.Uint64() * CashChequeBeneficiaryTransactionCost

if paidOut.Cmp(big.NewInt(int64(cheque.CumulativePayout))) > 0 {
cumulativePayout := cheque.CumulativePayout.Value()
if paidOut.Cmp(&cumulativePayout) > 0 {
return 0, transactionCosts, nil
}

expectedPayout = cheque.CumulativePayout - paidOut.Uint64()
expectedPayout = (&cumulativePayout).Uint64() - paidOut.Uint64()

return expectedPayout, transactionCosts, nil
}
Expand Down
16 changes: 12 additions & 4 deletions swap/cashout_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/log"
contract "github.com/ethersphere/swarm/contracts/swap"
"github.com/ethersphere/swarm/uint256"
)

// TestContractIntegration tests a end-to-end cheque interaction.
Expand Down Expand Up @@ -73,8 +74,13 @@ func TestContractIntegration(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if result.Uint64() != cheque.CumulativePayout {
t.Fatalf("Wrong cumulative payout %d", result)
paidOut, err := uint256.New().Set(*result)
if err != nil {
t.Fatal(err)
}

if !cheque.CumulativePayout.Equals(paidOut) {
t.Fatalf("Wrong cumulative payout %v", paidOut)
}
log.Debug("cheques result", "result", result)

Expand All @@ -84,7 +90,8 @@ func TestContractIntegration(t *testing.T) {
t.Fatal(err)
}

tx, err = chequebook.CashChequeBeneficiaryStart(opts, beneficiaryAddress, big.NewInt(int64(bouncingCheque.CumulativePayout)), bouncingCheque.Signature)
cumulativePayout := bouncingCheque.CumulativePayout.Value()
tx, err = chequebook.CashChequeBeneficiaryStart(opts, beneficiaryAddress, &cumulativePayout, bouncingCheque.Signature)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -136,7 +143,8 @@ func TestCashCheque(t *testing.T) {
t.Fatal(err)
}

if paidOut.Cmp(big.NewInt(int64(testCheque.CumulativePayout))) != 0 {
cumulativePayout := testCheque.CumulativePayout.Value()
if paidOut.Cmp(&cumulativePayout) != 0 {
t.Fatalf("paidOut does not equal the CumulativePayout: paidOut=%v expected=%v", paidOut, testCheque.CumulativePayout)
}
}
Expand Down
25 changes: 14 additions & 11 deletions swap/cheque.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,22 @@ package swap
import (
"bytes"
"crypto/ecdsa"
"encoding/binary"
"fmt"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethersphere/swarm/uint256"
)

// encodeForSignature encodes the cheque params in the format used in the signing procedure
func (cheque *ChequeParams) encodeForSignature() []byte {
cumulativePayoutBytes := make([]byte, 32)
// we need to write the last 8 bytes as we write a uint64 into a 32-byte array
// encoded in BigEndian because EVM uses BigEndian encoding
binary.BigEndian.PutUint64(cumulativePayoutBytes[24:], cheque.CumulativePayout)
cumulativePayout := cheque.CumulativePayout.Value()
chequePayoutBytes := (&cumulativePayout).Bytes()
copy(cumulativePayoutBytes[32-len(chequePayoutBytes):], chequePayoutBytes)

// construct the actual cheque
input := cheque.Contract.Bytes()
input = append(input, cheque.Beneficiary.Bytes()...)
Expand Down Expand Up @@ -94,7 +97,7 @@ func (cheque *Cheque) Equal(other *Cheque) bool {
return false
}

if cheque.CumulativePayout != other.CumulativePayout {
if !cheque.CumulativePayout.Equals(other.CumulativePayout) {
return false
}

Expand Down Expand Up @@ -130,24 +133,24 @@ func (cheque *Cheque) verifyChequeProperties(p *Peer, expectedBeneficiary common

// verifyChequeAgainstLast verifies that the amount is higher than in the previous cheque and the increase is as expected
// returns the actual amount received in this cheque
func (cheque *Cheque) verifyChequeAgainstLast(lastCheque *Cheque, expectedAmount uint64) (uint64, error) {
actualAmount := cheque.CumulativePayout
func (cheque *Cheque) verifyChequeAgainstLast(lastCheque *Cheque, expectedAmount *uint256.Uint256) (*uint256.Uint256, error) {
actualAmount := uint256.New().Copy(cheque.CumulativePayout)

if lastCheque != nil {
if cheque.CumulativePayout <= lastCheque.CumulativePayout {
return 0, fmt.Errorf("wrong cheque parameters: expected cumulative payout larger than %d, was: %d", lastCheque.CumulativePayout, cheque.CumulativePayout)
if cheque.CumulativePayout.Cmp(lastCheque.CumulativePayout) < 1 {
return nil, fmt.Errorf("wrong cheque parameters: expected cumulative payout larger than %v, was: %v", lastCheque.CumulativePayout, cheque.CumulativePayout)
}

actualAmount -= lastCheque.CumulativePayout
actualAmount.Sub(actualAmount, lastCheque.CumulativePayout)
}

if expectedAmount != actualAmount {
return 0, fmt.Errorf("unexpected amount for honey, expected %d was %d", expectedAmount, actualAmount)
if !expectedAmount.Equals(actualAmount) {
return nil, fmt.Errorf("unexpected amount for honey, expected %v was %v", expectedAmount, actualAmount)
}

return actualAmount, nil
}

func (cheque *Cheque) String() string {
return fmt.Sprintf("Contract: %x Beneficiary: %x CumulativePayout: %d Honey: %d", cheque.Contract, cheque.Beneficiary, cheque.CumulativePayout, cheque.Honey)
return fmt.Sprintf("Contract: %x Beneficiary: %x CumulativePayout: %v Honey: %d", cheque.Contract, cheque.Beneficiary, cheque.CumulativePayout, cheque.Honey)
}
11 changes: 6 additions & 5 deletions swap/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/ethersphere/swarm/network"
"github.com/ethersphere/swarm/p2p/protocols"
"github.com/ethersphere/swarm/state"
"github.com/ethersphere/swarm/uint256"
)

// swapTestBackend encapsulates the SimulatedBackend and can offer
Expand Down Expand Up @@ -167,7 +168,7 @@ func newTestCheque() *Cheque {
cheque := &Cheque{
ChequeParams: ChequeParams{
Contract: testChequeContract,
CumulativePayout: uint64(42),
CumulativePayout: uint256.FromUint64(42),
Beneficiary: beneficiaryAddress,
},
Honey: uint64(42),
Expand All @@ -180,7 +181,7 @@ func newSignedTestCheque(testChequeContract common.Address, beneficiaryAddress c
cheque := &Cheque{
ChequeParams: ChequeParams{
Contract: testChequeContract,
CumulativePayout: cumulativePayout.Uint64(),
CumulativePayout: uint256.FromUint64(cumulativePayout.Uint64()),
Beneficiary: beneficiaryAddress,
},
Honey: cumulativePayout.Uint64(),
Expand All @@ -196,15 +197,15 @@ func newSignedTestCheque(testChequeContract common.Address, beneficiaryAddress c

// creates a randomized cheque structure for testing
func newRandomTestCheque() *Cheque {
amount := mrand.Intn(100)
amount := uint64(mrand.Intn(100))

cheque := &Cheque{
ChequeParams: ChequeParams{
Contract: testChequeContract,
CumulativePayout: uint64(amount),
CumulativePayout: uint256.FromUint64(amount),
Beneficiary: beneficiaryAddress,
},
Honey: uint64(amount),
Honey: amount,
}

return cheque
Expand Down
16 changes: 11 additions & 5 deletions swap/peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethersphere/swarm/p2p/protocols"
"github.com/ethersphere/swarm/uint256"
)

// ErrDontOwe indictates that no balance is actially owned
Expand Down Expand Up @@ -116,12 +117,12 @@ func (p *Peer) setPendingCheque(cheque *Cheque) error {

// getLastSentCumulativePayout returns the cumulative payout of the last sent cheque or 0 if there is none
// the caller is expected to hold p.lock
func (p *Peer) getLastSentCumulativePayout() uint64 {
func (p *Peer) getLastSentCumulativePayout() *uint256.Uint256 {
lastCheque := p.getLastSentCheque()
if lastCheque != nil {
return lastCheque.CumulativePayout
}
return 0
return uint256.New()
}

// the caller is expected to hold p.lock
Expand Down Expand Up @@ -162,16 +163,21 @@ func (p *Peer) createCheque() (*Cheque, error) {
// the balance should be negative here, we take the absolute value:
honey := uint64(-p.getBalance())

amount, err := p.swap.honeyPriceOracle.GetPrice(honey)
oraclePrice, err := p.swap.honeyPriceOracle.GetPrice(honey)
if err != nil {
return nil, fmt.Errorf("error getting price from oracle: %v", err)
}
price := uint256.FromUint64(oraclePrice)

total := p.getLastSentCumulativePayout()
cumulativePayout := p.getLastSentCumulativePayout()
newCumulativePayout, err := uint256.New().Add(cumulativePayout, price)
if err != nil {
return nil, err
}

cheque = &Cheque{
ChequeParams: ChequeParams{
CumulativePayout: total + amount,
CumulativePayout: newCumulativePayout,
Contract: p.swap.GetParams().ContractAddress,
Beneficiary: p.beneficiary,
},
Expand Down
14 changes: 8 additions & 6 deletions swap/protocol_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
"github.com/ethereum/go-ethereum/rpc"
contract "github.com/ethersphere/swarm/contracts/swap"
p2ptest "github.com/ethersphere/swarm/p2p/testing"
"github.com/ethersphere/swarm/uint256"
colorable "github.com/mattn/go-colorable"
)

Expand Down Expand Up @@ -245,9 +246,10 @@ func TestEmitCheque(t *testing.T) {
// gasPrice on testBackend == 1
// estimated gas costs == 50000
// cheque should be sent if the accumulated amount of uncashed cheques is worth more than 100000
balance := uint64(100001)
balance := uint256.FromUint64(100001)
balanceValue := balance.Value()

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

Expand All @@ -260,7 +262,7 @@ func TestEmitCheque(t *testing.T) {

debitor := creditorSwap.getPeer(protocolTester.Nodes[0].ID())
// set balance artificially
if err = debitor.setBalance(int64(balance)); err != nil {
if err = debitor.setBalance(balanceValue.Int64()); err != nil {
t.Fatal(err)
}

Expand All @@ -275,7 +277,7 @@ func TestEmitCheque(t *testing.T) {
Beneficiary: creditorSwap.owner.address,
CumulativePayout: balance,
},
Honey: balance,
Honey: balanceValue.Uint64(),
}
cheque.Signature, err = cheque.Sign(debitorSwap.owner.privateKey)
if err != nil {
Expand Down Expand Up @@ -380,8 +382,8 @@ func TestTriggerPaymentThreshold(t *testing.T) {
t.Fatal("Expected pending cheque")
}

if pending.CumulativePayout != expectedAmount {
t.Fatalf("Expected cheque cumulative payout to be %d, but is %d", expectedAmount, pending.CumulativePayout)
if !pending.CumulativePayout.Equals(uint256.FromUint64(expectedAmount)) {
t.Fatalf("Expected cheque cumulative payout to be %d, but is %v", expectedAmount, pending.CumulativePayout)
}

if pending.Honey != expectedAmount {
Expand Down
Loading

0 comments on commit 0bc6bef

Please sign in to comment.