github.com/notegio/go-ethereum@v1.9.5-4/cmd/geth/txrelay.go (about) 1 // Copyright 2015 The go-ethereum Authors 2 // This file is part of go-ethereum. 3 // 4 // go-ethereum is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // go-ethereum is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. 16 17 package main 18 19 import ( 20 "context" 21 "fmt" 22 "github.com/ethereum/go-ethereum" 23 "github.com/ethereum/go-ethereum/cmd/utils" 24 "github.com/ethereum/go-ethereum/core/types" 25 "github.com/ethereum/go-ethereum/ethclient" 26 "github.com/ethereum/go-ethereum/rlp" 27 "github.com/ethereum/go-ethereum/ethdb/cdc" 28 "github.com/Shopify/sarama" 29 "gopkg.in/urfave/cli.v1" 30 "os" 31 "time" 32 "log" 33 ) 34 35 var ( 36 txrelayCommand = cli.Command{ 37 Action: utils.MigrateFlags(txrelay), // keep track of migration progress 38 Name: "txrelay", 39 Usage: "Broadcast signed transactions from a Kafka topic", 40 ArgsUsage: " ", 41 Category: "REPLICA COMMANDS", 42 Description: ` 43 Picks up transactions placed on Kafka topics by replicas an relays them to RPC 44 nodes. 45 `, 46 Flags: []cli.Flag{ 47 utils.KafkaLogBrokerFlag, 48 utils.KafkaTransactionTopicFlag, 49 utils.KafkaTransactionConsumerGroupFlag, 50 }, 51 } 52 ) 53 // replica starts replica node 54 func txrelay(ctx *cli.Context) error { 55 sarama.Logger = log.New(os.Stderr, "[sarama]", 0) 56 rpcEndpoint := ctx.Args().First() 57 if rpcEndpoint == "" { 58 rpcEndpoint = fmt.Sprintf("%s/.ethereum/geth.ipc", os.Getenv("HOME")) 59 } 60 brokerURL := ctx.GlobalString(utils.KafkaLogBrokerFlag.Name) 61 brokers, config := cdc.ParseKafkaURL(brokerURL) 62 topic := ctx.GlobalString(utils.KafkaTransactionTopicFlag.Name) 63 consumerGroupID := ctx.GlobalString(utils.KafkaTransactionConsumerGroupFlag.Name) 64 if err := cdc.CreateTopicIfDoesNotExist(brokerURL, topic); err != nil { 65 fmt.Println("Error creating topic") 66 return err 67 } 68 consumerGroup, err := sarama.NewConsumerGroup(brokers, consumerGroupID, config) 69 if err != nil { 70 fmt.Printf("Looks like %v isn't available\n", brokerURL) 71 return err 72 } 73 defer consumerGroup.Close() 74 conn, err := ethclient.Dial(rpcEndpoint) 75 if err != nil { 76 fmt.Println("Dial Error") 77 return err 78 } 79 for { 80 handler := relayConsumerGroup{conn} 81 if err := consumerGroup.Consume(context.Background(), []string{topic}, handler); err != nil { 82 return err 83 } 84 time.Sleep(500 * time.Millisecond) 85 } 86 } 87 88 89 type relayConsumerGroup struct{ 90 txs ethereum.TransactionSender 91 } 92 93 func (relayConsumerGroup) Setup(_ sarama.ConsumerGroupSession) error { return nil } 94 func (relayConsumerGroup) Cleanup(_ sarama.ConsumerGroupSession) error { return nil } 95 func (h relayConsumerGroup) ConsumeClaim(sess sarama.ConsumerGroupSession, claim sarama.ConsumerGroupClaim) error { 96 for msg := range claim.Messages() { 97 transaction := &types.Transaction{} 98 fmt.Printf("Msg: %v\n", msg) 99 if err := rlp.DecodeBytes(msg.Value, transaction); err != nil { 100 fmt.Printf("Error decoding: %v\n", err.Error()) 101 } 102 if err := h.txs.SendTransaction(context.Background(), transaction); err != nil { 103 fmt.Printf("Error Sending: %v\n", err.Error()) 104 } 105 sess.MarkMessage(msg, "") 106 fmt.Println("Processed a message\n") 107 } 108 return nil 109 }