diff --git a/contracts/swap/swap.go b/contracts/swap/swap.go index 6cfccd5616..4f972d5bab 100644 --- a/contracts/swap/swap.go +++ b/contracts/swap/swap.go @@ -89,12 +89,23 @@ func (s *Swap) ContractParams() *Params { } } -// SubmitChequeBeneficiary is used to cash in a cheque -func (s *Swap) SubmitChequeBeneficiary(opts *bind.TransactOpts, serial *big.Int, amount *big.Int, timeout *big.Int, ownerSig []byte) (*types.Transaction, error) { - return s.Instance.SubmitChequeBeneficiary(opts, serial, amount, timeout, ownerSig) +// SubmitChequeBeneficiary is used to cash in a cheque. It returns directly the transactionHash, a channel on which can be listened for the transaction to be mined and a channel where we can send an error +func (s *Swap) SubmitChequeBeneficiary(auth *bind.TransactOpts, backend Backend, serial *big.Int, amount *big.Int, timeout *big.Int, ownerSig []byte) (common.Hash, <-chan *types.Receipt, <-chan error) { + errorCh := make(chan error) + receiptCh := make(chan *types.Receipt) + tx, err := s.Instance.SubmitChequeBeneficiary(auth, serial, amount, timeout, ownerSig) + if err != nil { + errorCh <- err + } + go func() { + receipt, err := bind.WaitMined(auth.Context, backend, tx) + errorCh <- err + receiptCh <- receipt + }() + return tx.Hash(), receiptCh, errorCh } -func (s *Swap) InstanceAt(address common.Address, backend bind.ContractBackend) *contract.SimpleSwap { - ref, _ := contract.NewSimpleSwap(address, backend) - return ref +func (s *Swap) InstanceAt(address common.Address, backend bind.ContractBackend) error { + s.Instance, err = contract.NewSimpleSwap(address, backend) + return err } diff --git a/swap/peer.go b/swap/peer.go index db19a9bff6..e0da0b264e 100644 --- a/swap/peer.go +++ b/swap/peer.go @@ -23,7 +23,9 @@ import ( "math/big" "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethersphere/swarm/contracts/swap" cswap "github.com/ethersphere/swarm/contracts/swap" + "github.com/ethersphere/swarm/log" "github.com/ethersphere/swarm/p2p/protocols" ) @@ -178,11 +180,25 @@ func (sp *Peer) handleEmitChequeMsg(ctx context.Context, msg interface{}) error opts := bind.NewKeyedTransactor(sp.swap.owner.privateKey) opts.Context = ctx - // handling error - // asynchronous call to blockchain, might not get error back directly. If we get a txhash directly, we still have to check the result of this tx. - ref := sp.swap.contractReference.InstanceAt(cheque.Contract, sp.backend) - ref.SubmitChequeBeneficiary(opts, big.NewInt(int64(cheque.Serial)), big.NewInt(int64(cheque.Amount)), big.NewInt(int64(cheque.Timeout)), cheque.Sig) - //sp.swap.contractReference.SubmitChequeBeneficiary(opts, big.NewInt(int64(cheque.Serial)), big.NewInt(int64(cheque.Amount)), big.NewInt(int64(cheque.Timeout)), cheque.Sig) + //TODO: make instanceAt to directly return a swap type + otherSwap := swap.New() + err := otherSwap.InstanceAt(cheque.Contract, sp.backend) + if err != nil { + log.Info("Could not get an instance of simpleSwap") + return err + } + tx, receipt, err := otherSwap.SubmitChequeBeneficiary(opts, sp.backend, big.NewInt(int64(cheque.Serial)), big.NewInt(int64(cheque.Amount)), big.NewInt(int64(cheque.Timeout)), cheque.Sig) + log.Info(fmt.Sprintf("Got tx: %x", tx)) + select { + case err := <-err: + if err != nil { + log.Error("Got error when calling submitChequeBeneficiary: ", err) + } + case r := <-receipt: + log.Info("Transaction submitted to the blockchain", r) + //TODO: set up gorouting which waits the timeout and then calls cashCheque + //TODO: make sure we make a case where we listen to the possibiliyt of the peer shutting down. + } return nil }