diff --git a/accounts/abi/bind/auth.go b/accounts/abi/bind/auth.go index 4ce1d533c7..106349dc9c 100644 --- a/accounts/abi/bind/auth.go +++ b/accounts/abi/bind/auth.go @@ -132,7 +132,7 @@ func NewKeyStoreTransactorWithChainID(keystore *keystore.KeyStore, account accou if chainID == nil { return nil, ErrNoChainID } - signer := types.LatestSignerForChainID(chainID) + latestSigner := types.LatestSignerForChainID(chainID) return &TransactOpts{ From: account.Address, Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { @@ -140,6 +140,7 @@ func NewKeyStoreTransactorWithChainID(keystore *keystore.KeyStore, account accou return nil, ErrNotAuthorized } // Quorum + signer := latestSigner if tx.IsPrivate() { signer = types.QuorumPrivateTxSigner{} } @@ -160,7 +161,7 @@ func NewKeyedTransactorWithChainID(key *ecdsa.PrivateKey, chainID *big.Int) (*Tr if chainID == nil { return nil, ErrNoChainID } - signer := types.LatestSignerForChainID(chainID) + latestSigner := types.LatestSignerForChainID(chainID) return &TransactOpts{ From: keyAddr, Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { @@ -168,6 +169,7 @@ func NewKeyedTransactorWithChainID(key *ecdsa.PrivateKey, chainID *big.Int) (*Tr return nil, ErrNotAuthorized } // Quorum + signer := latestSigner if tx.IsPrivate() { signer = types.QuorumPrivateTxSigner{} } diff --git a/cmd/faucet/faucet.go b/cmd/faucet/faucet.go index f56bdf3d70..094f5a498b 100644 --- a/cmd/faucet/faucet.go +++ b/cmd/faucet/faucet.go @@ -851,9 +851,9 @@ func authFacebook(url string) (string, string, common.Address, error) { // Facebook recently changed their desktop webpage to use AJAX for loading post // content, so switch over to the mobile site for now. Will probably end up having // to use the API eventually. - //crawl := strings.Replace(url, "www.facebook.com", "m.facebook.com", 1) + crawl := strings.Replace(url, "www.facebook.com", "m.facebook.com", 1) - res, err := http.Get(url) + res, err := http.Get(crawl) if err != nil { return "", "", common.Address{}, err } diff --git a/eth/handler_eth_test.go b/eth/handler_eth_test.go index a9af7219c5..7557d5936e 100644 --- a/eth/handler_eth_test.go +++ b/eth/handler_eth_test.go @@ -20,6 +20,7 @@ import ( "fmt" "math/big" "math/rand" + "sync" "sync/atomic" "testing" "time" @@ -462,6 +463,87 @@ func testTransactionPropagation(t *testing.T, protocol uint) { } } +// Quorum +// Tests that transactions get propagated to all peers using TransactionMessages and not PooledTransactionHashesMsg +func TestQuorumTransactionPropagation64(t *testing.T) { testQuorumTransactionPropagation(t, 64) } +func TestQuorumTransactionPropagation65(t *testing.T) { testQuorumTransactionPropagation(t, 65) } + +func testQuorumTransactionPropagation(t *testing.T, protocol uint) { + t.Parallel() + + numberOfPeers := 10 + + // Create a source handler to send transactions from and a number of sinks + // to receive them. We need multiple sinks since a one-to-one peering would + // broadcast all transactions without announcement. + source := newTestHandler() + defer source.close() + + sinks := make([]*testHandler, numberOfPeers) + for i := 0; i < len(sinks); i++ { + sinks[i] = newTestHandler() + defer sinks[i].close() + + sinks[i].handler.acceptTxs = 1 // mark synced to accept transactions + } + + // create transactions + // Fill the source pool with transactions and wait for them at the sinks + txs := make([]*types.Transaction, 1024) + for nonce := range txs { + tx := types.NewTransaction(uint64(nonce), common.Address{}, big.NewInt(0), 100000, big.NewInt(0), nil) + tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey) + + txs[nonce] = tx + } + + // WaitGroup to make sure peers are registered before adding transactions to pool + wgPeersRegistered := sync.WaitGroup{} + wgPeersRegistered.Add(numberOfPeers * 2) + + // WaitGroup to make sure messages were shared to all peers + wgExpectPeerMessages := sync.WaitGroup{} + wgExpectPeerMessages.Add(numberOfPeers) + // Interconnect all the sink handlers with the source handler + for i, sink := range sinks { + sink := sink // Closure for gorotuine below + + sourcePipe, sinkPipe := p2p.MsgPipe() + defer sourcePipe.Close() + defer sinkPipe.Close() + + sourcePeer := eth.NewPeer(protocol, p2p.NewPeer(enode.ID{byte(i)}, "", nil), sourcePipe, source.txpool) + sinkPeer := eth.NewPeer(protocol, p2p.NewPeer(enode.ID{0}, "", nil), sinkPipe, sink.txpool) + defer sourcePeer.Close() + defer sinkPeer.Close() + + go source.handler.runEthPeer(sourcePeer, func(peer *eth.Peer) error { + wgPeersRegistered.Done() + // handle using the normal way + return eth.Handle((*ethHandler)(source.handler), peer) + }) + go sink.handler.runEthPeer(sinkPeer, func(peer *eth.Peer) error { + wgPeersRegistered.Done() + // intercept the received messages to make sure is the p2p type we are looking for + for e := peer.ExpectPeerMessage(uint64(eth.TransactionsMsg), txs); e != nil; { + t.Errorf("tx announce received on pre eth/65. errorL %s", e) + return e + } + wgExpectPeerMessages.Done() + return nil + }) + } + wgPeersRegistered.Wait() + + // add txs to pool + source.txpool.AddRemotes(txs) + + // wait until all messages are handled + wgExpectPeerMessages.Wait() +} + +// End Quorum + // Tests that post eth protocol handshake, clients perform a mutual checkpoint // challenge to validate each other's chains. Hash mismatches, or missing ones // during a fast sync should lead to the peer getting dropped. diff --git a/eth/protocols/eth/peer.go b/eth/protocols/eth/peer.go index fc08dadf7f..9edba1ae78 100644 --- a/eth/protocols/eth/peer.go +++ b/eth/protocols/eth/peer.go @@ -473,6 +473,10 @@ func (p *Peer) ExpectRequestHeadersByNumber(origin uint64, amount int, skip int, return p2p.ExpectMsg(p.rw, GetBlockHeadersMsg, req) } +func (p *Peer) ExpectPeerMessage(code uint64, content types.Transactions) error { + return p2p.ExpectMsg(p.rw, code, content) +} + // RequestBodies fetches a batch of blocks' bodies corresponding to the hashes // specified. func (p *Peer) RequestBodies(hashes []common.Hash) error { diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 9fef5fc263..42a5f90a83 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1974,11 +1974,14 @@ func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction, pr // Ensure only eip155 signed transactions are submitted if EIP155Required is set. return common.Hash{}, errors.New("only replay-protected (EIP-155) transactions allowed over RPC") } - if err := b.SendTx(ctx, tx); err != nil { - return common.Hash{}, err - } // Print a log with full tx details for manual investigations and interventions - signer := types.MakeSigner(b.ChainConfig(), b.CurrentBlock().Number()) + // Quorum + var signer types.Signer + if tx.IsPrivate() { + signer = types.QuorumPrivateTxSigner{} + } else { + signer = types.MakeSigner(b.ChainConfig(), b.CurrentBlock().Number()) + } from, err := types.Sender(signer, tx) if err != nil { return common.Hash{}, err