<commit_before>package nds

import (
	"appengine"
	"appengine/datastore"
	"appengine/memcache"
	"reflect"
	"sync"
)

// getMultiLimit is the App Engine datastore limit for the maximum number
// of entities that can be got by datastore.GetMulti at once.
// nds.GetMulti increases this limit by performing as many
// datastore.GetMulti as required concurrently and collating the results.
const getMultiLimit = 1000

// GetMulti works just like datastore.GetMulti except for two important
// advantages:
//
// 1) It removes the API limit of 1000 entities per request by
// calling the datastore as many times as required to fetch all the keys. It
// does this efficiently and concurrently.
//
// 2) If you use an appengine.Context created from this packages NewContext the
// GetMulti function will automatically invoke a caching mechanism identical
// to the Python ndb package. It also has the same strong cache consistency
// guarantees as the Python ndb package. It will check local memory for an
// entity, then check memcache and then the datastore. This has the potential
// to greatly speed up your entity access and reduce Google App Engine costs.
// Note that if you use GetMulti with this packages NewContext, you must do all
// your other datastore accesses with other methods from this package to ensure
// cache consistency.
//
// Increase the datastore timeout if you get datastore_v3: TIMEOUT errors when
// getting thousands of entities. You can do this using
// http://godoc.org/code.google.com/p/appengine-go/appengine#Timeout.
func GetMulti(c appengine.Context,
	keys []*datastore.Key, dst interface{}) error {

	v := reflect.ValueOf(dst)
	if err := checkMultiArgs(keys, v); err != nil {
		return err
	}

	if len(keys) == 0 {
		return nil
	}

	callCount := (len(keys)-1)/getMultiLimit + 1
	errs := make([]error, callCount)

	wg := sync.WaitGroup{}
	wg.Add(callCount)
	for i := 0; i < callCount; i++ {
		lo := i * getMultiLimit
		hi := (i + 1) * getMultiLimit
		if hi > len(keys) {
			hi = len(keys)
		}

        index := i
		keySlice := keys[lo:hi]
		dstSlice := v.Slice(lo, hi)

		go func() {
			// Default to datastore.GetMulti if we do not get a nds.context.
			if cc, ok := c.(*context); ok {
				errs[index] = getMulti(cc, keySlice, dstSlice)
			} else {
				errs[index] = datastore.GetMulti(c,
					keySlice, dstSlice.Interface())
			}
			wg.Done()
		}()
	}
	wg.Wait()

	// Quick escape if all errors are nil.
	errsNil := true
	for _, err := range errs {
		if err != nil {
			errsNil = false
		}
	}
	if errsNil {
		return nil
	}

	groupedErrs := make(appengine.MultiError, len(keys))
	for i, err := range errs {
		lo := i * getMultiLimit
		hi := (i + 1) * getMultiLimit
		if hi > len(keys) {
			hi = len(keys)
		}
		if me, ok := err.(appengine.MultiError); ok {
			copy(groupedErrs[lo:hi], me)
		} else if err != nil {
			return err
		}
	}
	return groupedErrs
}

// Get is a wrapper around GetMulti. Its return values are identical to
// datastore.Get.
func Get(c appengine.Context, key *datastore.Key, dst interface{}) error {
	err := GetMulti(c, []*datastore.Key{key}, []interface{}{dst})
	if me, ok := err.(appengine.MultiError); ok {
		return me[0]
	}
	return err
}

type getMultiState struct {
	keys      []*datastore.Key
	vals      reflect.Value
	errs      appengine.MultiError
	errsExist bool

	keyIndex map[*datastore.Key]int

	missingMemoryKeys map[*datastore.Key]bool

	missingMemcacheKeys map[*datastore.Key]bool

	// These are keys someone else has locked.
	lockedMemcacheKeys map[*datastore.Key]bool

	// These are keys we have locked.
	lockedMemcacheItems map[string]*memcache.Item

	missingDatastoreKeys map[*datastore.Key]bool
}

func newGetMultiState(keys []*datastore.Key,
	vals reflect.Value) *getMultiState {
	gs := &getMultiState{
		keys: keys,
		vals: vals,
		errs: make(appengine.MultiError, vals.Len()),

		keyIndex: make(map[*datastore.Key]int),

		missingMemoryKeys: make(map[*datastore.Key]bool),

		missingMemcacheKeys: make(map[*datastore.Key]bool),
		lockedMemcacheKeys:  make(map[*datastore.Key]bool),

		missingDatastoreKeys: make(map[*datastore.Key]bool),
	}

	for i, key := range keys {
		gs.keyIndex[key] = i
	}
	return gs
}

// getMulti attempts to get entities from local cache, memcache, then the
// datastore. It also tries to replenish each cache in turn if an entity is
// available.
// The not so obvious part is replenishing memcache with the datastore to
// ensure we don't write stale values.
//
// Here's how it works assuming there is nothing in local cache. (Note this is
// taken form Python ndb):
// Firstly get as many entities from memcache as possible. The returned values
// can be in one of three states: No entity, locked value or the acutal entity.
//
// Actual entity case:
// If the value from memcache is an actual entity then replensish the local
// cache and return that entity to the caller.
//
// Locked entity case:
// If the value is locked then just ignore that entity and go to the datastore
// to see if it exists.
//
// No entity case:
// If no entity is returned from memcache then do the following things to ensure
// we don't accidentally update memcache with stale values.
// 1) Lock that entity in memcache by setting memcacheLock on that entities key.
//    Note that the lock timeout is 32 seconds to cater for a datastore edge
//    case which I currently can't quite remember.
// 2) Immediately get that entity back from memcache ensuring the compare and
//    swap ID is set.
// 3) Get the entity from the datastore.
// 4) Set the entity in memcache using compare and swap. If this succeeds then
//    we are guaranteed to have the latest value in memcache. If it fails due
//    to a CAS failure then there must have been a concurrent write to
//    memcache and now the memcache for that key is out of action for 32
//    seconds.
//
// Note that within a transaction, much of this functionality is lost to ensure
// datastore consistency.
//
// dst argument must be a slice.
func getMulti(cc *context, keys []*datastore.Key, dst reflect.Value) error {

	gs := newGetMultiState(keys, dst)

	if err := loadMemory(cc, gs); err != nil {
		return err
	}

	if !cc.inTransaction {
		if err := loadMemcache(cc, gs); err != nil {
			return err
		}

		// Lock memcache while we get new data from the datastore.
		if err := lockMemcache(cc, gs); err != nil {
			return err
		}
	}

	if err := loadDatastore(cc, gs); err != nil {
		return err
	}

	if !cc.inTransaction {
		if err := saveMemcache(cc, gs); err != nil {
			return err
		}
	}

	if err := saveMemory(cc, gs); err != nil {
		return err
	}

	if gs.errsExist {
		return gs.errs
	}
	return nil
}

func loadMemory(cc *context, gs *getMultiState) error {
	cc.RLock()
	defer cc.RUnlock()

	for index, key := range gs.keys {
		if pl, ok := cc.cache[key.Encode()]; ok {
			if len(pl) == 0 {
				gs.errs[index] = datastore.ErrNoSuchEntity
				gs.errsExist = true
			} else {
				if err := setValue(index, gs.vals, &pl); err != nil {
					return err
				}
			}
		} else {
			gs.missingMemoryKeys[key] = true
		}
	}
	return nil
}

func loadMemcache(cc *context, gs *getMultiState) error {

	memcacheKeys := make([]string, 0, len(gs.missingMemoryKeys))
	for key := range gs.missingMemoryKeys {
		memcacheKeys = append(memcacheKeys, createMemcacheKey(key))
	}

	items, err := memcache.GetMulti(cc, memcacheKeys)
	if err != nil {
		return err
	}
	for key := range gs.missingMemoryKeys {
		memcacheKey := createMemcacheKey(key)

		if item, ok := items[memcacheKey]; ok {
			if isItemLocked(item) {
				gs.lockedMemcacheKeys[key] = true
			} else {
				pl, err := decodePropertyList(item.Value)
				if err != nil {
					return err
				}
				index := gs.keyIndex[key]
				if err := setValue(index, gs.vals, &pl); err != nil {
					return err
				}
			}
		} else {
			gs.missingMemcacheKeys[key] = true
		}
	}
	return nil
}

func loadDatastore(c appengine.Context, gs *getMultiState) error {

	keys := make([]*datastore.Key, 0,
		len(gs.missingMemoryKeys)+len(gs.lockedMemcacheKeys))
	for key := range gs.missingMemoryKeys {
		keys = append(keys, key)
	}
	for key := range gs.lockedMemcacheKeys {
		keys = append(keys, key)
	}
	pls := make([]datastore.PropertyList,
		len(gs.missingMemoryKeys)+len(gs.lockedMemcacheKeys))

	if err := datastore.GetMulti(c, keys, pls); err == nil {
		for i, key := range keys {
			index := gs.keyIndex[key]
			if err := setValue(index, gs.vals, &pls[i]); err != nil {
				return err
			}
		}
	} else if me, ok := err.(appengine.MultiError); ok {
		for i, err := range me {
			if err == nil {
				index := gs.keyIndex[keys[i]]
				if err := setValue(index, gs.vals, &pls[i]); err != nil {
					return err
				}
			} else if err == datastore.ErrNoSuchEntity {
				index := gs.keyIndex[keys[i]]
				gs.errs[index] = datastore.ErrNoSuchEntity
				gs.errsExist = true
				gs.missingDatastoreKeys[keys[i]] = true
			} else {
				return err
			}
		}
	} else {
		return err
	}
	return nil
}

func saveMemcache(c appengine.Context, gs *getMultiState) error {

	items := []*memcache.Item{}
	for key := range gs.missingMemcacheKeys {
		memcacheKey := createMemcacheKey(key)
		if !gs.missingDatastoreKeys[key] {
			index := gs.keyIndex[key]
			s := addrValue(gs.vals.Index(index))
			pl := datastore.PropertyList{}
			if err := saveStruct(s.Interface(), &pl); err != nil {
				return err
			}

			data, err := encodePropertyList(pl)
			if err != nil {
				return err
			}
			if item, ok := gs.lockedMemcacheItems[memcacheKey]; ok {
				item.Value = data
				item.Flags = 0
				items = append(items, item)
			} else {
				item := &memcache.Item{
					Key:   memcacheKey,
					Value: data,
				}
				items = append(items, item)
			}
		}
	}
	if err := memcache.CompareAndSwapMulti(
		c, items); err == memcache.ErrCASConflict {
		return nil
	} else if err == memcache.ErrNotStored {
		return nil
	} else {
		return err
	}
}

func saveMemory(cc *context, gs *getMultiState) error {
	cc.Lock()
	defer cc.Unlock()
	for i, err := range gs.errs {
		if err == nil {
			s := addrValue(gs.vals.Index(i))
			pl := datastore.PropertyList{}
			if err := saveStruct(s.Interface(), &pl); err != nil {
				return err
			}
			cc.cache[gs.keys[i].Encode()] = pl
		}
	}
	return nil
}

func isItemLocked(item *memcache.Item) bool {
	return item.Flags == memcacheLock
}

func lockMemcache(c appengine.Context, gs *getMultiState) error {

	lockItems := make([]*memcache.Item, 0, len(gs.missingMemcacheKeys))
	memcacheKeys := make([]string, 0, len(gs.missingMemcacheKeys))
	for key := range gs.missingMemcacheKeys {
		memcacheKey := createMemcacheKey(key)
		memcacheKeys = append(memcacheKeys, memcacheKey)

		item := &memcache.Item{
			Key:        memcacheKey,
			Flags:      memcacheLock,
			Value:      []byte{},
			Expiration: memcacheLockTime,
		}
		lockItems = append(lockItems, item)
	}
	if err := memcache.SetMulti(c, lockItems); err != nil {
		return err
	}

	items, err := memcache.GetMulti(c, memcacheKeys)
	if err != nil {
		return err
	}
	gs.lockedMemcacheItems = items

	return nil
}
<commit_msg>Run through with gofmt.<commit_after>package nds

import (
	"appengine"
	"appengine/datastore"
	"appengine/memcache"
	"reflect"
	"sync"
)

// getMultiLimit is the App Engine datastore limit for the maximum number
// of entities that can be got by datastore.GetMulti at once.
// nds.GetMulti increases this limit by performing as many
// datastore.GetMulti as required concurrently and collating the results.
const getMultiLimit = 1000

// GetMulti works just like datastore.GetMulti except for two important
// advantages:
//
// 1) It removes the API limit of 1000 entities per request by
// calling the datastore as many times as required to fetch all the keys. It
// does this efficiently and concurrently.
//
// 2) If you use an appengine.Context created from this packages NewContext the
// GetMulti function will automatically invoke a caching mechanism identical
// to the Python ndb package. It also has the same strong cache consistency
// guarantees as the Python ndb package. It will check local memory for an
// entity, then check memcache and then the datastore. This has the potential
// to greatly speed up your entity access and reduce Google App Engine costs.
// Note that if you use GetMulti with this packages NewContext, you must do all
// your other datastore accesses with other methods from this package to ensure
// cache consistency.
//
// Increase the datastore timeout if you get datastore_v3: TIMEOUT errors when
// getting thousands of entities. You can do this using
// http://godoc.org/code.google.com/p/appengine-go/appengine#Timeout.
func GetMulti(c appengine.Context,
	keys []*datastore.Key, dst interface{}) error {

	v := reflect.ValueOf(dst)
	if err := checkMultiArgs(keys, v); err != nil {
		return err
	}

	if len(keys) == 0 {
		return nil
	}

	callCount := (len(keys)-1)/getMultiLimit + 1
	errs := make([]error, callCount)

	wg := sync.WaitGroup{}
	wg.Add(callCount)
	for i := 0; i < callCount; i++ {
		lo := i * getMultiLimit
		hi := (i + 1) * getMultiLimit
		if hi > len(keys) {
			hi = len(keys)
		}

		index := i
		keySlice := keys[lo:hi]
		dstSlice := v.Slice(lo, hi)

		go func() {
			// Default to datastore.GetMulti if we do not get a nds.context.
			if cc, ok := c.(*context); ok {
				errs[index] = getMulti(cc, keySlice, dstSlice)
			} else {
				errs[index] = datastore.GetMulti(c,
					keySlice, dstSlice.Interface())
			}
			wg.Done()
		}()
	}
	wg.Wait()

	// Quick escape if all errors are nil.
	errsNil := true
	for _, err := range errs {
		if err != nil {
			errsNil = false
		}
	}
	if errsNil {
		return nil
	}

	groupedErrs := make(appengine.MultiError, len(keys))
	for i, err := range errs {
		lo := i * getMultiLimit
		hi := (i + 1) * getMultiLimit
		if hi > len(keys) {
			hi = len(keys)
		}
		if me, ok := err.(appengine.MultiError); ok {
			copy(groupedErrs[lo:hi], me)
		} else if err != nil {
			return err
		}
	}
	return groupedErrs
}

// Get is a wrapper around GetMulti. Its return values are identical to
// datastore.Get.
func Get(c appengine.Context, key *datastore.Key, dst interface{}) error {
	err := GetMulti(c, []*datastore.Key{key}, []interface{}{dst})
	if me, ok := err.(appengine.MultiError); ok {
		return me[0]
	}
	return err
}

type getMultiState struct {
	keys      []*datastore.Key
	vals      reflect.Value
	errs      appengine.MultiError
	errsExist bool

	keyIndex map[*datastore.Key]int

	missingMemoryKeys map[*datastore.Key]bool

	missingMemcacheKeys map[*datastore.Key]bool

	// These are keys someone else has locked.
	lockedMemcacheKeys map[*datastore.Key]bool

	// These are keys we have locked.
	lockedMemcacheItems map[string]*memcache.Item

	missingDatastoreKeys map[*datastore.Key]bool
}

func newGetMultiState(keys []*datastore.Key,
	vals reflect.Value) *getMultiState {
	gs := &getMultiState{
		keys: keys,
		vals: vals,
		errs: make(appengine.MultiError, vals.Len()),

		keyIndex: make(map[*datastore.Key]int),

		missingMemoryKeys: make(map[*datastore.Key]bool),

		missingMemcacheKeys: make(map[*datastore.Key]bool),
		lockedMemcacheKeys:  make(map[*datastore.Key]bool),

		missingDatastoreKeys: make(map[*datastore.Key]bool),
	}

	for i, key := range keys {
		gs.keyIndex[key] = i
	}
	return gs
}

// getMulti attempts to get entities from local cache, memcache, then the
// datastore. It also tries to replenish each cache in turn if an entity is
// available.
// The not so obvious part is replenishing memcache with the datastore to
// ensure we don't write stale values.
//
// Here's how it works assuming there is nothing in local cache. (Note this is
// taken form Python ndb):
// Firstly get as many entities from memcache as possible. The returned values
// can be in one of three states: No entity, locked value or the acutal entity.
//
// Actual entity case:
// If the value from memcache is an actual entity then replensish the local
// cache and return that entity to the caller.
//
// Locked entity case:
// If the value is locked then just ignore that entity and go to the datastore
// to see if it exists.
//
// No entity case:
// If no entity is returned from memcache then do the following things to ensure
// we don't accidentally update memcache with stale values.
// 1) Lock that entity in memcache by setting memcacheLock on that entities key.
//    Note that the lock timeout is 32 seconds to cater for a datastore edge
//    case which I currently can't quite remember.
// 2) Immediately get that entity back from memcache ensuring the compare and
//    swap ID is set.
// 3) Get the entity from the datastore.
// 4) Set the entity in memcache using compare and swap. If this succeeds then
//    we are guaranteed to have the latest value in memcache. If it fails due
//    to a CAS failure then there must have been a concurrent write to
//    memcache and now the memcache for that key is out of action for 32
//    seconds.
//
// Note that within a transaction, much of this functionality is lost to ensure
// datastore consistency.
//
// dst argument must be a slice.
func getMulti(cc *context, keys []*datastore.Key, dst reflect.Value) error {

	gs := newGetMultiState(keys, dst)

	if err := loadMemory(cc, gs); err != nil {
		return err
	}

	if !cc.inTransaction {
		if err := loadMemcache(cc, gs); err != nil {
			return err
		}

		// Lock memcache while we get new data from the datastore.
		if err := lockMemcache(cc, gs); err != nil {
			return err
		}
	}

	if err := loadDatastore(cc, gs); err != nil {
		return err
	}

	if !cc.inTransaction {
		if err := saveMemcache(cc, gs); err != nil {
			return err
		}
	}

	if err := saveMemory(cc, gs); err != nil {
		return err
	}

	if gs.errsExist {
		return gs.errs
	}
	return nil
}

func loadMemory(cc *context, gs *getMultiState) error {
	cc.RLock()
	defer cc.RUnlock()

	for index, key := range gs.keys {
		if pl, ok := cc.cache[key.Encode()]; ok {
			if len(pl) == 0 {
				gs.errs[index] = datastore.ErrNoSuchEntity
				gs.errsExist = true
			} else {
				if err := setValue(index, gs.vals, &pl); err != nil {
					return err
				}
			}
		} else {
			gs.missingMemoryKeys[key] = true
		}
	}
	return nil
}

func loadMemcache(cc *context, gs *getMultiState) error {

	memcacheKeys := make([]string, 0, len(gs.missingMemoryKeys))
	for key := range gs.missingMemoryKeys {
		memcacheKeys = append(memcacheKeys, createMemcacheKey(key))
	}

	items, err := memcache.GetMulti(cc, memcacheKeys)
	if err != nil {
		return err
	}
	for key := range gs.missingMemoryKeys {
		memcacheKey := createMemcacheKey(key)

		if item, ok := items[memcacheKey]; ok {
			if isItemLocked(item) {
				gs.lockedMemcacheKeys[key] = true
			} else {
				pl, err := decodePropertyList(item.Value)
				if err != nil {
					return err
				}
				index := gs.keyIndex[key]
				if err := setValue(index, gs.vals, &pl); err != nil {
					return err
				}
			}
		} else {
			gs.missingMemcacheKeys[key] = true
		}
	}
	return nil
}

func loadDatastore(c appengine.Context, gs *getMultiState) error {

	keys := make([]*datastore.Key, 0,
		len(gs.missingMemoryKeys)+len(gs.lockedMemcacheKeys))
	for key := range gs.missingMemoryKeys {
		keys = append(keys, key)
	}
	for key := range gs.lockedMemcacheKeys {
		keys = append(keys, key)
	}
	pls := make([]datastore.PropertyList,
		len(gs.missingMemoryKeys)+len(gs.lockedMemcacheKeys))

	if err := datastore.GetMulti(c, keys, pls); err == nil {
		for i, key := range keys {
			index := gs.keyIndex[key]
			if err := setValue(index, gs.vals, &pls[i]); err != nil {
				return err
			}
		}
	} else if me, ok := err.(appengine.MultiError); ok {
		for i, err := range me {
			if err == nil {
				index := gs.keyIndex[keys[i]]
				if err := setValue(index, gs.vals, &pls[i]); err != nil {
					return err
				}
			} else if err == datastore.ErrNoSuchEntity {
				index := gs.keyIndex[keys[i]]
				gs.errs[index] = datastore.ErrNoSuchEntity
				gs.errsExist = true
				gs.missingDatastoreKeys[keys[i]] = true
			} else {
				return err
			}
		}
	} else {
		return err
	}
	return nil
}

func saveMemcache(c appengine.Context, gs *getMultiState) error {

	items := []*memcache.Item{}
	for key := range gs.missingMemcacheKeys {
		memcacheKey := createMemcacheKey(key)
		if !gs.missingDatastoreKeys[key] {
			index := gs.keyIndex[key]
			s := addrValue(gs.vals.Index(index))
			pl := datastore.PropertyList{}
			if err := saveStruct(s.Interface(), &pl); err != nil {
				return err
			}

			data, err := encodePropertyList(pl)
			if err != nil {
				return err
			}
			if item, ok := gs.lockedMemcacheItems[memcacheKey]; ok {
				item.Value = data
				item.Flags = 0
				items = append(items, item)
			} else {
				item := &memcache.Item{
					Key:   memcacheKey,
					Value: data,
				}
				items = append(items, item)
			}
		}
	}
	if err := memcache.CompareAndSwapMulti(
		c, items); err == memcache.ErrCASConflict {
		return nil
	} else if err == memcache.ErrNotStored {
		return nil
	} else {
		return err
	}
}

func saveMemory(cc *context, gs *getMultiState) error {
	cc.Lock()
	defer cc.Unlock()
	for i, err := range gs.errs {
		if err == nil {
			s := addrValue(gs.vals.Index(i))
			pl := datastore.PropertyList{}
			if err := saveStruct(s.Interface(), &pl); err != nil {
				return err
			}
			cc.cache[gs.keys[i].Encode()] = pl
		}
	}
	return nil
}

func isItemLocked(item *memcache.Item) bool {
	return item.Flags == memcacheLock
}

func lockMemcache(c appengine.Context, gs *getMultiState) error {

	lockItems := make([]*memcache.Item, 0, len(gs.missingMemcacheKeys))
	memcacheKeys := make([]string, 0, len(gs.missingMemcacheKeys))
	for key := range gs.missingMemcacheKeys {
		memcacheKey := createMemcacheKey(key)
		memcacheKeys = append(memcacheKeys, memcacheKey)

		item := &memcache.Item{
			Key:        memcacheKey,
			Flags:      memcacheLock,
			Value:      []byte{},
			Expiration: memcacheLockTime,
		}
		lockItems = append(lockItems, item)
	}
	if err := memcache.SetMulti(c, lockItems); err != nil {
		return err
	}

	items, err := memcache.GetMulti(c, memcacheKeys)
	if err != nil {
		return err
	}
	gs.lockedMemcacheItems = items

	return nil
}
<|endoftext|>


<commit_before>// Copyright 2015 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package main

import (
	"crypto/sha256"
	"encoding/hex"
	"flag"
	"fmt"
	"os"

	"github.com/FactomProject/factom"
)

func get(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		man("get")
		return
	}

	switch args[0] {
	case "head":
		getHead()
	case "dblock":
		getDBlock(args)
	case "chain":
		getChain(args)
	case "eblock":
		getEBlock(args)
	case "entry":
		getEntry(args)
	case "chainid":
		getChainId(args)
	default:
		man("get")
	}
}

func getHead() {
	head, err := factom.GetDBlockHead()
	if err != nil {
		errorln(err)
		return
	}
	fmt.Println(head.KeyMR)
}

// We expect each element to be its own part in a chain ID
func getChainId(args []string) {
	if len(args) < 2 {
		fmt.Printf("No Chain Specification provided.  See help")
	}
	sum := sha256.New()
	fmt.Println("The chain components:")
	for i, str := range args {
		if i > 0 {
			fmt.Println("    ", str)
			x := sha256.Sum256([]byte(str))
			sum.Write(x[:])
		}
	}
	chainId := sum.Sum(nil)
	fmt.Println("produce the ChainID:")

	fmt.Println("    ", hex.EncodeToString(chainId))
}

func getDBlock(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		man("getDBlock")
		return
	}

	keymr := args[0]
	dblock, err := factom.GetDBlock(keymr)
	if err != nil {
		errorln(err)
		return
	}

	fmt.Println("PrevBlockKeyMR:", dblock.Header.PrevBlockKeyMR)
	fmt.Println("Timestamp:", dblock.Header.Timestamp)
	fmt.Println("SequenceNumber:", dblock.Header.SequenceNumber)

	for _, v := range dblock.EntryBlockList {
		fmt.Println("EntryBlock {")
		fmt.Println("	ChainID", v.ChainID)
		fmt.Println("	KeyMR", v.KeyMR)
		fmt.Println("}")
	}
}

func getChain(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		man("getChain")
		return
	}

	chainid := args[0]
	chain, err := factom.GetChainHead(chainid)
	if err != nil {
		errorln(err)
		return
	}

	fmt.Println(chain.ChainHead)
}

func getEBlock(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		man("getEBlock")
		return
	}

	keymr := args[0]
	eblock, err := factom.GetEBlock(keymr)
	if err != nil {
		errorln(err)
		return
	}

	fmt.Println("BlockSequenceNumber:", eblock.Header.BlockSequenceNumber)
	fmt.Println("ChainID:", eblock.Header.ChainID)
	fmt.Println("PrevKeyMR:", eblock.Header.PrevKeyMR)
	fmt.Println("Timestamp:", eblock.Header.Timestamp)

	for _, v := range eblock.EntryList {
		fmt.Println("EBEntry {")
		fmt.Println("	Timestamp", v.Timestamp)
		fmt.Println("	EntryHash", v.EntryHash)
		fmt.Println("}")
	}
}

func getEntry(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		man("getEntry")
		return
	}

	hash := args[0]
	entry, err := factom.GetEntry(hash)
	if err != nil {
		errorln(err)
		return
	}

	fmt.Println("ChainID:", entry.ChainID)
	for _, v := range entry.ExtIDs {
		fmt.Println("ExtID:", v)
	}

	data, _ := hex.DecodeString(entry.Content)
	fmt.Println("Content:")
	fmt.Println(string(data))
}
<commit_msg>Added call to get the current directory block height<commit_after>// Copyright 2015 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package main

import (
	"crypto/sha256"
	"encoding/hex"
	"flag"
	"fmt"
	"os"

	"github.com/FactomProject/factom"
)

func get(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		man("get")
		return
	}

	switch args[0] {
	case "head":
		getHead()
	case "height":
		getHeight()
	case "dblock":
		getDBlock(args)
	case "chain":
		getChain(args)
	case "eblock":
		getEBlock(args)
	case "entry":
		getEntry(args)
	case "chainid":
		getChainId(args)
	default:
		man("get")
	}
}

func getHead() {
	head, err := factom.GetDBlockHead()
	if err != nil {
		errorln(err)
		return
	}
	fmt.Println(head.KeyMR)
}

func getHeight() {
	height, err := factom.GetDBlockHeight()
	if err != nil {
		errorln(err)
		return
	}
	fmt.Printf("DirectoryBlockHeight=%d\n",height)
}

// We expect each element to be its own part in a chain ID
func getChainId(args []string) {
	if len(args) < 2 {
		fmt.Printf("No Chain Specification provided.  See help")
	}
	sum := sha256.New()
	fmt.Println("The chain components:")
	for i, str := range args {
		if i > 0 {
			fmt.Println("    ", str)
			x := sha256.Sum256([]byte(str))
			sum.Write(x[:])
		}
	}
	chainId := sum.Sum(nil)
	fmt.Println("produce the ChainID:")

	fmt.Println("    ", hex.EncodeToString(chainId))
}

func getDBlock(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		man("getDBlock")
		return
	}

	keymr := args[0]
	dblock, err := factom.GetDBlock(keymr)
	if err != nil {
		errorln(err)
		return
	}

	fmt.Println("PrevBlockKeyMR:", dblock.Header.PrevBlockKeyMR)
	fmt.Println("Timestamp:", dblock.Header.Timestamp)
	fmt.Println("SequenceNumber:", dblock.Header.SequenceNumber)

	for _, v := range dblock.EntryBlockList {
		fmt.Println("EntryBlock {")
		fmt.Println("	ChainID", v.ChainID)
		fmt.Println("	KeyMR", v.KeyMR)
		fmt.Println("}")
	}
}

func getChain(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		man("getChain")
		return
	}

	chainid := args[0]
	chain, err := factom.GetChainHead(chainid)
	if err != nil {
		errorln(err)
		return
	}

	fmt.Println(chain.ChainHead)
}

func getEBlock(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		man("getEBlock")
		return
	}

	keymr := args[0]
	eblock, err := factom.GetEBlock(keymr)
	if err != nil {
		errorln(err)
		return
	}

	fmt.Println("BlockSequenceNumber:", eblock.Header.BlockSequenceNumber)
	fmt.Println("ChainID:", eblock.Header.ChainID)
	fmt.Println("PrevKeyMR:", eblock.Header.PrevKeyMR)
	fmt.Println("Timestamp:", eblock.Header.Timestamp)

	for _, v := range eblock.EntryList {
		fmt.Println("EBEntry {")
		fmt.Println("	Timestamp", v.Timestamp)
		fmt.Println("	EntryHash", v.EntryHash)
		fmt.Println("}")
	}
}

func getEntry(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		man("getEntry")
		return
	}

	hash := args[0]
	entry, err := factom.GetEntry(hash)
	if err != nil {
		errorln(err)
		return
	}

	fmt.Println("ChainID:", entry.ChainID)
	for _, v := range entry.ExtIDs {
		fmt.Println("ExtID:", v)
	}

	data, _ := hex.DecodeString(entry.Content)
	fmt.Println("Content:")
	fmt.Println(string(data))
}
<|endoftext|>


<commit_before>// Dict and StringDict type
//
// The idea is that most dicts just have strings for keys so we use
// the simpler StringDict and promote it into a Dict when necessary

package py

var StringDictType = NewType("dict", "dict() -> new empty dictionary\ndict(mapping) -> new dictionary initialized from a mapping object's\n    (key, value) pairs\ndict(iterable) -> new dictionary initialized as if via:\n    d = {}\n    for k, v in iterable:\n        d[k] = v\ndict(**kwargs) -> new dictionary initialized with the name=value pairs\n    in the keyword argument list.  For example:  dict(one=1, two=2)")

var DictType = NewType("dict", "dict() -> new empty dictionary\ndict(mapping) -> new dictionary initialized from a mapping object's\n    (key, value) pairs\ndict(iterable) -> new dictionary initialized as if via:\n    d = {}\n    for k, v in iterable:\n        d[k] = v\ndict(**kwargs) -> new dictionary initialized with the name=value pairs\n    in the keyword argument list.  For example:  dict(one=1, two=2)")

// String to object dictionary
//
// Used for variables etc where the keys can only be strings
type StringDict map[string]Object

// Type of this StringDict object
func (o StringDict) Type() *Type {
	return StringDictType
}

// Make a new dictionary
func NewStringDict() StringDict {
	return make(StringDict)
}

// Make a new dictionary with reservation for n entries
func NewStringDictSized(n int) StringDict {
	return make(StringDict, n)
}

// Copy a dictionary
func (d StringDict) Copy() StringDict {
	e := make(StringDict, len(d))
	for k, v := range d {
		e[k] = v
	}
	return e
}

func (d StringDict) M__getitem__(key Object) Object {
	str, ok := key.(String)
	if ok {
		res, ok := d[string(str)]
		if ok {
			return res
		}
	}
	panic(ExceptionNewf(KeyError, "%v", key))
}

func (d StringDict) M__setitem__(key, value Object) Object {
	str, ok := key.(String)
	if !ok {
		panic("FIXME can only have string keys!")
	}
	d[string(str)] = value
	return None
}
<commit_msg>py: dict: implement __eq__ and __ne__<commit_after>// Dict and StringDict type
//
// The idea is that most dicts just have strings for keys so we use
// the simpler StringDict and promote it into a Dict when necessary

package py

var StringDictType = NewType("dict", "dict() -> new empty dictionary\ndict(mapping) -> new dictionary initialized from a mapping object's\n    (key, value) pairs\ndict(iterable) -> new dictionary initialized as if via:\n    d = {}\n    for k, v in iterable:\n        d[k] = v\ndict(**kwargs) -> new dictionary initialized with the name=value pairs\n    in the keyword argument list.  For example:  dict(one=1, two=2)")

var DictType = NewType("dict", "dict() -> new empty dictionary\ndict(mapping) -> new dictionary initialized from a mapping object's\n    (key, value) pairs\ndict(iterable) -> new dictionary initialized as if via:\n    d = {}\n    for k, v in iterable:\n        d[k] = v\ndict(**kwargs) -> new dictionary initialized with the name=value pairs\n    in the keyword argument list.  For example:  dict(one=1, two=2)")

// String to object dictionary
//
// Used for variables etc where the keys can only be strings
type StringDict map[string]Object

// Type of this StringDict object
func (o StringDict) Type() *Type {
	return StringDictType
}

// Make a new dictionary
func NewStringDict() StringDict {
	return make(StringDict)
}

// Make a new dictionary with reservation for n entries
func NewStringDictSized(n int) StringDict {
	return make(StringDict, n)
}

// Copy a dictionary
func (d StringDict) Copy() StringDict {
	e := make(StringDict, len(d))
	for k, v := range d {
		e[k] = v
	}
	return e
}

func (d StringDict) M__getitem__(key Object) Object {
	str, ok := key.(String)
	if ok {
		res, ok := d[string(str)]
		if ok {
			return res
		}
	}
	panic(ExceptionNewf(KeyError, "%v", key))
}

func (d StringDict) M__setitem__(key, value Object) Object {
	str, ok := key.(String)
	if !ok {
		panic("FIXME can only have string keys!")
	}
	d[string(str)] = value
	return None
}

func (a StringDict) M__eq__(other Object) Object {
	b, ok := other.(StringDict)
	if !ok {
		return NotImplemented
	}
	if len(a) != len(b) {
		return False
	}
	for k, av := range a {
		bv, ok := b[k]
		if !ok {
			return False
		}
		if Eq(av, bv) == False {
			return False
		}
	}
	return True
}

func (a StringDict) M__ne__(other Object) Object {
	if a.M__eq__(other) == True {
		return False
	}
	return True
}
<|endoftext|>


<commit_before>package gmx

import (
	"encoding/json"
	"io"
	"log"
	"net"
	"sync"
)

const GMX_VERSION = 0

var (
	r = &registry{
		entries: make(map[string]func() interface{}),
	}

	localsocket net.Listener
)

func init() {
	s, err := localSocket()
	if err != nil {
		log.Printf("gmx: unable to open local socket: %v", err)
		return
	}

	// register the registries keys for discovery
	Publish("keys", func() interface{} {
		return r.keys()
	})
	go serve(s, r)
	localsocket = s
}

// Publish registers the function f with the supplied key.
func Publish(key string, f func() interface{}) {
	r.register(key, f)
}

// Exit cleanly shuts down gmx.
// This is useful as a defer'ed function in main(), so the local gmx socket is cleaned up
func Exit() {
	if localsocket != nil {
		localsocket.Close()
		localsocket = nil
	}
}

func serve(l net.Listener, r *registry) {
	defer l.Close()
	for {
		c, err := l.Accept()
		if err != nil {
			return
		}
		go handle(c, r)
	}
}

func handle(nc net.Conn, reg *registry) {
	// conn makes it easier to send and receive json
	type conn struct {
		net.Conn
		*json.Encoder
		*json.Decoder
	}
	c := conn{
		nc,
		json.NewEncoder(nc),
		json.NewDecoder(nc),
	}
	defer c.Close()
	for {
		var keys []string
		if err := c.Decode(&keys); err != nil {
			if err != io.EOF {
				log.Printf("gmx: client %v sent invalid json request: %v", c.RemoteAddr(), err)
			}
			return
		}
		var result = make(map[string]interface{})
		for _, key := range keys {
			if f, ok := reg.value(key); ok {
				// invoke the function for key and store the result
				result[key] = f()
			}
		}
		if err := c.Encode(result); err != nil {
			log.Printf("gmx: could not send response to client %v: %v", c.RemoteAddr(), err)
			return
		}
	}
}

type registry struct {
	sync.Mutex // protects entries from concurrent mutation
	entries    map[string]func() interface{}
}

func (r *registry) register(key string, f func() interface{}) {
	r.Lock()
	r.entries[key] = f
	r.Unlock()
}

func (r *registry) value(key string) (func() interface{}, bool) {
	r.Lock()
	f, ok := r.entries[key]
	r.Unlock()
	return f, ok
}

func (r *registry) keys() []string {
	r.Lock()
	var k = make([]string, len(r.entries))
	for e := range r.entries {
		k = append(k, e)
	}
	r.Unlock()
	return k
}
<commit_msg>add an Unpublish function<commit_after>package gmx

import (
	"encoding/json"
	"io"
	"log"
	"net"
	"sync"
)

const GMX_VERSION = 0

var (
	r = &registry{
		entries: make(map[string]func() interface{}),
	}

	localsocket net.Listener
)

func init() {
	s, err := localSocket()
	if err != nil {
		log.Printf("gmx: unable to open local socket: %v", err)
		return
	}

	// register the registries keys for discovery
	Publish("keys", func() interface{} {
		return r.keys()
	})
	go serve(s, r)
	localsocket = s
}

// Publish registers the function f with the supplied key.
func Publish(key string, f func() interface{}) {
	r.register(key, f)
}

// Unpublish unregisters the key. If key is not currently registered it does nothing.
func Unpublish(key string) {
	r.unregister(key)
}

// Exit cleanly shuts down gmx.
// This is useful as a defer'ed function in main(), so the local gmx socket is cleaned up
func Exit() {
	if localsocket != nil {
		localsocket.Close()
		localsocket = nil
	}
}

func serve(l net.Listener, r *registry) {
	defer l.Close()
	for {
		c, err := l.Accept()
		if err != nil {
			return
		}
		go handle(c, r)
	}
}

func handle(nc net.Conn, reg *registry) {
	// conn makes it easier to send and receive json
	type conn struct {
		net.Conn
		*json.Encoder
		*json.Decoder
	}
	c := conn{
		nc,
		json.NewEncoder(nc),
		json.NewDecoder(nc),
	}
	defer c.Close()
	for {
		var keys []string
		if err := c.Decode(&keys); err != nil {
			if err != io.EOF {
				log.Printf("gmx: client %v sent invalid json request: %v", c.RemoteAddr(), err)
			}
			return
		}
		var result = make(map[string]interface{})
		for _, key := range keys {
			if f, ok := reg.value(key); ok {
				// invoke the function for key and store the result
				result[key] = f()
			}
		}
		if err := c.Encode(result); err != nil {
			log.Printf("gmx: could not send response to client %v: %v", c.RemoteAddr(), err)
			return
		}
	}
}

type registry struct {
	sync.Mutex // protects entries from concurrent mutation
	entries    map[string]func() interface{}
}

func (r *registry) register(key string, f func() interface{}) {
	r.Lock()
	r.entries[key] = f
	r.Unlock()
}

func (r *registry) unregister(key string) {
	r.Lock()
	delete(r.entries, key)
	r.Unlock()
}

func (r *registry) value(key string) (func() interface{}, bool) {
	r.Lock()
	f, ok := r.entries[key]
	r.Unlock()
	return f, ok
}

func (r *registry) keys() []string {
	r.Lock()
	var k = make([]string, len(r.entries))
	for e := range r.entries {
		k = append(k, e)
	}
	r.Unlock()
	return k
}
<|endoftext|>


<commit_before>//
// Copyright 2015 Rakuten Marketing LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

package gol

import (
	"fmt"
	"io"
)

// http://tools.ietf.org/html/rfc5424
const (
	// Emergency system is unusable
	Emergency = iota
	// Alert action must be taken immediately
	Alert
	// Critical critical conditions
	Critical
	// Error error conditions
	Error
	// Warning warning conditions
	Warning
	// Notice normal but significant condition
	Notice
	// Info informational messages
	Info
	// Debug debug-level messages
	Debug
)

// LogMessage is a log message.
type LogMessage map[string]interface{}

// LogFilter the interface a log filter needs to implement.
type LogFilter interface {
	Filter(*LogMessage) (bool, error)
}

// LogFormatter the interface a log message formatter needs to implement.
type LogFormatter interface {
	Format(*LogMessage) (string, error)
}

// Logger the interface a log message consumer must implement.
type Logger interface {
	Filter() LogFilter
	Formatter() LogFormatter
	Writer() io.Writer
	Send(*LogMessage) error
	SetFilter(LogFilter) error
	SetFormatter(LogFormatter) error
	SetWriter(io.Writer) error
}

// BaseLogger base implementation of a logger.
type BaseLogger struct {
	filter   LogFilter
	formatter   LogFormatter
	writer io.Writer
}

func (l *BaseLogger) Filter() LogFilter {
	return l.filter
}

func (l *BaseLogger) Formatter() LogFormatter {
	return l.formatter
}

func (l *BaseLogger) Writer() io.Writer {
	return l.writer
}

func (l *BaseLogger) Send(m *LogMessage) (err error)  {
	if m == nil {
		return fmt.Errorf("")
	}

	var filter bool
	if filter, err = l.filter.Filter(m); err != nil || filter {
		return
	}

	var msg string
	if msg, err = l.formatter.Format(m); err != nil {
		return
	}

	_, err = l.writer.Write([]byte(msg))
	return
}

func (l *BaseLogger) SetFilter(f LogFilter) (err error) {
	if f == nil {
		return fmt.Errorf("")
	}

	l.filter = f
	return
}

func (l *BaseLogger) SetFormatter(f LogFormatter) (err error)  {
	if f == nil {
		return fmt.Errorf("")
	}

	l.formatter = f
	return
}

func (l *BaseLogger) SetWriter(w io.Writer) (err error)  {
	if w == nil {
		return fmt.Errorf("")
	}

	l.writer = w
	return
}

var _ Logger = (*BaseLogger)(nil)
<commit_msg>moved message and severity levels to other files; added BaseLogger.<commit_after>//
// Copyright 2015 Rakuten Marketing LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

package gol

import (
	"fmt"
	"io"
)

// LogFilter the interface a log filter needs to implement.
type LogFilter interface {
	Filter(*LogMessage) (bool, error)
}

// LogFormatter the interface a log message formatter needs to implement.
type LogFormatter interface {
	Format(*LogMessage) (string, error)
}

// Logger the interface a log message consumer must implement.
type Logger interface {
	Filter() LogFilter
	Formatter() LogFormatter
	Writer() io.Writer
	Send(*LogMessage) error
	SetFilter(LogFilter) error
	SetFormatter(LogFormatter) error
	SetWriter(io.Writer) error
}

// BaseLogger base implementation of a logger.
type BaseLogger struct {
	filter   LogFilter
	formatter   LogFormatter
	writer io.Writer
}

// NewBaseLogger creates and initializes a BaseLogger struct.
func NewBaseLogger(f LogFilter, fmt LogFormatter, w io.Writer) (l Logger) {
	return &BaseLogger{
		filter: f,
		formatter: fmt,
		writer: w,
	}
}

// Filter returns the logger filter.
func (l *BaseLogger) Filter() LogFilter {
	return l.filter
}

// Formatter returns the logger formatter.
func (l *BaseLogger) Formatter() LogFormatter {
	return l.formatter
}

// Writer returns the logger writer.
func (l *BaseLogger) Writer() io.Writer {
	return l.writer
}

// Send process log message.
func (l *BaseLogger) Send(m *LogMessage) (err error)  {
	if m == nil {
		return fmt.Errorf("")
	}

	var filter bool
	if filter, err = l.filter.Filter(m); err != nil || filter {
		return
	}

	var msg string
	if msg, err = l.formatter.Format(m); err != nil {
		return
	}

	_, err = l.writer.Write([]byte(msg))
	return
}

// SetFilter sets the logger filter.
func (l *BaseLogger) SetFilter(f LogFilter) (err error) {
	if f == nil {
		return fmt.Errorf("")
	}

	l.filter = f
	return
}

// SetFormatter sets the logger formatter.
func (l *BaseLogger) SetFormatter(f LogFormatter) (err error)  {
	if f == nil {
		return fmt.Errorf("")
	}

	l.formatter = f
	return
}

// SetWriter sets the logger writer.
func (l *BaseLogger) SetWriter(w io.Writer) (err error)  {
	if w == nil {
		return fmt.Errorf("")
	}

	l.writer = w
	return
}

var _ Logger = (*BaseLogger)(nil)
<|endoftext|>


<commit_before>// Copyright (c) 2013 GPMGo Members. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

// gpm(Go Package Manager) is a Go package manage tool for search, install, update and share packages in Go.

package main

import (
	"encoding/json"
	"fmt"
	"io"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"runtime"
	"strings"
	"sync"
	"text/template"
	"unicode"
	"unicode/utf8"

	"github.com/BurntSushi/toml"
	"github.com/GPMGo/gpm/doc"
	"github.com/GPMGo/gpm/utils"
)

var (
	config  tomlConfig
	appPath string // Application path.
)

var (
	localNodes   []*doc.Node
	localBundles []*doc.Bundle
)

// Use for i18n, key is prompt code, value is corresponding message.
var promptMsg map[string]string

type tomlConfig struct {
	Title, Version string
	Lang           string `toml:"user_language"`
	AutoBackup     bool   `toml:"auto_backup"`
	Account        account
	AutoEnable     flagEnable `toml:"auto_enable"`
}

type flagEnable struct {
	Build, Install, Search, Check []string
}

type account struct {
	Username, Password  string
	Github_Access_Token string `toml:"github_access_token"`
}

// A Command is an implementation of a go command
// like go build or go fix.
type Command struct {
	// Run runs the command.
	// The args are the arguments after the command name.
	Run func(cmd *Command, args []string)

	// UsageLine is the one-line usage message.
	// The first word in the line is taken to be the command name.
	UsageLine string

	// Short is the short description shown in the 'go help' output.
	Short string

	// Long is the long message shown in the 'go help <this-command>' output.
	Long string

	// Flag is a set of flags specific to this command.
	Flags map[string]bool
}

// Name returns the command's name: the first word in the usage line.
func (c *Command) Name() string {
	name := c.UsageLine
	i := strings.Index(name, " ")
	if i >= 0 {
		name = name[:i]
	}
	return name
}

func (c *Command) Usage() {
	fmt.Fprintf(os.Stderr, "usage: %s\n\n", c.UsageLine)
	fmt.Fprintf(os.Stderr, "%s\n", strings.TrimSpace(c.Long))
	os.Exit(2)
}

// Runnable reports whether the command can be run; otherwise
// it is a documentation pseudo-command such as importpath.
func (c *Command) Runnable() bool {
	return c.Run != nil
}

// Commands lists the available commands and help topics.
// The order here is the order in which they are printed by 'gpm help'.
var commands = []*Command{
	cmdBuild,
	cmdSearch,
	cmdInstall,
	cmdRemove,
	cmdCheck,
}

// getAppPath returns application execute path for current process.
func getAppPath() bool {
	// Look up executable in PATH variable.
	appPath, _ = exec.LookPath(path.Base(os.Args[0]))
	// Check if run under $GOPATH/bin
	if len(appPath) == 0 {
		fmt.Printf("ERROR: getAppPath -> Unable to indicate current execute path.\n")
		return false
	}

	if runtime.GOOS == "windows" {
		// Replace all '\' to '/'.
		appPath = strings.Replace(filepath.Dir(appPath), "\\", "/", -1) + "/"
	}

	doc.SetAppConfig(appPath, config.AutoBackup)
	return true
}

// loadPromptMsg loads prompt messages according to user language.
func loadPromptMsg(lang string) bool {
	promptMsg = make(map[string]string)

	// Load prompt messages.
	f, err := os.Open(appPath + "i18n/" + lang + "/prompt.txt")
	if err != nil {
		fmt.Printf("ERROR: loadUsage -> Fail to load prompt messages[ %s ]\n", err)
		return false
	}
	defer f.Close()

	// Read prompt messages.
	fi, _ := f.Stat()
	promptBytes := make([]byte, fi.Size())
	f.Read(promptBytes)
	promptStrs := strings.Split(string(promptBytes), "\n")
	for _, p := range promptStrs {
		i := strings.Index(p, "=")
		if i > -1 {
			promptMsg[p[:i]] = p[i+1:]
		}
	}
	return true
}

// loadUsage loads usage according to user language.
func loadUsage(lang string) bool {
	if !loadPromptMsg(lang) {
		return false
	}

	// Load main usage.
	f, err := os.Open(appPath + "i18n/" + lang + "/usage.tpl")
	if err != nil {
		fmt.Printf(fmt.Sprintf("ERROR: loadUsage -> %s\n", promptMsg["LoadCommandUsage"]), "main", err)
		return false
	}
	defer f.Close()

	// Read main usages.
	fi, _ := f.Stat()
	usageBytes := make([]byte, fi.Size())
	f.Read(usageBytes)
	usageTemplate = string(usageBytes)

	// Load command usage.
	for _, cmd := range commands {
		f, err := os.Open(appPath + "i18n/" + lang + "/usage_" + cmd.Name() + ".txt")
		if err != nil {
			fmt.Printf(fmt.Sprintf("ERROR: loadUsage -> %s\n", promptMsg["LoadCommandUsage"]), cmd.Name(), err)
			return false
		}
		defer f.Close()

		// Read usage.
		fi, _ := f.Stat()
		usageBytes := make([]byte, fi.Size())
		f.Read(usageBytes)
		usages := strings.Split(string(usageBytes), "|||")
		if len(usages) < 2 {
			fmt.Printf(
				fmt.Sprintf("ERROR: loadUsage -> %s\n", promptMsg["ReadCoammndUsage"]), cmd.Name())
			return false
		}
		cmd.Short = usages[0]
		cmd.Long = usages[1]
	}

	return true
}

// loadLocalNodes loads nodes information from local file system.
func loadLocalNodes() bool {
	if !utils.IsExist(appPath + "data/nodes.json") {
		os.MkdirAll(appPath+"data/", os.ModePerm)
	} else {
		fr, err := os.Open(appPath + "data/nodes.json")
		if err != nil {
			fmt.Printf(fmt.Sprintf("ERROR: loadLocalNodes -> %s\n", promptMsg["LoadLocalData"]), err)
			return false
		}
		defer fr.Close()

		err = json.NewDecoder(fr).Decode(&localNodes)
		if err != nil && err != io.EOF {
			fmt.Printf(fmt.Sprintf("ERROR: loadLocalNodes -> %s\n", promptMsg["ParseJSON"]), err)
			return false
		}
	}
	return true
}

// loadLocalBundles loads bundles from local file system.
func loadLocalBundles() bool {
	// Find all bundles.
	dir, err := os.Open(appPath + "repo/bundles/")
	if err != nil {
		fmt.Printf(fmt.Sprintf("ERROR: loadLocalBundles -> %s\n", promptMsg["OpenFile"]), err)
		return false
	}
	defer dir.Close()

	fis, err := dir.Readdir(0)
	if err != nil {
		fmt.Printf(fmt.Sprintf("ERROR: loadLocalBundles -> %s\n", promptMsg["OpenFile"]), err)
		return false
	}

	for _, fi := range fis {
		// In case this folder contains unexpected directories.
		if !fi.IsDir() && strings.HasSuffix(fi.Name(), ".json") {
			fr, err := os.Open(appPath + "repo/bundles/" + fi.Name())
			if err != nil {
				fmt.Printf(fmt.Sprintf("ERROR: loadLocalBundles -> %s\n", promptMsg["OpenFile"]), err)
				return false
			}

			bundle := new(doc.Bundle)
			err = json.NewDecoder(fr).Decode(bundle)
			fr.Close()
			if err != nil && err != io.EOF {
				fmt.Printf(fmt.Sprintf("ERROR: loadLocalBundles -> %s\n", promptMsg["ParseJSON"]), err)
				return false
			}

			// Make sure bundle name is not empty.
			if len(bundle.Name) == 0 {
				bundle.Name = fi.Name()[:strings.Index(fi.Name(), ".")]
			}

			localBundles = append(localBundles, bundle)
		}
	}
	return true
}

// We don't use init() to initialize
// bacause we need to get execute path in runtime.
func initialize() bool {
	// Try to have highest performance.
	runtime.GOMAXPROCS(runtime.NumCPU())

	// Get application execute path.
	if !getAppPath() {
		return false
	}

	// Load configuration.
	if _, err := toml.DecodeFile(appPath+"conf/gpm.toml", &config); err != nil {
		fmt.Printf("initialize -> Fail to load configuration[ %s ]\n", err)
		return false
	}

	// Set github.com access token.
	doc.SetGithubCredentials(config.Account.Github_Access_Token)

	// Load usages by language.
	if !loadUsage(config.Lang) {
		return false
	}

	// Create bundle and snapshot directories.
	os.MkdirAll(appPath+"repo/bundles/", os.ModePerm)
	os.MkdirAll(appPath+"repo/snapshots/", os.ModePerm)
	// Create local tarball directories.
	os.MkdirAll(appPath+"repo/tarballs/", os.ModePerm)

	// Initialize local data.
	if !loadLocalNodes() || !loadLocalBundles() {
		return false
	}

	return true
}

func main() {
	// Initialization.
	if !initialize() {
		return
	}

	// Check length of arguments.
	args := os.Args[1:]
	if len(args) < 1 {
		usage()
		return
	}

	// Show help documentation.
	if args[0] == "help" {
		help(args[1:])
		return
	}

	// Check commands and run.
	for _, cmd := range commands {
		if cmd.Name() == args[0] && cmd.Run != nil {
			cmd.Run(cmd, args[1:])
			exit()
			return
		}
	}

	// Uknown commands.
	fmt.Fprintf(os.Stderr, fmt.Sprintf("%s\n", promptMsg["UnknownCommand"]), args[0])
	setExitStatus(2)
	exit()
}

var exitStatus = 0
var exitMu sync.Mutex

func setExitStatus(n int) {
	exitMu.Lock()
	if exitStatus < n {
		exitStatus = n
	}
	exitMu.Unlock()
}

var usageTemplate string
var helpTemplate = `{{if .Runnable}}usage: gpm {{.UsageLine}}

{{end}}{{.Long | trim}}
`

// tmpl executes the given template text on data, writing the result to w.
func tmpl(w io.Writer, text string, data interface{}) {
	t := template.New("top")
	t.Funcs(template.FuncMap{"trim": strings.TrimSpace, "capitalize": capitalize})
	template.Must(t.Parse(text))
	if err := t.Execute(w, data); err != nil {
		panic(err)
	}
}

func capitalize(s string) string {
	if s == "" {
		return s
	}
	r, n := utf8.DecodeRuneInString(s)
	return string(unicode.ToTitle(r)) + s[n:]
}

func printUsage(w io.Writer) {
	tmpl(w, usageTemplate, commands)
}

func usage() {
	printUsage(os.Stderr)
	os.Exit(2)
}

// help implements the 'help' command.
func help(args []string) {
	if len(args) == 0 {
		printUsage(os.Stdout)
		// not exit 2: succeeded at 'gpm help'.
		return
	}
	if len(args) != 1 {
		fmt.Fprintf(os.Stderr, "usage: gpm help command\n\nToo many arguments given.\n")
		os.Exit(2) // failed at 'gpm help'
	}

	arg := args[0]

	for _, cmd := range commands {
		if cmd.Name() == arg {
			tmpl(os.Stdout, helpTemplate, cmd)
			// not exit 2: succeeded at 'go help cmd'.
			return
		}
	}

	fmt.Fprintf(os.Stderr, "Unknown help topic %#q.  Run 'gpm help'.\n", arg)
	os.Exit(2) // failed at 'go help cmd'
}

var atexitFuncs []func()

func atexit(f func()) {
	atexitFuncs = append(atexitFuncs, f)
}

func exit() {
	for _, f := range atexitFuncs {
		f()
	}
	os.Exit(exitStatus)
}

// executeCommand executes commands in command line.
func executeCommand(cmd string, args []string) {
	cmdExec := exec.Command(cmd, args...)
	stdout, err := cmdExec.StdoutPipe()
	if err != nil {
		fmt.Println(err)
	}
	stderr, err := cmdExec.StderrPipe()
	if err != nil {
		fmt.Println(err)
	}
	err = cmdExec.Start()
	if err != nil {
		fmt.Println(err)
	}
	go io.Copy(os.Stdout, stdout)
	go io.Copy(os.Stderr, stderr)
	cmdExec.Wait()
}
<commit_msg>update<commit_after>// Copyright (c) 2013 GPMGo Members. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

// gpm(Go Package Manager) is a Go package manage tool for search, install, update and share packages in Go.

package main

import (
	"encoding/json"
	"fmt"
	"io"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"runtime"
	"strings"
	"sync"
	"text/template"
	"unicode"
	"unicode/utf8"

	"github.com/BurntSushi/toml"
	"github.com/GPMGo/gpm/doc"
	"github.com/GPMGo/gpm/utils"
)

var (
	config  tomlConfig
	appPath string // Application path.
)

var (
	localNodes   []*doc.Node
	localBundles []*doc.Bundle
)

// Use for i18n, key is prompt code, value is corresponding message.
var promptMsg map[string]string

type tomlConfig struct {
	Title, Version string
	Lang           string `toml:"user_language"`
	AutoBackup     bool   `toml:"auto_backup"`
	Account        account
	AutoEnable     flagEnable `toml:"auto_enable"`
}

type flagEnable struct {
	Build, Install, Search, Check []string
}

type account struct {
	Username, Password  string
	Github_Access_Token string `toml:"github_access_token"`
}

// A Command is an implementation of a go command
// like go build or go fix.
type Command struct {
	// Run runs the command.
	// The args are the arguments after the command name.
	Run func(cmd *Command, args []string)

	// UsageLine is the one-line usage message.
	// The first word in the line is taken to be the command name.
	UsageLine string

	// Short is the short description shown in the 'go help' output.
	Short string

	// Long is the long message shown in the 'go help <this-command>' output.
	Long string

	// Flag is a set of flags specific to this command.
	Flags map[string]bool
}

// Name returns the command's name: the first word in the usage line.
func (c *Command) Name() string {
	name := c.UsageLine
	i := strings.Index(name, " ")
	if i >= 0 {
		name = name[:i]
	}
	return name
}

func (c *Command) Usage() {
	fmt.Fprintf(os.Stderr, "usage: %s\n\n", c.UsageLine)
	fmt.Fprintf(os.Stderr, "%s\n", strings.TrimSpace(c.Long))
	os.Exit(2)
}

// Runnable reports whether the command can be run; otherwise
// it is a documentation pseudo-command such as importpath.
func (c *Command) Runnable() bool {
	return c.Run != nil
}

// Commands lists the available commands and help topics.
// The order here is the order in which they are printed by 'gpm help'.
var commands = []*Command{
	cmdBuild,
	cmdSearch,
	cmdInstall,
	cmdRemove,
	cmdCheck,
}

// getAppPath returns application execute path for current process.
func getAppPath() bool {
	// Look up executable in PATH variable.
	appPath, _ = exec.LookPath(path.Base(os.Args[0]))
	// Check if run under $GOPATH/bin

	if len(appPath) == 0 {
		fmt.Printf("ERROR: getAppPath -> Unable to indicate current execute path.\n")
		return false
	}

	appPath += "/"
	if runtime.GOOS == "windows" {
		// Replace all '\' to '/'.
		appPath = strings.Replace(filepath.Dir(appPath), "\\", "/", -1)
	}

	doc.SetAppConfig(appPath, config.AutoBackup)
	return true
}

// loadPromptMsg loads prompt messages according to user language.
func loadPromptMsg(lang string) bool {
	promptMsg = make(map[string]string)

	// Load prompt messages.
	f, err := os.Open(appPath + "i18n/" + lang + "/prompt.txt")
	if err != nil {
		fmt.Printf("ERROR: loadUsage -> Fail to load prompt messages[ %s ]\n", err)
		return false
	}
	defer f.Close()

	// Read prompt messages.
	fi, _ := f.Stat()
	promptBytes := make([]byte, fi.Size())
	f.Read(promptBytes)
	promptStrs := strings.Split(string(promptBytes), "\n")
	for _, p := range promptStrs {
		i := strings.Index(p, "=")
		if i > -1 {
			promptMsg[p[:i]] = p[i+1:]
		}
	}
	return true
}

// loadUsage loads usage according to user language.
func loadUsage(lang string) bool {
	if !loadPromptMsg(lang) {
		return false
	}

	// Load main usage.
	f, err := os.Open(appPath + "i18n/" + lang + "/usage.tpl")
	if err != nil {
		fmt.Printf(fmt.Sprintf("ERROR: loadUsage -> %s\n", promptMsg["LoadCommandUsage"]), "main", err)
		return false
	}
	defer f.Close()

	// Read main usages.
	fi, _ := f.Stat()
	usageBytes := make([]byte, fi.Size())
	f.Read(usageBytes)
	usageTemplate = string(usageBytes)

	// Load command usage.
	for _, cmd := range commands {
		f, err := os.Open(appPath + "i18n/" + lang + "/usage_" + cmd.Name() + ".txt")
		if err != nil {
			fmt.Printf(fmt.Sprintf("ERROR: loadUsage -> %s\n", promptMsg["LoadCommandUsage"]), cmd.Name(), err)
			return false
		}
		defer f.Close()

		// Read usage.
		fi, _ := f.Stat()
		usageBytes := make([]byte, fi.Size())
		f.Read(usageBytes)
		usages := strings.Split(string(usageBytes), "|||")
		if len(usages) < 2 {
			fmt.Printf(
				fmt.Sprintf("ERROR: loadUsage -> %s\n", promptMsg["ReadCoammndUsage"]), cmd.Name())
			return false
		}
		cmd.Short = usages[0]
		cmd.Long = usages[1]
	}

	return true
}

// loadLocalNodes loads nodes information from local file system.
func loadLocalNodes() bool {
	if !utils.IsExist(appPath + "data/nodes.json") {
		os.MkdirAll(appPath+"data/", os.ModePerm)
	} else {
		fr, err := os.Open(appPath + "data/nodes.json")
		if err != nil {
			fmt.Printf(fmt.Sprintf("ERROR: loadLocalNodes -> %s\n", promptMsg["LoadLocalData"]), err)
			return false
		}
		defer fr.Close()

		err = json.NewDecoder(fr).Decode(&localNodes)
		if err != nil && err != io.EOF {
			fmt.Printf(fmt.Sprintf("ERROR: loadLocalNodes -> %s\n", promptMsg["ParseJSON"]), err)
			return false
		}
	}
	return true
}

// loadLocalBundles loads bundles from local file system.
func loadLocalBundles() bool {
	// Find all bundles.
	dir, err := os.Open(appPath + "repo/bundles/")
	if err != nil {
		fmt.Printf(fmt.Sprintf("ERROR: loadLocalBundles -> %s\n", promptMsg["OpenFile"]), err)
		return false
	}
	defer dir.Close()

	fis, err := dir.Readdir(0)
	if err != nil {
		fmt.Printf(fmt.Sprintf("ERROR: loadLocalBundles -> %s\n", promptMsg["OpenFile"]), err)
		return false
	}

	for _, fi := range fis {
		// In case this folder contains unexpected directories.
		if !fi.IsDir() && strings.HasSuffix(fi.Name(), ".json") {
			fr, err := os.Open(appPath + "repo/bundles/" + fi.Name())
			if err != nil {
				fmt.Printf(fmt.Sprintf("ERROR: loadLocalBundles -> %s\n", promptMsg["OpenFile"]), err)
				return false
			}

			bundle := new(doc.Bundle)
			err = json.NewDecoder(fr).Decode(bundle)
			fr.Close()
			if err != nil && err != io.EOF {
				fmt.Printf(fmt.Sprintf("ERROR: loadLocalBundles -> %s\n", promptMsg["ParseJSON"]), err)
				return false
			}

			// Make sure bundle name is not empty.
			if len(bundle.Name) == 0 {
				bundle.Name = fi.Name()[:strings.Index(fi.Name(), ".")]
			}

			localBundles = append(localBundles, bundle)
		}
	}
	return true
}

// We don't use init() to initialize
// bacause we need to get execute path in runtime.
func initialize() bool {
	// Try to have highest performance.
	runtime.GOMAXPROCS(runtime.NumCPU())

	// Get application execute path.
	if !getAppPath() {
		return false
	}

	// Load configuration.
	if _, err := toml.DecodeFile(appPath+"conf/gpm.toml", &config); err != nil {
		fmt.Printf("initialize -> Fail to load configuration[ %s ]\n", err)
		return false
	}

	// Set github.com access token.
	doc.SetGithubCredentials(config.Account.Github_Access_Token)

	// Load usages by language.
	if !loadUsage(config.Lang) {
		return false
	}

	// Create bundle and snapshot directories.
	os.MkdirAll(appPath+"repo/bundles/", os.ModePerm)
	os.MkdirAll(appPath+"repo/snapshots/", os.ModePerm)
	// Create local tarball directories.
	os.MkdirAll(appPath+"repo/tarballs/", os.ModePerm)

	// Initialize local data.
	if !loadLocalNodes() || !loadLocalBundles() {
		return false
	}

	return true
}

func main() {
	// Initialization.
	if !initialize() {
		return
	}

	// Check length of arguments.
	args := os.Args[1:]
	if len(args) < 1 {
		usage()
		return
	}

	// Show help documentation.
	if args[0] == "help" {
		help(args[1:])
		return
	}

	// Check commands and run.
	for _, cmd := range commands {
		if cmd.Name() == args[0] && cmd.Run != nil {
			cmd.Run(cmd, args[1:])
			exit()
			return
		}
	}

	// Uknown commands.
	fmt.Fprintf(os.Stderr, fmt.Sprintf("%s\n", promptMsg["UnknownCommand"]), args[0])
	setExitStatus(2)
	exit()
}

var exitStatus = 0
var exitMu sync.Mutex

func setExitStatus(n int) {
	exitMu.Lock()
	if exitStatus < n {
		exitStatus = n
	}
	exitMu.Unlock()
}

var usageTemplate string
var helpTemplate = `{{if .Runnable}}usage: gpm {{.UsageLine}}

{{end}}{{.Long | trim}}
`

// tmpl executes the given template text on data, writing the result to w.
func tmpl(w io.Writer, text string, data interface{}) {
	t := template.New("top")
	t.Funcs(template.FuncMap{"trim": strings.TrimSpace, "capitalize": capitalize})
	template.Must(t.Parse(text))
	if err := t.Execute(w, data); err != nil {
		panic(err)
	}
}

func capitalize(s string) string {
	if s == "" {
		return s
	}
	r, n := utf8.DecodeRuneInString(s)
	return string(unicode.ToTitle(r)) + s[n:]
}

func printUsage(w io.Writer) {
	tmpl(w, usageTemplate, commands)
}

func usage() {
	printUsage(os.Stderr)
	os.Exit(2)
}

// help implements the 'help' command.
func help(args []string) {
	if len(args) == 0 {
		printUsage(os.Stdout)
		// not exit 2: succeeded at 'gpm help'.
		return
	}
	if len(args) != 1 {
		fmt.Fprintf(os.Stderr, "usage: gpm help command\n\nToo many arguments given.\n")
		os.Exit(2) // failed at 'gpm help'
	}

	arg := args[0]

	for _, cmd := range commands {
		if cmd.Name() == arg {
			tmpl(os.Stdout, helpTemplate, cmd)
			// not exit 2: succeeded at 'go help cmd'.
			return
		}
	}

	fmt.Fprintf(os.Stderr, "Unknown help topic %#q.  Run 'gpm help'.\n", arg)
	os.Exit(2) // failed at 'go help cmd'
}

var atexitFuncs []func()

func atexit(f func()) {
	atexitFuncs = append(atexitFuncs, f)
}

func exit() {
	for _, f := range atexitFuncs {
		f()
	}
	os.Exit(exitStatus)
}

// executeCommand executes commands in command line.
func executeCommand(cmd string, args []string) {
	cmdExec := exec.Command(cmd, args...)
	stdout, err := cmdExec.StdoutPipe()
	if err != nil {
		fmt.Println(err)
	}
	stderr, err := cmdExec.StderrPipe()
	if err != nil {
		fmt.Println(err)
	}
	err = cmdExec.Start()
	if err != nil {
		fmt.Println(err)
	}
	go io.Copy(os.Stdout, stdout)
	go io.Copy(os.Stderr, stderr)
	cmdExec.Wait()
}
<|endoftext|>


<commit_before>// Copyright 2014 The go-ethereum Authors
// 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 keystore

import (
	"crypto/rand"
	"fmt"
	"testing"

	"crypto/ecdsa"

	"github.com/lab2528/go-oneTime/crypto"
)

func TestGenerateOneTimeKeyAndCheck(t *testing.T) {
	key, _ := newKey(rand.Reader, rand.Reader)
	fmt.Println("------------newKey------------")
	fmt.Printf("address:\t %x\n", key.Address)
	fmt.Printf("A:\t %x\n", crypto.FromECDSAPub(&key.PrivateKey.PublicKey))
	fmt.Printf("a:\t %x\n", key.PrivateKey.D.Bytes())
	fmt.Printf("B:\t %x\n", crypto.FromECDSAPub(&key.PrivateKey2.PublicKey))
	fmt.Printf("b:\t %x\n", key.PrivateKey2.D.Bytes())
	fmt.Printf("b:\t %x\n", crypto.Keccak256(key.PrivateKey2.D.Bytes(), key.PrivateKey.D.Bytes(), crypto.FromECDSAPub(&key.PrivateKey2.PublicKey)))
	Okey, _ := GenerateOneTimeKey(key)
	ret := false
	ret = CheckOneTimeKey(key, Okey)
	fmt.Println("check OneTimeKey", ret)
	GenerateOneTimePrivateKey(key, Okey)
	ret = CheckOneTimePrivateKey(Okey)
	fmt.Println("check OneTimePrivateKey", ret)
}
func TestRingSignAndVerify(t *testing.T) {
	key1, _ := newKey(rand.Reader, rand.Reader)
	key2, _ := newKey(rand.Reader, rand.Reader)
	msg := []byte("abc")
	var pub = make([]*ecdsa.PublicKey, 0)
	pub = append(pub, &key1.PrivateKey.PublicKey, &key2.PrivateKey.PublicKey)
	//pub[1] = &key2.PrivateKey.PublicKey
	Pub, I, c, r := crypto.RingSign(msg, key1.PrivateKey.D, pub)
	ret := false
	ret = crypto.VerifyRingSign(msg, Pub, I, c, r)
	fmt.Println("check VerifyRingSign", ret)
}
<commit_msg>test2<commit_after>// Copyright 2014 The go-ethereum Authors
// 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/>.

//56
package keystore

import (
	"crypto/rand"
	"fmt"
	"testing"

	"crypto/ecdsa"

	"github.com/lab2528/go-oneTime/crypto"
)

func TestGenerateOneTimeKeyAndCheck(t *testing.T) {
	key, _ := newKey(rand.Reader, rand.Reader)
	fmt.Println("------------newKey------------")
	fmt.Printf("address:\t %x\n", key.Address)
	fmt.Printf("A:\t %x\n", crypto.FromECDSAPub(&key.PrivateKey.PublicKey))
	fmt.Printf("a:\t %x\n", key.PrivateKey.D.Bytes())
	fmt.Printf("B:\t %x\n", crypto.FromECDSAPub(&key.PrivateKey2.PublicKey))
	fmt.Printf("b:\t %x\n", key.PrivateKey2.D.Bytes())
	fmt.Printf("b:\t %x\n", crypto.Keccak256(key.PrivateKey2.D.Bytes(), key.PrivateKey.D.Bytes(), crypto.FromECDSAPub(&key.PrivateKey2.PublicKey)))
	Okey, _ := GenerateOneTimeKey(key)
	ret := false
	ret = CheckOneTimeKey(key, Okey)
	fmt.Println("check OneTimeKey", ret)
	GenerateOneTimePrivateKey(key, Okey)
	ret = CheckOneTimePrivateKey(Okey)
	fmt.Println("check OneTimePrivateKey", ret)
}
func TestRingSignAndVerify(t *testing.T) {
	key1, _ := newKey(rand.Reader, rand.Reader)
	key2, _ := newKey(rand.Reader, rand.Reader)
	msg := []byte("abc")
	var pub = make([]*ecdsa.PublicKey, 0)
	pub = append(pub, &key1.PrivateKey.PublicKey, &key2.PrivateKey.PublicKey)
	//pub[1] = &key2.PrivateKey.PublicKey
	Pub, I, c, r := crypto.RingSign(msg, key1.PrivateKey.D, pub)
	ret := false
	ret = crypto.VerifyRingSign(msg, Pub, I, c, r)
	fmt.Println("check VerifyRingSign", ret)
}
<|endoftext|>


<commit_before>/*
   Copyright 2013 Juliano Martinez <juliano@martinez.io>

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

      Based on http://github.com/nf/webfront

   @author: Juliano Martinez
*/

package main

import (
	"crypto/tls"
	"github.com/fiorix/go-redis/redis"
	hpr_utils "github.com/ncode/hot-potato-router/utils"
	"log"
	"net"
	"net/http"
	"net/http/httputil"
	"os"
	"strconv"
	"strings"
	"sync"
	"time"
)

type Server struct {
	mu    sync.RWMutex
	last  time.Time
	proxy map[string]http.Handler
}

type Proxy struct {
	Backend string
	handler http.Handler
}

var (
	cfg = hpr_utils.NewConfig()
	rc  = redis.New(cfg.Options["redis"]["server_list"])
)

func main() {
	probe_interval, _ := strconv.Atoi(cfg.Options["redis"]["probe_interval"])
	s, err := NewServer(time.Duration(probe_interval) * time.Second)
	if err != nil {
		log.Fatal(err)
	}
	http_fd, _ := strconv.Atoi(cfg.Options["hpr"]["http_fd"])
	https_fd, _ := strconv.Atoi(cfg.Options["hpr"]["https_fd"])
	if https_fd >= 3 || cfg.Options["hpr"]["https_addr"] != "" {
		cert, err := tls.LoadX509KeyPair(cfg.Options["hpr"]["cert_file"], cfg.Options["hpr"]["key_file"])
		if err != nil {
			log.Fatal(err)
		}
		c := &tls.Config{Certificates: []tls.Certificate{cert}}
		l := tls.NewListener(listen(https_fd, cfg.Options["hpr"]["https_addr"]), c)
		go func() {
			log.Fatal(http.Serve(l, s))
		}()
	}
	log.Fatal(http.Serve(listen(http_fd, cfg.Options["hpr"]["http_addr"]), s))
}

func listen(fd int, addr string) net.Listener {
	var l net.Listener
	var err error
	if fd >= 3 {
		l, err = net.FileListener(os.NewFile(uintptr(fd), "http"))
	} else {
		l, err = net.Listen("tcp", addr)
	}
	if err != nil {
		log.Fatal(err)
	}
	return l
}

func NewServer(probe time.Duration) (*Server, error) {
	s := new(Server)
	s.proxy = make(map[string]http.Handler)
	// go s.probe_backends(probe)
	return s, nil
}

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if h := s.handler(r); h != nil {
		h.ServeHTTP(w, r)
		return
	}
	http.Error(w, "Not found.", http.StatusNotFound)
}

func (s *Server) handler(req *http.Request) http.Handler {
	s.mu.RLock()
	defer s.mu.RUnlock()
	h := req.Host
	if i := strings.Index(h, ":"); i >= 0 {
		h = h[:i]
	}

	_, ok := s.proxy[h]
	if !ok {
		v, _ := rc.Get(h)
		s.proxy[h] = makeHandler(v)
	}
	return s.proxy[h]
}

func (s *Server) probe_backends(probe time.Duration) {
	for {
		s.mu.Lock()
		s.mu.Unlock()
		time.Sleep(probe)
	}
}

func makeHandler(f string) http.Handler {
	if f != "" {
		return &httputil.ReverseProxy{
			Director: func(req *http.Request) {
				req.URL.Scheme = "http"
				req.URL.Host = f
			},
		}
	}
	return nil
}
<commit_msg>started working on probes<commit_after>/*
   Copyright 2013 Juliano Martinez <juliano@martinez.io>

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

      Based on http://github.com/nf/webfront

   @author: Juliano Martinez
*/

package main

import (
	"crypto/tls"
	"github.com/fiorix/go-redis/redis"
	hpr_utils "github.com/ncode/hot-potato-router/utils"
	"log"
	"net"
	"net/http"
	"net/http/httputil"
	"os"
	"strconv"
	"strings"
	"sync"
	"time"
)

type Server struct {
	mu    sync.RWMutex
	last  time.Time
	proxy map[string]http.Handler
}

type Proxy struct {
	Backend string
	handler http.Handler
}

var (
	cfg = hpr_utils.NewConfig()
	rc  = redis.New(cfg.Options["redis"]["server_list"])
)

func main() {
	probe_interval, _ := strconv.Atoi(cfg.Options["redis"]["probe_interval"])
	s, err := NewServer(time.Duration(probe_interval) * time.Second)
	if err != nil {
		log.Fatal(err)
	}
	http_fd, _ := strconv.Atoi(cfg.Options["hpr"]["http_fd"])
	https_fd, _ := strconv.Atoi(cfg.Options["hpr"]["https_fd"])
	if https_fd >= 3 || cfg.Options["hpr"]["https_addr"] != "" {
		cert, err := tls.LoadX509KeyPair(cfg.Options["hpr"]["cert_file"], cfg.Options["hpr"]["key_file"])
		if err != nil {
			log.Fatal(err)
		}
		c := &tls.Config{Certificates: []tls.Certificate{cert}}
		l := tls.NewListener(listen(https_fd, cfg.Options["hpr"]["https_addr"]), c)
		go func() {
			log.Fatal(http.Serve(l, s))
		}()
	}
	log.Fatal(http.Serve(listen(http_fd, cfg.Options["hpr"]["http_addr"]), s))
}

func listen(fd int, addr string) net.Listener {
	var l net.Listener
	var err error
	if fd >= 3 {
		l, err = net.FileListener(os.NewFile(uintptr(fd), "http"))
	} else {
		l, err = net.Listen("tcp", addr)
	}
	if err != nil {
		log.Fatal(err)
	}
	return l
}

func NewServer(probe time.Duration) (*Server, error) {
	s := new(Server)
	s.proxy = make(map[string]http.Handler)
	go s.probe_backends(probe)
	return s, nil
}

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if h := s.handler(r); h != nil {
		h.ServeHTTP(w, r)
		return
	}
	http.Error(w, "Not found.", http.StatusNotFound)
}

func (s *Server) handler(req *http.Request) http.Handler {
	s.mu.RLock()
	defer s.mu.RUnlock()
	h := req.Host
	if i := strings.Index(h, ":"); i >= 0 {
		h = h[:i]
	}

	_, ok := s.proxy[h]
	if !ok {
		v, _ := rc.Get(h)
		s.proxy[h] = makeHandler(v)
	}
	return s.proxy[h]
}

func (s *Server) probe_backends(probe time.Duration) {
	for {
		//s.mu.Lock()
		//s.mu.Unlock()
		time.Sleep(probe)
	}
}

func makeHandler(f string) http.Handler {
	if f != "" {
		return &httputil.ReverseProxy{
			Director: func(req *http.Request) {
				req.URL.Scheme = "http"
				req.URL.Host = f
			},
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
    "log"
    "github.com/trendrr/cheshire-golang/cheshire"
    shards "github.com/dustismo/cheshire-shards/shards"
    "github.com/dustismo/cheshire-shards/admin/balancer"
    "github.com/trendrr/cheshire-golang/cheshire/impl/gocache"
    "flag"
    "time"
    "fmt"
)

//command line args
var (
    configFilename = flag.String("config-filename", "config.yaml", "filename of the config")
    dataDir = flag.String("data-dir", "data", "The local directory where data should be stored")
)

func main() {
    flag.Parse()
    bootstrap := cheshire.NewBootstrapFile(*configFilename)

    //Setup our cache.  this uses the local cache
    cache := gocache.New(10, 10)
    bootstrap.AddFilters(cheshire.NewSession(cache, 3600))

    balancer.Servs.DataDir = *dataDir
    balancer.Servs.Load()

    balancer.Servs.SetRouterTable(shards.NewRouterTable("Test"))

    //
    log.Println("Starting")
    go func() {
        c := time.Tick(5 * time.Second)
        for now := range c {
            str := fmt.Sprintf("%v %s\n", now, "Something something")
            balancer.Servs.Logger.Emit("test", str)
            balancer.Servs.Logger.Println("TESTING LOG")
        }
    }()

    //starts listening on all configured interfaces
    bootstrap.Start()

}<commit_msg>update main<commit_after>package main

import (
    "log"
    "github.com/trendrr/cheshire-golang/cheshire"
    shards "github.com/dustismo/cheshire-shards/shards"
    "github.com/dustismo/cheshire-shards/admin/balancer"
    "github.com/trendrr/cheshire-golang/cheshire/impl/gocache"
    "flag"
    // "time"
    // "fmt"
)

//command line args
var (
    configFilename = flag.String("config-filename", "config.yaml", "filename of the config")
    dataDir = flag.String("data-dir", "data", "The local directory where data should be stored")
)

func main() {
    flag.Parse()
    bootstrap := cheshire.NewBootstrapFile(*configFilename)

    //Setup our cache.  this uses the local cache
    cache := gocache.New(10, 10)
    bootstrap.AddFilters(cheshire.NewSession(cache, 3600))

    balancer.Servs.DataDir = *dataDir
    balancer.Servs.Load()

    testrt := shards.NewRouterTable("Test")
    balancer.Servs.SetRouterTable(testrt)

    //try creating entry
    entry := &shards.RouterEntry{
        Address : "localhost",
        JsonPort : 8009,
        HttpPort : 8010,
        Partitions : make([]int, 0),
    }

    log.Println("********************* ADD ENTRY")
    testrt.AddEntries(entry)

    //
    log.Println("Starting")
    // go func() {
    //     c := time.Tick(5 * time.Second)
    //     for now := range c {
    //         str := fmt.Sprintf("%v %s\n", now, "Something something")
    //         balancer.Servs.Logger.Emit("test", str)
    //         balancer.Servs.Logger.Println("TESTING LOG")
    //     }
    // }()

    //starts listening on all configured interfaces
    bootstrap.Start()

}<|endoftext|>