2021-08-14 13:47:11 +00:00
package main
import (
2023-02-13 05:17:01 +00:00
"context"
"errors"
2021-08-14 13:47:11 +00:00
"fmt"
"os"
2022-02-12 13:33:09 +00:00
"path/filepath"
2021-09-08 05:31:51 +00:00
"time"
2021-08-14 13:47:11 +00:00
2022-01-19 03:49:07 +00:00
"github.com/ledgerwatch/erigon-lib/common"
2022-11-20 03:41:30 +00:00
"github.com/ledgerwatch/erigon-lib/common/datadir"
2021-08-14 13:47:11 +00:00
"github.com/ledgerwatch/erigon-lib/direct"
"github.com/ledgerwatch/erigon-lib/gointerfaces"
2021-09-03 04:19:35 +00:00
"github.com/ledgerwatch/erigon-lib/gointerfaces/grpcutil"
2021-08-14 13:47:11 +00:00
"github.com/ledgerwatch/erigon-lib/gointerfaces/remote"
proto_sentry "github.com/ledgerwatch/erigon-lib/gointerfaces/sentry"
2021-09-13 07:58:25 +00:00
"github.com/ledgerwatch/erigon-lib/kv/kvcache"
2021-08-17 08:52:55 +00:00
"github.com/ledgerwatch/erigon-lib/kv/remotedb"
2021-09-15 07:22:57 +00:00
"github.com/ledgerwatch/erigon-lib/kv/remotedbserver"
2021-08-14 13:47:11 +00:00
"github.com/ledgerwatch/erigon-lib/txpool"
2021-09-08 05:31:51 +00:00
"github.com/ledgerwatch/erigon-lib/txpool/txpooluitl"
2022-04-11 03:05:07 +00:00
"github.com/ledgerwatch/erigon-lib/types"
2023-02-13 05:17:01 +00:00
"github.com/ledgerwatch/erigon/cmd/rpcdaemon/rpcdaemontest"
"github.com/ledgerwatch/erigon/ethdb/privateapi"
2023-01-13 18:12:18 +00:00
"github.com/ledgerwatch/log/v3"
"github.com/spf13/cobra"
2021-08-14 13:47:11 +00:00
"github.com/ledgerwatch/erigon/cmd/utils"
"github.com/ledgerwatch/erigon/common/paths"
2022-10-25 02:58:25 +00:00
"github.com/ledgerwatch/erigon/turbo/debug"
logging2 "github.com/ledgerwatch/erigon/turbo/logging"
2021-08-14 13:47:11 +00:00
)
var (
sentryAddr [ ] string // Address of the sentry <host>:<port>
2022-01-26 09:11:22 +00:00
traceSenders [ ] string
2021-08-14 13:47:11 +00:00
privateApiAddr string
2021-09-02 05:55:04 +00:00
txpoolApiAddr string
2022-06-07 03:24:50 +00:00
datadirCli string // Path to td working dir
2021-08-14 13:47:11 +00:00
TLSCertfile string
TLSCACert string
TLSKeyFile string
2021-09-29 07:48:19 +00:00
pendingPoolLimit int
baseFeePoolLimit int
queuedPoolLimit int
2021-10-02 10:34:57 +00:00
2022-06-29 12:44:22 +00:00
priceLimit uint64
accountSlots uint64
priceBump uint64
2021-08-14 13:47:11 +00:00
)
func init ( ) {
2022-10-25 02:58:25 +00:00
utils . CobraFlags ( rootCmd , debug . Flags , utils . MetricFlags , logging2 . Flags )
2021-08-14 13:47:11 +00:00
rootCmd . Flags ( ) . StringSliceVar ( & sentryAddr , "sentry.api.addr" , [ ] string { "localhost:9091" } , "comma separated sentry addresses '<host>:<port>,<host>:<port>'" )
2021-09-02 05:55:04 +00:00
rootCmd . Flags ( ) . StringVar ( & privateApiAddr , "private.api.addr" , "localhost:9090" , "execution service <host>:<port>" )
rootCmd . Flags ( ) . StringVar ( & txpoolApiAddr , "txpool.api.addr" , "localhost:9094" , "txpool service <host>:<port>" )
2022-06-07 03:24:50 +00:00
rootCmd . Flags ( ) . StringVar ( & datadirCli , utils . DataDirFlag . Name , paths . DefaultDataDir ( ) , utils . DataDirFlag . Usage )
2021-08-14 13:47:11 +00:00
if err := rootCmd . MarkFlagDirname ( utils . DataDirFlag . Name ) ; err != nil {
panic ( err )
}
rootCmd . PersistentFlags ( ) . StringVar ( & TLSCertfile , "tls.cert" , "" , "certificate for client side TLS handshake" )
rootCmd . PersistentFlags ( ) . StringVar ( & TLSKeyFile , "tls.key" , "" , "key file for client side TLS handshake" )
rootCmd . PersistentFlags ( ) . StringVar ( & TLSCACert , "tls.cacert" , "" , "CA certificate for client side TLS handshake" )
2021-09-29 07:48:19 +00:00
rootCmd . PersistentFlags ( ) . IntVar ( & pendingPoolLimit , "txpool.globalslots" , txpool . DefaultConfig . PendingSubPoolLimit , "Maximum number of executable transaction slots for all accounts" )
2021-09-29 07:55:43 +00:00
rootCmd . PersistentFlags ( ) . IntVar ( & baseFeePoolLimit , "txpool.globalbasefeeeslots" , txpool . DefaultConfig . BaseFeeSubPoolLimit , "Maximum number of non-executable transactions where only not enough baseFee" )
2021-09-29 07:48:19 +00:00
rootCmd . PersistentFlags ( ) . IntVar ( & queuedPoolLimit , "txpool.globalqueue" , txpool . DefaultConfig . QueuedSubPoolLimit , "Maximum number of non-executable transaction slots for all accounts" )
2021-10-02 10:34:57 +00:00
rootCmd . PersistentFlags ( ) . Uint64Var ( & priceLimit , "txpool.pricelimit" , txpool . DefaultConfig . MinFeeCap , "Minimum gas price (fee cap) limit to enforce for acceptance into the pool" )
2022-06-29 12:44:22 +00:00
rootCmd . PersistentFlags ( ) . Uint64Var ( & accountSlots , "txpool.accountslots" , txpool . DefaultConfig . AccountSlots , "Minimum number of executable transaction slots guaranteed per account" )
2021-11-26 14:39:26 +00:00
rootCmd . PersistentFlags ( ) . Uint64Var ( & priceBump , "txpool.pricebump" , txpool . DefaultConfig . PriceBump , "Price bump percentage to replace an already existing transaction" )
2022-01-26 09:11:22 +00:00
rootCmd . Flags ( ) . StringSliceVar ( & traceSenders , utils . TxPoolTraceSendersFlag . Name , [ ] string { } , utils . TxPoolTraceSendersFlag . Usage )
2021-08-14 13:47:11 +00:00
}
var rootCmd = & cobra . Command {
2022-01-24 07:12:34 +00:00
Use : "txpool" ,
Short : "Launch externa Transaction Pool instance - same as built-into Erigon, but as independent Service" ,
2021-08-14 13:47:11 +00:00
PersistentPreRunE : func ( cmd * cobra . Command , args [ ] string ) error {
return debug . SetupCobra ( cmd )
} ,
PersistentPostRun : func ( cmd * cobra . Command , args [ ] string ) {
debug . Exit ( )
} ,
2023-02-13 05:17:01 +00:00
Run : func ( cmd * cobra . Command , args [ ] string ) {
2022-10-25 02:58:25 +00:00
_ = logging2 . GetLoggerCmd ( "txpool" , cmd )
2021-08-14 13:47:11 +00:00
2023-02-13 05:17:01 +00:00
if err := doTxpool ( cmd . Context ( ) ) ; err != nil {
if ! errors . Is ( err , context . Canceled ) {
log . Error ( err . Error ( ) )
}
return
2021-08-14 13:47:11 +00:00
}
2023-02-13 05:17:01 +00:00
} ,
}
2021-08-14 13:47:11 +00:00
2023-02-13 05:17:01 +00:00
func doTxpool ( ctx context . Context ) error {
creds , err := grpcutil . TLS ( TLSCACert , TLSCertfile , TLSKeyFile )
if err != nil {
return fmt . Errorf ( "could not connect to remoteKv: %w" , err )
}
coreConn , err := grpcutil . Connect ( creds , privateApiAddr )
if err != nil {
return fmt . Errorf ( "could not connect to remoteKv: %w" , err )
}
2021-08-14 13:47:11 +00:00
2023-02-13 05:17:01 +00:00
kvClient := remote . NewKVClient ( coreConn )
coreDB , err := remotedb . NewRemote ( gointerfaces . VersionFromProto ( remotedbserver . KvServiceAPIVersion ) , log . New ( ) , kvClient ) . Open ( )
if err != nil {
return fmt . Errorf ( "could not connect to remoteKv: %w" , err )
}
2021-08-14 13:47:11 +00:00
2023-02-13 05:17:01 +00:00
log . Info ( "TxPool started" , "db" , filepath . Join ( datadirCli , "txpool" ) )
2021-08-14 13:47:11 +00:00
2023-02-13 05:17:01 +00:00
sentryClients := make ( [ ] direct . SentryClient , len ( sentryAddr ) )
for i := range sentryAddr {
creds , err := grpcutil . TLS ( TLSCACert , TLSCertfile , TLSKeyFile )
if err != nil {
return fmt . Errorf ( "could not connect to sentry: %w" , err )
2022-01-26 09:11:22 +00:00
}
2023-02-13 05:17:01 +00:00
sentryConn , err := grpcutil . Connect ( creds , sentryAddr [ i ] )
2021-08-14 13:47:11 +00:00
if err != nil {
2023-02-13 05:17:01 +00:00
return fmt . Errorf ( "could not connect to sentry: %w" , err )
2021-08-14 13:47:11 +00:00
}
2023-02-13 05:17:01 +00:00
sentryClients [ i ] = direct . NewSentryClientRemote ( proto_sentry . NewSentryClient ( sentryConn ) )
}
2021-09-03 04:19:35 +00:00
2023-02-13 05:17:01 +00:00
cfg := txpool . DefaultConfig
dirs := datadir . New ( datadirCli )
cfg . DBDir = dirs . TxPool
cfg . CommitEvery = 30 * time . Second
cfg . PendingSubPoolLimit = pendingPoolLimit
cfg . BaseFeeSubPoolLimit = baseFeePoolLimit
cfg . QueuedSubPoolLimit = queuedPoolLimit
cfg . MinFeeCap = priceLimit
cfg . AccountSlots = accountSlots
cfg . PriceBump = priceBump
cacheConfig := kvcache . DefaultCoherentConfig
cacheConfig . MetricsLabel = "txpool"
cfg . TracedSenders = make ( [ ] string , len ( traceSenders ) )
for i , senderHex := range traceSenders {
sender := common . HexToAddress ( senderHex )
cfg . TracedSenders [ i ] = string ( sender [ : ] )
}
newTxs := make ( chan types . Announcements , 1024 )
defer close ( newTxs )
txPoolDB , txPool , fetch , send , txpoolGrpcServer , err := txpooluitl . AllComponents ( ctx , cfg ,
kvcache . New ( cacheConfig ) , newTxs , coreDB , sentryClients , kvClient )
if err != nil {
return err
}
fetch . ConnectCore ( )
fetch . ConnectSentries ( )
/ *
var ethashApi * ethash . API
sif casted , ok := backend . engine . ( * ethash . Ethash ) ; ok {
ethashApi = casted . APIs ( nil ) [ 1 ] . Service . ( * ethash . API )
2021-09-02 05:55:04 +00:00
}
2023-02-13 05:17:01 +00:00
* /
miningGrpcServer := privateapi . NewMiningServer ( ctx , & rpcdaemontest . IsMiningMock { } , nil )
grpcServer , err := txpool . StartGrpc ( txpoolGrpcServer , miningGrpcServer , txpoolApiAddr , nil )
if err != nil {
return err
}
2021-09-02 05:55:04 +00:00
2023-02-13 05:17:01 +00:00
notifyMiner := func ( ) { }
txpool . MainLoop ( ctx , txPoolDB , coreDB , txPool , newTxs , send , txpoolGrpcServer . NewSlotsStreams , notifyMiner )
2021-08-14 13:47:11 +00:00
2023-02-13 05:17:01 +00:00
grpcServer . GracefulStop ( )
return nil
2021-08-14 13:47:11 +00:00
}
func main ( ) {
2022-01-19 03:49:07 +00:00
ctx , cancel := common . RootContext ( )
2021-08-14 13:47:11 +00:00
defer cancel ( )
if err := rootCmd . ExecuteContext ( ctx ) ; err != nil {
fmt . Println ( err )
os . Exit ( 1 )
}
}