Merge pull request #9 from getamis/feature/make-a-tool-to-generate-test-configuration

Feature/make a tool to generate test configuration
This commit is contained in:
bailantaotao 2017-08-11 13:48:47 +08:00 committed by GitHub
commit 01db708a51
15 changed files with 1692 additions and 608 deletions

View File

@ -17,14 +17,11 @@
package main package main
import ( import (
"bytes"
"fmt" "fmt"
"os" "os"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/getamis/istanbul-tools/cmd/istanbul/extradata"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
"github.com/naoina/toml" "github.com/naoina/toml"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -67,33 +64,37 @@ func encode(ctx *cli.Context) error {
} }
if len(path) != 0 { if len(path) != 0 {
if err := fromConfig(path); err != nil { extraData, err := fromConfig(path)
if err != nil {
return cli.NewExitError("Failed to encode from config data", 0) return cli.NewExitError("Failed to encode from config data", 0)
} }
fmt.Println("Encoded Istanbul extra-data:", extraData)
} }
if len(validators) != 0 { if len(validators) != 0 {
if err := fromRawData(ctx.String(VanityFlag.Name), validators); err != nil { extraData, err := fromRawData(ctx.String(VanityFlag.Name), validators)
if err != nil {
return cli.NewExitError("Failed to encode from flags", 0) return cli.NewExitError("Failed to encode from flags", 0)
} }
fmt.Println("Encoded Istanbul extra-data:", extraData)
} }
return nil return nil
} }
func fromRawData(vanity string, validators string) error { func fromRawData(vanity string, validators string) (string, error) {
vs := splitAndTrim(validators) vs := splitAndTrim(validators)
addrs := make([]common.Address, len(vs)) addrs := make([]common.Address, len(vs))
for i, v := range vs { for i, v := range vs {
addrs[i] = common.HexToAddress(v) addrs[i] = common.HexToAddress(v)
} }
return encodeExtraData(vanity, addrs) return extradata.Encode(vanity, addrs)
} }
func fromConfig(path string) error { func fromConfig(path string) (string, error) {
file, err := os.Open(path) file, err := os.Open(path)
if err != nil { if err != nil {
return cli.NewExitError(fmt.Sprintf("Failed to read config file: %v", err), 1) return "", cli.NewExitError(fmt.Sprintf("Failed to read config file: %v", err), 1)
} }
defer file.Close() defer file.Close()
@ -103,10 +104,10 @@ func fromConfig(path string) error {
} }
if err := toml.NewDecoder(file).Decode(&config); err != nil { if err := toml.NewDecoder(file).Decode(&config); err != nil {
return cli.NewExitError(fmt.Sprintf("Failed to parse config file: %v", err), 2) return "", cli.NewExitError(fmt.Sprintf("Failed to parse config file: %v", err), 2)
} }
return encodeExtraData(config.Vanity, config.Validators) return extradata.Encode(config.Vanity, config.Validators)
} }
func decode(ctx *cli.Context) error { func decode(ctx *cli.Context) error {
@ -114,47 +115,13 @@ func decode(ctx *cli.Context) error {
return cli.NewExitError("Must supply extra data", 10) return cli.NewExitError("Must supply extra data", 10)
} }
return decodeExtraData(ctx.String(ExtraDataFlag.Name)) extraString := ctx.String(ExtraDataFlag.Name)
} vanity, istanbulExtra, err := extradata.Decode(extraString)
func encodeExtraData(vanity string, validators []common.Address) error {
newVanity, err := hexutil.Decode(vanity)
if err != nil { if err != nil {
return err return err
} }
if len(newVanity) < types.IstanbulExtraVanity { fmt.Println("vanity: ", "0x"+common.Bytes2Hex(vanity))
newVanity = append(newVanity, bytes.Repeat([]byte{0x00}, types.IstanbulExtraVanity-len(newVanity))...)
}
newVanity = newVanity[:types.IstanbulExtraVanity]
ist := &types.IstanbulExtra{
Validators: validators,
Seal: make([]byte, types.IstanbulExtraSeal),
CommittedSeal: [][]byte{},
}
payload, err := rlp.EncodeToBytes(&ist)
if err != nil {
return err
}
fmt.Println("Encoded Istanbul extra-data:", "0x"+common.Bytes2Hex(append(newVanity, payload...)))
return nil
}
func decodeExtraData(extraData string) error {
extra, err := hexutil.Decode(extraData)
if err != nil {
return err
}
istanbulExtra, err := types.ExtractIstanbulExtra(&types.Header{Extra: extra})
if err != nil {
return err
}
fmt.Println("vanity: ", "0x"+common.Bytes2Hex(extra[:types.IstanbulExtraVanity]))
for _, v := range istanbulExtra.Validators { for _, v := range istanbulExtra.Validators {
fmt.Println("validator: ", v.Hex()) fmt.Println("validator: ", v.Hex())

View File

@ -0,0 +1,19 @@
package extradata
import (
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
)
func Decode(extraData string) ([]byte, *types.IstanbulExtra, error) {
extra, err := hexutil.Decode(extraData)
if err != nil {
return nil, nil, err
}
istanbulExtra, err := types.ExtractIstanbulExtra(&types.Header{Extra: extra})
if err != nil {
return nil, nil, err
}
return extra[:types.IstanbulExtraVanity], istanbulExtra, nil
}

View File

@ -0,0 +1,35 @@
package extradata
import (
"bytes"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/rlp"
atypes "github.com/getamis/go-ethereum/core/types"
)
func Encode(vanity string, validators []common.Address) (string, error) {
newVanity, err := hexutil.Decode(vanity)
if err != nil {
return "", err
}
if len(newVanity) < atypes.IstanbulExtraVanity {
newVanity = append(newVanity, bytes.Repeat([]byte{0x00}, atypes.IstanbulExtraVanity-len(newVanity))...)
}
newVanity = newVanity[:atypes.IstanbulExtraVanity]
ist := &atypes.IstanbulExtra{
Validators: validators,
Seal: make([]byte, atypes.IstanbulExtraSeal),
CommittedSeal: [][]byte{},
}
payload, err := rlp.EncodeToBytes(&ist)
if err != nil {
return "", err
}
return "0x" + common.Bytes2Hex(append(newVanity, payload...)), nil
}

166
core/cluster.go Normal file
View File

@ -0,0 +1,166 @@
// Copyright 2017 AMIS Technologies
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package core
import (
"crypto/ecdsa"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net"
"os"
"path/filepath"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/p2p/discover"
"github.com/satori/go.uuid"
)
const (
defaultBaseRpcPort = uint16(8545)
defaultHttpPort = uint16(30303)
defaultLocalDir = "/tmp/gdata"
datadirPrivateKey = "nodekey"
defaultIP = "localhost"
clientIdentifier = "geth"
staticNodeJson = "static-nodes.json"
genesisJson = "genesis.json"
)
func GenerateClusterKeys(numbers int) []*ecdsa.PrivateKey {
keys := make([]*ecdsa.PrivateKey, numbers)
for i := 0; i < len(keys); i++ {
key, err := crypto.GenerateKey()
if err != nil {
panic("couldn't generate key: " + err.Error())
}
keys[i] = key
}
return keys
}
type Env struct {
GethID int
HttpPort uint16
RpcPort uint16
DataDir string
Key *ecdsa.PrivateKey
}
func SetupEnv(prvKeys []*ecdsa.PrivateKey) []*Env {
envs := make([]*Env, len(prvKeys))
rpcPort := defaultBaseRpcPort
httpPort := defaultHttpPort
for i := 0; i < len(envs); i++ {
dataDir, err := saveNodeKey(prvKeys[i])
if err != nil {
panic("Failed to save node key")
}
envs[i] = &Env{
GethID: i,
HttpPort: httpPort,
RpcPort: rpcPort,
DataDir: dataDir,
Key: prvKeys[i],
}
rpcPort = rpcPort + 1
httpPort = httpPort + 1
}
return envs
}
func SetupNodes(envs []*Env) error {
nodes := transformToStaticNodes(envs)
for _, env := range envs {
if err := saveStaticNode(env.DataDir, nodes); err != nil {
return err
}
}
addrs := transformToAddress(envs)
genesis := GenerateGenesis(addrs)
for _, env := range envs {
if err := saveGenesis(env.DataDir, genesis); err != nil {
return err
}
}
return nil
}
func saveNodeKey(key *ecdsa.PrivateKey) (string, error) {
err := os.MkdirAll(filepath.Join(defaultLocalDir), 0700)
if err != nil {
log.Fatal(err)
}
instanceDir := filepath.Join(defaultLocalDir, fmt.Sprintf("%s%s", clientIdentifier, uuid.NewV4().String()))
if err := os.MkdirAll(instanceDir, 0700); err != nil {
log.Println(fmt.Sprintf("Failed to create instance dir: %v", err))
return "", err
}
keyDir := filepath.Join(instanceDir, clientIdentifier)
if err := os.MkdirAll(keyDir, 0700); err != nil {
log.Println(fmt.Sprintf("Failed to create key dir: %v", err))
return "", err
}
keyfile := filepath.Join(keyDir, datadirPrivateKey)
if err := crypto.SaveECDSA(keyfile, key); err != nil {
log.Println(fmt.Sprintf("Failed to persist node key: %v", err))
return "", err
}
return instanceDir, nil
}
func saveStaticNode(dataDir string, nodes []*discover.Node) error {
filePath := filepath.Join(dataDir, clientIdentifier)
keyPath := filepath.Join(filePath, staticNodeJson)
raw, err := json.Marshal(nodes)
if err != nil {
return err
}
return ioutil.WriteFile(keyPath, raw, 0600)
}
func transformToStaticNodes(envs []*Env) []*discover.Node {
nodes := make([]*discover.Node, len(envs))
for i, env := range envs {
nodeID := discover.PubkeyID(&env.Key.PublicKey)
nodes[i] = discover.NewNode(nodeID, net.ParseIP(defaultIP), 0, env.HttpPort)
}
return nodes
}
func transformToAddress(envs []*Env) []common.Address {
addrs := make([]common.Address, len(envs))
for i, env := range envs {
addrs[i] = crypto.PubkeyToAddress(env.Key.PublicKey)
}
return addrs
}

34
core/cluster_test.go Normal file
View File

@ -0,0 +1,34 @@
// Copyright 2017 AMIS Technologies
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package core
import (
"fmt"
"testing"
)
func TestWriteFile(t *testing.T) {
keys := GenerateClusterKeys(4)
envs := SetupEnv(keys)
err := SetupNodes(envs)
if err != nil {
t.Fatal("failed to setup nodes", err)
}
for _, env := range envs {
fmt.Println(fmt.Sprintf("%s%d%s%s", "geth ID:", env.GethID, ", dataDir:", env.DataDir))
}
}

71
core/genesis.go Normal file
View File

@ -0,0 +1,71 @@
// Copyright 2017 AMIS Technologies
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package core
import (
"encoding/json"
"fmt"
"io/ioutil"
"math/big"
"path/filepath"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/consensus/istanbul"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params"
"github.com/getamis/istanbul-tools/cmd/istanbul/extradata"
)
func GenerateGenesis(addrs []common.Address) *core.Genesis {
extraData, err := extradata.Encode("0x00", addrs)
if err != nil {
panic(fmt.Sprintf("%s%s", "Failed to generate genesis", err))
}
return &core.Genesis{
Timestamp: uint64(time.Now().Unix()),
GasLimit: 4700000,
Difficulty: big.NewInt(1),
Alloc: make(core.GenesisAlloc),
Config: &params.ChainConfig{
HomesteadBlock: big.NewInt(1),
EIP150Block: big.NewInt(2),
EIP155Block: big.NewInt(3),
EIP158Block: big.NewInt(3),
Istanbul: &params.IstanbulConfig{
ProposerPolicy: uint64(istanbul.DefaultConfig.ProposerPolicy),
Epoch: istanbul.DefaultConfig.Epoch,
},
},
Mixhash: types.IstanbulDigest,
ExtraData: hexutil.MustDecode(extraData),
}
}
func saveGenesis(dataDir string, genesis *core.Genesis) error {
filePath := filepath.Join(dataDir, genesisJson)
raw, err := json.Marshal(genesis)
if err != nil {
return err
}
return ioutil.WriteFile(filePath, raw, 0600)
}

7
glide.lock generated
View File

@ -1,5 +1,5 @@
hash: eb90dd3f38fb4dead998c624f39c7897e252105342c15e909f32835eb99d65fc hash: 89546c4f43145476a4e79907fdddddd9e982ddb8e035db13051ef08d03f07dcf
updated: 2017-08-09T16:37:30.171348623+08:00 updated: 2017-08-11T13:30:18.848541104+08:00
imports: imports:
- name: github.com/aristanetworks/goarista - name: github.com/aristanetworks/goarista
version: 8e44bec0a94d7c1f0cdf28ed5215e5cfab441ad0 version: 8e44bec0a94d7c1f0cdf28ed5215e5cfab441ad0
@ -115,6 +115,7 @@ imports:
version: 0f066fb0e5977635e543b2c8d008405c5abb734b version: 0f066fb0e5977635e543b2c8d008405c5abb734b
subpackages: subpackages:
- cmd/utils - cmd/utils
- core/types
- name: github.com/go-stack/stack - name: github.com/go-stack/stack
version: 817915b46b97fd7bb80e8ab6b69f01a53ac3eebf version: 817915b46b97fd7bb80e8ab6b69f01a53ac3eebf
- name: github.com/gogo/protobuf - name: github.com/gogo/protobuf
@ -180,6 +181,8 @@ imports:
- token - token
- name: github.com/rs/cors - name: github.com/rs/cors
version: eabcc6af4bbe5ad3a949d36450326a2b0b9894b8 version: eabcc6af4bbe5ad3a949d36450326a2b0b9894b8
- name: github.com/satori/go.uuid
version: 879c5887cd475cd7864858769793b2ceb0d44feb
- name: github.com/sirupsen/logrus - name: github.com/sirupsen/logrus
version: 181d419aa9e2223811b824e8f0b4af96f9ba9302 version: 181d419aa9e2223811b824e8f0b4af96f9ba9302
- name: github.com/syndtr/goleveldb - name: github.com/syndtr/goleveldb

View File

@ -2,8 +2,8 @@ package: github.com/getamis/istanbul-tools
import: import:
- package: github.com/ethereum/go-ethereum - package: github.com/ethereum/go-ethereum
version: istanbul/develop version: istanbul/develop
repo: git@github.com:getamis/go-ethereum repo: git@github.com:getamis/go-ethereum
vcs: git vcs: git
subpackages: subpackages:
- cmd/utils - cmd/utils
- common - common
@ -20,3 +20,5 @@ import:
- package: github.com/naoina/toml - package: github.com/naoina/toml
- package: github.com/urfave/cli - package: github.com/urfave/cli
- package: github.com/opencontainers/go-digest - package: github.com/opencontainers/go-digest
- package: github.com/satori/go.uuid
version: ~1.1.0

15
vendor/github.com/satori/go.uuid/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,15 @@
language: go
sudo: false
go:
- 1.2
- 1.3
- 1.4
- 1.5
- 1.6
before_install:
- go get github.com/mattn/goveralls
- go get golang.org/x/tools/cmd/cover
script:
- $HOME/gopath/bin/goveralls -service=travis-ci
notifications:
email: false

20
vendor/github.com/satori/go.uuid/LICENSE generated vendored Normal file
View File

@ -0,0 +1,20 @@
Copyright (C) 2013-2016 by Maxim Bublis <b@codemonkey.ru>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

65
vendor/github.com/satori/go.uuid/README.md generated vendored Normal file
View File

@ -0,0 +1,65 @@
# UUID package for Go language
[![Build Status](https://travis-ci.org/satori/go.uuid.png?branch=master)](https://travis-ci.org/satori/go.uuid)
[![Coverage Status](https://coveralls.io/repos/github/satori/go.uuid/badge.svg?branch=master)](https://coveralls.io/github/satori/go.uuid)
[![GoDoc](http://godoc.org/github.com/satori/go.uuid?status.png)](http://godoc.org/github.com/satori/go.uuid)
This package provides pure Go implementation of Universally Unique Identifier (UUID). Supported both creation and parsing of UUIDs.
With 100% test coverage and benchmarks out of box.
Supported versions:
* Version 1, based on timestamp and MAC address (RFC 4122)
* Version 2, based on timestamp, MAC address and POSIX UID/GID (DCE 1.1)
* Version 3, based on MD5 hashing (RFC 4122)
* Version 4, based on random numbers (RFC 4122)
* Version 5, based on SHA-1 hashing (RFC 4122)
## Installation
Use the `go` command:
$ go get github.com/satori/go.uuid
## Requirements
UUID package requires Go >= 1.2.
## Example
```go
package main
import (
"fmt"
"github.com/satori/go.uuid"
)
func main() {
// Creating UUID Version 4
u1 := uuid.NewV4()
fmt.Printf("UUIDv4: %s\n", u1)
// Parsing UUID from string input
u2, err := uuid.FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
if err != nil {
fmt.Printf("Something gone wrong: %s", err)
}
fmt.Printf("Successfully parsed: %s", u2)
}
```
## Documentation
[Documentation](http://godoc.org/github.com/satori/go.uuid) is hosted at GoDoc project.
## Links
* [RFC 4122](http://tools.ietf.org/html/rfc4122)
* [DCE 1.1: Authentication and Security Services](http://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01)
## Copyright
Copyright (C) 2013-2016 by Maxim Bublis <b@codemonkey.ru>.
UUID package released under MIT License.
See [LICENSE](https://github.com/satori/go.uuid/blob/master/LICENSE) for details.

121
vendor/github.com/satori/go.uuid/benchmarks_test.go generated vendored Normal file
View File

@ -0,0 +1,121 @@
// Copyright (C) 2013-2015 by Maxim Bublis <b@codemonkey.ru>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package uuid
import (
"testing"
)
func BenchmarkFromBytes(b *testing.B) {
bytes := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
for i := 0; i < b.N; i++ {
FromBytes(bytes)
}
}
func BenchmarkFromString(b *testing.B) {
s := "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
for i := 0; i < b.N; i++ {
FromString(s)
}
}
func BenchmarkFromStringUrn(b *testing.B) {
s := "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
for i := 0; i < b.N; i++ {
FromString(s)
}
}
func BenchmarkFromStringWithBrackets(b *testing.B) {
s := "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}"
for i := 0; i < b.N; i++ {
FromString(s)
}
}
func BenchmarkNewV1(b *testing.B) {
for i := 0; i < b.N; i++ {
NewV1()
}
}
func BenchmarkNewV2(b *testing.B) {
for i := 0; i < b.N; i++ {
NewV2(DomainPerson)
}
}
func BenchmarkNewV3(b *testing.B) {
for i := 0; i < b.N; i++ {
NewV3(NamespaceDNS, "www.example.com")
}
}
func BenchmarkNewV4(b *testing.B) {
for i := 0; i < b.N; i++ {
NewV4()
}
}
func BenchmarkNewV5(b *testing.B) {
for i := 0; i < b.N; i++ {
NewV5(NamespaceDNS, "www.example.com")
}
}
func BenchmarkMarshalBinary(b *testing.B) {
u := NewV4()
for i := 0; i < b.N; i++ {
u.MarshalBinary()
}
}
func BenchmarkMarshalText(b *testing.B) {
u := NewV4()
for i := 0; i < b.N; i++ {
u.MarshalText()
}
}
func BenchmarkUnmarshalBinary(b *testing.B) {
bytes := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
u := UUID{}
for i := 0; i < b.N; i++ {
u.UnmarshalBinary(bytes)
}
}
func BenchmarkUnmarshalText(b *testing.B) {
bytes := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
u := UUID{}
for i := 0; i < b.N; i++ {
u.UnmarshalText(bytes)
}
}
func BenchmarkMarshalToString(b *testing.B) {
u := NewV4()
for i := 0; i < b.N; i++ {
u.String()
}
}

488
vendor/github.com/satori/go.uuid/uuid.go generated vendored Normal file
View File

@ -0,0 +1,488 @@
// Copyright (C) 2013-2015 by Maxim Bublis <b@codemonkey.ru>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// Package uuid provides implementation of Universally Unique Identifier (UUID).
// Supported versions are 1, 3, 4 and 5 (as specified in RFC 4122) and
// version 2 (as specified in DCE 1.1).
package uuid
import (
"bytes"
"crypto/md5"
"crypto/rand"
"crypto/sha1"
"database/sql/driver"
"encoding/binary"
"encoding/hex"
"fmt"
"hash"
"net"
"os"
"sync"
"time"
)
// UUID layout variants.
const (
VariantNCS = iota
VariantRFC4122
VariantMicrosoft
VariantFuture
)
// UUID DCE domains.
const (
DomainPerson = iota
DomainGroup
DomainOrg
)
// Difference in 100-nanosecond intervals between
// UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970).
const epochStart = 122192928000000000
// Used in string method conversion
const dash byte = '-'
// UUID v1/v2 storage.
var (
storageMutex sync.Mutex
storageOnce sync.Once
epochFunc = unixTimeFunc
clockSequence uint16
lastTime uint64
hardwareAddr [6]byte
posixUID = uint32(os.Getuid())
posixGID = uint32(os.Getgid())
)
// String parse helpers.
var (
urnPrefix = []byte("urn:uuid:")
byteGroups = []int{8, 4, 4, 4, 12}
)
func initClockSequence() {
buf := make([]byte, 2)
safeRandom(buf)
clockSequence = binary.BigEndian.Uint16(buf)
}
func initHardwareAddr() {
interfaces, err := net.Interfaces()
if err == nil {
for _, iface := range interfaces {
if len(iface.HardwareAddr) >= 6 {
copy(hardwareAddr[:], iface.HardwareAddr)
return
}
}
}
// Initialize hardwareAddr randomly in case
// of real network interfaces absence
safeRandom(hardwareAddr[:])
// Set multicast bit as recommended in RFC 4122
hardwareAddr[0] |= 0x01
}
func initStorage() {
initClockSequence()
initHardwareAddr()
}
func safeRandom(dest []byte) {
if _, err := rand.Read(dest); err != nil {
panic(err)
}
}
// Returns difference in 100-nanosecond intervals between
// UUID epoch (October 15, 1582) and current time.
// This is default epoch calculation function.
func unixTimeFunc() uint64 {
return epochStart + uint64(time.Now().UnixNano()/100)
}
// UUID representation compliant with specification
// described in RFC 4122.
type UUID [16]byte
// NullUUID can be used with the standard sql package to represent a
// UUID value that can be NULL in the database
type NullUUID struct {
UUID UUID
Valid bool
}
// The nil UUID is special form of UUID that is specified to have all
// 128 bits set to zero.
var Nil = UUID{}
// Predefined namespace UUIDs.
var (
NamespaceDNS, _ = FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
NamespaceURL, _ = FromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8")
NamespaceOID, _ = FromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8")
NamespaceX500, _ = FromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8")
)
// And returns result of binary AND of two UUIDs.
func And(u1 UUID, u2 UUID) UUID {
u := UUID{}
for i := 0; i < 16; i++ {
u[i] = u1[i] & u2[i]
}
return u
}
// Or returns result of binary OR of two UUIDs.
func Or(u1 UUID, u2 UUID) UUID {
u := UUID{}
for i := 0; i < 16; i++ {
u[i] = u1[i] | u2[i]
}
return u
}
// Equal returns true if u1 and u2 equals, otherwise returns false.
func Equal(u1 UUID, u2 UUID) bool {
return bytes.Equal(u1[:], u2[:])
}
// Version returns algorithm version used to generate UUID.
func (u UUID) Version() uint {
return uint(u[6] >> 4)
}
// Variant returns UUID layout variant.
func (u UUID) Variant() uint {
switch {
case (u[8] & 0x80) == 0x00:
return VariantNCS
case (u[8]&0xc0)|0x80 == 0x80:
return VariantRFC4122
case (u[8]&0xe0)|0xc0 == 0xc0:
return VariantMicrosoft
}
return VariantFuture
}
// Bytes returns bytes slice representation of UUID.
func (u UUID) Bytes() []byte {
return u[:]
}
// Returns canonical string representation of UUID:
// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
func (u UUID) String() string {
buf := make([]byte, 36)
hex.Encode(buf[0:8], u[0:4])
buf[8] = dash
hex.Encode(buf[9:13], u[4:6])
buf[13] = dash
hex.Encode(buf[14:18], u[6:8])
buf[18] = dash
hex.Encode(buf[19:23], u[8:10])
buf[23] = dash
hex.Encode(buf[24:], u[10:])
return string(buf)
}
// SetVersion sets version bits.
func (u *UUID) SetVersion(v byte) {
u[6] = (u[6] & 0x0f) | (v << 4)
}
// SetVariant sets variant bits as described in RFC 4122.
func (u *UUID) SetVariant() {
u[8] = (u[8] & 0xbf) | 0x80
}
// MarshalText implements the encoding.TextMarshaler interface.
// The encoding is the same as returned by String.
func (u UUID) MarshalText() (text []byte, err error) {
text = []byte(u.String())
return
}
// UnmarshalText implements the encoding.TextUnmarshaler interface.
// Following formats are supported:
// "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}",
// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
func (u *UUID) UnmarshalText(text []byte) (err error) {
if len(text) < 32 {
err = fmt.Errorf("uuid: UUID string too short: %s", text)
return
}
t := text[:]
braced := false
if bytes.Equal(t[:9], urnPrefix) {
t = t[9:]
} else if t[0] == '{' {
braced = true
t = t[1:]
}
b := u[:]
for i, byteGroup := range byteGroups {
if i > 0 && t[0] == '-' {
t = t[1:]
} else if i > 0 && t[0] != '-' {
err = fmt.Errorf("uuid: invalid string format")
return
}
if i == 2 {
if !bytes.Contains([]byte("012345"), []byte{t[0]}) {
err = fmt.Errorf("uuid: invalid version number: %s", t[0])
return
}
}
if len(t) < byteGroup {
err = fmt.Errorf("uuid: UUID string too short: %s", text)
return
}
if i == 4 && len(t) > byteGroup &&
((braced && t[byteGroup] != '}') || len(t[byteGroup:]) > 1 || !braced) {
err = fmt.Errorf("uuid: UUID string too long: %s", t)
return
}
_, err = hex.Decode(b[:byteGroup/2], t[:byteGroup])
if err != nil {
return
}
t = t[byteGroup:]
b = b[byteGroup/2:]
}
return
}
// MarshalBinary implements the encoding.BinaryMarshaler interface.
func (u UUID) MarshalBinary() (data []byte, err error) {
data = u.Bytes()
return
}
// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
// It will return error if the slice isn't 16 bytes long.
func (u *UUID) UnmarshalBinary(data []byte) (err error) {
if len(data) != 16 {
err = fmt.Errorf("uuid: UUID must be exactly 16 bytes long, got %d bytes", len(data))
return
}
copy(u[:], data)
return
}
// Value implements the driver.Valuer interface.
func (u UUID) Value() (driver.Value, error) {
return u.String(), nil
}
// Scan implements the sql.Scanner interface.
// A 16-byte slice is handled by UnmarshalBinary, while
// a longer byte slice or a string is handled by UnmarshalText.
func (u *UUID) Scan(src interface{}) error {
switch src := src.(type) {
case []byte:
if len(src) == 16 {
return u.UnmarshalBinary(src)
}
return u.UnmarshalText(src)
case string:
return u.UnmarshalText([]byte(src))
}
return fmt.Errorf("uuid: cannot convert %T to UUID", src)
}
// Value implements the driver.Valuer interface.
func (u NullUUID) Value() (driver.Value, error) {
if !u.Valid {
return nil, nil
}
// Delegate to UUID Value function
return u.UUID.Value()
}
// Scan implements the sql.Scanner interface.
func (u *NullUUID) Scan(src interface{}) error {
if src == nil {
u.UUID, u.Valid = Nil, false
return nil
}
// Delegate to UUID Scan function
u.Valid = true
return u.UUID.Scan(src)
}
// FromBytes returns UUID converted from raw byte slice input.
// It will return error if the slice isn't 16 bytes long.
func FromBytes(input []byte) (u UUID, err error) {
err = u.UnmarshalBinary(input)
return
}
// FromBytesOrNil returns UUID converted from raw byte slice input.
// Same behavior as FromBytes, but returns a Nil UUID on error.
func FromBytesOrNil(input []byte) UUID {
uuid, err := FromBytes(input)
if err != nil {
return Nil
}
return uuid
}
// FromString returns UUID parsed from string input.
// Input is expected in a form accepted by UnmarshalText.
func FromString(input string) (u UUID, err error) {
err = u.UnmarshalText([]byte(input))
return
}
// FromStringOrNil returns UUID parsed from string input.
// Same behavior as FromString, but returns a Nil UUID on error.
func FromStringOrNil(input string) UUID {
uuid, err := FromString(input)
if err != nil {
return Nil
}
return uuid
}
// Returns UUID v1/v2 storage state.
// Returns epoch timestamp, clock sequence, and hardware address.
func getStorage() (uint64, uint16, []byte) {
storageOnce.Do(initStorage)
storageMutex.Lock()
defer storageMutex.Unlock()
timeNow := epochFunc()
// Clock changed backwards since last UUID generation.
// Should increase clock sequence.
if timeNow <= lastTime {
clockSequence++
}
lastTime = timeNow
return timeNow, clockSequence, hardwareAddr[:]
}
// NewV1 returns UUID based on current timestamp and MAC address.
func NewV1() UUID {
u := UUID{}
timeNow, clockSeq, hardwareAddr := getStorage()
binary.BigEndian.PutUint32(u[0:], uint32(timeNow))
binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
binary.BigEndian.PutUint16(u[8:], clockSeq)
copy(u[10:], hardwareAddr)
u.SetVersion(1)
u.SetVariant()
return u
}
// NewV2 returns DCE Security UUID based on POSIX UID/GID.
func NewV2(domain byte) UUID {
u := UUID{}
timeNow, clockSeq, hardwareAddr := getStorage()
switch domain {
case DomainPerson:
binary.BigEndian.PutUint32(u[0:], posixUID)
case DomainGroup:
binary.BigEndian.PutUint32(u[0:], posixGID)
}
binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32))
binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48))
binary.BigEndian.PutUint16(u[8:], clockSeq)
u[9] = domain
copy(u[10:], hardwareAddr)
u.SetVersion(2)
u.SetVariant()
return u
}
// NewV3 returns UUID based on MD5 hash of namespace UUID and name.
func NewV3(ns UUID, name string) UUID {
u := newFromHash(md5.New(), ns, name)
u.SetVersion(3)
u.SetVariant()
return u
}
// NewV4 returns random generated UUID.
func NewV4() UUID {
u := UUID{}
safeRandom(u[:])
u.SetVersion(4)
u.SetVariant()
return u
}
// NewV5 returns UUID based on SHA-1 hash of namespace UUID and name.
func NewV5(ns UUID, name string) UUID {
u := newFromHash(sha1.New(), ns, name)
u.SetVersion(5)
u.SetVariant()
return u
}
// Returns UUID based on hashing of namespace UUID and name.
func newFromHash(h hash.Hash, ns UUID, name string) UUID {
u := UUID{}
h.Write(ns[:])
h.Write([]byte(name))
copy(u[:], h.Sum(nil))
return u
}

633
vendor/github.com/satori/go.uuid/uuid_test.go generated vendored Normal file
View File

@ -0,0 +1,633 @@
// Copyright (C) 2013, 2015 by Maxim Bublis <b@codemonkey.ru>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package uuid
import (
"bytes"
"testing"
)
func TestBytes(t *testing.T) {
u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
bytes1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
if !bytes.Equal(u.Bytes(), bytes1) {
t.Errorf("Incorrect bytes representation for UUID: %s", u)
}
}
func TestString(t *testing.T) {
if NamespaceDNS.String() != "6ba7b810-9dad-11d1-80b4-00c04fd430c8" {
t.Errorf("Incorrect string representation for UUID: %s", NamespaceDNS.String())
}
}
func TestEqual(t *testing.T) {
if !Equal(NamespaceDNS, NamespaceDNS) {
t.Errorf("Incorrect comparison of %s and %s", NamespaceDNS, NamespaceDNS)
}
if Equal(NamespaceDNS, NamespaceURL) {
t.Errorf("Incorrect comparison of %s and %s", NamespaceDNS, NamespaceURL)
}
}
func TestOr(t *testing.T) {
u1 := UUID{0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff}
u2 := UUID{0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00}
u := UUID{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
if !Equal(u, Or(u1, u2)) {
t.Errorf("Incorrect bitwise OR result %s", Or(u1, u2))
}
}
func TestAnd(t *testing.T) {
u1 := UUID{0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff}
u2 := UUID{0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00}
u := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
if !Equal(u, And(u1, u2)) {
t.Errorf("Incorrect bitwise AND result %s", And(u1, u2))
}
}
func TestVersion(t *testing.T) {
u := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
if u.Version() != 1 {
t.Errorf("Incorrect version for UUID: %d", u.Version())
}
}
func TestSetVersion(t *testing.T) {
u := UUID{}
u.SetVersion(4)
if u.Version() != 4 {
t.Errorf("Incorrect version for UUID after u.setVersion(4): %d", u.Version())
}
}
func TestVariant(t *testing.T) {
u1 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
if u1.Variant() != VariantNCS {
t.Errorf("Incorrect variant for UUID variant %d: %d", VariantNCS, u1.Variant())
}
u2 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
if u2.Variant() != VariantRFC4122 {
t.Errorf("Incorrect variant for UUID variant %d: %d", VariantRFC4122, u2.Variant())
}
u3 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
if u3.Variant() != VariantMicrosoft {
t.Errorf("Incorrect variant for UUID variant %d: %d", VariantMicrosoft, u3.Variant())
}
u4 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
if u4.Variant() != VariantFuture {
t.Errorf("Incorrect variant for UUID variant %d: %d", VariantFuture, u4.Variant())
}
}
func TestSetVariant(t *testing.T) {
u := new(UUID)
u.SetVariant()
if u.Variant() != VariantRFC4122 {
t.Errorf("Incorrect variant for UUID after u.setVariant(): %d", u.Variant())
}
}
func TestFromBytes(t *testing.T) {
u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
u1, err := FromBytes(b1)
if err != nil {
t.Errorf("Error parsing UUID from bytes: %s", err)
}
if !Equal(u, u1) {
t.Errorf("UUIDs should be equal: %s and %s", u, u1)
}
b2 := []byte{}
_, err = FromBytes(b2)
if err == nil {
t.Errorf("Should return error parsing from empty byte slice, got %s", err)
}
}
func TestMarshalBinary(t *testing.T) {
u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
b2, err := u.MarshalBinary()
if err != nil {
t.Errorf("Error marshaling UUID: %s", err)
}
if !bytes.Equal(b1, b2) {
t.Errorf("Marshaled UUID should be %s, got %s", b1, b2)
}
}
func TestUnmarshalBinary(t *testing.T) {
u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
u1 := UUID{}
err := u1.UnmarshalBinary(b1)
if err != nil {
t.Errorf("Error unmarshaling UUID: %s", err)
}
if !Equal(u, u1) {
t.Errorf("UUIDs should be equal: %s and %s", u, u1)
}
b2 := []byte{}
u2 := UUID{}
err = u2.UnmarshalBinary(b2)
if err == nil {
t.Errorf("Should return error unmarshalling from empty byte slice, got %s", err)
}
}
func TestFromString(t *testing.T) {
u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
s1 := "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
s2 := "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}"
s3 := "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8"
_, err := FromString("")
if err == nil {
t.Errorf("Should return error trying to parse empty string, got %s", err)
}
u1, err := FromString(s1)
if err != nil {
t.Errorf("Error parsing UUID from string: %s", err)
}
if !Equal(u, u1) {
t.Errorf("UUIDs should be equal: %s and %s", u, u1)
}
u2, err := FromString(s2)
if err != nil {
t.Errorf("Error parsing UUID from string: %s", err)
}
if !Equal(u, u2) {
t.Errorf("UUIDs should be equal: %s and %s", u, u2)
}
u3, err := FromString(s3)
if err != nil {
t.Errorf("Error parsing UUID from string: %s", err)
}
if !Equal(u, u3) {
t.Errorf("UUIDs should be equal: %s and %s", u, u3)
}
}
func TestFromStringShort(t *testing.T) {
// Invalid 35-character UUID string
s1 := "6ba7b810-9dad-11d1-80b4-00c04fd430c"
for i := len(s1); i >= 0; i-- {
_, err := FromString(s1[:i])
if err == nil {
t.Errorf("Should return error trying to parse too short string, got %s", err)
}
}
}
func TestFromStringLong(t *testing.T) {
// Invalid 37+ character UUID string
s := []string{
"6ba7b810-9dad-11d1-80b4-00c04fd430c8=",
"6ba7b810-9dad-11d1-80b4-00c04fd430c8}",
"{6ba7b810-9dad-11d1-80b4-00c04fd430c8}f",
"6ba7b810-9dad-11d1-80b4-00c04fd430c800c04fd430c8",
}
for _, str := range s {
_, err := FromString(str)
if err == nil {
t.Errorf("Should return error trying to parse too long string, passed %s", str)
}
}
}
func TestFromStringInvalid(t *testing.T) {
// Invalid UUID string formats
s := []string{
"6ba7b8109dad11d180b400c04fd430c8",
"6ba7b8109dad11d180b400c04fd430c86ba7b8109dad11d180b400c04fd430c8",
"urn:uuid:{6ba7b810-9dad-11d1-80b4-00c04fd430c8}",
"6ba7b8109-dad-11d1-80b4-00c04fd430c8",
"6ba7b810-9dad1-1d1-80b4-00c04fd430c8",
"6ba7b810-9dad-11d18-0b4-00c04fd430c8",
"6ba7b810-9dad-11d1-80b40-0c04fd430c8",
"6ba7b810+9dad+11d1+80b4+00c04fd430c8",
"6ba7b810-9dad11d180b400c04fd430c8",
"6ba7b8109dad-11d180b400c04fd430c8",
"6ba7b8109dad11d1-80b400c04fd430c8",
"6ba7b8109dad11d180b4-00c04fd430c8",
}
for _, str := range s {
_, err := FromString(str)
if err == nil {
t.Errorf("Should return error trying to parse invalid string, passed %s", str)
}
}
}
func TestFromStringOrNil(t *testing.T) {
u := FromStringOrNil("")
if u != Nil {
t.Errorf("Should return Nil UUID on parse failure, got %s", u)
}
}
func TestFromBytesOrNil(t *testing.T) {
b := []byte{}
u := FromBytesOrNil(b)
if u != Nil {
t.Errorf("Should return Nil UUID on parse failure, got %s", u)
}
}
func TestMarshalText(t *testing.T) {
u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
b1 := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
b2, err := u.MarshalText()
if err != nil {
t.Errorf("Error marshaling UUID: %s", err)
}
if !bytes.Equal(b1, b2) {
t.Errorf("Marshaled UUID should be %s, got %s", b1, b2)
}
}
func TestUnmarshalText(t *testing.T) {
u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
b1 := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
u1 := UUID{}
err := u1.UnmarshalText(b1)
if err != nil {
t.Errorf("Error unmarshaling UUID: %s", err)
}
if !Equal(u, u1) {
t.Errorf("UUIDs should be equal: %s and %s", u, u1)
}
b2 := []byte("")
u2 := UUID{}
err = u2.UnmarshalText(b2)
if err == nil {
t.Errorf("Should return error trying to unmarshal from empty string")
}
}
func TestValue(t *testing.T) {
u, err := FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
if err != nil {
t.Errorf("Error parsing UUID from string: %s", err)
}
val, err := u.Value()
if err != nil {
t.Errorf("Error getting UUID value: %s", err)
}
if val != u.String() {
t.Errorf("Wrong value returned, should be equal: %s and %s", val, u)
}
}
func TestValueNil(t *testing.T) {
u := UUID{}
val, err := u.Value()
if err != nil {
t.Errorf("Error getting UUID value: %s", err)
}
if val != Nil.String() {
t.Errorf("Wrong value returned, should be equal to UUID.Nil: %s", val)
}
}
func TestNullUUIDValueNil(t *testing.T) {
u := NullUUID{}
val, err := u.Value()
if err != nil {
t.Errorf("Error getting UUID value: %s", err)
}
if val != nil {
t.Errorf("Wrong value returned, should be nil: %s", val)
}
}
func TestScanBinary(t *testing.T) {
u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
u1 := UUID{}
err := u1.Scan(b1)
if err != nil {
t.Errorf("Error unmarshaling UUID: %s", err)
}
if !Equal(u, u1) {
t.Errorf("UUIDs should be equal: %s and %s", u, u1)
}
b2 := []byte{}
u2 := UUID{}
err = u2.Scan(b2)
if err == nil {
t.Errorf("Should return error unmarshalling from empty byte slice, got %s", err)
}
}
func TestScanString(t *testing.T) {
u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
s1 := "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
u1 := UUID{}
err := u1.Scan(s1)
if err != nil {
t.Errorf("Error unmarshaling UUID: %s", err)
}
if !Equal(u, u1) {
t.Errorf("UUIDs should be equal: %s and %s", u, u1)
}
s2 := ""
u2 := UUID{}
err = u2.Scan(s2)
if err == nil {
t.Errorf("Should return error trying to unmarshal from empty string")
}
}
func TestScanText(t *testing.T) {
u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
b1 := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8")
u1 := UUID{}
err := u1.Scan(b1)
if err != nil {
t.Errorf("Error unmarshaling UUID: %s", err)
}
if !Equal(u, u1) {
t.Errorf("UUIDs should be equal: %s and %s", u, u1)
}
b2 := []byte("")
u2 := UUID{}
err = u2.Scan(b2)
if err == nil {
t.Errorf("Should return error trying to unmarshal from empty string")
}
}
func TestScanUnsupported(t *testing.T) {
u := UUID{}
err := u.Scan(true)
if err == nil {
t.Errorf("Should return error trying to unmarshal from bool")
}
}
func TestScanNil(t *testing.T) {
u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
err := u.Scan(nil)
if err == nil {
t.Errorf("Error UUID shouldn't allow unmarshalling from nil")
}
}
func TestNullUUIDScanValid(t *testing.T) {
u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}
s1 := "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
u1 := NullUUID{}
err := u1.Scan(s1)
if err != nil {
t.Errorf("Error unmarshaling NullUUID: %s", err)
}
if !u1.Valid {
t.Errorf("NullUUID should be valid")
}
if !Equal(u, u1.UUID) {
t.Errorf("UUIDs should be equal: %s and %s", u, u1.UUID)
}
}
func TestNullUUIDScanNil(t *testing.T) {
u := NullUUID{UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}, true}
err := u.Scan(nil)
if err != nil {
t.Errorf("Error unmarshaling NullUUID: %s", err)
}
if u.Valid {
t.Errorf("NullUUID should not be valid")
}
if !Equal(u.UUID, Nil) {
t.Errorf("NullUUID value should be equal to Nil: %s", u)
}
}
func TestNewV1(t *testing.T) {
u := NewV1()
if u.Version() != 1 {
t.Errorf("UUIDv1 generated with incorrect version: %d", u.Version())
}
if u.Variant() != VariantRFC4122 {
t.Errorf("UUIDv1 generated with incorrect variant: %d", u.Variant())
}
u1 := NewV1()
u2 := NewV1()
if Equal(u1, u2) {
t.Errorf("UUIDv1 generated two equal UUIDs: %s and %s", u1, u2)
}
oldFunc := epochFunc
epochFunc = func() uint64 { return 0 }
u3 := NewV1()
u4 := NewV1()
if Equal(u3, u4) {
t.Errorf("UUIDv1 generated two equal UUIDs: %s and %s", u3, u4)
}
epochFunc = oldFunc
}
func TestNewV2(t *testing.T) {
u1 := NewV2(DomainPerson)
if u1.Version() != 2 {
t.Errorf("UUIDv2 generated with incorrect version: %d", u1.Version())
}
if u1.Variant() != VariantRFC4122 {
t.Errorf("UUIDv2 generated with incorrect variant: %d", u1.Variant())
}
u2 := NewV2(DomainGroup)
if u2.Version() != 2 {
t.Errorf("UUIDv2 generated with incorrect version: %d", u2.Version())
}
if u2.Variant() != VariantRFC4122 {
t.Errorf("UUIDv2 generated with incorrect variant: %d", u2.Variant())
}
}
func TestNewV3(t *testing.T) {
u := NewV3(NamespaceDNS, "www.example.com")
if u.Version() != 3 {
t.Errorf("UUIDv3 generated with incorrect version: %d", u.Version())
}
if u.Variant() != VariantRFC4122 {
t.Errorf("UUIDv3 generated with incorrect variant: %d", u.Variant())
}
if u.String() != "5df41881-3aed-3515-88a7-2f4a814cf09e" {
t.Errorf("UUIDv3 generated incorrectly: %s", u.String())
}
u = NewV3(NamespaceDNS, "python.org")
if u.String() != "6fa459ea-ee8a-3ca4-894e-db77e160355e" {
t.Errorf("UUIDv3 generated incorrectly: %s", u.String())
}
u1 := NewV3(NamespaceDNS, "golang.org")
u2 := NewV3(NamespaceDNS, "golang.org")
if !Equal(u1, u2) {
t.Errorf("UUIDv3 generated different UUIDs for same namespace and name: %s and %s", u1, u2)
}
u3 := NewV3(NamespaceDNS, "example.com")
if Equal(u1, u3) {
t.Errorf("UUIDv3 generated same UUIDs for different names in same namespace: %s and %s", u1, u2)
}
u4 := NewV3(NamespaceURL, "golang.org")
if Equal(u1, u4) {
t.Errorf("UUIDv3 generated same UUIDs for sane names in different namespaces: %s and %s", u1, u4)
}
}
func TestNewV4(t *testing.T) {
u := NewV4()
if u.Version() != 4 {
t.Errorf("UUIDv4 generated with incorrect version: %d", u.Version())
}
if u.Variant() != VariantRFC4122 {
t.Errorf("UUIDv4 generated with incorrect variant: %d", u.Variant())
}
}
func TestNewV5(t *testing.T) {
u := NewV5(NamespaceDNS, "www.example.com")
if u.Version() != 5 {
t.Errorf("UUIDv5 generated with incorrect version: %d", u.Version())
}
if u.Variant() != VariantRFC4122 {
t.Errorf("UUIDv5 generated with incorrect variant: %d", u.Variant())
}
u = NewV5(NamespaceDNS, "python.org")
if u.String() != "886313e1-3b8a-5372-9b90-0c9aee199e5d" {
t.Errorf("UUIDv5 generated incorrectly: %s", u.String())
}
u1 := NewV5(NamespaceDNS, "golang.org")
u2 := NewV5(NamespaceDNS, "golang.org")
if !Equal(u1, u2) {
t.Errorf("UUIDv5 generated different UUIDs for same namespace and name: %s and %s", u1, u2)
}
u3 := NewV5(NamespaceDNS, "example.com")
if Equal(u1, u3) {
t.Errorf("UUIDv5 generated same UUIDs for different names in same namespace: %s and %s", u1, u2)
}
u4 := NewV5(NamespaceURL, "golang.org")
if Equal(u1, u4) {
t.Errorf("UUIDv3 generated same UUIDs for sane names in different namespaces: %s and %s", u1, u4)
}
}

555
vendor/vendor.json vendored
View File

@ -1,555 +0,0 @@
{
"comment": "",
"ignore": "test",
"package": [
{
"checksumSHA1": "o/3cn04KAiwC7NqNVvmfVTD+hgA=",
"path": "github.com/Microsoft/go-winio",
"revision": "78439966b38d69bf38227fbf57ac8a6fee70f69a",
"revisionTime": "2017-08-04T20:09:54Z"
},
{
"checksumSHA1": "W5qMYydPUfwKPyvbgSfF7YSAx6w=",
"path": "github.com/btcsuite/btcd/btcec",
"revision": "1bdb71328511a5225d6300c3c08a79172f667996",
"revisionTime": "2016-07-09T19:04:59Z"
},
{
"checksumSHA1": "Gj+xR1VgFKKmFXYOJMnAczC3Znk=",
"path": "github.com/docker/distribution/digestset",
"revision": "7a8efe719e55bbfaff7bc5718cdf0ed51ca821df",
"revisionTime": "2017-08-04T19:10:18Z"
},
{
"checksumSHA1": "2Fe4D6PGaVE2he4fUeenLmhC1lE=",
"path": "github.com/docker/distribution/reference",
"revision": "7a8efe719e55bbfaff7bc5718cdf0ed51ca821df",
"revisionTime": "2017-08-04T19:10:18Z"
},
{
"checksumSHA1": "XyK3nE86q9ek+9jiypeunC25o0M=",
"path": "github.com/docker/docker/api",
"revision": "202cf001dd7e6ca6c171aa52f454cc7b10f865bf",
"revisionTime": "2017-08-07T23:54:05Z"
},
{
"checksumSHA1": "DmVjBB1a8uZzckWdWIu7pXWVTUc=",
"path": "github.com/docker/docker/api/types",
"revision": "202cf001dd7e6ca6c171aa52f454cc7b10f865bf",
"revisionTime": "2017-08-07T23:54:05Z"
},
{
"checksumSHA1": "jVJDbe0IcyjoKc2xbohwzQr+FF0=",
"path": "github.com/docker/docker/api/types/blkiodev",
"revision": "202cf001dd7e6ca6c171aa52f454cc7b10f865bf",
"revisionTime": "2017-08-07T23:54:05Z"
},
{
"checksumSHA1": "AeSC0BOu1uapkGqfSXtfVSpwJzs=",
"path": "github.com/docker/docker/api/types/container",
"revision": "202cf001dd7e6ca6c171aa52f454cc7b10f865bf",
"revisionTime": "2017-08-07T23:54:05Z"
},
{
"checksumSHA1": "XDP7i6sMYGnUKeFzgt+mFBJwjjw=",
"path": "github.com/docker/docker/api/types/events",
"revision": "202cf001dd7e6ca6c171aa52f454cc7b10f865bf",
"revisionTime": "2017-08-07T23:54:05Z"
},
{
"checksumSHA1": "J2OKngfI3vgswudr9PZVUFcRRu0=",
"path": "github.com/docker/docker/api/types/filters",
"revision": "202cf001dd7e6ca6c171aa52f454cc7b10f865bf",
"revisionTime": "2017-08-07T23:54:05Z"
},
{
"checksumSHA1": "yeB781yxPhnN6OXQ9/qSsyih3ek=",
"path": "github.com/docker/docker/api/types/image",
"revision": "202cf001dd7e6ca6c171aa52f454cc7b10f865bf",
"revisionTime": "2017-08-07T23:54:05Z"
},
{
"checksumSHA1": "euB/9WeNBA8r1siHY4seCkRBBng=",
"path": "github.com/docker/docker/api/types/mount",
"revision": "202cf001dd7e6ca6c171aa52f454cc7b10f865bf",
"revisionTime": "2017-08-07T23:54:05Z"
},
{
"checksumSHA1": "Gskp+nvbVe8Gk1xPLHylZvNmqTg=",
"path": "github.com/docker/docker/api/types/network",
"revision": "202cf001dd7e6ca6c171aa52f454cc7b10f865bf",
"revisionTime": "2017-08-07T23:54:05Z"
},
{
"checksumSHA1": "r2vWq7Uc3ExKzMqYgH0b4AKjLKY=",
"path": "github.com/docker/docker/api/types/registry",
"revision": "202cf001dd7e6ca6c171aa52f454cc7b10f865bf",
"revisionTime": "2017-08-07T23:54:05Z"
},
{
"checksumSHA1": "VTxWyFud/RedrpllGdQonVtGM/A=",
"path": "github.com/docker/docker/api/types/strslice",
"revision": "202cf001dd7e6ca6c171aa52f454cc7b10f865bf",
"revisionTime": "2017-08-07T23:54:05Z"
},
{
"checksumSHA1": "WNhyKx+2cJ5Gx3jdCeDr0J43F3Y=",
"path": "github.com/docker/docker/api/types/swarm",
"revision": "202cf001dd7e6ca6c171aa52f454cc7b10f865bf",
"revisionTime": "2017-08-07T23:54:05Z"
},
{
"checksumSHA1": "mi8EDCDjtrZEONRXPG7VHJosDwY=",
"path": "github.com/docker/docker/api/types/swarm/runtime",
"revision": "202cf001dd7e6ca6c171aa52f454cc7b10f865bf",
"revisionTime": "2017-08-07T23:54:05Z"
},
{
"checksumSHA1": "B7ZwKzrv3t3Vlox6/bYMHhMjsM8=",
"path": "github.com/docker/docker/api/types/time",
"revision": "202cf001dd7e6ca6c171aa52f454cc7b10f865bf",
"revisionTime": "2017-08-07T23:54:05Z"
},
{
"checksumSHA1": "uDPQ3nHsrvGQc9tg/J9OSC4N5dQ=",
"path": "github.com/docker/docker/api/types/versions",
"revision": "202cf001dd7e6ca6c171aa52f454cc7b10f865bf",
"revisionTime": "2017-08-07T23:54:05Z"
},
{
"checksumSHA1": "IBJy2zPEnYmcFJ3lM1eiRWnCxTA=",
"path": "github.com/docker/docker/api/types/volume",
"revision": "202cf001dd7e6ca6c171aa52f454cc7b10f865bf",
"revisionTime": "2017-08-07T23:54:05Z"
},
{
"checksumSHA1": "jsjQr20W2W6Gewf8Un3D8IKu2I8=",
"path": "github.com/docker/docker/pkg/ioutils",
"revision": "202cf001dd7e6ca6c171aa52f454cc7b10f865bf",
"revisionTime": "2017-08-07T23:54:05Z"
},
{
"checksumSHA1": "ndnAFCfsGC3upNQ6jAEwzxcurww=",
"path": "github.com/docker/docker/pkg/longpath",
"revision": "202cf001dd7e6ca6c171aa52f454cc7b10f865bf",
"revisionTime": "2017-08-07T23:54:05Z"
},
{
"checksumSHA1": "OftwMeqd/CPdOXNrCD99oKui8YE=",
"path": "github.com/docker/docker/pkg/mount",
"revision": "202cf001dd7e6ca6c171aa52f454cc7b10f865bf",
"revisionTime": "2017-08-07T23:54:05Z"
},
{
"checksumSHA1": "Aa2l7tUYFCEvHd+C//15fQnAfqQ=",
"path": "github.com/docker/docker/pkg/system",
"revision": "202cf001dd7e6ca6c171aa52f454cc7b10f865bf",
"revisionTime": "2017-08-07T23:54:05Z"
},
{
"checksumSHA1": "ZLK19eBuLoOIEE92Dwxx6qHHxDI=",
"path": "github.com/docker/docker/pkg/tlsconfig",
"revision": "202cf001dd7e6ca6c171aa52f454cc7b10f865bf",
"revisionTime": "2017-08-07T23:54:05Z"
},
{
"checksumSHA1": "JbiWTzH699Sqz25XmDlsARpMN9w=",
"path": "github.com/docker/go-connections/nat",
"revision": "3ede32e2033de7505e6500d6c868c2b9ed9f169d",
"revisionTime": "2017-06-23T20:36:43Z"
},
{
"checksumSHA1": "jUfDG3VQsA2UZHvvIXncgiddpYA=",
"path": "github.com/docker/go-connections/sockets",
"revision": "3ede32e2033de7505e6500d6c868c2b9ed9f169d",
"revisionTime": "2017-06-23T20:36:43Z"
},
{
"checksumSHA1": "c6lDGNwTm5mYq18IHP+lqYpk8xU=",
"path": "github.com/docker/go-connections/tlsconfig",
"revision": "3ede32e2033de7505e6500d6c868c2b9ed9f169d",
"revisionTime": "2017-06-23T20:36:43Z"
},
{
"checksumSHA1": "UmXGieuTJQOzJPspPJTVKKKMiUA=",
"path": "github.com/docker/go-units",
"revision": "0dadbb0345b35ec7ef35e228dabb8de89a65bf52",
"revisionTime": "2017-01-27T09:51:30Z"
},
{
"checksumSHA1": "sNAU9ojYVUhO6dVXey6T3JhRQpw=",
"path": "github.com/docker/libtrust",
"revision": "aabc10ec26b754e797f9028f4589c5b7bd90dc20",
"revisionTime": "2016-07-08T17:25:13Z"
},
{
"checksumSHA1": "/Y/IvLkd3hSX1h3PDMHkkCBwK+4=",
"path": "github.com/ethereum/go-ethereum/common",
"revision": "431cf2a1e453346bcc627ac1fb9df3950a6c3499",
"revisionTime": "2017-06-16T14:11:54Z"
},
{
"checksumSHA1": "NIN7nslnw4fUJlVcuxf5anvxAKQ=",
"path": "github.com/ethereum/go-ethereum/common/hexutil",
"revision": "431cf2a1e453346bcc627ac1fb9df3950a6c3499",
"revisionTime": "2017-06-16T14:11:54Z"
},
{
"checksumSHA1": "Hd1Y5DkzYULQzJlSgYv2w5SiEAo=",
"path": "github.com/ethereum/go-ethereum/common/math",
"revision": "431cf2a1e453346bcc627ac1fb9df3950a6c3499",
"revisionTime": "2017-06-16T14:11:54Z"
},
{
"checksumSHA1": "rofYNlEqnMen5Lg1N2+VcihuaIU=",
"path": "github.com/ethereum/go-ethereum/crypto",
"revision": "431cf2a1e453346bcc627ac1fb9df3950a6c3499",
"revisionTime": "2017-06-16T14:11:54Z"
},
{
"checksumSHA1": "VsqOiLFDRSDa67wPeqlxKJmE0XE=",
"path": "github.com/ethereum/go-ethereum/crypto/secp256k1",
"revision": "431cf2a1e453346bcc627ac1fb9df3950a6c3499",
"revisionTime": "2017-06-16T14:11:54Z"
},
{
"checksumSHA1": "yunX3AjO6JiMz0NSY/krvG3VWsk=",
"path": "github.com/ethereum/go-ethereum/crypto/sha3",
"revision": "431cf2a1e453346bcc627ac1fb9df3950a6c3499",
"revisionTime": "2017-06-16T14:11:54Z"
},
{
"checksumSHA1": "CXoPEShhsjec6AmfyC6h5Ym8j18=",
"path": "github.com/ethereum/go-ethereum/ethdb",
"revision": "693d9ccbfbbcf7c32d3ff9fd8a432941e129a4ac",
"revisionTime": "2017-06-20T16:26:09Z"
},
{
"checksumSHA1": "O56Cc6a0S2pK0oO9wZYO71xXeRM=",
"path": "github.com/ethereum/go-ethereum/event",
"revision": "693d9ccbfbbcf7c32d3ff9fd8a432941e129a4ac",
"revisionTime": "2017-06-20T16:26:09Z"
},
{
"checksumSHA1": "NbRntdNRuwam0wGGNJ6HrR83P0M=",
"path": "github.com/ethereum/go-ethereum/log",
"revision": "431cf2a1e453346bcc627ac1fb9df3950a6c3499",
"revisionTime": "2017-06-16T14:11:54Z"
},
{
"checksumSHA1": "LnUcnRFuZD3J8fsevk5kAJ+DlmU=",
"path": "github.com/ethereum/go-ethereum/metrics",
"revision": "693d9ccbfbbcf7c32d3ff9fd8a432941e129a4ac",
"revisionTime": "2017-06-20T16:26:09Z"
},
{
"checksumSHA1": "dsD/vq8IdIgaiJJTfRnwKjF35oE=",
"path": "github.com/ethereum/go-ethereum/params",
"revision": "431cf2a1e453346bcc627ac1fb9df3950a6c3499",
"revisionTime": "2017-06-16T14:11:54Z"
},
{
"checksumSHA1": "QARWkeJSFKOQF+/ryq6vqNmN8Q8=",
"path": "github.com/ethereum/go-ethereum/rlp",
"revision": "431cf2a1e453346bcc627ac1fb9df3950a6c3499",
"revisionTime": "2017-06-16T14:11:54Z"
},
{
"checksumSHA1": "320PHjE15MUavTek9x6qojwQf7s=",
"path": "github.com/ethereum/go-ethereum/rpc",
"revision": "693d9ccbfbbcf7c32d3ff9fd8a432941e129a4ac",
"revisionTime": "2017-06-20T16:26:09Z"
},
{
"checksumSHA1": "FdPv4Z5zhexDUEQDUDAnCQIKXnI=",
"path": "github.com/ethereum/go-ethereum/trie",
"revision": "431cf2a1e453346bcc627ac1fb9df3950a6c3499",
"revisionTime": "2017-06-16T14:11:54Z"
},
{
"checksumSHA1": "tZVtZ5Zm7Q9AtARo7xfYh28ELXI=",
"path": "github.com/getamis/go-ethereum/common",
"revision": "57750cbf051bb25fce769f3f4869eb216672f22f",
"revisionTime": "2017-06-19T05:54:01Z",
"version": "=feature/pbft",
"versionExact": "feature/pbft"
},
{
"checksumSHA1": "YvypTMzv0Ec9C9iwOCIRbBcl9XY=",
"path": "github.com/getamis/go-ethereum/common/hexutil",
"revision": "57750cbf051bb25fce769f3f4869eb216672f22f",
"revisionTime": "2017-06-19T05:54:01Z",
"version": "=feature/pbft",
"versionExact": "feature/pbft"
},
{
"checksumSHA1": "kSu3LWnvEXHTgSH9KB3Q/eGAHAk=",
"path": "github.com/getamis/go-ethereum/core",
"revision": "431cf2a1e453346bcc627ac1fb9df3950a6c3499",
"revisionTime": "2017-06-16T14:11:54Z"
},
{
"checksumSHA1": "xCsTCsFLsh4eJhcOXQfaIWQxtKo=",
"path": "github.com/getamis/go-ethereum/core/types",
"revision": "57750cbf051bb25fce769f3f4869eb216672f22f",
"revisionTime": "2017-06-19T05:54:01Z",
"version": "=feature/pbft",
"versionExact": "feature/pbft"
},
{
"checksumSHA1": "ovKUpgF7FRdoZ+7ojAtKlUcBn/Q=",
"path": "github.com/getamis/go-ethereum/params",
"revision": "431cf2a1e453346bcc627ac1fb9df3950a6c3499",
"revisionTime": "2017-06-16T14:11:54Z"
},
{
"checksumSHA1": "602c64HqPYM1v7dRjkFHEKxYinM=",
"path": "github.com/getamis/go-ethereum/rlp",
"revision": "57750cbf051bb25fce769f3f4869eb216672f22f",
"revisionTime": "2017-06-19T05:54:01Z",
"version": "=feature/pbft",
"versionExact": "feature/pbft"
},
{
"checksumSHA1": "VcLNrvCcnZuSnebTxMRyNtzY3ZY=",
"path": "github.com/go-stack/stack",
"revision": "7a2f19628aabfe68f0766b59e74d6315f8347d22",
"revisionTime": "2017-05-04T03:43:18Z"
},
{
"checksumSHA1": "haZp9uoO6N2UX4RwEtnlm9nR/AU=",
"path": "github.com/gogo/protobuf/proto",
"revision": "1c2b16bc280d6635de6c52fc1471ab962dc36ec9",
"revisionTime": "2017-08-08T05:47:17Z"
},
{
"checksumSHA1": "p/8vSviYF91gFflhrt5vkyksroo=",
"path": "github.com/golang/snappy",
"revision": "553a641470496b2327abcac10b36396bd98e45c9",
"revisionTime": "2017-02-15T23:32:05Z"
},
{
"checksumSHA1": "d9PxF1XQGLMJZRct2R8qVM/eYlE=",
"path": "github.com/hashicorp/golang-lru",
"revision": "0a025b7e63adc15a622f29b0b2c4c3848243bbf6",
"revisionTime": "2016-08-13T22:13:03Z"
},
{
"checksumSHA1": "9hffs0bAIU6CquiRhKQdzjHnKt0=",
"path": "github.com/hashicorp/golang-lru/simplelru",
"revision": "0a025b7e63adc15a622f29b0b2c4c3848243bbf6",
"revisionTime": "2016-08-13T22:13:03Z"
},
{
"checksumSHA1": "NBPHJLGwUSAVVpz1I++Rb0iAsGg=",
"path": "github.com/moby/moby/client",
"revision": "202cf001dd7e6ca6c171aa52f454cc7b10f865bf",
"revisionTime": "2017-08-07T23:54:05Z"
},
{
"checksumSHA1": "A6nZdZ1/lTOVINhIndyw2ZWN9JU=",
"path": "github.com/naoina/go-stringutil",
"revision": "6b638e95a32d0c1131db0e7fe83775cbea4a0d0b",
"revisionTime": "2015-11-18T23:44:43Z"
},
{
"checksumSHA1": "2w8GeWfyeUrrVyj5MitxcHhaO7s=",
"path": "github.com/naoina/toml",
"revision": "e6f5723bf2a66af014955e0888881314cf294129",
"revisionTime": "2017-04-28T05:41:52Z"
},
{
"checksumSHA1": "xZBlSMT5o/A+EDOro6KbfHZwSNc=",
"path": "github.com/naoina/toml/ast",
"revision": "e6f5723bf2a66af014955e0888881314cf294129",
"revisionTime": "2017-04-28T05:41:52Z"
},
{
"checksumSHA1": "OFNit1Qx2DdWhotfREKodDNUwCM=",
"path": "github.com/opencontainers/go-digest",
"revision": "279bed98673dd5bef374d3b6e4b09e2af76183bf",
"revisionTime": "2017-06-07T19:53:33Z"
},
{
"checksumSHA1": "ZGlIwSRjdLYCUII7JLE++N4w7Xc=",
"path": "github.com/opencontainers/image-spec/specs-go",
"revision": "710038243d857231f17df1c3f4c10850154bd1f7",
"revisionTime": "2017-07-31T13:49:31Z"
},
{
"checksumSHA1": "jdbXRRzeu0njLE9/nCEZG+Yg/Jk=",
"path": "github.com/opencontainers/image-spec/specs-go/v1",
"revision": "710038243d857231f17df1c3f4c10850154bd1f7",
"revisionTime": "2017-07-31T13:49:31Z"
},
{
"checksumSHA1": "rJab1YdNhQooDiBWNnt7TLWPyBU=",
"path": "github.com/pkg/errors",
"revision": "c605e284fe17294bda444b34710735b29d1a9d90",
"revisionTime": "2017-05-05T04:36:39Z"
},
{
"checksumSHA1": "KAzbLjI9MzW2tjfcAsK75lVRp6I=",
"path": "github.com/rcrowley/go-metrics",
"revision": "1f30fe9094a513ce4c700b9a54458bbb0c96996c",
"revisionTime": "2016-11-28T21:05:44Z"
},
{
"checksumSHA1": "q/d9nXRQYKEJ/EWn+5y6jL8rPGs=",
"path": "github.com/rcrowley/go-metrics/exp",
"revision": "1f30fe9094a513ce4c700b9a54458bbb0c96996c",
"revisionTime": "2016-11-28T21:05:44Z"
},
{
"checksumSHA1": "lZmPAbekxLbMFQirB/vzbdI+5O8=",
"path": "github.com/rs/cors",
"revision": "8dd4211afb5d08dbb39a533b9bb9e4b486351df6",
"revisionTime": "2017-06-08T16:51:55Z"
},
{
"checksumSHA1": "I5DMrLM0FpmvG81tAWZ3zoydBIo=",
"path": "github.com/sirupsen/logrus",
"revision": "181d419aa9e2223811b824e8f0b4af96f9ba9302",
"revisionTime": "2017-07-28T07:42:14Z"
},
{
"checksumSHA1": "HcDa/j4eMiKGYEo8qmrW+2NDFcE=",
"path": "github.com/syndtr/goleveldb/leveldb",
"revision": "8c81ea47d4c41a385645e133e15510fc6a2a74b4",
"revisionTime": "2017-04-09T01:48:31Z"
},
{
"checksumSHA1": "EKIow7XkgNdWvR/982ffIZxKG8Y=",
"path": "github.com/syndtr/goleveldb/leveldb/cache",
"revision": "8c81ea47d4c41a385645e133e15510fc6a2a74b4",
"revisionTime": "2017-04-09T01:48:31Z"
},
{
"checksumSHA1": "5KPgnvCPlR0ysDAqo6jApzRQ3tw=",
"path": "github.com/syndtr/goleveldb/leveldb/comparer",
"revision": "8c81ea47d4c41a385645e133e15510fc6a2a74b4",
"revisionTime": "2017-04-09T01:48:31Z"
},
{
"checksumSHA1": "1DRAxdlWzS4U0xKN/yQ/fdNN7f0=",
"path": "github.com/syndtr/goleveldb/leveldb/errors",
"revision": "8c81ea47d4c41a385645e133e15510fc6a2a74b4",
"revisionTime": "2017-04-09T01:48:31Z"
},
{
"checksumSHA1": "eqKeD6DS7eNCtxVYZEHHRKkyZrw=",
"path": "github.com/syndtr/goleveldb/leveldb/filter",
"revision": "8c81ea47d4c41a385645e133e15510fc6a2a74b4",
"revisionTime": "2017-04-09T01:48:31Z"
},
{
"checksumSHA1": "8dXuAVIsbtaMiGGuHjzGR6Ny/5c=",
"path": "github.com/syndtr/goleveldb/leveldb/iterator",
"revision": "8c81ea47d4c41a385645e133e15510fc6a2a74b4",
"revisionTime": "2017-04-09T01:48:31Z"
},
{
"checksumSHA1": "gJY7bRpELtO0PJpZXgPQ2BYFJ88=",
"path": "github.com/syndtr/goleveldb/leveldb/journal",
"revision": "8c81ea47d4c41a385645e133e15510fc6a2a74b4",
"revisionTime": "2017-04-09T01:48:31Z"
},
{
"checksumSHA1": "j+uaQ6DwJ50dkIdfMQu1TXdlQcY=",
"path": "github.com/syndtr/goleveldb/leveldb/memdb",
"revision": "8c81ea47d4c41a385645e133e15510fc6a2a74b4",
"revisionTime": "2017-04-09T01:48:31Z"
},
{
"checksumSHA1": "UmQeotV+m8/FduKEfLOhjdp18rs=",
"path": "github.com/syndtr/goleveldb/leveldb/opt",
"revision": "8c81ea47d4c41a385645e133e15510fc6a2a74b4",
"revisionTime": "2017-04-09T01:48:31Z"
},
{
"checksumSHA1": "tQ2AqXXAEy9icbZI9dLVdZGvWMw=",
"path": "github.com/syndtr/goleveldb/leveldb/storage",
"revision": "8c81ea47d4c41a385645e133e15510fc6a2a74b4",
"revisionTime": "2017-04-09T01:48:31Z"
},
{
"checksumSHA1": "gWFPMz8OQeul0t54RM66yMTX49g=",
"path": "github.com/syndtr/goleveldb/leveldb/table",
"revision": "8c81ea47d4c41a385645e133e15510fc6a2a74b4",
"revisionTime": "2017-04-09T01:48:31Z"
},
{
"checksumSHA1": "4zil8Gwg8VPkDn1YzlgCvtukJFU=",
"path": "github.com/syndtr/goleveldb/leveldb/util",
"revision": "8c81ea47d4c41a385645e133e15510fc6a2a74b4",
"revisionTime": "2017-04-09T01:48:31Z"
},
{
"checksumSHA1": "y/oIaxq2d3WPizRZfVjo8RCRYTU=",
"path": "golang.org/x/crypto/ripemd160",
"revision": "adbae1b6b6fb4b02448a0fc0dbbc9ba2b95b294d",
"revisionTime": "2017-06-19T06:03:41Z"
},
{
"checksumSHA1": "8wbHSD24FGJUJDS1F6wbtEt8z+w=",
"path": "golang.org/x/crypto/ssh/terminal",
"revision": "81db3efc71b576a04b145ca576c0bb9c0fb74d4f",
"revisionTime": "2017-07-29T20:27:48Z"
},
{
"checksumSHA1": "dr5+PfIRzXeN+l1VG+s0lea9qz8=",
"path": "golang.org/x/net/context",
"revision": "945ddfdd3bb885ce838728b0169bf94ae76970c8",
"revisionTime": "2017-07-20T22:15:25Z"
},
{
"checksumSHA1": "WHc3uByvGaMcnSoI21fhzYgbOgg=",
"path": "golang.org/x/net/context/ctxhttp",
"revision": "945ddfdd3bb885ce838728b0169bf94ae76970c8",
"revisionTime": "2017-07-20T22:15:25Z"
},
{
"checksumSHA1": "QEm/dePZ0lOnyOs+m22KjXfJ/IU=",
"path": "golang.org/x/net/proxy",
"revision": "945ddfdd3bb885ce838728b0169bf94ae76970c8",
"revisionTime": "2017-07-20T22:15:25Z"
},
{
"checksumSHA1": "7EZyXN0EmZLgGxZxK01IJua4c8o=",
"path": "golang.org/x/net/websocket",
"revision": "fe686d45ea04bc1bd4eff6a52865ce8757320325",
"revisionTime": "2017-06-18T05:18:41Z"
},
{
"checksumSHA1": "fwb6FNBUs0SOyUpUx5R31Xf22GY=",
"path": "golang.org/x/sys/unix",
"revision": "d8f5ea21b9295e315e612b4bcf4bedea93454d4d",
"revisionTime": "2017-08-03T09:04:06Z"
},
{
"checksumSHA1": "LkAsnLUlAZSg3lRYk7BEyNfog3A=",
"path": "golang.org/x/sys/windows",
"revision": "d8f5ea21b9295e315e612b4bcf4bedea93454d4d",
"revisionTime": "2017-08-03T09:04:06Z"
},
{
"checksumSHA1": "NGg7/qIJVUfXi7xnEyyDLocdi6Y=",
"path": "gopkg.in/fatih/set.v0",
"revision": "27c40922c40b43fe04554d8223a402af3ea333f3",
"revisionTime": "2014-12-10T08:48:24Z"
},
{
"checksumSHA1": "DQXNV0EivoHm4q+bkdahYXrjjfE=",
"path": "gopkg.in/karalabe/cookiejar.v2/collections/prque",
"revision": "8dcd6a7f4951f6ff3ee9cbb919a06d8925822e57",
"revisionTime": "2015-07-24T13:16:13Z"
},
{
"checksumSHA1": "0xgs8lwcWLUffemlj+SsgKlxvDU=",
"path": "gopkg.in/natefinch/npipe.v2",
"revision": "c1b8fa8bdccecb0b8db834ee0b92fdbcfa606dd6",
"revisionTime": "2016-06-21T03:49:01Z"
}
],
"rootPath": "github.com/getamis/istanbul-tools"
}