Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

swarm: add config file #15548

Merged
merged 1 commit into from
Dec 11, 2017
Merged

swarm: add config file #15548

merged 1 commit into from
Dec 11, 2017

Conversation

holisticode
Copy link
Contributor

This PR adds a TOML configuration option to swarm.
It reuses the TOML configuration structure used in geth with swarm customized items.

The PR:

  • Adds a dumpconfig command to the swarm executable which allows printing the (default!) configuration to STDOUT, which then can be redirected to a file in order to customize it
  • Adds a config <file> option to the swarm executable which will allow to load a configuration file in TOML format from the specified location in order to initialize the Swarm node

The override priorities are like follows:
ENVIRONMENT VARIABLES override COMMAND LINE ARGUMENTS override CONFIG FILE override DEFAULT CONFIG.

@@ -325,6 +327,7 @@ DEPRECATED: use 'swarm db clean'.
CorsStringFlag,
EnsAPIFlag,
EnsAddrFlag,
SwarmTomlConfigPathFlag,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrong rename: cmd/swarm/main.go:330:3: undefined: SwarmTomlConfigPathFlag. This should refer to swarmTomlConfigFileFlag I guess.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something went terribly wrong after rebasing. Hang on

return stack, cfg
}

func makeFullNode(ctx *cli.Context) *node.Node {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't appear to be used anywhere. I suggest we don't add it, unless it becomes needed.

return cfg
}

func makeConfigNode(ctx *cli.Context) (*node.Node, bzzConfig) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not used either. I am not sure if we plan to use it very soon, but if not - probably best to add it only when we need it.

Copy link
Contributor

@nolash nolash left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes also touch on the same territory as the swarm binary fix I did earlier.

Have we had a comprehensive analysis that all the params that need to be there are addressed properly? And maybe we should take the opportunity to weed out if there are any redundant or obsolete ones?

//a few steps need to be done after the config phase is completed,
//due to overriding behavior
initSwarmNode(bzzconfig, stack, ctx)
//now we can boot the Swarm node
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the config.go file the right place to actually create the key?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As opposed to...? It was previously done in main.go right in registerBzzService, but this is now not possible anymore because we first need to evaluate the final config, as the key needs the bzzaccount parameter, which could have been overridden. As the config is built up in config.go, that's where the key is created now.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As opposed to the buildConfig caller, I would say was more natural. I'm not sure how to argue strongly for it, just having it in the config routine seems too trivial somehow.

if networkId == 0 {
self.NetworkId = network.NetworkId
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there goes the first change I made to the go-ethereum codebase ;')

FieldToKey: func(rt reflect.Type, field string) string {
return field
},
MissingField: func(rt reflect.Type, field string) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are NormFieldName and FieldToKey just supposed to return the second param?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I literally copied this section from the geth code, which apparently is needed to match go structures to TOML , check cmd/geth/config.go

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it works don't fix it :)

link := ""
if unicode.IsUpper(rune(rt.Name()[0])) && rt.PkgPath() != "main" {
link = fmt.Sprintf(", see https://godoc.org/%s#%s for available fields", rt.PkgPath(), rt.Name())
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

godoc.org is not relevant here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here, literally copied from geth assuming this is needed to match go code to TOML

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably change this as the godoc.org link will point to an empty location?

// exit if the deprecated --ethapi flag is set
if ctx.GlobalString(DeprecatedEthAPIFlag.Name) != "" {
utils.Fatalf("--ethapi is no longer a valid command line flag, please use --ens-api and/or --swap-api.")
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why and/OR --swap-api? Can it replace --ens-api?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message is the same as currently on master. I understand it to indicate that the user may have been wanting to use swap-api instead of ethapi and just mistyped, but it feels rather confusing, I agree

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should clear this up in the orange-lounge?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously --ethapi was used for all eth interactions. This has now been split up into ENS and SWAP allowing us to use mainnet ENS while testing SWAP on ropsten for example.
Thus 'and/or' is correct. If you were using your --ethapi just for ENS (most cases), then you should now use --ens-api

//note that we are decoding into the existing defaultConfig;
//if an entry is not present in the file, the default entry is kept
err = tomlSettings.NewDecoder(bufio.NewReader(f)).Decode(&conf)
// Add file name to errors that have a line number.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need buffered reader? Can't you just pass f?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The interface for NewDecoder takes a io.Reader, so I guess using directly f should work.

config = cmdLineOverride(config, ctx)
//override settings provided by environment variables
config = envVarsOverride(config)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't command line vars override envvars?

Copy link
Contributor Author

@holisticode holisticode Nov 29, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good question. I thought to follow @lmars implementing this:

Lewis Marshall @lmars Nov 15 12:06
so typically, command line flags take precedence, then env vars, then config file, all for the same set of parameters

But I may have indeed misinterpreted him, in that he seems to say that command line would override envvars. If you can confirm you understand this like that, I will change it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

He seems to concur that cmd line vars would take precedence. When you think about it, it would be strange otherwise. It's the "easiest" switch to flip, somehow.

cfg, err := buildConfig(ctx)
if err != nil {
utils.Fatalf(fmt.Sprintf("Uh oh - dumpconfig bumped triggered an error %v", err))
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bumped triggered? :D

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:)


self.Swap.SetKey(prvKey)
self.PublicKey = pubkeyhex
self.BzzKey = keyhex

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was under the impression that we did not want to be able to infer the overlay address from predictable underlying data?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?
I should have not changed any logic in this respect, just reorganizing stuff which was there before, but only allowing things to happen after the complete config with the overrides has been evaluated.

This is the old way, where the config was initialized in swarm/api/config.go with NewConfig():

60 func NewConfig(path string, contract common.Address, prvKey *ecdsa.PrivateKey, networkId uint64) (self *Config, err error) {
 61   address := crypto.PubkeyToAddress(prvKey.PublicKey) // default beneficiary address
 62   dirpath := filepath.Join(path, "bzz-"+common.Bytes2Hex(address.Bytes()))
 63   err = os.MkdirAll(dirpath, os.ModePerm)
 64   if err != nil {
 65     return
 66   }
 67   confpath := filepath.Join(dirpath, "config.json")
 68   var data []byte
 69   pubkey := crypto.FromECDSAPub(&prvKey.PublicKey)
 70   pubkeyhex := common.ToHex(pubkey)
 71   keyhex := crypto.Keccak256Hash(pubkey).Hex()
 72 
 73   self = &Config{
 74     SyncParams:    network.NewSyncParams(dirpath),
 75     HiveParams:    network.NewHiveParams(dirpath),
 76     ChunkerParams: storage.NewChunkerParams(),
 77     StoreParams:   storage.NewStoreParams(dirpath),
 78     ListenAddr:    DefaultHTTPListenAddr,
 79     Port:          DefaultHTTPPort,
 80     Path:          dirpath,
 81     Swap:          swap.DefaultSwapParams(contract, prvKey),
 82     PublicKey:     pubkeyhex,
 83     BzzKey:        keyhex,
 84     EnsRoot:       ens.TestNetAddress,
 85     NetworkId:     networkId,
 86   }

Or I did misunderstand your comment :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No from my understanding of the ultimate intention, the old method is also wrong. I though the overlay address should be totally independent / random. We've discussed this erratically a few times, but never really had a firm discussion about it, which maybe we should. We can address it in a separate issue, so I suggest leave this for now as it is.

self.EnsRoot = ens.TestNetAddress
//create the directory if it doesn't exist
if _, err := os.Stat(self.Path); os.IsNotExist(err) {
os.MkdirAll(self.Path, os.ModePerm)
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this create the <datadir>/swarm/bzz-<key> datadir? Now it's set to the same as the node's?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only if it doesn't exist?

It would actually create --datadir if it wouldn't exist - which should not happen at this point, but added this just to be safe.

I actually added this last minute, after some running tests were producing errors (which then turned out not being related to the datadir). I wonder if this is needed indeed?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well it could happen if we never ran geth before and are running swarm --ens-api ''?

My point was where is the swarm/bzz-xxxx subdir created? I missed it maybe?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a spot-on remark! Made me realize quite a few things! Thanks @nolash ! (And bzz-xxxx wasn't even being created at all!)

@holisticode
Copy link
Contributor Author

Retest this please

@fjl fjl merged commit 32516c7 into ethereum:master Dec 11, 2017
@karalabe karalabe added this to the 1.8.0 milestone Dec 14, 2017
b00ris pushed a commit to b00ris/go-ethereum that referenced this pull request Jan 19, 2018
This commit adds a TOML configuration option to swarm. It reuses
the TOML configuration structure used in geth with swarm
customized items.

The commit:

* Adds a "dumpconfig" command to the swarm executable which
  allows printing the (default) configuration to stdout, which
  then can be redirected to a file in order to customize it.
* Adds a "--config <file>" option to the swarm executable which will
  allow to load a configuration file in TOML format from the
  specified location in order to initialize the Swarm node The
  override priorities are like follows: environment variables
  override command line arguments override config file override
  default config.
mariameda pushed a commit to NiluPlatform/go-nilu that referenced this pull request Aug 23, 2018
This commit adds a TOML configuration option to swarm. It reuses
the TOML configuration structure used in geth with swarm
customized items.

The commit:

* Adds a "dumpconfig" command to the swarm executable which
  allows printing the (default) configuration to stdout, which
  then can be redirected to a file in order to customize it.
* Adds a "--config <file>" option to the swarm executable which will
  allow to load a configuration file in TOML format from the
  specified location in order to initialize the Swarm node The
  override priorities are like follows: environment variables
  override command line arguments override config file override
  default config.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants