Skip to content

Commit

Permalink
change the way we get transaction initiator
Browse files Browse the repository at this point in the history
  • Loading branch information
anatollupacescu committed May 7, 2021
1 parent fe273cb commit f11136b
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 73 deletions.
4 changes: 3 additions & 1 deletion pkg/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,9 @@ func NewBee(addr string, swarmAddress swarm.Address, publicKey ecdsa.PublicKey,
return nil, err
}

p2ps, err := libp2p.New(p2pCtx, signer, networkID, swarmAddress, addr, addressbook, stateStore, lightNodes, swapBackend, logger, tracer, libp2p.Options{
vd := transaction.NewValidator(swapBackend, chainID)

p2ps, err := libp2p.New(p2pCtx, signer, networkID, swarmAddress, addr, addressbook, stateStore, lightNodes, vd.MatchesSender, logger, tracer, libp2p.Options{
PrivateKey: libp2pPrivateKey,
NATAddr: o.NATAddr,
EnableWS: o.EnableWS,
Expand Down
19 changes: 9 additions & 10 deletions pkg/p2p/libp2p/internal/handshake/handshake.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ var (
ErrInvalidSyn = errors.New("invalid syn")

// ErrAddressNotFound is returned if observable address in ack is not a valid..
ErrAddressNotFound = errors.New("address not found on blockchain")
ErrAddressNotFound = errors.New("address not found")

// ErrWelcomeMessageLength is returned if the welcome message is longer than the maximum length
ErrWelcomeMessageLength = fmt.Errorf("handshake welcome message longer than maximum of %d characters", MaxWelcomeMessageLength)
Expand All @@ -72,7 +72,7 @@ type SwapBackend interface {
type Service struct {
signer crypto.Signer
advertisableAddresser AdvertisableAddressResolver
swapBackend SwapBackend
isSender SenderMatcher
overlay swarm.Address
fullNode bool
transaction string
Expand All @@ -99,8 +99,10 @@ func (i *Info) LightString() string {
return ""
}

type SenderMatcher func(context.Context, string, uint64, swarm.Address) (bool, error)

// New creates a new handshake Service.
func New(signer crypto.Signer, advertisableAddresser AdvertisableAddressResolver, swapBackend SwapBackend, overlay swarm.Address, networkID uint64, fullNode bool, transaction string, welcomeMessage string, logger logging.Logger) (*Service, error) {
func New(signer crypto.Signer, advertisableAddresser AdvertisableAddressResolver, isSender SenderMatcher, overlay swarm.Address, networkID uint64, fullNode bool, transaction string, welcomeMessage string, logger logging.Logger) (*Service, error) {
if len(welcomeMessage) > MaxWelcomeMessageLength {
return nil, ErrWelcomeMessageLength
}
Expand All @@ -112,7 +114,7 @@ func New(signer crypto.Signer, advertisableAddresser AdvertisableAddressResolver
networkID: networkID,
fullNode: fullNode,
transaction: transaction,
swapBackend: swapBackend,
isSender: isSender,
receivedHandshakes: make(map[libp2ppeer.ID]struct{}),
logger: logger,
Notifiee: new(network.NoopNotifiee),
Expand Down Expand Up @@ -286,15 +288,12 @@ func (s *Service) Handle(ctx context.Context, stream p2p.Stream, remoteMultiaddr
s.logger.Infof("greeting \"%s\" from peer: %s", ack.WelcomeMessage, remoteBzzAddress.Overlay.String())
}

incomingTx := common.HexToHash(ack.Transaction)

txReceipt, err := s.swapBackend.TransactionReceipt(ctx, incomingTx)
matchesSender, err := s.isSender(ctx, ack.Transaction, s.networkID, remoteBzzAddress.Overlay)
if err != nil {
return nil, fmt.Errorf("get transaction receipt: %w", err)
return nil, err
}

expectedRemoteBzzAddress := crypto.NewOverlayFromEthereumAddress(txReceipt.ContractAddress.Bytes(), s.networkID)
if !expectedRemoteBzzAddress.Equal(remoteBzzAddress.Overlay) {
if !matchesSender {
return nil, fmt.Errorf("given address is not registered on Ethereum: %v: %w", remoteBzzAddress.Overlay, ErrAddressNotFound)
}

Expand Down
24 changes: 6 additions & 18 deletions pkg/p2p/libp2p/internal/handshake/handshake_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,16 @@ import (
"errors"
"fmt"
"io/ioutil"
"math/big"
"testing"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethersphere/bee/pkg/bzz"
"github.com/ethersphere/bee/pkg/crypto"
"github.com/ethersphere/bee/pkg/logging"
"github.com/ethersphere/bee/pkg/p2p/libp2p/internal/handshake"
"github.com/ethersphere/bee/pkg/p2p/libp2p/internal/handshake/mock"
"github.com/ethersphere/bee/pkg/p2p/libp2p/internal/handshake/pb"
"github.com/ethersphere/bee/pkg/p2p/protobuf"
"github.com/ethersphere/bee/pkg/swarm"

libp2ppeer "github.com/libp2p/go-libp2p-core/peer"
ma "github.com/multiformats/go-multiaddr"
Expand Down Expand Up @@ -95,9 +93,8 @@ func TestHandshake(t *testing.T) {

aaddresser := &AdvertisableAddresserMock{}

ethAddr, _ := signer2.EthereumAddress()
swapBackend := &swapBackendMock{
contractAddr: ethAddr,
swapBackend := func(context.Context, string, uint64, swarm.Address) (bool, error) {
return true, nil
}

handshakeService, err := handshake.New(signer1, aaddresser, swapBackend, node1Info.BzzAddress.Overlay, networkID, true, "", testWelcomeMessage, logger)
Expand Down Expand Up @@ -644,9 +641,10 @@ func TestHandshake(t *testing.T) {
})

t.Run("Handle - transaction is not on the blockchain", func(t *testing.T) {
sbMock := &swapBackendMock{
contractAddr: common.BigToAddress(big.NewInt(11)),
sbMock := func(context.Context, string, uint64, swarm.Address) (bool, error) {
return false, nil
}

handshakeService, err := handshake.New(signer1, aaddresser, sbMock, node1Info.BzzAddress.Overlay, networkID, true, "0xff", "", logger)
if err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -739,13 +737,3 @@ func (a *AdvertisableAddresserMock) Resolve(observedAdddress ma.Multiaddr) (ma.M

return observedAdddress, nil
}

type swapBackendMock struct {
contractAddr common.Address
}

func (s *swapBackendMock) TransactionReceipt(context.Context, common.Hash) (*types.Receipt, error) {
return &types.Receipt{
ContractAddress: s.contractAddr,
}, nil
}
2 changes: 1 addition & 1 deletion pkg/p2p/libp2p/libp2p.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ type Options struct {
Transaction string
}

func New(ctx context.Context, signer beecrypto.Signer, networkID uint64, overlay swarm.Address, addr string, ab addressbook.Putter, storer storage.StateStorer, lightNodes *lightnode.Container, swapBackend handshake.SwapBackend, logger logging.Logger, tracer *tracing.Tracer, o Options) (*Service, error) {
func New(ctx context.Context, signer beecrypto.Signer, networkID uint64, overlay swarm.Address, addr string, ab addressbook.Putter, storer storage.StateStorer, lightNodes *lightnode.Container, swapBackend handshake.SenderMatcher, logger logging.Logger, tracer *tracing.Tracer, o Options) (*Service, error) {
host, port, err := net.SplitHostPort(addr)
if err != nil {
return nil, fmt.Errorf("address: %w", err)
Expand Down
47 changes: 4 additions & 43 deletions pkg/p2p/libp2p/libp2p_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,10 @@ import (
"crypto/ecdsa"
"io/ioutil"
"sort"
"sync"
"testing"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethersphere/bee/pkg/addressbook"
"github.com/ethersphere/bee/pkg/crypto"
"github.com/ethersphere/bee/pkg/logging"
Expand All @@ -36,11 +33,6 @@ type libp2pServiceOpts struct {
libp2pOpts libp2p.Options
}

// mockSwapBackend is used in spoofed address validation
var mockSwapBackend = &SwapBackend{
addrs: make(map[common.Hash]common.Address),
}

// newService constructs a new libp2p service.
func newService(t *testing.T, networkID uint64, o libp2pServiceOpts) (s *libp2p.Service, overlay swarm.Address) {
t.Helper()
Expand Down Expand Up @@ -82,12 +74,11 @@ func newService(t *testing.T, networkID uint64, o libp2pServiceOpts) (s *libp2p.
opts := o.libp2pOpts
opts.Transaction = hexutil.EncodeUint64(o.PrivateKey.Y.Uint64())

signer := crypto.NewDefaultSigner(swarmKey)
ethAddr, _ := signer.EthereumAddress()
tx := common.HexToHash(opts.Transaction)
mockSwapBackend.add(tx, ethAddr)
senderMatcher := func(context.Context, string, uint64, swarm.Address) (bool, error) {
return true, nil
}

s, err = libp2p.New(ctx, signer, networkID, overlay, addr, o.Addressbook, statestore, lightnodes, mockSwapBackend, o.Logger, nil, opts)
s, err = libp2p.New(ctx, crypto.NewDefaultSigner(swarmKey), networkID, overlay, addr, o.Addressbook, statestore, lightnodes, senderMatcher, o.Logger, nil, opts)
if err != nil {
t.Fatal(err)
}
Expand All @@ -96,7 +87,6 @@ func newService(t *testing.T, networkID uint64, o libp2pServiceOpts) (s *libp2p.
t.Cleanup(func() {
cancel()
s.Close()
mockSwapBackend.remove(tx)
})
return s, overlay
}
Expand Down Expand Up @@ -169,32 +159,3 @@ func serviceUnderlayAddress(t *testing.T, s *libp2p.Service) multiaddr.Multiaddr
}
return addrs[0]
}

// SwapBackend maps overlay to eth address
type SwapBackend struct {
addrs map[common.Hash]common.Address
m sync.RWMutex
}

func (sb *SwapBackend) add(tx common.Hash, ethAddr common.Address) {
sb.m.Lock()
defer sb.m.Unlock()

sb.addrs[tx] = ethAddr
}

func (sb *SwapBackend) remove(tx common.Hash) {
sb.m.Lock()
defer sb.m.Unlock()

delete(sb.addrs, tx)
}

func (sb *SwapBackend) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) {
sb.m.RLock()
defer sb.m.RUnlock()

return &types.Receipt{
ContractAddress: sb.addrs[txHash],
}, nil
}
46 changes: 46 additions & 0 deletions pkg/settlement/swap/transaction/sender_validator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package transaction

import (
"context"
"fmt"
"math/big"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethersphere/bee/pkg/crypto"
"github.com/ethersphere/bee/pkg/swarm"
)

type validator struct {
backend Backend
signer types.Signer
}

func NewValidator(backend Backend, chainID int64) validator {
return validator{
backend: backend,
signer: types.NewEIP155Signer(big.NewInt(chainID)),
}
}

func (s validator) MatchesSender(ctx context.Context, tx string, networkID uint64, senderOverlay swarm.Address) (bool, error) {
incomingTx := common.HexToHash(tx)

nTx, isPending, err := s.backend.TransactionByHash(ctx, incomingTx)
if err != nil {
return false, err
}

if isPending {
return false, fmt.Errorf("transaction still pending")
}

sender, err := types.Sender(nil, nTx)
if err != nil {
return false, err
}

expectedRemoteBzzAddress := crypto.NewOverlayFromEthereumAddress(sender.Bytes(), networkID)

return expectedRemoteBzzAddress.Equal(senderOverlay), nil
}

0 comments on commit f11136b

Please sign in to comment.