@@ -28,6 +28,7 @@ import (
2828 "math/big"
2929 "net"
3030 "net/http"
31+ "net/url"
3132 "os"
3233 "path/filepath"
3334 godebug "runtime/debug"
@@ -723,6 +724,23 @@ var (
723724 Value : node .DefaultConfig .BatchResponseMaxSize ,
724725 Category : flags .APICategory ,
725726 }
727+ BlockReplicationTargetsFlag = & cli.StringFlag {
728+ Name : "replication.targets" ,
729+ Usage : "Comma separated URLs for message-queue delivery of block specimens" ,
730+ Value : "" ,
731+ }
732+ ReplicaEnableSpecimenFlag = & cli.BoolFlag {
733+ Name : "replica.specimen" ,
734+ Usage : "Enables export of fields that comprise a block-specimen" ,
735+ }
736+ ReplicaEnableResultFlag = & cli.BoolFlag {
737+ Name : "replica.result" ,
738+ Usage : "Enables export of fields that comprise a block-result" ,
739+ }
740+ ReplicaEnableBlobFlag = & cli.BoolFlag {
741+ Name : "replica.blob" ,
742+ Usage : "Enables export of fields that comprise a block-blob" ,
743+ }
726744
727745 // Network Settings
728746 MaxPeersFlag = & cli.IntFlag {
@@ -1584,7 +1602,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
15841602 setMiner (ctx , & cfg .Miner )
15851603 setRequiredBlocks (ctx , cfg )
15861604 setLes (ctx , cfg )
1587-
1605+ if ctx .IsSet (BlockReplicationTargetsFlag .Name ) {
1606+ setBlockReplicationTargets (ctx , cfg )
1607+ }
15881608 // Cap the cache allowance and tune the garbage collector
15891609 mem , err := gopsutil .VirtualMemory ()
15901610 if err == nil {
@@ -2245,3 +2265,63 @@ func MakeTrieDatabase(ctx *cli.Context, disk ethdb.Database, preimage bool, read
22452265 }
22462266 return triedb .NewDatabase (disk , config )
22472267}
2268+
2269+ // setBlockResultTargets creates a list of replication targets from the command line flags.
2270+ func setBlockReplicationTargets (ctx * cli.Context , cfg * eth.Config ) {
2271+ var urls []string
2272+
2273+ if ctx .IsSet (BlockReplicationTargetsFlag .Name ) {
2274+ urls = strings .Split (ctx .String (BlockReplicationTargetsFlag .Name ), "," )
2275+ }
2276+
2277+ cfg .BlockReplicationTargets = make ([]string , 0 , len (urls ))
2278+ for _ , urlStr := range urls {
2279+ if urlStr != "" {
2280+ _ , err := url .Parse (urlStr )
2281+ if err != nil {
2282+ log .Crit ("Replication-target URL invalid" , "url" , urlStr , "err" , err )
2283+ os .Exit (1 )
2284+ }
2285+ cfg .BlockReplicationTargets = append (cfg .BlockReplicationTargets , urlStr )
2286+ }
2287+ }
2288+ if ctx .IsSet (ReplicaEnableResultFlag .Name ) || ctx .IsSet (ReplicaEnableSpecimenFlag .Name ) {
2289+ if ctx .Bool (ReplicaEnableSpecimenFlag .Name ) {
2290+ cfg .ReplicaEnableSpecimen = true
2291+ }
2292+ if ctx .Bool (ReplicaEnableResultFlag .Name ) {
2293+ cfg .ReplicaEnableResult = true
2294+ }
2295+ if ctx .Bool (ReplicaEnableBlobFlag .Name ) {
2296+ cfg .ReplicaEnableBlob = true
2297+ }
2298+ } else {
2299+ Fatalf ("--replication.targets flag is invalid without --replica.specimen and/or --replica.result, ONLY ADD --replica.blob with both replica.specimen AND replica.result flags for complete unified state capture)" )
2300+ }
2301+ }
2302+
2303+ func CreateReplicators (config * eth.Config ) []* core.ChainReplicator {
2304+ replicators := make ([]* core.ChainReplicator , 0 )
2305+
2306+ for _ , blockReplicationTargets := range config .BlockReplicationTargets {
2307+ blockRepl , err := eth .CreateReplicator (blockReplicationTargets )
2308+ if err != nil {
2309+ Fatalf ("Can't create replication target: %v" , err )
2310+ }
2311+ replicators = append (replicators , blockRepl )
2312+ }
2313+
2314+ return replicators
2315+ }
2316+
2317+ func AttachReplicators (replicators []* core.ChainReplicator , chain * core.BlockChain ) {
2318+ for _ , replicator := range replicators {
2319+ replicator .Start (chain , chain .ReplicaConfig )
2320+ }
2321+ }
2322+
2323+ func DrainReplicators (replicators []* core.ChainReplicator ) {
2324+ for _ , replicator := range replicators {
2325+ replicator .Stop ()
2326+ }
2327+ }
0 commit comments