threefoldtecharchive / rivine

Blockchain technology for creating custom chains.
Apache License 2.0
22 stars 12 forks source link

create `rivinecg` tool: a rivine blockchain generator #555

Closed GlenDC closed 5 years ago

GlenDC commented 5 years ago

For the TFB chain ticket (#534) I already started creating a template Rivine chain repo at https://github.com/threefoldtech/rivine-chain-template. It still requires a lot of manual work however to replace all the stuff, with a lot of information to be replaced duplicate information. We cannot simply make a chain repo that is ready to compile simply be providing a config file that it reads on runtime. We can however go pretty close to that. That is where the rivinecg tool comes into the picture.

Goal would be that the template repo is really files that are either already ready to use-as-is, or they end in the .template suffix and thus will be parsed using the rivinecg tool chain generation process injecting the variables provided by the chain config as is.

Commands

Generation commands we would provide:

rivinecg generate blockchain \
    --config blockchain.cfg \ 
    --directory my-awesome-chain

Will generate a new chain in the target directory. If no target directory is specified the current directory will be used on the condition that it is empty (with a single cfg file as exception). A config has to be specified and contains the variables that will configure the blockchain.

rivinecg generate config \
    --output blockchain.cfg

Generate a config that can be used to generate a blockchain with the rivinecg generate blockchain command.

rivinecg generate seed \
    -n 1

Generates a new seed as useable for Rivine-based blockchain accounts. The seed is returned as a mnemonic on the STDOUT in a single line. By default also the first address is returned, but you can return more addresses by specifying a higher amount with the -n flag.

Other command that we would provide:

rivinecg version

Returns the current version.

Blockchain Generation Config

The config used for the blockchain generation would look as follows:

template: # optional, will be defined as-is shown here if undefined
    repository: https://github.com/threefoldtech/rivine-chain-template
    version: master # can also be a release tag, but for now there is only a master branch
blockchain:
    name: rivine # required
    repository: github.com/threefoldtech/rivine # required, repo of your blockchain
    currency: # required
        unit: ROC
        precision: 9
    ports: # required
        api: 23110
        rpc: 23112
    binaries: # optional
        # name of binary client
        client: rivinec # optional, will be `<blockchain.name>c` if undefined
        # name of binary daemon
        daemon: rivindc # optional, will be `<blockchain.name>d` if undefined
    tranactions:
        default: # optional, by default it is 1
            version: 1
        minting:
            mintConditionUpdate: # required if minting defined
                version: 128 # required
            coinCreation:
                version: 129  # required
            coinDestruction: # optional, disabled if not defined
                version: 130 # required if parent defined
            requireMinerFees: No
    networks: # at least one network is required, possible networks: standard, testnet and devnet (no other name is allowed)
        standard:
            genesis: # required
                coinOutputs:
                    - value: 100000000 # expressed in one coin unit
                      condition: 01b5e42056ef394f2ad9b511a61cec874d25bebe2095682dd37455cbafed4bec154e382a23f90e
                blockStakeOutputs:
                    - value: 1000000
                      condition: 01b5e42056ef394f2ad9b511a61cec874d25bebe2095682dd37455cbafed4bec154e382a23f90e
                minting: # required only if minting transactions have been defined
                    condition: # can also be single sig, a multisig condition is expressed as follows:
                        addresses:
                            - 01434535fd01243c02c277cd58d71423163767a575a8ae44e15807bf545e4a8456a5c4afabad51
                            - 01334cf68f312026ff9df84fc023558db8624bedd717adcc9edc6900488cf6df54ac8e3d1c89a8
                            - 0149a5496fea27315b7db6251e5dfda23bc9d4bf677c5a5c2d70f1382c44357197d8453d9dfa32
                        signaturesRequired: 2
            # optional, if no defined the block creator gets the fee, otherwise this pool address will receive all tx fees
            transactionFeePool: 017267221ef1947bb18506e390f1f9446b995acfb6d08d8e39508bb974d9830b8cb8fdca788e34
            # all the options below have sane defaults for the networks: standard, testnet and devnet
            blockSizeLimit: 2e6
            arbitraryDataSizeLimit: 83
            blockCreatorFee: 1.0
            minimumTransactionFee: 0.1
            blockFrequency: 120
            maturityDelay: 144 # expressed in blocks
            medianTimestampWindow: 11
            targetWindow: 1e3
            maxAdjustmentUp: 25/10
            maxAdjustmentDown: 10/25
            futureThreshold: 1h
            extremeFutureThreshold: 2h
            stakeModifierDelay: 2000s
            blockStakeAging: 1d
            transactionPool:
                transactionSizeLimit: 16e3
                transactionSetSizeLimit: 250e3
                poolSizeLimit: 2e6 - 5e3 - 250e3
        testnet:
            genesis: # required
                coinOutputs:
                    - value: 100000000 # expressed in one coin unit
                      condition: 01fc8714235d549f890f35e52d745b9eeeee34926f96c4b9ef1689832f338d9349b453898f7e51
                blockStakeOutputs:
                    - value: 3000
                      condition: 01fc8714235d549f890f35e52d745b9eeeee34926f96c4b9ef1689832f338d9349b453898f7e51
                minting: # required only if minting transactions have been defined
                    condition: # can also be single sig, a multisig condition is expressed as follows:
                        addresses:
                            - 016148ac9b17828e0933796eaca94418a376f2aa3fefa15685cea5fa462093f0150e09067f7512
                            - 01d553fab496f3fd6092e25ce60e6f72e24b57950bffc0d372d659e38e5a95e89fb117b4eb3481
                            - 013a787bf6248c518aee3a040a14b0dd3a029bc8e9b19a1823faf5bcdde397f4201ad01aace4c9
                        signaturesRequired: 2
            # all the options below have sane defaults for the networks: standard, testnet and devnet
            blockSizeLimit: 2e6
            arbitraryDataSizeLimit: 83
            blockCreatorFee: 10.0
            minimumTransactionFee: 0.1
            blockFrequency: 120
            maturityDelay: 720
            medianTimestampWindow: 11
            targetWindow: 1e3
            maxAdjustmentUp: 25/10
            maxAdjustmentDown: 10/25
            futureThreshold: 3s
            extremeFutureThreshold: 6s
            stakeModifierDelay: 20s
            blockStakeAging: 1024s
            transactionPool:
                transactionSizeLimit: 16e3
                transactionSetSizeLimit: 250e3
                poolSizeLimit: 2e6 - 5e3 - 250e3
        devnet:
            genesis: # required
                coinOutputs:
                    - value: 100000000 # expressed in one coin unit
                      # belong to wallet with mnemonic:
                      # carbon boss inject cover mountain fetch fiber fit tornado cloth wing dinosaur proof joy intact fabric thumb rebel borrow poet chair network expire else
                      condition: 015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f
                blockStakeOutputs:
                    - value: 1000000
                      condition: 015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f
                minting: # required only if minting transactions have been defined
                    condition: 015a080a9259b9d4aaa550e2156f49b1a79a64c7ea463d810d4493e8242e6791584fbdac553e6f
            # all the options below have sane defaults for the networks: standard, testnet and devnet
            blockSizeLimit: 2e6
            arbitraryDataSizeLimit: 83
            blockCreatorFee: 10.0
            minimumTransactionFee: 0.1
            blockFrequency: 12
            maturityDelay: 10
            medianTimestampWindow: 11
            targetWindow: 20
            maxAdjustmentUp: 120/100
            maxAdjustmentDown: 100/120
            futureThreshold: 2m
            extremeFutureThreshold: 4m
            stakeModifierDelay: 2000s
            blockStakeAging: 1024s
            transactionPool:
                transactionSizeLimit: 16e3
                transactionSetSizeLimit: 250e3
                poolSizeLimit: 2e6 - 5e3 - 250e3

Templates

For .template files we can simply use the template format as defined by the Go std package https://golang.org/pkg/text/template/, no need to go crazier, it has all we needs. This we can apply to all Go, JS, Documentation, Makefile, script and all other files that require templating, based on the config as defined in the "Blockchain Generation Config" section.

How to create a chain

Creating a chain will than become very easy, and can be done as follows

  1. create an empty (NOT initialized) repository at GitHub (or any other remote provider) as myorg/awesomechain (or however you want to name it)
  2. create and go to repo: mkdir -p $GOPATH/github.com/myorg/awesomechain && cd $GOPATH/github.com/myorg/awesomechain
  3. install/update rivinecg tool: go get -u github.com/threefoldtech/rivine/cmd/rivinecg
  4. generate the default config, to be modified: rivinecg generate config
  5. modify the generated config to suit your needs: vim blockchain.cfg
  6. generate your blockchain: rivinecg generate blockchain
  7. initialize your git repo: git init
  8. commit your initial blockchain: git add -A && git commit -m "initial commit: blockchain codebase ready to be used"
  9. vendor all the dependencies, we recommend dep but you can any tool you wish. For dep you would do it as follows: dep init
  10. commit your dependencies: git add -A && git commit -m "add all blockchain code dependencies"
  11. add your remote: git remote add git@github.com:myorg/awesomechain.git
  12. push your codebase ready to be used by others git push origin master

You know have your blockchain codebase ready to be used by you and others, fully working out of the box.

To build in development mode (DEBUG=TRUE) you can use make install, to build in production mode you can use make install-std.

Once you have your blockchain installed you can launch your daemon anywhere using:

awesomechaind

You can control your daemon using the CLI client awesomechainc. Please consult the --help flag for both awesomechaind and awesomechainc for more information on how to use these binaries.

Please also read the README generated for your awesome chain to know how to start playing with your blockchain on a local devnet.

Conclusion

Creating a new Rivine-based blockchain becomes super easy and fast once we have this tool. I therefore recommend that we wait with task #534 (create TFB chain) and #533 (create FFT chain) until we have this tool. In fact I would wait until we have Rivine 1.2 in a stable and releasable state, so that we don't require any further updates to the TFB and FFT codebase once it is generated.

GlenDC commented 5 years ago

Template files will have to be worked on and committed to https://github.com/threefoldtech/rivine-chain-template repo (master branch). The tool can be worked on from a local version, on the feat/rivinecg branch.

For the CLI use https://github.com/spf13/cobra, we already use it for our other commands as well. For the blockchain config files I would say use https://github.com/spf13/viper, so we can support JSON/YAML/TOML with ease, and let's use YAML by default.

The tool should come under ./cmd/rivinecg of this repo (under the feat/rivinecg Git branch)

Tasks:

DylanVerstraete commented 5 years ago

I completed the validation for the config struct, now writing some tests. Need to test following cases.

GlenDC commented 5 years ago

Merged and ready to use. Might make some further improvements while I review the ThreefoldBonus Chain tomorrow, as ideally a generated rivine blockchain doesn't modify manually any generated files.