From 3270d0c56189187f3609c468f3da98dfde6d387a Mon Sep 17 00:00:00 2001 From: Benjamin Bollen <ben@monax.io> Date: Mon, 30 Jan 2017 14:19:53 +0100 Subject: [PATCH] genesis: rework genesis --- genesis/gen_test.go | 15 +++++++ genesis/genesis.go | 75 +++++++++++++++++++++++++++++++++ genesis/genesis_test.go | 28 ++++++++++++ genesis/types.go | 69 ++++++++++++++++++++++++++++++ permission/types/permissions.go | 15 +++++++ 5 files changed, 202 insertions(+) create mode 100644 genesis/genesis.go create mode 100644 genesis/genesis_test.go diff --git a/genesis/gen_test.go b/genesis/gen_test.go index 18ff69a7..403da98e 100644 --- a/genesis/gen_test.go +++ b/genesis/gen_test.go @@ -1,3 +1,18 @@ +// Copyright 2015-2017 Monax Industries Limited. +// This file is part of the Monax platform (Monax) + +// Monax is free software: you can use, redistribute it and/or modify +// it only under the terms of the GNU General Public License, version +// 3, as published by the Free Software Foundation. + +// Monax is distributed WITHOUT ANY WARRANTY pursuant to +// the terms of the Gnu General Public Licence, version 3, including +// (but not limited to) Clause 15 thereof. See the text of the +// GNU General Public License, version 3 for full terms. + +// You should have received a copy of the GNU General Public License, +// version 3, with Monax. If not, see <http://www.gnu.org/licenses/>. + package genesis import ( diff --git a/genesis/genesis.go b/genesis/genesis.go new file mode 100644 index 00000000..a33386a1 --- /dev/null +++ b/genesis/genesis.go @@ -0,0 +1,75 @@ +// Copyright 2015-2017 Monax Industries Limited. +// This file is part of the Monax platform (Monax) + +// Monax is free software: you can use, redistribute it and/or modify +// it only under the terms of the GNU General Public License, version +// 3, as published by the Free Software Foundation. + +// Monax is distributed WITHOUT ANY WARRANTY pursuant to +// the terms of the Gnu General Public Licence, version 3, including +// (but not limited to) Clause 15 thereof. See the text of the +// GNU General Public License, version 3 for full terms. + +// You should have received a copy of the GNU General Public License, +// version 3, with Monax. If not, see <http://www.gnu.org/licenses/>. + +package genesis + +import ( + "bytes" + "encoding/json" + "time" + + ptypes "github.com/eris-ltd/eris-db/permission/types" + wire "github.com/tendermint/go-wire" +) + +// MakeGenesisDocFromAccounts takes a chainName and a slice of GenesisAccount, +// and a slice of GenesisValidator to construct a GenesisDoc, or returns an error on +// failure. In particular MakeGenesisDocFromAccount uses the local time as a +// timestamp for the GenesisDoc. +func MakeGenesisDocFromAccounts(chainName string, accounts []*GenesisAccount, validators []*GenesisValidator) ( + GenesisDoc, error) { + + // TODO: assert valid accounts and validators + // TODO: [ben] expose setting global permissions + globalPermissions := ptypes.DefaultAccountPermissions.Clone() + genesisParameters := &GenesisParams{ + GlobalPermissions: &globalPermissions, + } + // copy slices of validators and accounts + accountsCopy := make([]GenesisAccount, len(accounts)) + copy(accountsCopy, accounts) + + genesisDoc := GenesisDoc{ + GenesisTime: time.Now(), + // TODO: this needs to be corrected for ChainName, and ChainId + // is the derived hash from the GenesisDoc serialised bytes + ChainID: chainName, + Params: genesisParameters, + Accounts: accounts, + Validators: validators, + } + return genesisDoc, nil +} + +// GetGenesisFileBytes returns the JSON (not-yet) canonical bytes for a given +// GenesisDoc or an error. In a first rewrite, rely on go-wire +// for the JSON serialisation with type-bytes. +func GetGenesisFileBytes(genesisDoc *GenesisDoc) ([]byte, error) { + + // TODO: write JSON in canonical order + + buffer, n, err := new(bytes.Buffer), new(int), new(error) + // write JSON with go-wire type-bytes (for public keys); deprecate + wire.WriteJSON(genesisDoc, buffer, n, &err) + if err != nil { + return nil, err + } + // rewrite buffer with indentation + indentedBuffer := new(bytes.Buffer) + if err := json.Indent(indentedBuffer, buffer.Bytes(), "", "\t"); err != nil { + return nil, err + } + return indentedBuffer.Bytes(), nil +} diff --git a/genesis/genesis_test.go b/genesis/genesis_test.go new file mode 100644 index 00000000..269c28f8 --- /dev/null +++ b/genesis/genesis_test.go @@ -0,0 +1,28 @@ +// Copyright 2015-2017 Monax Industries Limited. +// This file is part of the Monax platform (Monax) + +// Monax is free software: you can use, redistribute it and/or modify +// it only under the terms of the GNU General Public License, version +// 3, as published by the Free Software Foundation. + +// Monax is distributed WITHOUT ANY WARRANTY pursuant to +// the terms of the Gnu General Public Licence, version 3, including +// (but not limited to) Clause 15 thereof. See the text of the +// GNU General Public License, version 3 for full terms. + +// You should have received a copy of the GNU General Public License, +// version 3, with Monax. If not, see <http://www.gnu.org/licenses/>. + +package genesis + +import ( + "bytes" + "io/ioutil" + "os" + "path/filepath" + "testing" +) + +func TestGenesisFileBytes(t *testing.T) { + +} diff --git a/genesis/types.go b/genesis/types.go index 3469684b..2e25f32a 100644 --- a/genesis/types.go +++ b/genesis/types.go @@ -1,3 +1,18 @@ +// Copyright 2015-2017 Monax Industries Limited. +// This file is part of the Monax platform (Monax) + +// Monax is free software: you can use, redistribute it and/or modify +// it only under the terms of the GNU General Public License, version +// 3, as published by the Free Software Foundation. + +// Monax is distributed WITHOUT ANY WARRANTY pursuant to +// the terms of the Gnu General Public Licence, version 3, including +// (but not limited to) Clause 15 thereof. See the text of the +// GNU General Public License, version 3 for full terms. + +// You should have received a copy of the GNU General Public License, +// version 3, with Monax. If not, see <http://www.gnu.org/licenses/>. + package genesis import ( @@ -78,3 +93,57 @@ func GenesisDocFromJSON(jsonBlob []byte) (genState *GenesisDoc) { } return } + +//------------------------------------------------------------ +// Methods for genesis types +// NOTE: breaks formatting convention +// TODO: split each genesis type in its own file definition + +//------------------------------------------------------------ +// GenesisAccount methods + +// Clone clones the genesis account +func (genesisAccount *GenesisAccount) Clone() GenesisAccount { + // clone the address + addressClone := make([]byte, len(genesisAccount.Address)) + copy(addressClone, genesisAccount.Address) + // clone the account permissions + accountPermissionsClone := genesisAccount.Permissions.Clone() + return GenesisAccount{ + Address: addressClone, + Amount: genesisAccount.Amount, + Name: genesisAccount.Name, + Permissions: &accountPermissionsClone, + } +} + +//------------------------------------------------------------ +// GenesisValidator methods + +// Clone clones the genesis validator +func (genesisValidator *GenesisValidator) Clone() GenesisValidator { + // clone the public key + + // clone the account permissions + accountPermissionsClone := genesisAccount.Permissions.Clone() + return GenesisAccount{ + Address: addressClone, + Amount: genesisAccount.amount, + Name: genesisAccount.Name, + Permissions: &accountPermissionsClone, + } +} + +//------------------------------------------------------------ +// BasicAccount methods + +// Clone clones the basic account +func (basicAccount *BasicAccount) Clone() BasicAccount { + // clone the address + addressClone := make([]byte, len(basicAccount.Address)) + copy(addressClone, basicAccount.Address) + return GenesisAccount{ + Address: addressClone, + Amount: basicAccount.Amount, + } +} \ No newline at end of file diff --git a/permission/types/permissions.go b/permission/types/permissions.go index 15706c9f..d20908a0 100644 --- a/permission/types/permissions.go +++ b/permission/types/permissions.go @@ -162,6 +162,21 @@ func (aP *AccountPermissions) RmRole(role string) bool { return false } +// Clone clones the account permissions +func (accountPermissions *AccountPermissions) Clone() AccountPermissions { + // clone base permissions + basePermissionsClone := accountPermissions.Base + // clone roles []string + rolesClone := make([]string, len(accountPermissions.Roles)) + // strings are immutable so copy suffices + copy(rolesClone, accountPermissions.Roles) + + return AccountPermissions{ + Base: basePermissionsClone, + Roles: rolesClone, + } +} + //-------------------------------------------------------------------------------- // string utilities -- GitLab