<commit_before>package micha

type InlineQueryResults []InlineQueryResult

type InlineQueryResult interface {
	_ItsInlineQueryResult()
}

type InlineQueryResultBase struct {
	Type string `json:"type"`
	Id   string `json:"id"`

	// Optional
	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
	InputMessageContent InputMessageContent   `json:"input_message_content,omitempty"`
}

func (i InlineQueryResultBase) _ItsInlineQueryResult() {}

// InlineQueryResultArticle is an inline query response article.
type InlineQueryResultArticle struct {
	InlineQueryResultBase
	Title string `json:"title"`

	// Optional
	Url         string `json:"url"`
	HideUrl     bool   `json:"hide_url"`
	Description string `json:"description"`
	ThumbUrl    string `json:"thumb_url"`
	ThumbWidth  int    `json:"thumb_width"`
	ThumbHeight int    `json:"thumb_height"`
}

// InlineQueryResultPhoto is an inline query response photo.
type InlineQueryResultPhoto struct {
	InlineQueryResultBase
	PhotoUrl string `json:"photo_url"`

	// Optional
	MimeType    string `json:"mime_type"`
	PhotoWidth  int    `json:"photo_width"`
	PhotoHeight int    `json:"photo_height"`
	ThumbUrl    string `json:"thumb_url"`
	Title       string `json:"title"`
	Description string `json:"description"`
	Caption     string `json:"caption"`
}

// InlineQueryResultGIF is an inline query response GIF.
type InlineQueryResultGIF struct {
	InlineQueryResultBase
	GifUrl string `json:"gif_url"`

	// Optional
	GifWidth  int    `json:"gif_width"`
	GifHeight int    `json:"gif_height"`
	ThumbUrl  string `json:"thumb_url"`
	Title     string `json:"title"`
	Caption   string `json:"caption"`
}

// InlineQueryResultMPEG4GIF is an inline query response MPEG4 GIF.
type InlineQueryResultMPEG4GIF struct {
	InlineQueryResultBase
	Mpeg4Url string `json:"mpeg4_url"`

	// Optional
	Mpeg4Width  int    `json:"mpeg4_width"`
	Mpeg4Height int    `json:"mpeg4_height"`
	ThumbURL    string `json:"thumb_url"`
	Title       string `json:"title"`
	Caption     string `json:"caption"`
}

// InlineQueryResultVideo is an inline query response video.
type InlineQueryResultVideo struct {
	InlineQueryResultBase
	VideoUrl string `json:"video_url"`
	MimeType string `json:"mime_type"`

	// Optional
	ThumbUrl      string `json:"thumb_url"`
	Title         string `json:"title"`
	Caption       string `json:"caption"`
	VideoWidth    int    `json:"video_width"`
	VideoHeight   int    `json:"video_height"`
	VideoDuration int    `json:"video_duration"`
	Description   string `json:"description"`
}

// InlineQueryResultAudio is an inline query response audio.
type InlineQueryResultAudio struct {
	InlineQueryResultBase
	AudioUrl string `json:"audio_url"`
	Title    string `json:"title"`

	// Optional
	Performer     string `json:"performer"`
	AudioDuration int    `json:"audio_duration"`
}

// InlineQueryResultVoice is an inline query response voice.
type InlineQueryResultVoice struct {
	InlineQueryResultBase
	VoiceUrl string `json:"voice_url"`
	Title    string `json:"title"`

	// Optional
	VoiceDuration int `json:"voice_duration"`
}

// InlineQueryResultDocument is an inline query response document.
type InlineQueryResultDocument struct {
	InlineQueryResultBase
	Title       string `json:"title"`
	DocumentUrl string `json:"document_url"`
	MimeType    string `json:"mime_type"`

	// Optional
	Caption     string `json:"caption"`
	Description string `json:"description"`
	ThumbURL    string `json:"thumb_url"`
	ThumbWidth  int    `json:"thumb_width"`
	ThumbHeight int    `json:"thumb_height"`
}

// InlineQueryResultLocation is an inline query response location.
type InlineQueryResultLocation struct {
	InlineQueryResultBase
	Latitude  float64 `json:"latitude"`
	Longitude float64 `json:"longitude"`
	Title     string  `json:"title"`

	// Optional
	ThumbUrl    string `json:"thumb_url"`
	ThumbWidth  int    `json:"thumb_width"`
	ThumbHeight int    `json:"thumb_height"`
}

type InputMessageContent interface {
	_ItsInputMessageContent()
}

type InputMessageContentBase struct{}

func (i InlineQueryResultBase) _ItsInputMessageContent() {}

// InputTextMessageContent contains text for displaying as an inline query result.
type InputTextMessageContent struct {
	InputMessageContentBase
	MessageText           string `json:"message_text"`
	ParseMode             string `json:"parse_mode"`
	DisableWebPagePreview bool   `json:"disable_web_page_preview"`
}

// InputLocationMessageContent contains a location for displaying as an inline query result.
type InputLocationMessageContent struct {
	InputMessageContentBase
	Latitude  float64 `json:"latitude"`
	Longitude float64 `json:"longitude"`
}

// InputVenueMessageContent contains a venue for displaying an inline query result.
type InputVenueMessageContent struct {
	InputMessageContentBase
	Latitude     float64 `json:"latitude"`
	Longitude    float64 `json:"longitude"`
	Title        string  `json:"title"`
	Address      string  `json:"address"`
	FoursquareId string  `json:"foursquare_id"`
}

// InputContactMessageContent contains a contact for displaying as an inline query result.
type InputContactMessageContent struct {
	InputMessageContentBase
	PhoneNumber string `json:"phone_number"`
	FirstName   string `json:"first_name"`
	LastName    string `json:"last_name"`
}
<commit_msg>Inline types refactoring.<commit_after>package micha

const (
	INLINE_TYPE_ARTICLE  = "article"
	INLINE_TYPE_PHOTO    = "photo"
	INLINE_TYPE_GIF      = "gif"
	INLINE_TYPE_VIDEO    = "video"
	INLINE_TYPE_AUDIO    = "audio"
	INLINE_TYPE_DOCUMENT = "document"
	INLINE_TYPE_VOICE    = "voice"
	INLINE_TYPE_LOCATION = "location"
)

type InlineQueryResults []InlineQueryResult

type InlineQueryResult interface {
	_ItsInlineQueryResult()
}

type InlineQueryResultImplementation struct{}

func (i InlineQueryResultImplementation) _ItsInlineQueryResult() {}

// InlineQueryResultArticle is an inline query response article.
type InlineQueryResultArticle struct {
	InlineQueryResultImplementation
	Type  string `json:"type"`
	Id    string `json:"id"`
	Title string `json:"title"`

	// Optional
	Url                 string                `json:"url,omitempty"`
	HideUrl             bool                  `json:"hide_url,omitempty"`
	Description         string                `json:"description,omitempty"`
	ThumbUrl            string                `json:"thumb_url,omitempty"`
	ThumbWidth          int                   `json:"thumb_width,omitempty"`
	ThumbHeight         int                   `json:"thumb_height,omitempty"`
	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
	InputMessageContent InputMessageContent   `json:"input_message_content,omitempty"`
}

// InlineQueryResultPhoto is an inline query response photo.
type InlineQueryResultPhoto struct {
	InlineQueryResultImplementation
	Type     string `json:"type"`
	Id       string `json:"id"`
	PhotoUrl string `json:"photo_url"`

	// Optional
	MimeType            string                `json:"mime_type,omitempty"`
	PhotoWidth          int                   `json:"photo_width,omitempty"`
	PhotoHeight         int                   `json:"photo_height,omitempty"`
	ThumbUrl            string                `json:"thumb_url,omitempty"`
	Title               string                `json:"title,omitempty"`
	Description         string                `json:"description,omitempty"`
	Caption             string                `json:"caption,omitempty"`
	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
	InputMessageContent InputMessageContent   `json:"input_message_content,omitempty"`
}

// InlineQueryResultGIF is an inline query response GIF.
type InlineQueryResultGif struct {
	InlineQueryResultImplementation
	Type   string `json:"type"`
	Id     string `json:"id"`
	GifUrl string `json:"gif_url"`

	// Optional
	GifWidth            int                   `json:"gif_width,omitempty"`
	GifHeight           int                   `json:"gif_height,omitempty"`
	ThumbUrl            string                `json:"thumb_url,omitempty"`
	Title               string                `json:"title,omitempty"`
	Caption             string                `json:"caption,omitempty"`
	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
	InputMessageContent InputMessageContent   `json:"input_message_content,omitempty"`
}

// InlineQueryResultMPEG4GIF is an inline query response MPEG4 GIF.
type InlineQueryResultMpeg4Gif struct {
	InlineQueryResultImplementation
	Type     string `json:"type"`
	Id       string `json:"id"`
	Mpeg4Url string `json:"mpeg4_url"`

	// Optional
	Mpeg4Width          int                   `json:"mpeg4_width,omitempty"`
	Mpeg4Height         int                   `json:"mpeg4_height,omitempty"`
	ThumbUrl            string                `json:"thumb_url,omitempty"`
	Title               string                `json:"title,omitempty"`
	Caption             string                `json:"caption,omitempty"`
	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
	InputMessageContent InputMessageContent   `json:"input_message_content,omitempty"`
}

// InlineQueryResultVideo is an inline query response video.
type InlineQueryResultVideo struct {
	InlineQueryResultImplementation
	Type     string `json:"type"`
	Id       string `json:"id"`
	VideoUrl string `json:"video_url"`
	MimeType string `json:"mime_type"`

	// Optional
	ThumbUrl            string                `json:"thumb_url,omitempty"`
	Title               string                `json:"title,omitempty"`
	Caption             string                `json:"caption,omitempty"`
	VideoWidth          int                   `json:"video_width,omitempty"`
	VideoHeight         int                   `json:"video_height,omitempty"`
	VideoDuration       int                   `json:"video_duration,omitempty"`
	Description         string                `json:"description,omitempty"`
	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
	InputMessageContent InputMessageContent   `json:"input_message_content,omitempty"`
}

// InlineQueryResultAudio is an inline query response audio.
type InlineQueryResultAudio struct {
	InlineQueryResultImplementation
	Type     string `json:"type"`
	Id       string `json:"id"`
	AudioUrl string `json:"audio_url"`
	Title    string `json:"title"`

	// Optional
	Performer           string                `json:"performer,omitempty"`
	AudioDuration       int                   `json:"audio_duration,omitempty"`
	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
	InputMessageContent InputMessageContent   `json:"input_message_content,omitempty"`
}

// InlineQueryResultVoice is an inline query response voice.
type InlineQueryResultVoice struct {
	InlineQueryResultImplementation
	Type     string `json:"type"`
	Id       string `json:"id"`
	VoiceUrl string `json:"voice_url"`
	Title    string `json:"title"`

	// Optional
	VoiceDuration       int                   `json:"voice_duration,omitempty"`
	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
	InputMessageContent InputMessageContent   `json:"input_message_content,omitempty"`
}

// InlineQueryResultDocument is an inline query response document.
type InlineQueryResultDocument struct {
	InlineQueryResultImplementation
	Type        string `json:"type"`
	Id          string `json:"id"`
	Title       string `json:"title"`
	DocumentUrl string `json:"document_url"`
	MimeType    string `json:"mime_type"`

	// Optional
	Caption             string                `json:"caption,omitempty"`
	Description         string                `json:"description,omitempty"`
	ThumbURL            string                `json:"thumb_url,omitempty"`
	ThumbWidth          int                   `json:"thumb_width,omitempty"`
	ThumbHeight         int                   `json:"thumb_height,omitempty"`
	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
	InputMessageContent InputMessageContent   `json:"input_message_content,omitempty"`
}

// InlineQueryResultLocation is an inline query response location.
type InlineQueryResultLocation struct {
	InlineQueryResultImplementation
	Type      string  `json:"type"`
	Id        string  `json:"id"`
	Latitude  float64 `json:"latitude"`
	Longitude float64 `json:"longitude"`
	Title     string  `json:"title"`

	// Optional
	ThumbUrl            string                `json:"thumb_url,omitempty"`
	ThumbWidth          int                   `json:"thumb_width,omitempty"`
	ThumbHeight         int                   `json:"thumb_height,omitempty"`
	ReplyMarkup         *InlineKeyboardMarkup `json:"reply_markup,omitempty"`
	InputMessageContent InputMessageContent   `json:"input_message_content,omitempty"`
}

type InputMessageContent interface {
	_ItsInputMessageContent()
}

type InputMessageContentImplementation struct{}

func (i InputMessageContentImplementation) _ItsInputMessageContent() {}

// InputTextMessageContent contains text for displaying as an inline query result.
type InputTextMessageContent struct {
	InputMessageContentImplementation
	MessageText           string `json:"message_text"`
	ParseMode             string `json:"parse_mode"`
	DisableWebPagePreview bool   `json:"disable_web_page_preview"`
}

// InputLocationMessageContent contains a location for displaying as an inline query result.
type InputLocationMessageContent struct {
	InputMessageContentImplementation
	Latitude  float64 `json:"latitude"`
	Longitude float64 `json:"longitude"`
}

// InputVenueMessageContent contains a venue for displaying an inline query result.
type InputVenueMessageContent struct {
	InputMessageContentImplementation
	Latitude     float64 `json:"latitude"`
	Longitude    float64 `json:"longitude"`
	Title        string  `json:"title"`
	Address      string  `json:"address"`
	FoursquareId string  `json:"foursquare_id"`
}

// InputContactMessageContent contains a contact for displaying as an inline query result.
type InputContactMessageContent struct {
	InputMessageContentImplementation
	PhoneNumber string `json:"phone_number"`
	FirstName   string `json:"first_name"`
	LastName    string `json:"last_name"`
}
<|endoftext|>


<commit_before>package adm

import (
	"encoding/json"
	"fmt"

	"gopkg.in/resty.v0"
)

func ActivateAccount(c *resty.Client, a *auth.Token) (*auth.Token, error) {
	var (
		kex  *auth.Kex
		err  error
		resp *resty.Response
		body []byte
	)
	jBytes := &[]byte{}
	cipher := &[]byte{}
	plain := &[]byte{}
	cred := &auth.Token{}

	if *jBytes, err = json.Marshal(a); err != nil {
		return nil, err
	}

	// establish key exchange for credential transmission
	if kex, err = KeyExchange(c); err != nil {
		return nil, err
	}

	// encrypt credentials
	if err = kex.EncryptAndEncode(jBytes, cipher); err != nil {
		return nil, err
	}

	// Send request
	if resp, err = c.R().
		SetHeader(`Content-Type`, `application/octet-stream`).
		SetBody(*cipher).
		Put(fmt.Sprintf(
			"/authenticate/activate/%s", kex.Request.String())); err != nil {
		return nil, err
	} else if resp.StatusCode() != 200 {
		return nil, fmt.Errorf("Activation failed with status code: %d", resp.StatusCode())
	}

	// decrypt reply
	body = resp.Body()
	if err = kex.DecodeAndDecrypt(&body, plain); err != nil {
		return nil, err
	}
	if err = json.Unmarshal(*plain, *cred); err != nil {
		return nil, err
	}

	return cred, nil
}

// vim: ts=4 sw=4 sts=4 noet fenc=utf-8 ffs=unix
<commit_msg>FIX: json unmarshal, not pointer value<commit_after>package adm

import (
	"encoding/json"
	"fmt"

	"gopkg.in/resty.v0"
)

func ActivateAccount(c *resty.Client, a *auth.Token) (*auth.Token, error) {
	var (
		kex  *auth.Kex
		err  error
		resp *resty.Response
		body []byte
	)
	jBytes := &[]byte{}
	cipher := &[]byte{}
	plain := &[]byte{}
	cred := &auth.Token{}

	if *jBytes, err = json.Marshal(a); err != nil {
		return nil, err
	}

	// establish key exchange for credential transmission
	if kex, err = KeyExchange(c); err != nil {
		return nil, err
	}

	// encrypt credentials
	if err = kex.EncryptAndEncode(jBytes, cipher); err != nil {
		return nil, err
	}

	// Send request
	if resp, err = c.R().
		SetHeader(`Content-Type`, `application/octet-stream`).
		SetBody(*cipher).
		Put(fmt.Sprintf(
			"/authenticate/activate/%s", kex.Request.String())); err != nil {
		return nil, err
	} else if resp.StatusCode() != 200 {
		return nil, fmt.Errorf("Activation failed with status code: %d", resp.StatusCode())
	}

	// decrypt reply
	body = resp.Body()
	if err = kex.DecodeAndDecrypt(&body, plain); err != nil {
		return nil, err
	}
	if err = json.Unmarshal(*plain, cred); err != nil {
		return nil, err
	}

	return cred, nil
}

// vim: ts=4 sw=4 sts=4 noet fenc=utf-8 ffs=unix
<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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 lease

import (
	"fmt"
	"io"
	"log"
	"sync"
)

// Create a ReadLease that never expires, unless voluntarily revoked or
// upgraded.
//
// The supplied function will be used to obtain the read lease contents, the
// first time and whenever the supplied file leaser decides to expire the
// temporary copy thus obtained. It must return the same contents every time,
// and the contents must be of the given size.
//
// This magic is not preserved after the lease is upgraded.
func NewAutoRefreshingReadLease(
	fl FileLeaser,
	size int64,
	f func() (io.ReadCloser, error)) (rl ReadLease) {
	rl = &autoRefreshingReadLease{
		leaser: fl,
		size:   size,
		f:      f,
	}

	return
}

type autoRefreshingReadLease struct {
	mu sync.Mutex

	/////////////////////////
	// Constant data
	/////////////////////////

	size int64

	/////////////////////////
	// Dependencies
	/////////////////////////

	leaser FileLeaser
	f      func() (io.ReadCloser, error)

	/////////////////////////
	// Mutable state
	/////////////////////////

	// The current wrapped lease, or nil if one has never been issued.
	//
	// GUARDED_BY(mu)
	wrapped ReadLease
}

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

// Attempt to clean up after the supplied read/write lease.
func destroyReadWriteLease(rwl ReadWriteLease) {
	var err error
	defer func() {
		if err != nil {
			log.Printf("Error destroying read/write lease: %v", err)
		}
	}()

	// Downgrade to a read lease.
	rl, err := rwl.Downgrade()
	if err != nil {
		err = fmt.Errorf("Downgrade: %v", err)
		return
	}

	// Revoke the read lease.
	rl.Revoke()
}

// Set up a read/write lease and fill in our contents.
//
// REQUIRES: The caller has observed that rl.lease has expired.
//
// LOCKS_REQUIRED(rl.mu)
func (rl *autoRefreshingReadLease) getContents() (
	rwl ReadWriteLease, err error) {
	// Obtain some space to write the contents.
	rwl, err = rl.leaser.NewFile()
	if err != nil {
		err = fmt.Errorf("NewFile: %v", err)
		return
	}

	// Attempt to clean up if we exit early.
	defer func() {
		if err != nil {
			destroyReadWriteLease(rwl)
		}
	}()

	// Obtain the reader for our contents.
	rc, err := rl.f()
	if err != nil {
		err = fmt.Errorf("User function: %v", err)
		return
	}

	defer func() {
		closeErr := rc.Close()
		if closeErr != nil && err == nil {
			err = fmt.Errorf("Close: %v", closeErr)
		}
	}()

	// Copy into the read/write lease.
	copied, err := io.Copy(rwl, rc)
	if err != nil {
		err = fmt.Errorf("Copy: %v", err)
		return
	}

	// Did the user lie about the size?
	if copied != rl.Size() {
		err = fmt.Errorf("Copied %v bytes; expected %v", copied, rl.Size())
		return
	}

	return
}

// Downgrade and save the supplied read/write lease obtained with getContents
// for later use.
//
// LOCKS_REQUIRED(rl.mu)
func (rl *autoRefreshingReadLease) saveContents(rwl ReadWriteLease) {
	downgraded, err := rwl.Downgrade()
	if err != nil {
		log.Printf("Failed to downgrade write lease (%q); abandoning.", err.Error())
		return
	}

	rl.wrapped = downgraded
}

////////////////////////////////////////////////////////////////////////
// Public interface
////////////////////////////////////////////////////////////////////////

func (rl *autoRefreshingReadLease) Read(p []byte) (n int, err error) {
	rl.mu.Lock()
	defer rl.mu.Unlock()

	// Common case: is the existing lease still valid?
	if rl.wrapped != nil {
		panic("TODO")
	}

	// Get hold of a read/write lease containing our contents.
	rwl, err := rl.getContents()
	if err != nil {
		err = fmt.Errorf("getContents: %v", err)
		return
	}

	defer rl.saveContents(rwl)

	// Serve from the read/write lease.
	n, err = rwl.Read(p)

	return
}

func (rl *autoRefreshingReadLease) Seek(
	offset int64,
	whence int) (off int64, err error) {
	rl.mu.Lock()
	defer rl.mu.Unlock()

	// Common case: is the existing lease still valid?
	if rl.wrapped != nil {
		panic("TODO")
	}

	// Get hold of a read/write lease containing our contents.
	rwl, err := rl.getContents()
	if err != nil {
		err = fmt.Errorf("getContents: %v", err)
		return
	}

	defer rl.saveContents(rwl)

	// Serve from the read/write lease.
	off, err = rwl.Seek(offset, whence)

	return
}

func (rl *autoRefreshingReadLease) ReadAt(
	p []byte,
	off int64) (n int, err error) {
	rl.mu.Lock()
	defer rl.mu.Unlock()

	// Common case: is the existing lease still valid?
	if rl.wrapped != nil {
		panic("TODO")
	}

	// Get hold of a read/write lease containing our contents.
	rwl, err := rl.getContents()
	if err != nil {
		err = fmt.Errorf("getContents: %v", err)
		return
	}

	defer rl.saveContents(rwl)

	// Serve from the read/write lease.
	n, err = rwl.ReadAt(p, off)

	return
}

func (rl *autoRefreshingReadLease) Size() (size int64) {
	size = rl.size
	return
}

func (rl *autoRefreshingReadLease) Revoked() (revoked bool) {
	panic("TODO")
}

func (rl *autoRefreshingReadLease) Upgrade() (rwl ReadWriteLease, err error) {
	panic("TODO")
}

func (rl *autoRefreshingReadLease) Revoke() {
	panic("TODO")
}
<commit_msg>AutoRefreshingReadLeaseTest.Revoked<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
//
// 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 lease

import (
	"fmt"
	"io"
	"log"
	"sync"
)

// Create a ReadLease that never expires, unless voluntarily revoked or
// upgraded.
//
// The supplied function will be used to obtain the read lease contents, the
// first time and whenever the supplied file leaser decides to expire the
// temporary copy thus obtained. It must return the same contents every time,
// and the contents must be of the given size.
//
// This magic is not preserved after the lease is upgraded.
func NewAutoRefreshingReadLease(
	fl FileLeaser,
	size int64,
	f func() (io.ReadCloser, error)) (rl ReadLease) {
	rl = &autoRefreshingReadLease{
		leaser: fl,
		size:   size,
		f:      f,
	}

	return
}

type autoRefreshingReadLease struct {
	mu sync.Mutex

	/////////////////////////
	// Constant data
	/////////////////////////

	size int64

	/////////////////////////
	// Dependencies
	/////////////////////////

	leaser FileLeaser
	f      func() (io.ReadCloser, error)

	/////////////////////////
	// Mutable state
	/////////////////////////

	// Set to true when we've been revoked for good.
	//
	// GUARDED_BY(mu)
	revoked bool

	// The current wrapped lease, or nil if one has never been issued.
	//
	// GUARDED_BY(mu)
	wrapped ReadLease
}

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

// Attempt to clean up after the supplied read/write lease.
func destroyReadWriteLease(rwl ReadWriteLease) {
	var err error
	defer func() {
		if err != nil {
			log.Printf("Error destroying read/write lease: %v", err)
		}
	}()

	// Downgrade to a read lease.
	rl, err := rwl.Downgrade()
	if err != nil {
		err = fmt.Errorf("Downgrade: %v", err)
		return
	}

	// Revoke the read lease.
	rl.Revoke()
}

// Set up a read/write lease and fill in our contents.
//
// REQUIRES: The caller has observed that rl.lease has expired.
//
// LOCKS_REQUIRED(rl.mu)
func (rl *autoRefreshingReadLease) getContents() (
	rwl ReadWriteLease, err error) {
	// Obtain some space to write the contents.
	rwl, err = rl.leaser.NewFile()
	if err != nil {
		err = fmt.Errorf("NewFile: %v", err)
		return
	}

	// Attempt to clean up if we exit early.
	defer func() {
		if err != nil {
			destroyReadWriteLease(rwl)
		}
	}()

	// Obtain the reader for our contents.
	rc, err := rl.f()
	if err != nil {
		err = fmt.Errorf("User function: %v", err)
		return
	}

	defer func() {
		closeErr := rc.Close()
		if closeErr != nil && err == nil {
			err = fmt.Errorf("Close: %v", closeErr)
		}
	}()

	// Copy into the read/write lease.
	copied, err := io.Copy(rwl, rc)
	if err != nil {
		err = fmt.Errorf("Copy: %v", err)
		return
	}

	// Did the user lie about the size?
	if copied != rl.Size() {
		err = fmt.Errorf("Copied %v bytes; expected %v", copied, rl.Size())
		return
	}

	return
}

// Downgrade and save the supplied read/write lease obtained with getContents
// for later use.
//
// LOCKS_REQUIRED(rl.mu)
func (rl *autoRefreshingReadLease) saveContents(rwl ReadWriteLease) {
	downgraded, err := rwl.Downgrade()
	if err != nil {
		log.Printf("Failed to downgrade write lease (%q); abandoning.", err.Error())
		return
	}

	rl.wrapped = downgraded
}

////////////////////////////////////////////////////////////////////////
// Public interface
////////////////////////////////////////////////////////////////////////

func (rl *autoRefreshingReadLease) Read(p []byte) (n int, err error) {
	rl.mu.Lock()
	defer rl.mu.Unlock()

	// Common case: is the existing lease still valid?
	if rl.wrapped != nil {
		panic("TODO")
	}

	// Get hold of a read/write lease containing our contents.
	rwl, err := rl.getContents()
	if err != nil {
		err = fmt.Errorf("getContents: %v", err)
		return
	}

	defer rl.saveContents(rwl)

	// Serve from the read/write lease.
	n, err = rwl.Read(p)

	return
}

func (rl *autoRefreshingReadLease) Seek(
	offset int64,
	whence int) (off int64, err error) {
	rl.mu.Lock()
	defer rl.mu.Unlock()

	// Common case: is the existing lease still valid?
	if rl.wrapped != nil {
		panic("TODO")
	}

	// Get hold of a read/write lease containing our contents.
	rwl, err := rl.getContents()
	if err != nil {
		err = fmt.Errorf("getContents: %v", err)
		return
	}

	defer rl.saveContents(rwl)

	// Serve from the read/write lease.
	off, err = rwl.Seek(offset, whence)

	return
}

func (rl *autoRefreshingReadLease) ReadAt(
	p []byte,
	off int64) (n int, err error) {
	rl.mu.Lock()
	defer rl.mu.Unlock()

	// Common case: is the existing lease still valid?
	if rl.wrapped != nil {
		panic("TODO")
	}

	// Get hold of a read/write lease containing our contents.
	rwl, err := rl.getContents()
	if err != nil {
		err = fmt.Errorf("getContents: %v", err)
		return
	}

	defer rl.saveContents(rwl)

	// Serve from the read/write lease.
	n, err = rwl.ReadAt(p, off)

	return
}

func (rl *autoRefreshingReadLease) Size() (size int64) {
	size = rl.size
	return
}

func (rl *autoRefreshingReadLease) Revoked() (revoked bool) {
	rl.mu.Lock()
	defer rl.mu.Unlock()

	revoked = rl.revoked
	return
}

func (rl *autoRefreshingReadLease) Upgrade() (rwl ReadWriteLease, err error) {
	panic("TODO")
}

func (rl *autoRefreshingReadLease) Revoke() {
	panic("TODO")
}
<|endoftext|>


<commit_before>package integration_test

import (
	"encoding/json"
	"flag"
	"fmt"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"time"

	"github.com/blang/semver"
	"github.com/cloudfoundry/libbuildpack/cutlass"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"testing"
)

var bpDir string
var buildpackVersion string
var packagedBuildpack cutlass.VersionedBuildpackPackage

func init() {
	flag.StringVar(&buildpackVersion, "version", "", "version to use (builds if empty)")
	flag.BoolVar(&cutlass.Cached, "cached", true, "cached buildpack")
	flag.StringVar(&cutlass.DefaultMemory, "memory", "128M", "default memory for pushed apps")
	flag.StringVar(&cutlass.DefaultDisk, "disk", "384M", "default disk for pushed apps")
	flag.Parse()
}

var _ = SynchronizedBeforeSuite(func() []byte {
	// Run once
	if buildpackVersion == "" {
		packagedBuildpack, err := cutlass.PackageUniquelyVersionedBuildpack()
		Expect(err).NotTo(HaveOccurred())

		data, err := json.Marshal(packagedBuildpack)
		Expect(err).NotTo(HaveOccurred())
		return data
	}

	return []byte{}
}, func(data []byte) {
	// Run on all nodes
	var err error
	if len(data) > 0 {
		err = json.Unmarshal(data, &packagedBuildpack)
		Expect(err).NotTo(HaveOccurred())
		buildpackVersion = packagedBuildpack.Version
	}

	bpDir, err = cutlass.FindRoot()
	Expect(err).NotTo(HaveOccurred())

	cutlass.SeedRandom()
	cutlass.DefaultStdoutStderr = GinkgoWriter
})

var _ = SynchronizedAfterSuite(func() {
	// Run on all nodes
}, func() {
	// Run once
	// Expect(cutlass.RemovePackagedBuildpack(packagedBuildpack)).To(Succeed())
	Expect(cutlass.DeleteOrphanedRoutes()).To(Succeed())
})

func TestIntegration(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "Integration Suite")
}

func PushAppAndConfirm(app *cutlass.App) {
	Expect(app.Push()).To(Succeed())
	Eventually(func() ([]string, error) { return app.InstanceStates() }, 20*time.Second).Should(Equal([]string{"RUNNING"}))
	Expect(app.ConfirmBuildpack(buildpackVersion)).To(Succeed())
}

func Restart(app *cutlass.App) {
	Expect(app.Restart()).To(Succeed())
	Eventually(func() ([]string, error) { return app.InstanceStates() }, 20*time.Second).Should(Equal([]string{"RUNNING"}))
}

func ApiHasTask() bool {
	apiVersionString, err := cutlass.ApiVersion()
	Expect(err).To(BeNil())
	apiVersion, err := semver.Make(apiVersionString)
	Expect(err).To(BeNil())
	apiHasTask, err := semver.ParseRange(">= 2.75.0")
	Expect(err).To(BeNil())
	return apiHasTask(apiVersion)
}

func AssertUsesProxyDuringStagingIfPresent(fixtureName string) {
	Context("with an uncached buildpack", func() {
		BeforeEach(func() {
			if cutlass.Cached {
				Skip("Running cached tests")
			}
		})

		It("uses a proxy during staging if present", func() {
			proxy, err := cutlass.NewProxy()
			Expect(err).To(BeNil())
			defer proxy.Close()

			bpFile := filepath.Join(bpDir, buildpackVersion+"tmp")
			cmd := exec.Command("cp", packagedBuildpack.File, bpFile)
			err = cmd.Run()
			Expect(err).To(BeNil())
			defer os.Remove(bpFile)

			traffic, err := cutlass.InternetTraffic(
				bpDir,
				filepath.Join("fixtures", fixtureName),
				bpFile,
				[]string{"HTTP_PROXY=" + proxy.URL, "HTTPS_PROXY=" + proxy.URL},
			)
			Expect(err).To(BeNil())

			destUrl, err := url.Parse(proxy.URL)
			Expect(err).To(BeNil())

			Expect(cutlass.UniqueDestination(
				traffic, fmt.Sprintf("%s.%s", destUrl.Hostname(), destUrl.Port()),
			)).To(BeNil())
		})
	})
}

func AssertNoInternetTraffic(fixtureName string) {
	It("has no traffic", func() {
		if !cutlass.Cached {
			Skip("Running uncached tests")
		}

		bpFile := filepath.Join(bpDir, buildpackVersion+"tmp")
		cmd := exec.Command("cp", packagedBuildpack.File, bpFile)
		err := cmd.Run()
		Expect(err).To(BeNil())
		defer os.Remove(bpFile)

		traffic, err := cutlass.InternetTraffic(
			bpDir,
			filepath.Join("fixtures", fixtureName),
			bpFile,
			[]string{},
		)
		Expect(err).To(BeNil())
		Expect(traffic).To(BeEmpty())
	})
}
<commit_msg>Use cutlass test helper CopyCfHome [#150860504]<commit_after>package integration_test

import (
	"encoding/json"
	"flag"
	"fmt"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"time"

	"github.com/blang/semver"
	"github.com/cloudfoundry/libbuildpack/cutlass"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"testing"
)

var bpDir string
var buildpackVersion string
var packagedBuildpack cutlass.VersionedBuildpackPackage

func init() {
	flag.StringVar(&buildpackVersion, "version", "", "version to use (builds if empty)")
	flag.BoolVar(&cutlass.Cached, "cached", true, "cached buildpack")
	flag.StringVar(&cutlass.DefaultMemory, "memory", "128M", "default memory for pushed apps")
	flag.StringVar(&cutlass.DefaultDisk, "disk", "384M", "default disk for pushed apps")
	flag.Parse()
}

var _ = SynchronizedBeforeSuite(func() []byte {
	// Run once
	if buildpackVersion == "" {
		packagedBuildpack, err := cutlass.PackageUniquelyVersionedBuildpack()
		Expect(err).NotTo(HaveOccurred())

		data, err := json.Marshal(packagedBuildpack)
		Expect(err).NotTo(HaveOccurred())
		return data
	}

	return []byte{}
}, func(data []byte) {
	// Run on all nodes
	var err error
	if len(data) > 0 {
		err = json.Unmarshal(data, &packagedBuildpack)
		Expect(err).NotTo(HaveOccurred())
		buildpackVersion = packagedBuildpack.Version
	}

	bpDir, err = cutlass.FindRoot()
	Expect(err).NotTo(HaveOccurred())

	Expect(cutlass.CopyCfHome()).To(Succeed())
	cutlass.SeedRandom()
	cutlass.DefaultStdoutStderr = GinkgoWriter
})

var _ = SynchronizedAfterSuite(func() {
	// Run on all nodes
	Expect(os.RemoveAll("CF_HOME")).To(Succeed())
}, func() {
	// Run once
	// Expect(cutlass.RemovePackagedBuildpack(packagedBuildpack)).To(Succeed())
	Expect(cutlass.DeleteOrphanedRoutes()).To(Succeed())
})

func TestIntegration(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "Integration Suite")
}

func PushAppAndConfirm(app *cutlass.App) {
	Expect(app.Push()).To(Succeed())
	Eventually(func() ([]string, error) { return app.InstanceStates() }, 20*time.Second).Should(Equal([]string{"RUNNING"}))
	Expect(app.ConfirmBuildpack(buildpackVersion)).To(Succeed())
}

func Restart(app *cutlass.App) {
	Expect(app.Restart()).To(Succeed())
	Eventually(func() ([]string, error) { return app.InstanceStates() }, 20*time.Second).Should(Equal([]string{"RUNNING"}))
}

func ApiHasTask() bool {
	apiVersionString, err := cutlass.ApiVersion()
	Expect(err).To(BeNil())
	apiVersion, err := semver.Make(apiVersionString)
	Expect(err).To(BeNil())
	apiHasTask, err := semver.ParseRange(">= 2.75.0")
	Expect(err).To(BeNil())
	return apiHasTask(apiVersion)
}

func AssertUsesProxyDuringStagingIfPresent(fixtureName string) {
	Context("with an uncached buildpack", func() {
		BeforeEach(func() {
			if cutlass.Cached {
				Skip("Running cached tests")
			}
		})

		It("uses a proxy during staging if present", func() {
			proxy, err := cutlass.NewProxy()
			Expect(err).To(BeNil())
			defer proxy.Close()

			bpFile := filepath.Join(bpDir, buildpackVersion+"tmp")
			cmd := exec.Command("cp", packagedBuildpack.File, bpFile)
			err = cmd.Run()
			Expect(err).To(BeNil())
			defer os.Remove(bpFile)

			traffic, err := cutlass.InternetTraffic(
				bpDir,
				filepath.Join("fixtures", fixtureName),
				bpFile,
				[]string{"HTTP_PROXY=" + proxy.URL, "HTTPS_PROXY=" + proxy.URL},
			)
			Expect(err).To(BeNil())

			destUrl, err := url.Parse(proxy.URL)
			Expect(err).To(BeNil())

			Expect(cutlass.UniqueDestination(
				traffic, fmt.Sprintf("%s.%s", destUrl.Hostname(), destUrl.Port()),
			)).To(BeNil())
		})
	})
}

func AssertNoInternetTraffic(fixtureName string) {
	It("has no traffic", func() {
		if !cutlass.Cached {
			Skip("Running uncached tests")
		}

		bpFile := filepath.Join(bpDir, buildpackVersion+"tmp")
		cmd := exec.Command("cp", packagedBuildpack.File, bpFile)
		err := cmd.Run()
		Expect(err).To(BeNil())
		defer os.Remove(bpFile)

		traffic, err := cutlass.InternetTraffic(
			bpDir,
			filepath.Join("fixtures", fixtureName),
			bpFile,
			[]string{},
		)
		Expect(err).To(BeNil())
		Expect(traffic).To(BeEmpty())
	})
}
<|endoftext|>


<commit_before>package utils

import (
	"encoding/base64"
	"errors"
	"fmt"
	"net/http"
	"regexp"
	"strings"
	"time"

	ct "github.com/flynn/flynn/controller/types"
	"github.com/flynn/flynn/discoverd/client"
	"github.com/flynn/flynn/host/types"
	"github.com/flynn/flynn/host/volume"
	"github.com/flynn/flynn/pkg/cluster"
	"github.com/flynn/flynn/pkg/stream"
)

func JobConfig(f *ct.ExpandedFormation, name, hostID string) *host.Job {
	t := f.Release.Processes[name]
	env := make(map[string]string, len(f.Release.Env)+len(t.Env)+4)
	for k, v := range f.Release.Env {
		env[k] = v
	}
	for k, v := range t.Env {
		env[k] = v
	}
	id := cluster.GenerateJobID(hostID)
	env["FLYNN_APP_ID"] = f.App.ID
	env["FLYNN_RELEASE_ID"] = f.Release.ID
	env["FLYNN_PROCESS_TYPE"] = name
	env["FLYNN_JOB_ID"] = id
	job := &host.Job{
		ID: id,
		Metadata: map[string]string{
			"flynn-controller.app":      f.App.ID,
			"flynn-controller.app_name": f.App.Name,
			"flynn-controller.release":  f.Release.ID,
			"flynn-controller.type":     name,
		},
		Artifact: host.Artifact{
			Type: f.Artifact.Type,
			URI:  f.Artifact.URI,
		},
		Config: host.ContainerConfig{
			Cmd:         t.Cmd,
			Env:         env,
			HostNetwork: t.HostNetwork,
		},
		Resurrect: t.Resurrect,
		Resources: t.Resources,
	}
	if len(t.Entrypoint) > 0 {
		job.Config.Entrypoint = t.Entrypoint
	}
	job.Config.Ports = make([]host.Port, len(t.Ports))
	for i, p := range t.Ports {
		job.Config.Ports[i].Proto = p.Proto
		job.Config.Ports[i].Port = p.Port
		job.Config.Ports[i].Service = p.Service
	}
	return job
}

func ProvisionVolume(h VolumeCreator, job *host.Job) error {
	vol, err := h.CreateVolume("default")
	if err != nil {
		return err
	}
	job.Config.Volumes = []host.VolumeBinding{{
		Target:    "/data",
		VolumeID:  vol.ID,
		Writeable: true,
	}}
	return nil
}

func JobMetaFromMetadata(metadata map[string]string) map[string]string {
	jobMeta := make(map[string]string, len(metadata))
	for k, v := range metadata {
		if strings.HasPrefix(k, "flynn-controller.") {
			continue
		}
		jobMeta[k] = v
	}
	return jobMeta
}

type FormationKey struct {
	AppID, ReleaseID string
}

func NewFormationKey(appID, releaseID string) FormationKey {
	return FormationKey{AppID: appID, ReleaseID: releaseID}
}

func ExpandFormation(c ControllerClient, f *ct.Formation) (*ct.ExpandedFormation, error) {
	app, err := c.GetApp(f.AppID)
	if err != nil {
		return nil, fmt.Errorf("error getting app: %s", err)
	}

	release, err := c.GetRelease(f.ReleaseID)
	if err != nil {
		return nil, fmt.Errorf("error getting release: %s", err)
	}

	artifact, err := c.GetArtifact(release.ArtifactID)
	if err != nil {
		return nil, fmt.Errorf("error getting artifact: %s", err)
	}

	procs := make(map[string]int)
	for typ, count := range f.Processes {
		procs[typ] = count
	}

	ef := &ct.ExpandedFormation{
		App:       app,
		Release:   release,
		Artifact:  artifact,
		Processes: procs,
		UpdatedAt: time.Now(),
	}
	if f.UpdatedAt != nil {
		ef.UpdatedAt = *f.UpdatedAt
	}
	return ef, nil
}

type VolumeCreator interface {
	CreateVolume(string) (*volume.Info, error)
}

type HostClient interface {
	VolumeCreator
	ID() string
	AddJob(*host.Job) error
	GetJob(id string) (*host.ActiveJob, error)
	Attach(*host.AttachReq, bool) (cluster.AttachClient, error)
	StopJob(string) error
	ListJobs() (map[string]host.ActiveJob, error)
	StreamEvents(id string, ch chan *host.Event) (stream.Stream, error)
	GetStatus() (*host.HostStatus, error)
}

type ClusterClient interface {
	Host(string) (HostClient, error)
	Hosts() ([]HostClient, error)
	StreamHostEvents(chan *discoverd.Event) (stream.Stream, error)
}

type ControllerClient interface {
	GetApp(appID string) (*ct.App, error)
	GetRelease(releaseID string) (*ct.Release, error)
	GetArtifact(artifactID string) (*ct.Artifact, error)
	GetFormation(appID, releaseID string) (*ct.Formation, error)
	CreateApp(app *ct.App) error
	CreateRelease(release *ct.Release) error
	CreateArtifact(artifact *ct.Artifact) error
	PutFormation(formation *ct.Formation) error
	StreamFormations(since *time.Time, ch chan<- *ct.ExpandedFormation) (stream.Stream, error)
	AppList() ([]*ct.App, error)
	FormationList(appID string) ([]*ct.Formation, error)
	PutJob(*ct.Job) error
}

func ClusterClientWrapper(c *cluster.Client) clusterClientWrapper {
	return clusterClientWrapper{c}
}

type clusterClientWrapper struct {
	*cluster.Client
}

func (c clusterClientWrapper) Host(id string) (HostClient, error) {
	return c.Client.Host(id)
}

func (c clusterClientWrapper) Hosts() ([]HostClient, error) {
	hosts, err := c.Client.Hosts()
	if err != nil {
		return nil, err
	}
	res := make([]HostClient, len(hosts))
	for i, h := range hosts {
		res[i] = h
	}
	return res, nil
}

func (c clusterClientWrapper) StreamHostEvents(ch chan *discoverd.Event) (stream.Stream, error) {
	return c.Client.StreamHostEvents(ch)
}

var AppNamePattern = regexp.MustCompile(`^[a-z\d]+(-[a-z\d]+)*$`)

func ParseBasicAuth(h http.Header) (username, password string, err error) {
	s := strings.SplitN(h.Get("Authorization"), " ", 2)

	if len(s) != 2 {
		return "", "", errors.New("failed to parse authentication string")
	}
	if s[0] != "Basic" {
		return "", "", fmt.Errorf("authorization scheme is %v, not Basic", s[0])
	}

	c, err := base64.StdEncoding.DecodeString(s[1])
	if err != nil {
		return "", "", errors.New("failed to parse base64 basic credentials")
	}

	s = strings.SplitN(string(c), ":", 2)
	if len(s) != 2 {
		return "", "", errors.New("failed to parse basic credentials")
	}

	return s[0], s[1], nil
}
<commit_msg>controller: Inject Flynn app name to the apps ENV vars<commit_after>package utils

import (
	"encoding/base64"
	"errors"
	"fmt"
	"net/http"
	"regexp"
	"strings"
	"time"

	ct "github.com/flynn/flynn/controller/types"
	"github.com/flynn/flynn/discoverd/client"
	"github.com/flynn/flynn/host/types"
	"github.com/flynn/flynn/host/volume"
	"github.com/flynn/flynn/pkg/cluster"
	"github.com/flynn/flynn/pkg/stream"
)

func JobConfig(f *ct.ExpandedFormation, name, hostID string) *host.Job {
	t := f.Release.Processes[name]
	env := make(map[string]string, len(f.Release.Env)+len(t.Env)+4)
	for k, v := range f.Release.Env {
		env[k] = v
	}
	for k, v := range t.Env {
		env[k] = v
	}
	id := cluster.GenerateJobID(hostID)
	env["FLYNN_APP_ID"] = f.App.ID
	env["FLYNN_APP_NAME"] = f.App.Name
	env["FLYNN_RELEASE_ID"] = f.Release.ID
	env["FLYNN_PROCESS_TYPE"] = name
	env["FLYNN_JOB_ID"] = id
	job := &host.Job{
		ID: id,
		Metadata: map[string]string{
			"flynn-controller.app":      f.App.ID,
			"flynn-controller.app_name": f.App.Name,
			"flynn-controller.release":  f.Release.ID,
			"flynn-controller.type":     name,
		},
		Artifact: host.Artifact{
			Type: f.Artifact.Type,
			URI:  f.Artifact.URI,
		},
		Config: host.ContainerConfig{
			Cmd:         t.Cmd,
			Env:         env,
			HostNetwork: t.HostNetwork,
		},
		Resurrect: t.Resurrect,
		Resources: t.Resources,
	}
	if len(t.Entrypoint) > 0 {
		job.Config.Entrypoint = t.Entrypoint
	}
	job.Config.Ports = make([]host.Port, len(t.Ports))
	for i, p := range t.Ports {
		job.Config.Ports[i].Proto = p.Proto
		job.Config.Ports[i].Port = p.Port
		job.Config.Ports[i].Service = p.Service
	}
	return job
}

func ProvisionVolume(h VolumeCreator, job *host.Job) error {
	vol, err := h.CreateVolume("default")
	if err != nil {
		return err
	}
	job.Config.Volumes = []host.VolumeBinding{{
		Target:    "/data",
		VolumeID:  vol.ID,
		Writeable: true,
	}}
	return nil
}

func JobMetaFromMetadata(metadata map[string]string) map[string]string {
	jobMeta := make(map[string]string, len(metadata))
	for k, v := range metadata {
		if strings.HasPrefix(k, "flynn-controller.") {
			continue
		}
		jobMeta[k] = v
	}
	return jobMeta
}

type FormationKey struct {
	AppID, ReleaseID string
}

func NewFormationKey(appID, releaseID string) FormationKey {
	return FormationKey{AppID: appID, ReleaseID: releaseID}
}

func ExpandFormation(c ControllerClient, f *ct.Formation) (*ct.ExpandedFormation, error) {
	app, err := c.GetApp(f.AppID)
	if err != nil {
		return nil, fmt.Errorf("error getting app: %s", err)
	}

	release, err := c.GetRelease(f.ReleaseID)
	if err != nil {
		return nil, fmt.Errorf("error getting release: %s", err)
	}

	artifact, err := c.GetArtifact(release.ArtifactID)
	if err != nil {
		return nil, fmt.Errorf("error getting artifact: %s", err)
	}

	procs := make(map[string]int)
	for typ, count := range f.Processes {
		procs[typ] = count
	}

	ef := &ct.ExpandedFormation{
		App:       app,
		Release:   release,
		Artifact:  artifact,
		Processes: procs,
		UpdatedAt: time.Now(),
	}
	if f.UpdatedAt != nil {
		ef.UpdatedAt = *f.UpdatedAt
	}
	return ef, nil
}

type VolumeCreator interface {
	CreateVolume(string) (*volume.Info, error)
}

type HostClient interface {
	VolumeCreator
	ID() string
	AddJob(*host.Job) error
	GetJob(id string) (*host.ActiveJob, error)
	Attach(*host.AttachReq, bool) (cluster.AttachClient, error)
	StopJob(string) error
	ListJobs() (map[string]host.ActiveJob, error)
	StreamEvents(id string, ch chan *host.Event) (stream.Stream, error)
	GetStatus() (*host.HostStatus, error)
}

type ClusterClient interface {
	Host(string) (HostClient, error)
	Hosts() ([]HostClient, error)
	StreamHostEvents(chan *discoverd.Event) (stream.Stream, error)
}

type ControllerClient interface {
	GetApp(appID string) (*ct.App, error)
	GetRelease(releaseID string) (*ct.Release, error)
	GetArtifact(artifactID string) (*ct.Artifact, error)
	GetFormation(appID, releaseID string) (*ct.Formation, error)
	CreateApp(app *ct.App) error
	CreateRelease(release *ct.Release) error
	CreateArtifact(artifact *ct.Artifact) error
	PutFormation(formation *ct.Formation) error
	StreamFormations(since *time.Time, ch chan<- *ct.ExpandedFormation) (stream.Stream, error)
	AppList() ([]*ct.App, error)
	FormationList(appID string) ([]*ct.Formation, error)
	PutJob(*ct.Job) error
}

func ClusterClientWrapper(c *cluster.Client) clusterClientWrapper {
	return clusterClientWrapper{c}
}

type clusterClientWrapper struct {
	*cluster.Client
}

func (c clusterClientWrapper) Host(id string) (HostClient, error) {
	return c.Client.Host(id)
}

func (c clusterClientWrapper) Hosts() ([]HostClient, error) {
	hosts, err := c.Client.Hosts()
	if err != nil {
		return nil, err
	}
	res := make([]HostClient, len(hosts))
	for i, h := range hosts {
		res[i] = h
	}
	return res, nil
}

func (c clusterClientWrapper) StreamHostEvents(ch chan *discoverd.Event) (stream.Stream, error) {
	return c.Client.StreamHostEvents(ch)
}

var AppNamePattern = regexp.MustCompile(`^[a-z\d]+(-[a-z\d]+)*$`)

func ParseBasicAuth(h http.Header) (username, password string, err error) {
	s := strings.SplitN(h.Get("Authorization"), " ", 2)

	if len(s) != 2 {
		return "", "", errors.New("failed to parse authentication string")
	}
	if s[0] != "Basic" {
		return "", "", fmt.Errorf("authorization scheme is %v, not Basic", s[0])
	}

	c, err := base64.StdEncoding.DecodeString(s[1])
	if err != nil {
		return "", "", errors.New("failed to parse base64 basic credentials")
	}

	s = strings.SplitN(string(c), ":", 2)
	if len(s) != 2 {
		return "", "", errors.New("failed to parse basic credentials")
	}

	return s[0], s[1], nil
}
<|endoftext|>


<commit_before>package etcdhttp

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"time"

	"code.google.com/p/go.net/context"
	"github.com/coreos/etcd/elog"
	etcdserver "github.com/coreos/etcd/etcdserver2"
	"github.com/coreos/etcd/raft"
	"github.com/coreos/etcd/store"
)

var errClosed = errors.New("etcdhttp: client closed connection")

const DefaultTimeout = 500 * time.Millisecond

type Handler struct {
	Timeout time.Duration
	Server  etcdserver.Server
}

func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	// TODO: set read/write timeout?

	timeout := h.Timeout
	if timeout == 0 {
		timeout = DefaultTimeout
	}

	ctx, cancel := context.WithTimeout(context.Background(), timeout)
	defer cancel()

	switch {
	case strings.HasPrefix(r.URL.Path, "/raft"):
		h.serveRaft(ctx, w, r)
	case strings.HasPrefix(r.URL.Path, "/keys/"):
		h.serveKeys(ctx, w, r)
	default:
		http.NotFound(w, r)
	}
}

func (h Handler) serveKeys(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	rr, err := parseRequest(r)
	if err != nil {
		http.Error(w, err.Error(), 400)
		return
	}

	resp, err := h.Server.Do(ctx, rr)
	if err != nil {
		// TODO(bmizerany): switch on store errors and etcdserver.ErrUnknownMethod
		panic("TODO")
	}

	if err := encodeResponse(ctx, w, resp); err != nil {
		http.Error(w, "Timeout while waiting for response", 504)
	}
}

func (h Handler) serveRaft(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	b, err := ioutil.ReadAll(r.Body)
	if err != nil {
		elog.TODO()
	}
	var m raft.Message
	if err := m.Unmarshal(b); err != nil {
		elog.TODO()
	}
	if err := h.Server.Node.Step(ctx, m); err != nil {
		elog.TODO()
	}
}

func parseRequest(r *http.Request) (etcdserver.Request, error) {
	return etcdserver.Request{}, nil
}

func encodeResponse(ctx context.Context, w http.ResponseWriter, resp etcdserver.Response) (err error) {
	var ev *store.Event
	switch {
	case resp.Event != nil:
		ev = resp.Event
	case resp.Watcher != nil:
		ev, err = waitForEvent(ctx, w, resp.Watcher)
		if err != nil {
			return err
		}
	default:
		panic("should not be reachable")
	}

	w.Header().Set("Content-Type", "application/json")
	w.Header().Add("X-Etcd-Index", fmt.Sprint(ev.Index()))

	if ev.IsCreated() {
		w.WriteHeader(http.StatusCreated)
	} else {
		w.WriteHeader(http.StatusOK)
	}

	if err := json.NewEncoder(w).Encode(ev); err != nil {
		panic(err) // should never be reached
	}
	return nil
}

func waitForEvent(ctx context.Context, w http.ResponseWriter, wa *store.Watcher) (*store.Event, error) {
	// TODO(bmizerany): support streaming?
	defer wa.Remove()
	var nch <-chan bool
	if x, ok := w.(http.CloseNotifier); ok {
		nch = x.CloseNotify()
	}

	select {
	case ev := <-wa.EventChan:
		return ev, nil
	case <-nch:
		elog.TODO()
		return nil, errClosed
	case <-ctx.Done():
		return nil, ctx.Err()
	}
}
<commit_msg>etcdserver/etcdhttp: parseRequest<commit_after>package etcdhttp

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"strconv"
	"strings"
	"time"

	"code.google.com/p/go.net/context"
	"github.com/coreos/etcd/elog"
	etcdserver "github.com/coreos/etcd/etcdserver2"
	"github.com/coreos/etcd/raft"
	"github.com/coreos/etcd/store"
)

var errClosed = errors.New("etcdhttp: client closed connection")

const DefaultTimeout = 500 * time.Millisecond

type Handler struct {
	Timeout time.Duration
	Server  etcdserver.Server
}

func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	// TODO: set read/write timeout?

	timeout := h.Timeout
	if timeout == 0 {
		timeout = DefaultTimeout
	}

	ctx, cancel := context.WithTimeout(context.Background(), timeout)
	defer cancel()

	switch {
	case strings.HasPrefix(r.URL.Path, "/raft"):
		h.serveRaft(ctx, w, r)
	case strings.HasPrefix(r.URL.Path, "/keys/"):
		h.serveKeys(ctx, w, r)
	default:
		http.NotFound(w, r)
	}
}

func (h Handler) serveKeys(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	rr, err := parseRequest(r)
	if err != nil {
		http.Error(w, err.Error(), 400)
		return
	}

	resp, err := h.Server.Do(ctx, rr)
	if err != nil {
		// TODO(bmizerany): switch on store errors and etcdserver.ErrUnknownMethod
		panic("TODO")
	}

	if err := encodeResponse(ctx, w, resp); err != nil {
		http.Error(w, "Timeout while waiting for response", 504)
	}
}

func (h Handler) serveRaft(ctx context.Context, w http.ResponseWriter, r *http.Request) {
	b, err := ioutil.ReadAll(r.Body)
	if err != nil {
		elog.TODO()
	}
	var m raft.Message
	if err := m.Unmarshal(b); err != nil {
		elog.TODO()
	}
	if err := h.Server.Node.Step(ctx, m); err != nil {
		elog.TODO()
	}
}

func genId() int64 {
	panic("implement me")
}

func parseRequest(r *http.Request) (etcdserver.Request, error) {
	q := r.URL.Query()
	rr := etcdserver.Request{
		Id:        genId(),
		Method:    r.Method,
		Path:      r.URL.Path[len("/keys/"):],
		Val:       q.Get("value"),
		PrevValue: q.Get("prevValue"),
		PrevIndex: parseUint64(q.Get("prevIndex")),
		Recursive: parseBool(q.Get("recursive")),
		Since:     parseUint64(q.Get("waitIndex")),
		Sorted:    parseBool(q.Get("sorted")),
		Wait:      parseBool(q.Get("wait")),
	}

	// PrevExists is nullable, so we leave it null if prevExist wasn't
	// specified.
	_, ok := q["wait"]
	if ok {
		bv := parseBool(q.Get("wait"))
		rr.PrevExists = &bv
	}

	ttl := parseUint64(q.Get("ttl"))
	if ttl > 0 {
		expr := time.Duration(ttl) * time.Second
		rr.Expiration = time.Now().Add(expr).UnixNano()
	}

	return rr, nil
}

func parseBool(s string) bool {
	v, _ := strconv.ParseBool(s)
	return v
}

func parseUint64(s string) uint64 {
	v, _ := strconv.ParseUint(s, 10, 64)
	return v
}

func encodeResponse(ctx context.Context, w http.ResponseWriter, resp etcdserver.Response) (err error) {
	var ev *store.Event
	switch {
	case resp.Event != nil:
		ev = resp.Event
	case resp.Watcher != nil:
		ev, err = waitForEvent(ctx, w, resp.Watcher)
		if err != nil {
			return err
		}
	default:
		panic("should not be reachable")
	}

	w.Header().Set("Content-Type", "application/json")
	w.Header().Add("X-Etcd-Index", fmt.Sprint(ev.Index()))

	if ev.IsCreated() {
		w.WriteHeader(http.StatusCreated)
	} else {
		w.WriteHeader(http.StatusOK)
	}

	if err := json.NewEncoder(w).Encode(ev); err != nil {
		panic(err) // should never be reached
	}
	return nil
}

func waitForEvent(ctx context.Context, w http.ResponseWriter, wa *store.Watcher) (*store.Event, error) {
	// TODO(bmizerany): support streaming?
	defer wa.Remove()
	var nch <-chan bool
	if x, ok := w.(http.CloseNotifier); ok {
		nch = x.CloseNotify()
	}

	select {
	case ev := <-wa.EventChan:
		return ev, nil
	case <-nch:
		elog.TODO()
		return nil, errClosed
	case <-ctx.Done():
		return nil, ctx.Err()
	}
}
<|endoftext|>


<commit_before>package ethchain

import (
	"fmt"
	"github.com/ethereum/eth-go/ethtrie"
	"github.com/ethereum/eth-go/ethutil"
	"math/big"
)

/*
 * The State transitioning model
 *
 * A state transition is a change made when a transaction is applied to the current world state
 * The state transitioning model does all all the necessary work to work out a valid new state root.
 * 1) Nonce handling
 * 2) Pre pay / buy gas of the coinbase (miner)
 * 3) Create a new state object if the recipient is \0*32
 * 4) Value transfer
 * == If contract creation ==
 * 4a) Attempt to run transaction data
 * 4b) If valid, use result as code for the new state object
 * == end ==
 * 5) Run Script section
 * 6) Derive new state root
 */
type StateTransition struct {
	coinbase, receiver []byte
	tx                 *Transaction
	gas, gasPrice      *big.Int
	value              *big.Int
	data               []byte
	state              *State
	block              *Block

	cb, rec, sen *StateObject
}

func NewStateTransition(coinbase *StateObject, tx *Transaction, state *State, block *Block) *StateTransition {
	return &StateTransition{coinbase.Address(), tx.Recipient, tx, new(big.Int), new(big.Int).Set(tx.GasPrice), tx.Value, tx.Data, state, block, coinbase, nil, nil}
}

func (self *StateTransition) Coinbase() *StateObject {
	if self.cb != nil {
		return self.cb
	}

	self.cb = self.state.GetAccount(self.coinbase)
	return self.cb
}
func (self *StateTransition) Sender() *StateObject {
	if self.sen != nil {
		return self.sen
	}

	self.sen = self.state.GetAccount(self.tx.Sender())

	return self.sen
}
func (self *StateTransition) Receiver() *StateObject {
	if self.tx != nil && self.tx.CreatesContract() {
		return nil
	}

	if self.rec != nil {
		return self.rec
	}

	self.rec = self.state.GetAccount(self.tx.Recipient)
	return self.rec
}

func (self *StateTransition) MakeStateObject(state *State, tx *Transaction) *StateObject {
	contract := MakeContract(tx, state)

	return contract
}

func (self *StateTransition) UseGas(amount *big.Int) error {
	if self.gas.Cmp(amount) < 0 {
		return OutOfGasError()
	}
	self.gas.Sub(self.gas, amount)

	return nil
}

func (self *StateTransition) AddGas(amount *big.Int) {
	self.gas.Add(self.gas, amount)
}

func (self *StateTransition) BuyGas() error {
	var err error

	sender := self.Sender()
	if sender.Amount.Cmp(self.tx.GasValue()) < 0 {
		return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", self.tx.GasValue(), sender.Amount)
	}

	coinbase := self.Coinbase()
	err = coinbase.BuyGas(self.tx.Gas, self.tx.GasPrice)
	if err != nil {
		return err
	}

	self.AddGas(self.tx.Gas)
	sender.SubAmount(self.tx.GasValue())

	return nil
}

func (self *StateTransition) RefundGas() {
	coinbase, sender := self.Coinbase(), self.Sender()
	coinbase.RefundGas(self.gas, self.tx.GasPrice)

	// Return remaining gas
	remaining := new(big.Int).Mul(self.gas, self.tx.GasPrice)
	sender.AddAmount(remaining)
}

func (self *StateTransition) preCheck() (err error) {
	var (
		tx     = self.tx
		sender = self.Sender()
	)

	// Make sure this transaction's nonce is correct
	if sender.Nonce != tx.Nonce {
		return NonceError(tx.Nonce, sender.Nonce)
	}

	// Pre-pay gas / Buy gas of the coinbase account
	if err = self.BuyGas(); err != nil {
		return err
	}

	return nil
}

func (self *StateTransition) TransitionState() (err error) {
	statelogger.Infof("(~) %x\n", self.tx.Hash())

	/*
		defer func() {
			if r := recover(); r != nil {
				logger.Infoln(r)
				err = fmt.Errorf("state transition err %v", r)
			}
		}()
	*/

	// XXX Transactions after this point are considered valid.
	if err = self.preCheck(); err != nil {
		return
	}

	var (
		tx       = self.tx
		sender   = self.Sender()
		receiver *StateObject
	)

	defer self.RefundGas()

	// Increment the nonce for the next transaction
	sender.Nonce += 1

	// Transaction gas
	if err = self.UseGas(GasTx); err != nil {
		return
	}

	// Pay data gas
	dataPrice := big.NewInt(int64(len(self.data)))
	dataPrice.Mul(dataPrice, GasData)
	if err = self.UseGas(dataPrice); err != nil {
		return
	}

	/* FIXME
	 * If tx goes TO "0", goes OOG during init, reverse changes, but initial endowment should happen. The ether is lost forever
	 */
	var snapshot *State

	// If the receiver is nil it's a contract (\0*32).
	if tx.CreatesContract() {
		snapshot = self.state.Copy()

		// Create a new state object for the contract
		receiver = self.MakeStateObject(self.state, tx)
		self.rec = receiver
		if receiver == nil {
			return fmt.Errorf("Unable to create contract")
		}
	} else {
		receiver = self.Receiver()
	}

	// Transfer value from sender to receiver
	if err = self.transferValue(sender, receiver); err != nil {
		return
	}

	if snapshot == nil {
		snapshot = self.state.Copy()
	}

	// Process the init code and create 'valid' contract
	if IsContractAddr(self.receiver) {
		// Evaluate the initialization script
		// and use the return value as the
		// script section for the state object.
		self.data = nil

		code, err := self.Eval(receiver.Init(), receiver, "init")
		if err != nil {
			self.state.Set(snapshot)

			return fmt.Errorf("Error during init execution %v", err)
		}

		receiver.script = code
	} else {
		if len(receiver.Script()) > 0 {
			_, err = self.Eval(receiver.Script(), receiver, "code")
			if err != nil {
				self.state.Set(snapshot)

				return fmt.Errorf("Error during code execution %v", err)
			}
		}
	}

	return
}

func (self *StateTransition) transferValue(sender, receiver *StateObject) error {
	if sender.Amount.Cmp(self.value) < 0 {
		return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Amount)
	}

	// Subtract the amount from the senders account
	sender.SubAmount(self.value)
	// Add the amount to receivers account which should conclude this transaction
	receiver.AddAmount(self.value)

	return nil
}

func (self *StateTransition) Eval(script []byte, context *StateObject, typ string) (ret []byte, err error) {
	var (
		block     = self.block
		initiator = self.Sender()
		state     = self.state
	)

	closure := NewClosure(initiator, context, script, state, self.gas, self.gasPrice)
	vm := NewVm(state, nil, RuntimeVars{
		Origin:      initiator.Address(),
		Block:       block,
		BlockNumber: block.Number,
		PrevHash:    block.PrevHash,
		Coinbase:    block.Coinbase,
		Time:        block.Time,
		Diff:        block.Difficulty,
		Value:       self.value,
	})
	vm.Verbose = true
	vm.Fn = typ

	ret, err = Call(vm, closure, self.data)

	return
}

func Call(vm *Vm, closure *Closure, data []byte) (ret []byte, err error) {
	ret, _, err = closure.Call(vm, data)

	if ethutil.Config.Paranoia {
		var (
			context = closure.object
			trie    = context.state.trie
		)

		valid, t2 := ethtrie.ParanoiaCheck(trie)
		if !valid {
			// TODO FIXME ASAP
			context.state.trie = t2

			statelogger.Infoln("Warn: PARANOIA: Different state object roots during copy")
		}
	}

	return
}
<commit_msg>Paranoia check moved<commit_after>package ethchain

import (
	"fmt"
	"math/big"
)

/*
 * The State transitioning model
 *
 * A state transition is a change made when a transaction is applied to the current world state
 * The state transitioning model does all all the necessary work to work out a valid new state root.
 * 1) Nonce handling
 * 2) Pre pay / buy gas of the coinbase (miner)
 * 3) Create a new state object if the recipient is \0*32
 * 4) Value transfer
 * == If contract creation ==
 * 4a) Attempt to run transaction data
 * 4b) If valid, use result as code for the new state object
 * == end ==
 * 5) Run Script section
 * 6) Derive new state root
 */
type StateTransition struct {
	coinbase, receiver []byte
	tx                 *Transaction
	gas, gasPrice      *big.Int
	value              *big.Int
	data               []byte
	state              *State
	block              *Block

	cb, rec, sen *StateObject
}

func NewStateTransition(coinbase *StateObject, tx *Transaction, state *State, block *Block) *StateTransition {
	return &StateTransition{coinbase.Address(), tx.Recipient, tx, new(big.Int), new(big.Int).Set(tx.GasPrice), tx.Value, tx.Data, state, block, coinbase, nil, nil}
}

func (self *StateTransition) Coinbase() *StateObject {
	if self.cb != nil {
		return self.cb
	}

	self.cb = self.state.GetAccount(self.coinbase)
	return self.cb
}
func (self *StateTransition) Sender() *StateObject {
	if self.sen != nil {
		return self.sen
	}

	self.sen = self.state.GetAccount(self.tx.Sender())

	return self.sen
}
func (self *StateTransition) Receiver() *StateObject {
	if self.tx != nil && self.tx.CreatesContract() {
		return nil
	}

	if self.rec != nil {
		return self.rec
	}

	self.rec = self.state.GetAccount(self.tx.Recipient)
	return self.rec
}

func (self *StateTransition) MakeStateObject(state *State, tx *Transaction) *StateObject {
	contract := MakeContract(tx, state)

	return contract
}

func (self *StateTransition) UseGas(amount *big.Int) error {
	if self.gas.Cmp(amount) < 0 {
		return OutOfGasError()
	}
	self.gas.Sub(self.gas, amount)

	return nil
}

func (self *StateTransition) AddGas(amount *big.Int) {
	self.gas.Add(self.gas, amount)
}

func (self *StateTransition) BuyGas() error {
	var err error

	sender := self.Sender()
	if sender.Amount.Cmp(self.tx.GasValue()) < 0 {
		return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", self.tx.GasValue(), sender.Amount)
	}

	coinbase := self.Coinbase()
	err = coinbase.BuyGas(self.tx.Gas, self.tx.GasPrice)
	if err != nil {
		return err
	}

	self.AddGas(self.tx.Gas)
	sender.SubAmount(self.tx.GasValue())

	return nil
}

func (self *StateTransition) RefundGas() {
	coinbase, sender := self.Coinbase(), self.Sender()
	coinbase.RefundGas(self.gas, self.tx.GasPrice)

	// Return remaining gas
	remaining := new(big.Int).Mul(self.gas, self.tx.GasPrice)
	sender.AddAmount(remaining)
}

func (self *StateTransition) preCheck() (err error) {
	var (
		tx     = self.tx
		sender = self.Sender()
	)

	// Make sure this transaction's nonce is correct
	if sender.Nonce != tx.Nonce {
		return NonceError(tx.Nonce, sender.Nonce)
	}

	// Pre-pay gas / Buy gas of the coinbase account
	if err = self.BuyGas(); err != nil {
		return err
	}

	return nil
}

func (self *StateTransition) TransitionState() (err error) {
	statelogger.Infof("(~) %x\n", self.tx.Hash())

	/*
		defer func() {
			if r := recover(); r != nil {
				logger.Infoln(r)
				err = fmt.Errorf("state transition err %v", r)
			}
		}()
	*/

	// XXX Transactions after this point are considered valid.
	if err = self.preCheck(); err != nil {
		return
	}

	var (
		tx       = self.tx
		sender   = self.Sender()
		receiver *StateObject
	)

	defer self.RefundGas()

	// Increment the nonce for the next transaction
	sender.Nonce += 1

	// Transaction gas
	if err = self.UseGas(GasTx); err != nil {
		return
	}

	// Pay data gas
	dataPrice := big.NewInt(int64(len(self.data)))
	dataPrice.Mul(dataPrice, GasData)
	if err = self.UseGas(dataPrice); err != nil {
		return
	}

	/* FIXME
	 * If tx goes TO "0", goes OOG during init, reverse changes, but initial endowment should happen. The ether is lost forever
	 */
	var snapshot *State

	// If the receiver is nil it's a contract (\0*32).
	if tx.CreatesContract() {
		snapshot = self.state.Copy()

		// Create a new state object for the contract
		receiver = self.MakeStateObject(self.state, tx)
		self.rec = receiver
		if receiver == nil {
			return fmt.Errorf("Unable to create contract")
		}
	} else {
		receiver = self.Receiver()
	}

	// Transfer value from sender to receiver
	if err = self.transferValue(sender, receiver); err != nil {
		return
	}

	if snapshot == nil {
		snapshot = self.state.Copy()
	}

	// Process the init code and create 'valid' contract
	if IsContractAddr(self.receiver) {
		// Evaluate the initialization script
		// and use the return value as the
		// script section for the state object.
		self.data = nil

		code, err := self.Eval(receiver.Init(), receiver, "init")
		if err != nil {
			self.state.Set(snapshot)

			return fmt.Errorf("Error during init execution %v", err)
		}

		receiver.script = code
	} else {
		if len(receiver.Script()) > 0 {
			_, err = self.Eval(receiver.Script(), receiver, "code")
			if err != nil {
				self.state.Set(snapshot)

				return fmt.Errorf("Error during code execution %v", err)
			}
		}
	}

	return
}

func (self *StateTransition) transferValue(sender, receiver *StateObject) error {
	if sender.Amount.Cmp(self.value) < 0 {
		return fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", self.value, sender.Amount)
	}

	// Subtract the amount from the senders account
	sender.SubAmount(self.value)
	// Add the amount to receivers account which should conclude this transaction
	receiver.AddAmount(self.value)

	return nil
}

func (self *StateTransition) Eval(script []byte, context *StateObject, typ string) (ret []byte, err error) {
	var (
		block     = self.block
		initiator = self.Sender()
		state     = self.state
	)

	closure := NewClosure(initiator, context, script, state, self.gas, self.gasPrice)
	vm := NewVm(state, nil, RuntimeVars{
		Origin:      initiator.Address(),
		Block:       block,
		BlockNumber: block.Number,
		PrevHash:    block.PrevHash,
		Coinbase:    block.Coinbase,
		Time:        block.Time,
		Diff:        block.Difficulty,
		Value:       self.value,
	})
	vm.Verbose = true
	vm.Fn = typ

	ret, err = Call(vm, closure, self.data)

	return
}

func Call(vm *Vm, closure *Closure, data []byte) (ret []byte, err error) {
	ret, _, err = closure.Call(vm, data)

	return
}
<|endoftext|>


<commit_before>// Copyright 2016 Richard Hawkins
//
// 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 app manages the main game loop.

package main

import (
	_ "image/png"
	"log"
	"runtime"

	"github.com/go-gl/gl/v4.1-core/gl"
	"github.com/go-gl/glfw/v3.1/glfw"
	"github.com/go-gl/mathgl/mgl32"
	"github.com/hurricanerix/shade/display"
	"github.com/hurricanerix/shade/events"
	"github.com/hurricanerix/shade/light"
	"github.com/hurricanerix/shade/sprite"
)

const windowWidth = 640
const windowHeight = 480

func init() {
	// GLFW event handling must run on the main OS thread
	runtime.LockOSThread()
}

func main() {
	screen, err := display.SetMode("03-lighting", windowWidth, windowHeight)
	if err != nil {
		log.Fatalln("failed to set display mode:", err)
	}
	ambientColor := mgl32.Vec4{0.2, 0.2, 0.2, 1.0}

	face, err := loadSprite("color.png", "normal.png", 1, 1)
	if err != nil {
		panic(err)
	}
	face.Bind(screen.Program)

	light := light.Positional{
		Pos:   mgl32.Vec3{0.5, 0.5, 1.0},
		Color: mgl32.Vec4{0.8, 0.8, 1.0, 1.0},
		Power: 1000,
	}

	for running := true; running; {
		screen.Fill(0.0, 0.0, 0.0)

		// TODO move this somewhere else (maybe a Clear method of display
		gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)

		// TODO refector events to be cleaner
		if screen.Window.ShouldClose() {
			running = !screen.Window.ShouldClose()
		}

		for _, event := range events.Get() {
			if event.KeyEvent && event.Action == glfw.Press && event.Key == glfw.KeyEscape {
				running = false
				event.Window.SetShouldClose(true)
			}
			if !event.KeyEvent {
				light.Pos[0] = event.X
				light.Pos[1] = float32(windowHeight) - event.Y
			}
		}

		pos := mgl32.Vec3{
			windowWidth/2 - float32(face.Width)/2,
			windowHeight/2 - float32(face.Height)/2,
			0}
		e := sprite.Effects{
			Scale:          mgl32.Vec3{1.0, 1.0, 1.0},
			EnableLighting: true,
			AmbientColor:   ambientColor,
			Light:          light,
		}
		face.Draw(pos, &e)

		screen.Flip()

		// TODO refector events to be cleaner
		glfw.PollEvents()
	}

}

func loadSprite(colorPath, normalPath string, framesWide, framesHigh int) (*sprite.Context, error) {
	c, err := sprite.Load(colorPath)
	if err != nil {
		return nil, err
	}

	n, err := sprite.Load(normalPath)
	if err != nil {
		return nil, err
	}

	s, err := sprite.New(c, n, framesWide, framesHigh)
	if err != nil {
		return nil, err
	}

	return s, nil
}
<commit_msg>Fix lighting<commit_after>// Copyright 2016 Richard Hawkins
//
// 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 app manages the main game loop.

package main

import (
	_ "image/png"
	"log"
	"runtime"

	"github.com/go-gl/gl/v4.1-core/gl"
	"github.com/go-gl/glfw/v3.1/glfw"
	"github.com/go-gl/mathgl/mgl32"
	"github.com/hurricanerix/shade/display"
	"github.com/hurricanerix/shade/events"
	"github.com/hurricanerix/shade/light"
	"github.com/hurricanerix/shade/sprite"
)

const windowWidth = 640
const windowHeight = 480

func init() {
	// GLFW event handling must run on the main OS thread
	runtime.LockOSThread()
}

func main() {
	screen, err := display.SetMode("03-lighting", windowWidth, windowHeight)
	if err != nil {
		log.Fatalln("failed to set display mode:", err)
	}
	ambientColor := mgl32.Vec4{0.2, 0.2, 0.2, 1.0}

	face, err := loadSprite("color.png", "normal.png", 1, 1)
	if err != nil {
		panic(err)
	}
	face.Bind(screen.Program)

	light := light.Positional{
		Pos:   mgl32.Vec3{0.5, 0.5, 100.0},
		Color: mgl32.Vec4{0.8, 0.8, 1.0, 1.0},
		Power: 10000,
	}

	for running := true; running; {
		screen.Fill(0.0, 0.0, 0.0)

		// TODO move this somewhere else (maybe a Clear method of display
		gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)

		// TODO refector events to be cleaner
		if screen.Window.ShouldClose() {
			running = !screen.Window.ShouldClose()
		}

		for _, event := range events.Get() {
			if event.KeyEvent && event.Action == glfw.Press && event.Key == glfw.KeyEscape {
				running = false
				event.Window.SetShouldClose(true)
			}
			if !event.KeyEvent {
				light.Pos[0] = event.X
				light.Pos[1] = float32(windowHeight) - event.Y
			}
		}

		pos := mgl32.Vec3{
			windowWidth/2 - float32(face.Width)/2,
			windowHeight/2 - float32(face.Height)/2,
			0}
		e := sprite.Effects{
			Scale:          mgl32.Vec3{1.0, 1.0, 1.0},
			EnableLighting: true,
			AmbientColor:   ambientColor,
			Light:          light,
		}
		face.Draw(pos, &e)

		screen.Flip()

		// TODO refector events to be cleaner
		glfw.PollEvents()
	}

}

func loadSprite(colorPath, normalPath string, framesWide, framesHigh int) (*sprite.Context, error) {
	c, err := sprite.Load(colorPath)
	if err != nil {
		return nil, err
	}

	n, err := sprite.Load(normalPath)
	if err != nil {
		return nil, err
	}

	s, err := sprite.New(c, n, framesWide, framesHigh)
	if err != nil {
		return nil, err
	}

	return s, nil
}
<|endoftext|>


<commit_before>package errgroup

import (
	"errors"
	"fmt"
	"sort"
	"strings"
)

// Check reports whether the "err" is not nil.
// If it is a group then it returns true if that or its children contains any error.
func Check(err error) error {
	if isNotNil(err) {
		return err
	}

	return nil
}

// Walk loops through each of the errors of "err".
// If "err" is *Group then it fires the "visitor" for each of its errors, including children.
// if "err" is *Error then it fires the "visitor" with its type and wrapped error.
// Otherwise it fires the "visitor" once with typ of nil and err as "err".
func Walk(err error, visitor func(typ interface{}, err error)) error {
	if err == nil {
		return nil
	}

	if group, ok := err.(*Group); ok {
		list := group.getAllErrors()
		for _, entry := range list {
			if e, ok := entry.(*Error); ok {
				visitor(e.Type, e.Err) // e.Unwrap() <-no.
			} else {
				visitor(nil, err)
			}
		}
	} else if e, ok := err.(*Error); ok {
		visitor(e.Type, e.Err)
	} else {
		visitor(nil, err)
	}

	return err
}

/*
func Errors(err error, conv bool) []error {
	if err == nil {
		return nil
	}

	if group, ok := err.(*Group); ok {
		list := group.getAllErrors()
		if conv {
			for i, entry := range list {
				if _, ok := entry.(*Error); !ok {
					list[i] = &Error{Err: entry, Type: group.Type}
				}
			}
		}

		return list
	}

	return []error{err}
}

func Type(err error) interface{} {
	if err == nil {
		return nil
	}

	if e, ok := err.(*Error); ok && e.Err != nil {
		return e.Type
	}

	return nil
}

func Fill(parent *Group, errors []*Error) {
	for _, err := range errors {
		if err.Type == parent.Type {
			parent.Add(err)
			continue
		}

		parent.Group(err.Type).Err(err)
	}
	return
}
*/

// Error implements the error interface.
// It is a special error type which keep the "Type" of the
// Group that it's created through Group's `Err` and `Errf` methods.
type Error struct {
	Err  error       `json:"error" xml:"Error" yaml:"Error" toml:"Error" sql:"error"`
	Type interface{} `json:"type" xml:"Type" yaml:"Type" toml:"Type" sql:"type"`
}

// Error returns the error message of the "Err".
func (e *Error) Error() string {
	return e.Err.Error()
}

// Unwrap calls and returns the result of the "Err" Unwrap method or nil.
func (e *Error) Unwrap() error {
	return errors.Unwrap(e.Err)
}

// Is reports whether the "err" is an *Error.
func (e *Error) Is(err error) bool {
	if err == nil {
		return false
	}

	ok := errors.Is(e.Err, err)
	if !ok {
		te, ok := err.(*Error)
		if !ok {
			return false
		}

		return errors.Is(e.Err, te.Err)
	}

	return ok
}

// As reports whether the "target" can be used as &Error{target.Type: ?}.
func (e *Error) As(target interface{}) bool {
	if target == nil {
		return target == e
	}

	ok := errors.As(e.Err, target)
	if !ok {
		te, ok := target.(*Error)
		if !ok {
			return false
		}

		if te.Type != nil {
			if te.Type != e.Type {
				return false
			}
		}

		return errors.As(e.Err, &te.Err)
	}

	return ok
}

// Group is an error container of a specific Type and can have child containers per type too.
type Group struct {
	parent *Group
	// a list of children groups, used to get or create new group through Group method.
	children map[interface{}]*Group
	depth    int

	Type   interface{}
	Errors []error // []*Error

	// if true then this Group's Error method will return the messages of the errors made by this Group's Group method.
	// Defaults to true.
	IncludeChildren bool // it clones.
	// IncludeTypeText bool
	index int // group index.
}

// New returns a new empty Group.
func New(typ interface{}) *Group {
	return &Group{
		Type:            typ,
		IncludeChildren: true,
	}
}

const delim = "\n"

func (g *Group) Error() (s string) {
	if len(g.Errors) > 0 {
		msgs := make([]string, len(g.Errors), len(g.Errors))
		for i, err := range g.Errors {
			msgs[i] = err.Error()
		}

		s = strings.Join(msgs, delim)
	}

	if g.IncludeChildren && len(g.children) > 0 {
		// return with order of definition.
		groups := g.getAllChildren()
		sortGroups(groups)

		for _, ge := range groups {
			for _, childErr := range ge.Errors {
				s += childErr.Error() + delim
			}
		}

		if s != "" {
			return s[:len(s)-1]
		}
	}

	return
}

func (g *Group) getAllErrors() []error {
	list := g.Errors[:]

	if len(g.children) > 0 {
		// return with order of definition.
		groups := g.getAllChildren()
		sortGroups(groups)

		for _, ge := range groups {
			list = append(list, ge.Errors...)
		}
	}

	return list
}

func (g *Group) getAllChildren() []*Group {
	if len(g.children) == 0 {
		return nil
	}

	var groups []*Group
	for _, child := range g.children {
		groups = append(groups, append([]*Group{child}, child.getAllChildren()...)...)
	}

	return groups
}

// Unwrap implements the dynamic std errors interface and it returns the parent Group.
func (g *Group) Unwrap() error {
	return g.parent
}

// Group creates a new group of "typ" type, if does not exist, and returns it.
func (g *Group) Group(typ interface{}) *Group {
	if g.children == nil {
		g.children = make(map[interface{}]*Group)
	} else {
		for _, child := range g.children {
			if child.Type == typ {
				return child
			}
		}
	}

	child := &Group{
		Type:            typ,
		parent:          g,
		depth:           g.depth + 1,
		IncludeChildren: g.IncludeChildren,
		index:           g.index + 1 + len(g.children),
	}

	g.children[typ] = child

	return child
}

// Add adds an error to the group.
func (g *Group) Add(err error) {
	if err == nil {
		return
	}

	g.Errors = append(g.Errors, err)
}

// Addf adds an error to the group like `fmt.Errorf` and returns it.
func (g *Group) Addf(format string, args ...interface{}) error {
	err := fmt.Errorf(format, args...)
	g.Add(err)
	return err
}

// Err adds an error the the group, it transforms it to an Error type if necessary and returns it.
func (g *Group) Err(err error) error {
	if err == nil {
		return nil
	}

	e, ok := err.(*Error)
	if !ok {
		if ge, ok := err.(*Group); ok {
			if g.children == nil {
				g.children = make(map[interface{}]*Group)
			}

			g.children[ge.Type] = ge
			return ge
		}

		e = &Error{err, 0}
	}
	e.Type = g.Type

	g.Add(e)
	return e
}

// Errf adds an error like `fmt.Errorf` and returns it.
func (g *Group) Errf(format string, args ...interface{}) error {
	return g.Err(fmt.Errorf(format, args...))
}

func sortGroups(groups []*Group) {
	sort.Slice(groups, func(i, j int) bool {
		return groups[i].index < groups[j].index
	})
}

func tryGetTypeText(typ interface{}) string {
	if typ == nil {
		return ""
	}

	switch v := typ.(type) {
	case string:
		return v
	case fmt.Stringer:
		return v.String()
	default:
		return ""
	}
}

func isNotNil(err error) bool {
	if g, ok := err.(*Group); ok {
		if len(g.Errors) > 0 {
			return true
		}

		if len(g.children) > 0 {
			for _, child := range g.children {
				if isNotNil(child) {
					return true
				}
			}
		}

		return false
	}

	return err != nil
}
<commit_msg>Fix typo<commit_after>package errgroup

import (
	"errors"
	"fmt"
	"sort"
	"strings"
)

// Check reports whether the "err" is not nil.
// If it is a group then it returns true if that or its children contains any error.
func Check(err error) error {
	if isNotNil(err) {
		return err
	}

	return nil
}

// Walk loops through each of the errors of "err".
// If "err" is *Group then it fires the "visitor" for each of its errors, including children.
// if "err" is *Error then it fires the "visitor" with its type and wrapped error.
// Otherwise it fires the "visitor" once with typ of nil and err as "err".
func Walk(err error, visitor func(typ interface{}, err error)) error {
	if err == nil {
		return nil
	}

	if group, ok := err.(*Group); ok {
		list := group.getAllErrors()
		for _, entry := range list {
			if e, ok := entry.(*Error); ok {
				visitor(e.Type, e.Err) // e.Unwrap() <-no.
			} else {
				visitor(nil, err)
			}
		}
	} else if e, ok := err.(*Error); ok {
		visitor(e.Type, e.Err)
	} else {
		visitor(nil, err)
	}

	return err
}

/*
func Errors(err error, conv bool) []error {
	if err == nil {
		return nil
	}

	if group, ok := err.(*Group); ok {
		list := group.getAllErrors()
		if conv {
			for i, entry := range list {
				if _, ok := entry.(*Error); !ok {
					list[i] = &Error{Err: entry, Type: group.Type}
				}
			}
		}

		return list
	}

	return []error{err}
}

func Type(err error) interface{} {
	if err == nil {
		return nil
	}

	if e, ok := err.(*Error); ok && e.Err != nil {
		return e.Type
	}

	return nil
}

func Fill(parent *Group, errors []*Error) {
	for _, err := range errors {
		if err.Type == parent.Type {
			parent.Add(err)
			continue
		}

		parent.Group(err.Type).Err(err)
	}
	return
}
*/

// Error implements the error interface.
// It is a special error type which keep the "Type" of the
// Group that it's created through Group's `Err` and `Errf` methods.
type Error struct {
	Err  error       `json:"error" xml:"Error" yaml:"Error" toml:"Error" sql:"error"`
	Type interface{} `json:"type" xml:"Type" yaml:"Type" toml:"Type" sql:"type"`
}

// Error returns the error message of the "Err".
func (e *Error) Error() string {
	return e.Err.Error()
}

// Unwrap calls and returns the result of the "Err" Unwrap method or nil.
func (e *Error) Unwrap() error {
	return errors.Unwrap(e.Err)
}

// Is reports whether the "err" is an *Error.
func (e *Error) Is(err error) bool {
	if err == nil {
		return false
	}

	ok := errors.Is(e.Err, err)
	if !ok {
		te, ok := err.(*Error)
		if !ok {
			return false
		}

		return errors.Is(e.Err, te.Err)
	}

	return ok
}

// As reports whether the "target" can be used as &Error{target.Type: ?}.
func (e *Error) As(target interface{}) bool {
	if target == nil {
		return target == e
	}

	ok := errors.As(e.Err, target)
	if !ok {
		te, ok := target.(*Error)
		if !ok {
			return false
		}

		if te.Type != nil {
			if te.Type != e.Type {
				return false
			}
		}

		return errors.As(e.Err, &te.Err)
	}

	return ok
}

// Group is an error container of a specific Type and can have child containers per type too.
type Group struct {
	parent *Group
	// a list of children groups, used to get or create new group through Group method.
	children map[interface{}]*Group
	depth    int

	Type   interface{}
	Errors []error // []*Error

	// if true then this Group's Error method will return the messages of the errors made by this Group's Group method.
	// Defaults to true.
	IncludeChildren bool // it clones.
	// IncludeTypeText bool
	index int // group index.
}

// New returns a new empty Group.
func New(typ interface{}) *Group {
	return &Group{
		Type:            typ,
		IncludeChildren: true,
	}
}

const delim = "\n"

func (g *Group) Error() (s string) {
	if len(g.Errors) > 0 {
		msgs := make([]string, len(g.Errors), len(g.Errors))
		for i, err := range g.Errors {
			msgs[i] = err.Error()
		}

		s = strings.Join(msgs, delim)
	}

	if g.IncludeChildren && len(g.children) > 0 {
		// return with order of definition.
		groups := g.getAllChildren()
		sortGroups(groups)

		for _, ge := range groups {
			for _, childErr := range ge.Errors {
				s += childErr.Error() + delim
			}
		}

		if s != "" {
			return s[:len(s)-1]
		}
	}

	return
}

func (g *Group) getAllErrors() []error {
	list := g.Errors[:]

	if len(g.children) > 0 {
		// return with order of definition.
		groups := g.getAllChildren()
		sortGroups(groups)

		for _, ge := range groups {
			list = append(list, ge.Errors...)
		}
	}

	return list
}

func (g *Group) getAllChildren() []*Group {
	if len(g.children) == 0 {
		return nil
	}

	var groups []*Group
	for _, child := range g.children {
		groups = append(groups, append([]*Group{child}, child.getAllChildren()...)...)
	}

	return groups
}

// Unwrap implements the dynamic std errors interface and it returns the parent Group.
func (g *Group) Unwrap() error {
	return g.parent
}

// Group creates a new group of "typ" type, if does not exist, and returns it.
func (g *Group) Group(typ interface{}) *Group {
	if g.children == nil {
		g.children = make(map[interface{}]*Group)
	} else {
		for _, child := range g.children {
			if child.Type == typ {
				return child
			}
		}
	}

	child := &Group{
		Type:            typ,
		parent:          g,
		depth:           g.depth + 1,
		IncludeChildren: g.IncludeChildren,
		index:           g.index + 1 + len(g.children),
	}

	g.children[typ] = child

	return child
}

// Add adds an error to the group.
func (g *Group) Add(err error) {
	if err == nil {
		return
	}

	g.Errors = append(g.Errors, err)
}

// Addf adds an error to the group like `fmt.Errorf` and returns it.
func (g *Group) Addf(format string, args ...interface{}) error {
	err := fmt.Errorf(format, args...)
	g.Add(err)
	return err
}

// Err adds an error to the group, it transforms it to an Error type if necessary and returns it.
func (g *Group) Err(err error) error {
	if err == nil {
		return nil
	}

	e, ok := err.(*Error)
	if !ok {
		if ge, ok := err.(*Group); ok {
			if g.children == nil {
				g.children = make(map[interface{}]*Group)
			}

			g.children[ge.Type] = ge
			return ge
		}

		e = &Error{err, 0}
	}
	e.Type = g.Type

	g.Add(e)
	return e
}

// Errf adds an error like `fmt.Errorf` and returns it.
func (g *Group) Errf(format string, args ...interface{}) error {
	return g.Err(fmt.Errorf(format, args...))
}

func sortGroups(groups []*Group) {
	sort.Slice(groups, func(i, j int) bool {
		return groups[i].index < groups[j].index
	})
}

func tryGetTypeText(typ interface{}) string {
	if typ == nil {
		return ""
	}

	switch v := typ.(type) {
	case string:
		return v
	case fmt.Stringer:
		return v.String()
	default:
		return ""
	}
}

func isNotNil(err error) bool {
	if g, ok := err.(*Group); ok {
		if len(g.Errors) > 0 {
			return true
		}

		if len(g.children) > 0 {
			for _, child := range g.children {
				if isNotNil(child) {
					return true
				}
			}
		}

		return false
	}

	return err != nil
}
<|endoftext|>


<commit_before>package core

import (
	"testing"

	context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
	config "github.com/ipfs/go-ipfs/repo/config"
	"github.com/ipfs/go-ipfs/util/testutil"
	"github.com/ipfs/go-ipfs/repo"
	path "github.com/ipfs/go-ipfs/path"
)

func TestResolveInvalidPath(t *testing.T) {
	ctx := context.TODO()
	id := testIdentity

	r := &repo.Mock{
		C: config.Config{
			Identity: id,
			Datastore: config.Datastore{
				Type: "memory",
			},
			Addresses: config.Addresses{
				Swarm: []string{"/ip4/0.0.0.0/tcp/4001"},
				API:   "/ip4/127.0.0.1/tcp/8000",
			},
		},
		D: testutil.ThreadSafeCloserMapDatastore(),
	}

	n, err := NewIPFSNode(ctx, Standard(r, false))
	if n == nil || err != nil {
		t.Error("Should have constructed.", err)
	}

	_, err = Resolve(ctx, n, path.Path("/ipfs/"))
	if err == nil {
		t.Error("Should get invalid path")
	}

}
<commit_msg>Fixed tests to actually test for the error we are seeking<commit_after>package core

import (
	"testing"

	path "github.com/ipfs/go-ipfs/path"
	"strings"
)

func TestResolveInvalidPath(t *testing.T) {
	n, err := NewMockNode()
	if n == nil || err != nil {
		t.Fatal("Should have constructed.", err)
	}

	_, err = Resolve(n.Context(), n, path.Path("/ipfs/"))
	if !strings.HasPrefix(err.Error(), "invalid path") {
		t.Fatal("Should get invalid path.", err)
	}

}
<|endoftext|>


<commit_before>package types

import (
	"crypto/ecdsa"
	"errors"
	"fmt"
	"math/big"

	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/logger"
	"github.com/ethereum/go-ethereum/logger/glog"
	"github.com/ethereum/go-ethereum/rlp"
)

func IsContractAddr(addr []byte) bool {
	return len(addr) == 0
}

type Transaction struct {
	AccountNonce uint64
	Price        *big.Int
	GasLimit     *big.Int
	Recipient    *common.Address `rlp:"nil"` // nil means contract creation
	Amount       *big.Int
	Payload      []byte
	V            byte
	R, S         *big.Int
}

func NewContractCreationTx(amount, gasLimit, gasPrice *big.Int, data []byte) *Transaction {
	return &Transaction{
		Recipient: nil,
		Amount:    amount,
		GasLimit:  gasLimit,
		Price:     gasPrice,
		Payload:   data,
		R:         new(big.Int),
		S:         new(big.Int),
	}
}

func NewTransactionMessage(to common.Address, amount, gasAmount, gasPrice *big.Int, data []byte) *Transaction {
	return &Transaction{
		Recipient: &to,
		Amount:    amount,
		GasLimit:  gasAmount,
		Price:     gasPrice,
		Payload:   data,
		R:         new(big.Int),
		S:         new(big.Int),
	}
}

func NewTransactionFromBytes(data []byte) *Transaction {
	// TODO: remove this function if possible. callers would
	// much better off decoding into transaction directly.
	// it's not that hard.
	tx := new(Transaction)
	rlp.DecodeBytes(data, tx)
	return tx
}

func (tx *Transaction) Hash() common.Hash {
	return rlpHash([]interface{}{
		tx.AccountNonce, tx.Price, tx.GasLimit, tx.Recipient, tx.Amount, tx.Payload,
	})
}

func (self *Transaction) Data() []byte {
	return self.Payload
}

func (self *Transaction) Gas() *big.Int {
	return self.GasLimit
}

func (self *Transaction) GasPrice() *big.Int {
	return self.Price
}

func (self *Transaction) Value() *big.Int {
	return self.Amount
}

func (self *Transaction) Nonce() uint64 {
	return self.AccountNonce
}

func (self *Transaction) SetNonce(AccountNonce uint64) {
	self.AccountNonce = AccountNonce
}

func (self *Transaction) From() (common.Address, error) {
	pubkey, err := self.PublicKey()
	if err != nil {
		return common.Address{}, err
	}

	var addr common.Address
	copy(addr[:], crypto.Sha3(pubkey[1:])[12:])
	return addr, nil
}

// To returns the recipient of the transaction.
// If transaction is a contract creation (with no recipient address)
// To returns nil.
func (tx *Transaction) To() *common.Address {
	return tx.Recipient
}

func (tx *Transaction) GetSignatureValues() (v byte, r []byte, s []byte) {
	v = byte(tx.V)
	r = common.LeftPadBytes(tx.R.Bytes(), 32)
	s = common.LeftPadBytes(tx.S.Bytes(), 32)
	return
}

func (tx *Transaction) PublicKey() ([]byte, error) {
	if !crypto.ValidateSignatureValues(tx.V, tx.R, tx.S) {
		return nil, errors.New("invalid v, r, s values")
	}

	hash := tx.Hash()
	v, r, s := tx.GetSignatureValues()
	sig := append(r, s...)
	sig = append(sig, v-27)

	p, err := crypto.SigToPub(hash[:], sig)
	if err != nil {
		glog.V(logger.Error).Infof("Could not get pubkey from signature: ", err)
		return nil, err
	}

	pubkey := crypto.FromECDSAPub(p)
	if len(pubkey) == 0 || pubkey[0] != 4 {
		return nil, errors.New("invalid public key")
	}
	return pubkey, nil
}

func (tx *Transaction) SetSignatureValues(sig []byte) error {
	tx.R = common.Bytes2Big(sig[:32])
	tx.S = common.Bytes2Big(sig[32:64])
	tx.V = sig[64] + 27
	return nil
}

func (tx *Transaction) SignECDSA(prv *ecdsa.PrivateKey) error {
	h := tx.Hash()
	sig, err := crypto.Sign(h[:], prv)
	if err != nil {
		return err
	}
	tx.SetSignatureValues(sig)
	return nil
}

// TODO: remove
func (tx *Transaction) RlpData() interface{} {
	data := []interface{}{tx.AccountNonce, tx.Price, tx.GasLimit, tx.Recipient, tx.Amount, tx.Payload}
	return append(data, tx.V, tx.R.Bytes(), tx.S.Bytes())
}

func (tx *Transaction) String() string {
	var from, to string
	if f, err := tx.From(); err != nil {
		from = "[invalid sender]"
	} else {
		from = fmt.Sprintf("%x", f[:])
	}
	if t := tx.To(); t == nil {
		to = "[contract creation]"
	} else {
		to = fmt.Sprintf("%x", t[:])
	}
	enc, _ := rlp.EncodeToBytes(tx)
	return fmt.Sprintf(`
	TX(%x)
	Contract: %v
	From:     %s
	To:       %s
	Nonce:    %v
	GasPrice: %v
	GasLimit  %v
	Value:    %v
	Data:     0x%x
	V:        0x%x
	R:        0x%x
	S:        0x%x
	Hex:      %x
`,
		tx.Hash(),
		len(tx.Recipient) == 0,
		from,
		to,
		tx.AccountNonce,
		tx.Price,
		tx.GasLimit,
		tx.Amount,
		tx.Payload,
		tx.V,
		tx.R,
		tx.S,
		enc,
	)
}

// Transaction slice type for basic sorting
type Transactions []*Transaction

// TODO: remove
func (self Transactions) RlpData() interface{} {
	// Marshal the transactions of this block
	enc := make([]interface{}, len(self))
	for i, tx := range self {
		// Cast it to a string (safe)
		enc[i] = tx.RlpData()
	}

	return enc
}

func (s Transactions) Len() int      { return len(s) }
func (s Transactions) Swap(i, j int) { s[i], s[j] = s[j], s[i] }

func (s Transactions) GetRlp(i int) []byte {
	enc, _ := rlp.EncodeToBytes(s[i])
	return enc
}

type TxByNonce struct{ Transactions }

func (s TxByNonce) Less(i, j int) bool {
	return s.Transactions[i].AccountNonce < s.Transactions[j].AccountNonce
}
<commit_msg>core/types: add Transaction.Size<commit_after>package types

import (
	"crypto/ecdsa"
	"errors"
	"fmt"
	"math/big"

	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/logger"
	"github.com/ethereum/go-ethereum/logger/glog"
	"github.com/ethereum/go-ethereum/rlp"
)

func IsContractAddr(addr []byte) bool {
	return len(addr) == 0
}

type Transaction struct {
	AccountNonce uint64
	Price        *big.Int
	GasLimit     *big.Int
	Recipient    *common.Address `rlp:"nil"` // nil means contract creation
	Amount       *big.Int
	Payload      []byte
	V            byte
	R, S         *big.Int
}

func NewContractCreationTx(amount, gasLimit, gasPrice *big.Int, data []byte) *Transaction {
	return &Transaction{
		Recipient: nil,
		Amount:    amount,
		GasLimit:  gasLimit,
		Price:     gasPrice,
		Payload:   data,
		R:         new(big.Int),
		S:         new(big.Int),
	}
}

func NewTransactionMessage(to common.Address, amount, gasAmount, gasPrice *big.Int, data []byte) *Transaction {
	return &Transaction{
		Recipient: &to,
		Amount:    amount,
		GasLimit:  gasAmount,
		Price:     gasPrice,
		Payload:   data,
		R:         new(big.Int),
		S:         new(big.Int),
	}
}

func NewTransactionFromBytes(data []byte) *Transaction {
	// TODO: remove this function if possible. callers would
	// much better off decoding into transaction directly.
	// it's not that hard.
	tx := new(Transaction)
	rlp.DecodeBytes(data, tx)
	return tx
}

func (tx *Transaction) Hash() common.Hash {
	return rlpHash([]interface{}{
		tx.AccountNonce, tx.Price, tx.GasLimit, tx.Recipient, tx.Amount, tx.Payload,
	})
}

// Size returns the encoded RLP size of tx.
func (self *Transaction) Size() common.StorageSize {
	c := writeCounter(0)
	rlp.Encode(&c, self)
	return common.StorageSize(c)
}

func (self *Transaction) Data() []byte {
	return self.Payload
}

func (self *Transaction) Gas() *big.Int {
	return self.GasLimit
}

func (self *Transaction) GasPrice() *big.Int {
	return self.Price
}

func (self *Transaction) Value() *big.Int {
	return self.Amount
}

func (self *Transaction) Nonce() uint64 {
	return self.AccountNonce
}

func (self *Transaction) SetNonce(AccountNonce uint64) {
	self.AccountNonce = AccountNonce
}

func (self *Transaction) From() (common.Address, error) {
	pubkey, err := self.PublicKey()
	if err != nil {
		return common.Address{}, err
	}

	var addr common.Address
	copy(addr[:], crypto.Sha3(pubkey[1:])[12:])
	return addr, nil
}

// To returns the recipient of the transaction.
// If transaction is a contract creation (with no recipient address)
// To returns nil.
func (tx *Transaction) To() *common.Address {
	return tx.Recipient
}

func (tx *Transaction) GetSignatureValues() (v byte, r []byte, s []byte) {
	v = byte(tx.V)
	r = common.LeftPadBytes(tx.R.Bytes(), 32)
	s = common.LeftPadBytes(tx.S.Bytes(), 32)
	return
}

func (tx *Transaction) PublicKey() ([]byte, error) {
	if !crypto.ValidateSignatureValues(tx.V, tx.R, tx.S) {
		return nil, errors.New("invalid v, r, s values")
	}

	hash := tx.Hash()
	v, r, s := tx.GetSignatureValues()
	sig := append(r, s...)
	sig = append(sig, v-27)

	p, err := crypto.SigToPub(hash[:], sig)
	if err != nil {
		glog.V(logger.Error).Infof("Could not get pubkey from signature: ", err)
		return nil, err
	}

	pubkey := crypto.FromECDSAPub(p)
	if len(pubkey) == 0 || pubkey[0] != 4 {
		return nil, errors.New("invalid public key")
	}
	return pubkey, nil
}

func (tx *Transaction) SetSignatureValues(sig []byte) error {
	tx.R = common.Bytes2Big(sig[:32])
	tx.S = common.Bytes2Big(sig[32:64])
	tx.V = sig[64] + 27
	return nil
}

func (tx *Transaction) SignECDSA(prv *ecdsa.PrivateKey) error {
	h := tx.Hash()
	sig, err := crypto.Sign(h[:], prv)
	if err != nil {
		return err
	}
	tx.SetSignatureValues(sig)
	return nil
}

// TODO: remove
func (tx *Transaction) RlpData() interface{} {
	data := []interface{}{tx.AccountNonce, tx.Price, tx.GasLimit, tx.Recipient, tx.Amount, tx.Payload}
	return append(data, tx.V, tx.R.Bytes(), tx.S.Bytes())
}

func (tx *Transaction) String() string {
	var from, to string
	if f, err := tx.From(); err != nil {
		from = "[invalid sender]"
	} else {
		from = fmt.Sprintf("%x", f[:])
	}
	if t := tx.To(); t == nil {
		to = "[contract creation]"
	} else {
		to = fmt.Sprintf("%x", t[:])
	}
	enc, _ := rlp.EncodeToBytes(tx)
	return fmt.Sprintf(`
	TX(%x)
	Contract: %v
	From:     %s
	To:       %s
	Nonce:    %v
	GasPrice: %v
	GasLimit  %v
	Value:    %v
	Data:     0x%x
	V:        0x%x
	R:        0x%x
	S:        0x%x
	Hex:      %x
`,
		tx.Hash(),
		len(tx.Recipient) == 0,
		from,
		to,
		tx.AccountNonce,
		tx.Price,
		tx.GasLimit,
		tx.Amount,
		tx.Payload,
		tx.V,
		tx.R,
		tx.S,
		enc,
	)
}

// Transaction slice type for basic sorting
type Transactions []*Transaction

// TODO: remove
func (self Transactions) RlpData() interface{} {
	// Marshal the transactions of this block
	enc := make([]interface{}, len(self))
	for i, tx := range self {
		// Cast it to a string (safe)
		enc[i] = tx.RlpData()
	}

	return enc
}

func (s Transactions) Len() int      { return len(s) }
func (s Transactions) Swap(i, j int) { s[i], s[j] = s[j], s[i] }

func (s Transactions) GetRlp(i int) []byte {
	enc, _ := rlp.EncodeToBytes(s[i])
	return enc
}

type TxByNonce struct{ Transactions }

func (s TxByNonce) Less(i, j int) bool {
	return s.Transactions[i].AccountNonce < s.Transactions[j].AccountNonce
}
<|endoftext|>