Skip to content

Commit

Permalink
common: implement ParseGenesisOrDefault
Browse files Browse the repository at this point in the history
For cosmos/ethermint-archive#244.

ParseGenesisOrDefault replaces the step in which while
init-ing ethermint, we have to
* cd $GOPATH/src/github.com/tendermint/ethermint
* ethermint --datadir ~/.ethermint init setup/genesis.json
so we have the serialized record of the setup/genesis.json
that will be used by default, if the file:
a) doesn't exist
b) doesn't have content ie less than {}

+ Why here:
Since $GOPATH/src/tendermint/ethermint/cmd/ethermint
has a bunch of initializers in:
ethUtils "github.com/ethereum/go-ethereum/cmd/utils"
```go
app = ethUtils.NewApp(version.Version, "the ethermint command line interface")
```
whose definition in flags.go
```go
func NewApp(gitcommit, usage string) *cli.App {
  app := cli.NewApp()
  app.Name = filepath.Base(os.Args[0])
```
that depend on os.Args[0]

so we can't be running tests in there without periliously
trying to change os.Args that isn't populated when we run
```shell
$ go test -run=TestParse
```
or in our CI
thus extract and move that utility to here, the common utilities area
  • Loading branch information
odeke-em committed Aug 13, 2017
1 parent 7537298 commit 96642ec
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 0 deletions.
68 changes: 68 additions & 0 deletions common/parse.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package common

import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"reflect"

"github.com/ethereum/go-ethereum/core"
)

// defaultGenesisBlob is the JSON representation of the default
// genesis file in $GOPATH/src/github.com/tendermint/ethermint/setup/genesis.json
var defaultGenesisBlob = []byte(`
{
"config": {
"chainId": 15,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"nonce": "0xdeadbeefdeadbeef",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"difficulty": "0x40",
"gasLimit": "0x8000000",
"alloc": {
"0x7eff122b94897ea5b0e2a9abf47b86337fafebdc": { "balance": "10000000000000000000000000000000000" },
"0xc6713982649D9284ff56c32655a9ECcCDA78422A": { "balance": "10000000000000000000000000000000000" }
}
}`)

var blankGenesis = new(core.Genesis)

var errBlankGenesis = errors.New("could not parse a valid/non-blank Genesis")

// ParseGenesisOrDefault tries to read the content from provided
// genesisPath. If the path is empty or doesn't exist, it will
// use defaultGenesisBytes as the fallback genesis source. Otherwise,
// it will open that path and if it encounters an error that doesn't
// satisfy os.IsNotExist, it returns that error.
func ParseGenesisOrDefault(genesisPath string) (*core.Genesis, error) {
var genesisBlob = defaultGenesisBlob[:]
if len(genesisPath) > 0 {
blob, err := ioutil.ReadFile(genesisPath)
fmt.Printf("path: %q blob: %s err: %v\n", genesisPath, blob, err)
if err != nil && !os.IsNotExist(err) {
return nil, err
}
if len(blob) >= 2 { // Expecting atleast "{}"
genesisBlob = blob
}
}

genesis := new(core.Genesis)
if err := json.Unmarshal(genesisBlob, genesis); err != nil {
return nil, err
}

if reflect.DeepEqual(blankGenesis, genesis) {
return nil, errBlankGenesis
}

return genesis, nil
}
72 changes: 72 additions & 0 deletions common/parse_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package common

import (
"encoding/json"
"fmt"
"log"
"math/big"
"math/rand"
"testing"

"github.com/stretchr/testify/assert"

ethCommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
)

var defaultGenesis *core.Genesis = func() *core.Genesis {
g := new(core.Genesis)
if err := json.Unmarshal(defaultGenesisBlob, g); err != nil {
log.Fatalf("parsing defaultGenesis: %v", err)
}
return g
}()

func bigString(s string) *big.Int {
b, _ := big.NewInt(0).SetString(s, 10)
return b
}

var genesis1 = &core.Genesis{
Difficulty: big.NewInt(0x40),
GasLimit: 0x8000000,
Alloc: core.GenesisAlloc{
ethCommon.HexToAddress("0x7eff122b94897ea5b0e2a9abf47b86337fafebdc"): {
Balance: bigString("10000000000000000000000000000000000"),
},
ethCommon.HexToAddress("0xc6713982649D9284ff56c32655a9ECcCDA78422A"): {
Balance: bigString("10000000000000000000000000000000000"),
},
},
}

func TestParseGenesisOrDefault(t *testing.T) {
tests := [...]struct {
path string
want *core.Genesis
wantErr bool
}{
0: {path: "", want: defaultGenesis},
1: {want: defaultGenesis},
2: {path: fmt.Sprintf("non-existent-%d", rand.Int()), want: defaultGenesis},
3: {path: "./testdata/blank-genesis.json", want: defaultGenesis},
4: {path: "./testdata/genesis1.json", want: genesis1},
5: {path: "./testdata/non-genesis.json", wantErr: true},
}

for i, tt := range tests {
gen, err := ParseGenesisOrDefault(tt.path)
if tt.wantErr {
assert.NotNil(t, err, "#%d: cannot be nil", i)
continue
}

if err != nil {
t.Errorf("#%d: path=%q unexpected error: %v", i, tt.path, err)
continue
}

assert.NotEqual(t, blankGenesis, gen, true, "#%d: expecting a non-blank", i)
assert.Equal(t, gen, tt.want, "#%d: expected them to be the same", i)
}
}
Empty file.
8 changes: 8 additions & 0 deletions common/testdata/genesis1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"difficulty": "0x40",
"gasLimit": "0x8000000",
"alloc": {
"0x7eff122b94897ea5b0e2a9abf47b86337fafebdc": { "balance": "10000000000000000000000000000000000" },
"0xc6713982649D9284ff56c32655a9ECcCDA78422A": { "balance": "10000000000000000000000000000000000" }
}
}
4 changes: 4 additions & 0 deletions common/testdata/non-genesis.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"tendermint": true,
"introduction": "https://tendermint.com"
}

0 comments on commit 96642ec

Please sign in to comment.