<commit_before>package api

import (
	"errors"
	"fmt"
	"net"
	"net/http"
	"regexp"
	"strings"

	"code.cloudfoundry.org/lager"
)

var ErrGetP2pUrlFailed = errors.New("failed to get p2p url")

func NewP2pServer(
	logger lager.Logger,
	p2pInterfacePattern *regexp.Regexp,
	p2pInterfaceFamily int,
	p2pStreamPort uint16,
) *P2pServer {
	return &P2pServer{
		p2pInterfacePattern: p2pInterfacePattern,
		p2pInterfaceFamily:  p2pInterfaceFamily,
		p2pStreamPort:       p2pStreamPort,
		logger:              logger,
	}
}

type P2pServer struct {
	p2pInterfacePattern *regexp.Regexp
	p2pInterfaceFamily  int
	p2pStreamPort       uint16

	logger lager.Logger
}

func (server *P2pServer) GetP2pUrl(w http.ResponseWriter, req *http.Request) {
	hLog := server.logger.Session("get-p2p-url")
	hLog.Debug("start")
	defer hLog.Debug("done")

	ifaces, err := net.Interfaces()
	if err != nil {
		RespondWithError(w, ErrGetP2pUrlFailed, http.StatusInternalServerError)
		return
	}

	for _, i := range ifaces {
		if !server.p2pInterfacePattern.MatchString(i.Name) {
			continue
		}

		addrs, err := i.Addrs()
		if err != nil {
			RespondWithError(w, ErrGetP2pUrlFailed, http.StatusInternalServerError)
			return
		}

		for _, addr := range addrs {
			var ip net.IP
			switch v := addr.(type) {
			case *net.IPNet:
				ip = v.IP
			case *net.IPAddr:
				ip = v.IP
			}

			if server.p2pInterfaceFamily == 6 {
				if strings.Contains(ip.String(), ".") {
					continue
				}
			} else { // Default to use IPv4
				if strings.Contains(ip.String(), ":") {
					continue
				}
			}
			hLog.Debug("found-ip", lager.Data{"ip": ip.String()})

			fmt.Fprintf(w, "http://%s:%d", ip.String(), server.p2pStreamPort)
			return
		}
	}

	RespondWithError(w, ErrGetP2pUrlFailed, http.StatusInternalServerError)
}
<commit_msg>explicit error messeges in p2p streaming<commit_after>package api

import (
	"errors"
	"fmt"
	"net"
	"net/http"
	"regexp"
	"strings"

	"code.cloudfoundry.org/lager"
)

var ErrGetP2pUrlFailed = errors.New("failed to get p2p url, network interface list is empty")
var ErrGetListSysNetworkInterface = errors.New("failed to get a list of the system's network interface")
var ErrGetNetworkInterfaceAddr = errors.New("failed to get network interface addr for given interface")

func NewP2pServer(
	logger lager.Logger,
	p2pInterfacePattern *regexp.Regexp,
	p2pInterfaceFamily int,
	p2pStreamPort uint16,
) *P2pServer {
	return &P2pServer{
		p2pInterfacePattern: p2pInterfacePattern,
		p2pInterfaceFamily:  p2pInterfaceFamily,
		p2pStreamPort:       p2pStreamPort,
		logger:              logger,
	}
}

type P2pServer struct {
	p2pInterfacePattern *regexp.Regexp
	p2pInterfaceFamily  int
	p2pStreamPort       uint16

	logger lager.Logger
}

func (server *P2pServer) GetP2pUrl(w http.ResponseWriter, req *http.Request) {
	hLog := server.logger.Session("get-p2p-url")
	hLog.Debug("start")
	defer hLog.Debug("done")

	ifaces, err := net.Interfaces()
	if err != nil {
		RespondWithError(w, ErrGetListSysNetworkInterface, http.StatusInternalServerError)
		return
	}

	for _, i := range ifaces {
		if !server.p2pInterfacePattern.MatchString(i.Name) {
			continue
		}

		addrs, err := i.Addrs()
		if err != nil {
			RespondWithError(w, ErrGetNetworkInterfaceAddr, http.StatusInternalServerError)
			return
		}

		for _, addr := range addrs {
			var ip net.IP
			switch v := addr.(type) {
			case *net.IPNet:
				ip = v.IP
			case *net.IPAddr:
				ip = v.IP
			}

			if server.p2pInterfaceFamily == 6 {
				if strings.Contains(ip.String(), ".") {
					continue
				}
			} else { // Default to use IPv4
				if strings.Contains(ip.String(), ":") {
					continue
				}
			}
			hLog.Debug("found-ip", lager.Data{"ip": ip.String()})

			fmt.Fprintf(w, "http://%s:%d", ip.String(), server.p2pStreamPort)
			return
		}
	}

	RespondWithError(w, ErrGetP2pUrlFailed, http.StatusInternalServerError)
}
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes Authors.

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 awsup

import (
	"github.com/aws/aws-sdk-go/aws/client"
	"github.com/aws/aws-sdk-go/aws/request"
	"github.com/golang/glog"
	"time"
)

// LoggingRetryer adds some logging when we are retrying, so we have some idea what is happening
// Right now it is very basic - e.g. it only logs when we retry (so doesn't log when we fail due to too many retries)
type LoggingRetryer struct {
	client.DefaultRetryer
}

var _ request.Retryer = &LoggingRetryer{}

func newLoggingRetryer(maxRetries int) *LoggingRetryer {
	return &LoggingRetryer{
		client.DefaultRetryer{NumMaxRetries: maxRetries},
	}
}

func (l LoggingRetryer) RetryRules(r *request.Request) time.Duration {
	duration := l.DefaultRetryer.RetryRules(r)

	service := r.ClientInfo.ServiceName
	name := "?"
	if r.Operation != nil {
		name = r.Operation.Name
	}
	methodDescription := service + "/" + name

	glog.Infof("Retryable error %d (%s) from %s - will retry after delay of %v", r.HTTPResponse.StatusCode, r.HTTPResponse.Status, methodDescription, duration)

	return duration
}
<commit_msg>Improve error logging<commit_after>/*
Copyright 2016 The Kubernetes Authors.

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 awsup

import (
	"fmt"
	"github.com/aws/aws-sdk-go/aws/client"
	"github.com/aws/aws-sdk-go/aws/request"
	"github.com/golang/glog"
	"time"
)

// LoggingRetryer adds some logging when we are retrying, so we have some idea what is happening
// Right now it is very basic - e.g. it only logs when we retry (so doesn't log when we fail due to too many retries)
type LoggingRetryer struct {
	client.DefaultRetryer
}

var _ request.Retryer = &LoggingRetryer{}

func newLoggingRetryer(maxRetries int) *LoggingRetryer {
	return &LoggingRetryer{
		client.DefaultRetryer{NumMaxRetries: maxRetries},
	}
}

func (l LoggingRetryer) RetryRules(r *request.Request) time.Duration {
	duration := l.DefaultRetryer.RetryRules(r)

	service := r.ClientInfo.ServiceName
	name := "?"
	if r.Operation != nil {
		name = r.Operation.Name
	}
	methodDescription := service + "/" + name

	var errorDescription string
	if r.Error != nil {
		// We could check aws error Code & Message, but we expect them to be in the string
		errorDescription = fmt.Sprintf("%v", r.Error)
	} else {
		errorDescription = fmt.Sprintf("%d %s", r.HTTPResponse.StatusCode, r.HTTPResponse.Status)
	}

	glog.Infof("Retryable error (%s) from %s - will retry after delay of %v", errorDescription, methodDescription, duration)

	return duration
}
<|endoftext|>


<commit_before>package assemble

import (
	"errors"
	"fmt"
)

type pseudoinst interface {
	translate(labels map[string]uint, pc uint) []instruction
	size() uint
}

type dummy struct{}

func (d dummy) translate(labels map[string]uint, pc uint) []instruction {
	return []instruction{}
}

func (d dummy) size() uint {
	return 0
}

type loadimm struct {
	val uint8
}

func (i loadimm) translate(labels map[string]uint, pc uint) []instruction {
	return []instruction{
		loadi{true, i.val & 0xF},
		loadi{false, (i.val & 0xF0) >> 4},
	}
}

func (i loadimm) size() uint {
	return 2
}

type lra struct {
	dest  uint8
	label string
}

func (i lra) translate(labels map[string]uint, pc uint) []instruction {
	addr, ok := labels[i.label]
	if !ok {
		panic(errors.New(fmt.Sprint("%v label not found", i.label)))
	}
	offset := uint8(int(addr) - int(pc+i.size()))
	insts := []instruction{}
	insts = append(insts, devio{out, 0, 0})
	insts = append(insts, loadimm{offset}.translate(labels, pc)...)
	insts = append(insts, devio{in, 0, 0})
	return insts
}

func (i lra) size() uint {
	return 1 + 2 + 1
}

type laa struct {
	highreg uint8
	lowreg  uint8
	label   string
}

func (i laa) translate(labels map[string]uint, pc uint) []instruction {
	addr, ok := labels[i.label]
	if !ok {
		panic(errors.New(fmt.Sprint("%v label not found", i.label)))
	}
	insts := []instruction{}
	if i.hasR0() {
		if !i.highR0() {
			insts = append(insts, loadimm{uint8((addr & 0xFF00) >> 8)}.translate(labels, pc)...)
			insts = append(insts, tworeg{mov, i.highreg, 0})
		}
		insts = append(insts, loadimm{uint8(addr & 0xFF)}.translate(labels, pc)...)
		insts = append(insts, tworeg{mov, i.lowreg, 0})
		if i.highR0() {
			insts = append(insts, loadimm{uint8((addr & 0xFF00) >> 8)}.translate(labels, pc)...)
			insts = append(insts, tworeg{mov, i.highreg, 0})
		}
	} else {
		insts = append(insts, loadimm{uint8((addr & 0xFF00) >> 8)}.translate(labels, pc)...)
		insts = append(insts, tworeg{mov, i.highreg, 0})
		insts = append(insts, loadimm{uint8(addr & 0xFF)}.translate(labels, pc)...)
		insts = append(insts, tworeg{mov, i.lowreg, 0})
	}
	return insts
}

func (i laa) hasR0() bool {
	return i.highreg != 0 || i.lowreg != 0
}

func (i laa) highR0() bool {
	return i.highreg == 0
}

func (i laa) size() uint {
	return 4
}

type rawbytes struct {
	bytes []byte
}

func (i rawbytes) translate(labels map[string]uint, pc uint) (out []instruction) {
	for _, b := range i.bytes {
		out = append(out, rawbyte{b})
	}
	return
}

func (i rawbytes) size() uint {
	return uint(len(i.bytes))
}
<commit_msg>Fixed<commit_after>package assemble

import (
	"errors"
	"fmt"
)

type pseudoinst interface {
	translate(labels map[string]uint, pc uint) []instruction
	size() uint
}

type dummy struct{}

func (d dummy) translate(labels map[string]uint, pc uint) []instruction {
	return []instruction{}
}

func (d dummy) size() uint {
	return 0
}

type loadimm struct {
	val uint8
}

func (i loadimm) translate(labels map[string]uint, pc uint) []instruction {
	return []instruction{
		loadi{true, i.val & 0xF},
		loadi{false, (i.val & 0xF0) >> 4},
	}
}

func (i loadimm) size() uint {
	return 2
}

type lra struct {
	dest  uint8
	label string
}

func (i lra) translate(labels map[string]uint, pc uint) []instruction {
	addr, ok := labels[i.label]
	if !ok {
		panic(errors.New(fmt.Sprint("%v label not found", i.label)))
	}
	offset := uint8(int(addr) - int(pc+i.size()+1))
	insts := []instruction{}
	insts = append(insts, loadimm{offset}.translate(labels, pc)...)
	return insts
}

func (i lra) size() uint {
	return 2
}

type laa struct {
	highreg uint8
	lowreg  uint8
	label   string
}

func (i laa) translate(labels map[string]uint, pc uint) []instruction {
	addr, ok := labels[i.label]
	if !ok {
		panic(errors.New(fmt.Sprint("%v label not found", i.label)))
	}
	insts := []instruction{}
	if i.hasR0() {
		if !i.highR0() {
			insts = append(insts, loadimm{uint8((addr & 0xFF00) >> 8)}.translate(labels, pc)...)
			insts = append(insts, tworeg{mov, i.highreg, 0})
		}
		insts = append(insts, loadimm{uint8(addr & 0xFF)}.translate(labels, pc)...)
		insts = append(insts, tworeg{mov, i.lowreg, 0})
		if i.highR0() {
			insts = append(insts, loadimm{uint8((addr & 0xFF00) >> 8)}.translate(labels, pc)...)
			insts = append(insts, tworeg{mov, i.highreg, 0})
		}
	} else {
		insts = append(insts, loadimm{uint8((addr & 0xFF00) >> 8)}.translate(labels, pc)...)
		insts = append(insts, tworeg{mov, i.highreg, 0})
		insts = append(insts, loadimm{uint8(addr & 0xFF)}.translate(labels, pc)...)
		insts = append(insts, tworeg{mov, i.lowreg, 0})
	}
	return insts
}

func (i laa) hasR0() bool {
	return i.highreg != 0 || i.lowreg != 0
}

func (i laa) highR0() bool {
	return i.highreg == 0
}

func (i laa) size() uint {
	return 2 + 1 + 2 + 1
}

type rawbytes struct {
	bytes []byte
}

func (i rawbytes) translate(labels map[string]uint, pc uint) (out []instruction) {
	for _, b := range i.bytes {
		out = append(out, rawbyte{b})
	}
	return
}

func (i rawbytes) size() uint {
	return uint(len(i.bytes))
}
<|endoftext|>


<commit_before>/*
Copyright 2017 The Kubernetes Authors.

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 gce

import (
	"net/http"

	computealpha "google.golang.org/api/compute/v0.alpha"
	compute "google.golang.org/api/compute/v1"
)

func newBackendServiceMetricContext(request, region string) *metricContext {
	return newBackendServiceMetricContextWithVersion(request, region, computeV1Version)
}

func newBackendServiceMetricContextWithVersion(request, region, version string) *metricContext {
	return newGenericMetricContext("backendservice", request, region, unusedMetricLabel, version)
}

// GetGlobalBackendService retrieves a backend by name.
func (gce *GCECloud) GetGlobalBackendService(name string) (*compute.BackendService, error) {
	mc := newBackendServiceMetricContext("get", "")
	v, err := gce.service.BackendServices.Get(gce.projectID, name).Do()
	return v, mc.Observe(err)
}

// UpdateGlobalBackendService applies the given BackendService as an update to an existing service.
func (gce *GCECloud) UpdateGlobalBackendService(bg *compute.BackendService) error {
	mc := newBackendServiceMetricContext("update", "")
	op, err := gce.service.BackendServices.Update(gce.projectID, bg.Name, bg).Do()
	if err != nil {
		return mc.Observe(err)
	}

	return gce.waitForGlobalOp(op, mc)
}

// UpdateAlphaGlobalBackendService applies the given alpha BackendService as an update to an existing service.
func (gce *GCECloud) UpdateAlphaGlobalBackendService(bg *computealpha.BackendService) error {
	mc := newBackendServiceMetricContextWithVersion("update", "", computeAlphaVersion)
	op, err := gce.serviceAlpha.BackendServices.Update(gce.projectID, bg.Name, bg).Do()
	if err != nil {
		return mc.Observe(err)
	}

	return gce.waitForGlobalOp(op, mc)
}

// DeleteGlobalBackendService deletes the given BackendService by name.
func (gce *GCECloud) DeleteGlobalBackendService(name string) error {
	mc := newBackendServiceMetricContext("delete", "")
	op, err := gce.service.BackendServices.Delete(gce.projectID, name).Do()
	if err != nil {
		if isHTTPErrorCode(err, http.StatusNotFound) {
			return nil
		}
		return mc.Observe(err)
	}

	return gce.waitForGlobalOp(op, mc)
}

// CreateGlobalBackendService creates the given BackendService.
func (gce *GCECloud) CreateGlobalBackendService(bg *compute.BackendService) error {
	mc := newBackendServiceMetricContext("create", "")
	op, err := gce.service.BackendServices.Insert(gce.projectID, bg).Do()
	if err != nil {
		return mc.Observe(err)
	}

	return gce.waitForGlobalOp(op, mc)
}

// CreateAlphaGlobalBackendService creates the given alpha BackendService.
func (gce *GCECloud) CreateAlphaGlobalBackendService(bg *computealpha.BackendService) error {
	mc := newBackendServiceMetricContextWithVersion("create", "", computeAlphaVersion)
	op, err := gce.serviceAlpha.BackendServices.Insert(gce.projectID, bg).Do()
	if err != nil {
		return mc.Observe(err)
	}

	return gce.waitForGlobalOp(op, mc)
}

// ListGlobalBackendServices lists all backend services in the project.
func (gce *GCECloud) ListGlobalBackendServices() (*compute.BackendServiceList, error) {
	mc := newBackendServiceMetricContext("list", "")
	// TODO: use PageToken to list all not just the first 500
	v, err := gce.service.BackendServices.List(gce.projectID).Do()
	return v, mc.Observe(err)
}

// GetGlobalBackendServiceHealth returns the health of the BackendService identified by the given
// name, in the given instanceGroup. The instanceGroupLink is the fully
// qualified self link of an instance group.
func (gce *GCECloud) GetGlobalBackendServiceHealth(name string, instanceGroupLink string) (*compute.BackendServiceGroupHealth, error) {
	mc := newBackendServiceMetricContext("get_health", "")
	groupRef := &compute.ResourceGroupReference{Group: instanceGroupLink}
	v, err := gce.service.BackendServices.GetHealth(gce.projectID, name, groupRef).Do()
	return v, mc.Observe(err)
}

// GetRegionBackendService retrieves a backend by name.
func (gce *GCECloud) GetRegionBackendService(name, region string) (*compute.BackendService, error) {
	mc := newBackendServiceMetricContext("get", region)
	v, err := gce.service.RegionBackendServices.Get(gce.projectID, region, name).Do()
	return v, mc.Observe(err)
}

// UpdateRegionBackendService applies the given BackendService as an update to an existing service.
func (gce *GCECloud) UpdateRegionBackendService(bg *compute.BackendService, region string) error {
	mc := newBackendServiceMetricContext("update", region)
	op, err := gce.service.RegionBackendServices.Update(gce.projectID, region, bg.Name, bg).Do()
	if err != nil {
		return mc.Observe(err)
	}

	return gce.waitForRegionOp(op, region, mc)
}

// DeleteRegionBackendService deletes the given BackendService by name.
func (gce *GCECloud) DeleteRegionBackendService(name, region string) error {
	mc := newBackendServiceMetricContext("delete", region)
	op, err := gce.service.RegionBackendServices.Delete(gce.projectID, region, name).Do()
	if err != nil {
		if isHTTPErrorCode(err, http.StatusNotFound) {
			return nil
		}
		return mc.Observe(err)
	}

	return gce.waitForRegionOp(op, region, mc)
}

// CreateRegionBackendService creates the given BackendService.
func (gce *GCECloud) CreateRegionBackendService(bg *compute.BackendService, region string) error {
	mc := newBackendServiceMetricContext("create", region)
	op, err := gce.service.RegionBackendServices.Insert(gce.projectID, region, bg).Do()
	if err != nil {
		return mc.Observe(err)
	}

	return gce.waitForRegionOp(op, region, mc)
}

// ListRegionBackendServices lists all backend services in the project.
func (gce *GCECloud) ListRegionBackendServices(region string) (*compute.BackendServiceList, error) {
	mc := newBackendServiceMetricContext("list", region)
	// TODO: use PageToken to list all not just the first 500
	v, err := gce.service.RegionBackendServices.List(gce.projectID, region).Do()
	return v, mc.Observe(err)
}

// GetRegionalBackendServiceHealth returns the health of the BackendService identified by the given
// name, in the given instanceGroup. The instanceGroupLink is the fully
// qualified self link of an instance group.
func (gce *GCECloud) GetRegionalBackendServiceHealth(name, region string, instanceGroupLink string) (*compute.BackendServiceGroupHealth, error) {
	mc := newBackendServiceMetricContext("get_health", region)
	groupRef := &compute.ResourceGroupReference{Group: instanceGroupLink}
	v, err := gce.service.RegionBackendServices.GetHealth(gce.projectID, region, name, groupRef).Do()
	return v, mc.Observe(err)
}
<commit_msg>add get alpha backend service into cloud provider<commit_after>/*
Copyright 2017 The Kubernetes Authors.

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 gce

import (
	"net/http"

	computealpha "google.golang.org/api/compute/v0.alpha"
	compute "google.golang.org/api/compute/v1"
)

func newBackendServiceMetricContext(request, region string) *metricContext {
	return newBackendServiceMetricContextWithVersion(request, region, computeV1Version)
}

func newBackendServiceMetricContextWithVersion(request, region, version string) *metricContext {
	return newGenericMetricContext("backendservice", request, region, unusedMetricLabel, version)
}

// GetGlobalBackendService retrieves a backend by name.
func (gce *GCECloud) GetGlobalBackendService(name string) (*compute.BackendService, error) {
	mc := newBackendServiceMetricContext("get", "")
	v, err := gce.service.BackendServices.Get(gce.projectID, name).Do()
	return v, mc.Observe(err)
}

// GetAlphaGlobalBackendService retrieves alpha backend by name.
func (gce *GCECloud) GetAlphaGlobalBackendService(name string) (*computealpha.BackendService, error) {
	mc := newBackendServiceMetricContextWithVersion("get", "", computeAlphaVersion)
	v, err := gce.serviceAlpha.BackendServices.Get(gce.projectID, name).Do()
	return v, mc.Observe(err)
}

// UpdateGlobalBackendService applies the given BackendService as an update to an existing service.
func (gce *GCECloud) UpdateGlobalBackendService(bg *compute.BackendService) error {
	mc := newBackendServiceMetricContext("update", "")
	op, err := gce.service.BackendServices.Update(gce.projectID, bg.Name, bg).Do()
	if err != nil {
		return mc.Observe(err)
	}

	return gce.waitForGlobalOp(op, mc)
}

// UpdateAlphaGlobalBackendService applies the given alpha BackendService as an update to an existing service.
func (gce *GCECloud) UpdateAlphaGlobalBackendService(bg *computealpha.BackendService) error {
	mc := newBackendServiceMetricContextWithVersion("update", "", computeAlphaVersion)
	op, err := gce.serviceAlpha.BackendServices.Update(gce.projectID, bg.Name, bg).Do()
	if err != nil {
		return mc.Observe(err)
	}

	return gce.waitForGlobalOp(op, mc)
}

// DeleteGlobalBackendService deletes the given BackendService by name.
func (gce *GCECloud) DeleteGlobalBackendService(name string) error {
	mc := newBackendServiceMetricContext("delete", "")
	op, err := gce.service.BackendServices.Delete(gce.projectID, name).Do()
	if err != nil {
		if isHTTPErrorCode(err, http.StatusNotFound) {
			return nil
		}
		return mc.Observe(err)
	}

	return gce.waitForGlobalOp(op, mc)
}

// CreateGlobalBackendService creates the given BackendService.
func (gce *GCECloud) CreateGlobalBackendService(bg *compute.BackendService) error {
	mc := newBackendServiceMetricContext("create", "")
	op, err := gce.service.BackendServices.Insert(gce.projectID, bg).Do()
	if err != nil {
		return mc.Observe(err)
	}

	return gce.waitForGlobalOp(op, mc)
}

// CreateAlphaGlobalBackendService creates the given alpha BackendService.
func (gce *GCECloud) CreateAlphaGlobalBackendService(bg *computealpha.BackendService) error {
	mc := newBackendServiceMetricContextWithVersion("create", "", computeAlphaVersion)
	op, err := gce.serviceAlpha.BackendServices.Insert(gce.projectID, bg).Do()
	if err != nil {
		return mc.Observe(err)
	}

	return gce.waitForGlobalOp(op, mc)
}

// ListGlobalBackendServices lists all backend services in the project.
func (gce *GCECloud) ListGlobalBackendServices() (*compute.BackendServiceList, error) {
	mc := newBackendServiceMetricContext("list", "")
	// TODO: use PageToken to list all not just the first 500
	v, err := gce.service.BackendServices.List(gce.projectID).Do()
	return v, mc.Observe(err)
}

// GetGlobalBackendServiceHealth returns the health of the BackendService identified by the given
// name, in the given instanceGroup. The instanceGroupLink is the fully
// qualified self link of an instance group.
func (gce *GCECloud) GetGlobalBackendServiceHealth(name string, instanceGroupLink string) (*compute.BackendServiceGroupHealth, error) {
	mc := newBackendServiceMetricContext("get_health", "")
	groupRef := &compute.ResourceGroupReference{Group: instanceGroupLink}
	v, err := gce.service.BackendServices.GetHealth(gce.projectID, name, groupRef).Do()
	return v, mc.Observe(err)
}

// GetRegionBackendService retrieves a backend by name.
func (gce *GCECloud) GetRegionBackendService(name, region string) (*compute.BackendService, error) {
	mc := newBackendServiceMetricContext("get", region)
	v, err := gce.service.RegionBackendServices.Get(gce.projectID, region, name).Do()
	return v, mc.Observe(err)
}

// UpdateRegionBackendService applies the given BackendService as an update to an existing service.
func (gce *GCECloud) UpdateRegionBackendService(bg *compute.BackendService, region string) error {
	mc := newBackendServiceMetricContext("update", region)
	op, err := gce.service.RegionBackendServices.Update(gce.projectID, region, bg.Name, bg).Do()
	if err != nil {
		return mc.Observe(err)
	}

	return gce.waitForRegionOp(op, region, mc)
}

// DeleteRegionBackendService deletes the given BackendService by name.
func (gce *GCECloud) DeleteRegionBackendService(name, region string) error {
	mc := newBackendServiceMetricContext("delete", region)
	op, err := gce.service.RegionBackendServices.Delete(gce.projectID, region, name).Do()
	if err != nil {
		if isHTTPErrorCode(err, http.StatusNotFound) {
			return nil
		}
		return mc.Observe(err)
	}

	return gce.waitForRegionOp(op, region, mc)
}

// CreateRegionBackendService creates the given BackendService.
func (gce *GCECloud) CreateRegionBackendService(bg *compute.BackendService, region string) error {
	mc := newBackendServiceMetricContext("create", region)
	op, err := gce.service.RegionBackendServices.Insert(gce.projectID, region, bg).Do()
	if err != nil {
		return mc.Observe(err)
	}

	return gce.waitForRegionOp(op, region, mc)
}

// ListRegionBackendServices lists all backend services in the project.
func (gce *GCECloud) ListRegionBackendServices(region string) (*compute.BackendServiceList, error) {
	mc := newBackendServiceMetricContext("list", region)
	// TODO: use PageToken to list all not just the first 500
	v, err := gce.service.RegionBackendServices.List(gce.projectID, region).Do()
	return v, mc.Observe(err)
}

// GetRegionalBackendServiceHealth returns the health of the BackendService identified by the given
// name, in the given instanceGroup. The instanceGroupLink is the fully
// qualified self link of an instance group.
func (gce *GCECloud) GetRegionalBackendServiceHealth(name, region string, instanceGroupLink string) (*compute.BackendServiceGroupHealth, error) {
	mc := newBackendServiceMetricContext("get_health", region)
	groupRef := &compute.ResourceGroupReference{Group: instanceGroupLink}
	v, err := gce.service.RegionBackendServices.GetHealth(gce.projectID, region, name, groupRef).Do()
	return v, mc.Observe(err)
}
<|endoftext|>


<commit_before>// my-go-examples rsa-asymmetric-cryptography-wth-digital-signature.go

package main

import (
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"encoding/hex"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"

	log "github.com/sirupsen/logrus"
)

var filename string

func checkErr(err error) {
	if err != nil {
		fmt.Printf("Error is %+v\n", err)
		log.Fatal("ERROR:", err)
	}
}

func readFile(filename string) string {

	plainTextByte, err := ioutil.ReadFile(filename)
	checkErr(err)
	// Convert to string
	plainText := string(plainTextByte)
	return plainText

}

func generateRSAKeys() (*rsa.PrivateKey, *rsa.PublicKey) {

	// GENERATE PRIVATE & PUBLIC KEY PAIR
	privateKeyRaw, err := rsa.GenerateKey(rand.Reader, 2048)
	checkErr(err)

	// EXTRACT PUBLIC KEY
	publicKeyRaw := &privateKeyRaw.PublicKey

	return privateKeyRaw, publicKeyRaw

}

func encryptMessage(publicKeyRaw *rsa.PublicKey, plainText string) string {

	plainTextByte := []byte(plainText)
	label := []byte("")
	hash := sha256.New()

	// ENCRYPT
	cipherTextByte, err := rsa.EncryptOAEP(
		hash,
		rand.Reader,
		publicKeyRaw,
		plainTextByte,
		label,
	)
	checkErr(err)

	// ENCODE - RETURN HEX
	cipherText := hex.EncodeToString(cipherTextByte)
	return cipherText

}

func decryptMessage(privateKeyRaw *rsa.PrivateKey, cipherText string) string {

	// DECODE cipherText
	cipherTextByte, _ := hex.DecodeString(cipherText)

	label := []byte("")
	hash := sha256.New()

	// DECRYPT DATA
	plainTextByte, err := rsa.DecryptOAEP(
		hash,
		rand.Reader,
		privateKeyRaw,
		cipherTextByte,
		label,
	)
	checkErr(err)

	// RETURN STRING
	plainText := string(plainTextByte[:])
	return plainText

}

func createSignature(senderPrivateKeyRaw *rsa.PrivateKey, plainText string) string {

	var opts rsa.PSSOptions
	opts.SaltLength = rsa.PSSSaltLengthAuto
	PSSmessage := []byte(plainText)
	newhash := crypto.SHA256
	pssh := newhash.New()
	pssh.Write(PSSmessage)
	hashed := pssh.Sum(nil)

	// CREATE SIGNATURE
	signatureByte, err := rsa.SignPSS(
		rand.Reader,
		senderPrivateKeyRaw,
		newhash,
		hashed,
		&opts,
	)
	checkErr(err)

	// ENCODE - RETURN HEX
	signature := hex.EncodeToString(signatureByte)

	return signature

}

func verifySignature(senderPublicKeyRaw *rsa.PublicKey, signature string, plainText string) bool {

	var result bool

	// DECODE signature
	signatureByte, _ := hex.DecodeString(signature)

	var opts rsa.PSSOptions
	opts.SaltLength = rsa.PSSSaltLengthAuto
	PSSmessage := []byte(plainText)
	newhash := crypto.SHA256
	pssh := newhash.New()
	pssh.Write(PSSmessage)
	hashed := pssh.Sum(nil)

	// VERIFY SIGNATURE
	err := rsa.VerifyPSS(
		senderPublicKeyRaw,
		newhash,
		hashed,
		signatureByte,
		&opts,
	)
	if err != nil {
		verifyStatus = false
	} else {
		verifyStatus = true
	}

	return verifyStatus
}

func init() {

	// GET FILE NAME FROM ARGS
	flag.Parse()
	filenameSlice := flag.Args()
	if len(filenameSlice) != 1 {
		err := errors.New("Only one filename allowed")
		checkErr(err)
	}

	filename = filenameSlice[0] // Make it a string

}

func main() {

	fmt.Println(" ")

	// READ FILE INTO STRING
	plainText := readFile(filename)
	fmt.Printf("The original message contains:\n\n%s\n\n", plainText)

	// SENDER GENERATE RSA KEYS
	senderPrivateKeyRaw, senderPublicKeyRaw := generateRSAKeys()

	// RECEIVER GENERATE RSA KEYS
	receiverPrivateKeyRaw, receiverPublicKeyRaw := generateRSAKeys()

	// ENCRYPT MESSAGE USING PRIVATE KEY
	cipherText := encryptMessage(receiverPublicKeyRaw, plainText)
	fmt.Printf("The encrypted message contains:\n\n%s\n\n", cipherText)

	// CREATE SIGNATURE
	signature := createSignature(senderPrivateKeyRaw, plainText)
	fmt.Printf("The senders signature:\n\n%s\n\n", signature)

	// DECRYPT MESSAGE USING PUBLIC KEY
	plainText = decryptMessage(receiverPrivateKeyRaw, cipherText)
	fmt.Printf("The received message contains:\n\n%s\n\n", plainText)

	// VERIFY SIGNATURE
	verifyStatus := verifySignature(senderPublicKeyRaw, signature, plainText)
	fmt.Printf("The senders signature is: %v\n\n", verifyStatus)

}
<commit_msg>cleaned up asymetrical cryptography<commit_after>// my-go-examples rsa-asymmetric-cryptography-wth-digital-signature.go

package main

import (
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"encoding/hex"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"

	log "github.com/sirupsen/logrus"
)

var filename string

func checkErr(err error) {
	if err != nil {
		fmt.Printf("Error is %+v\n", err)
		log.Fatal("ERROR:", err)
	}
}

func readFile(filename string) string {

	plainTextByte, err := ioutil.ReadFile(filename)
	checkErr(err)
	// Convert to string
	plainText := string(plainTextByte)
	return plainText

}

func generateRSAKeys() (*rsa.PrivateKey, *rsa.PublicKey) {

	// GENERATE PRIVATE & PUBLIC KEY PAIR
	privateKeyRaw, err := rsa.GenerateKey(rand.Reader, 2048)
	checkErr(err)

	// EXTRACT PUBLIC KEY
	publicKeyRaw := &privateKeyRaw.PublicKey

	return privateKeyRaw, publicKeyRaw

}

func encryptMessage(publicKeyRaw *rsa.PublicKey, plainText string) string {

	plainTextByte := []byte(plainText)
	label := []byte("")
	hash := sha256.New()

	// ENCRYPT
	cipherTextByte, err := rsa.EncryptOAEP(
		hash,
		rand.Reader,
		publicKeyRaw,
		plainTextByte,
		label,
	)
	checkErr(err)

	// ENCODE - RETURN HEX
	cipherText := hex.EncodeToString(cipherTextByte)
	return cipherText

}

func decryptMessage(privateKeyRaw *rsa.PrivateKey, cipherText string) string {

	// DECODE cipherText
	cipherTextByte, _ := hex.DecodeString(cipherText)

	label := []byte("")
	hash := sha256.New()

	// DECRYPT DATA
	plainTextByte, err := rsa.DecryptOAEP(
		hash,
		rand.Reader,
		privateKeyRaw,
		cipherTextByte,
		label,
	)
	checkErr(err)

	// RETURN STRING
	plainText := string(plainTextByte[:])
	return plainText

}

func createSignature(senderPrivateKeyRaw *rsa.PrivateKey, plainText string) string {

	var opts rsa.PSSOptions
	opts.SaltLength = rsa.PSSSaltLengthAuto
	PSSmessage := []byte(plainText)
	newhash := crypto.SHA256
	pssh := newhash.New()
	pssh.Write(PSSmessage)
	hashed := pssh.Sum(nil)

	// CREATE SIGNATURE
	signatureByte, err := rsa.SignPSS(
		rand.Reader,
		senderPrivateKeyRaw,
		newhash,
		hashed,
		&opts,
	)
	checkErr(err)

	// ENCODE - RETURN HEX
	signature := hex.EncodeToString(signatureByte)

	return signature

}

func verifySignature(senderPublicKeyRaw *rsa.PublicKey, signature string, plainText string) bool {

	var verifyStatus bool

	// DECODE signature
	signatureByte, _ := hex.DecodeString(signature)

	var opts rsa.PSSOptions
	opts.SaltLength = rsa.PSSSaltLengthAuto
	PSSmessage := []byte(plainText)
	newhash := crypto.SHA256
	pssh := newhash.New()
	pssh.Write(PSSmessage)
	hashed := pssh.Sum(nil)

	// VERIFY SIGNATURE
	err := rsa.VerifyPSS(
		senderPublicKeyRaw,
		newhash,
		hashed,
		signatureByte,
		&opts,
	)
	if err != nil {
		verifyStatus = false
	} else {
		verifyStatus = true
	}

	return verifyStatus
}

func init() {

	// GET FILE NAME FROM ARGS
	flag.Parse()
	filenameSlice := flag.Args()
	if len(filenameSlice) != 1 {
		err := errors.New("Only one filename allowed")
		checkErr(err)
	}

	filename = filenameSlice[0] // Make it a string

}

func main() {

	fmt.Println(" ")

	// READ FILE INTO STRING
	plainText := readFile(filename)
	fmt.Printf("The original message contains:\n\n%s\n\n", plainText)

	// SENDER GENERATE RSA KEYS
	senderPrivateKeyRaw, senderPublicKeyRaw := generateRSAKeys()

	// RECEIVER GENERATE RSA KEYS
	receiverPrivateKeyRaw, receiverPublicKeyRaw := generateRSAKeys()

	// ENCRYPT MESSAGE USING PRIVATE KEY
	cipherText := encryptMessage(receiverPublicKeyRaw, plainText)
	fmt.Printf("The encrypted message contains:\n\n%s\n\n", cipherText)

	// CREATE SIGNATURE
	signature := createSignature(senderPrivateKeyRaw, plainText)
	fmt.Printf("The senders signature:\n\n%s\n\n", signature)

	// DECRYPT MESSAGE USING PUBLIC KEY
	plainText = decryptMessage(receiverPrivateKeyRaw, cipherText)
	fmt.Printf("The received message contains:\n\n%s\n\n", plainText)

	// VERIFY SIGNATURE
	verifyStatus := verifySignature(senderPublicKeyRaw, signature, plainText)
	fmt.Printf("The senders signature is: %v\n\n", verifyStatus)

}
<|endoftext|>


<commit_before>package google

import (
	"fmt"
	"reflect"
	"time"

	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
	"github.com/hashicorp/terraform-plugin-sdk/helper/structure"
	"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
)

func monitoringDashboardDiffSuppress(k, old, new string, d *schema.ResourceData) bool {
	computedFields := []string{"etag", "name"}

	oldMap, err := structure.ExpandJsonFromString(old)
	if err != nil {
		return false
	}

	newMap, err := structure.ExpandJsonFromString(new)
	if err != nil {
		return false
	}

	for _, f := range computedFields {
		delete(oldMap, f)
		delete(newMap, f)
	}

	return reflect.DeepEqual(oldMap, newMap)
}

func resourceMonitoringDashboard() *schema.Resource {
	return &schema.Resource{
		Create: resourceMonitoringDashboardCreate,
		Read:   resourceMonitoringDashboardRead,
		Update: resourceMonitoringDashboardUpdate,
		Delete: resourceMonitoringDashboardDelete,

		Importer: &schema.ResourceImporter{
			State: resourceMonitoringDashboardImport,
		},

		Timeouts: &schema.ResourceTimeout{
			Create: schema.DefaultTimeout(4 * time.Minute),
			Update: schema.DefaultTimeout(4 * time.Minute),
			Delete: schema.DefaultTimeout(4 * time.Minute),
		},

		Schema: map[string]*schema.Schema{
			"dashboard_json": {
				Type:             schema.TypeString,
				Required:         true,
				ValidateFunc:     validation.ValidateJsonString,
				DiffSuppressFunc: monitoringDashboardDiffSuppress,
				StateFunc: func(v interface{}) string {
					json, _ := structure.NormalizeJsonString(v)
					return json
				},
			},
			"project": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},
		},
	}
}

func resourceMonitoringDashboardCreate(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	obj, err := structure.ExpandJsonFromString(d.Get("dashboard_json").(string))
	if err != nil {
		return err
	}

	project, err := getProject(d, config)
	if err != nil {
		return err
	}

	url, err := replaceVars(d, config, "{{MonitoringBasePath}}v1/projects/{{project}}/dashboards")
	if err != nil {
		return err
	}
	res, err := sendRequestWithTimeout(config, "POST", project, url, obj, d.Timeout(schema.TimeoutCreate), isMonitoringConcurrentEditError)
	if err != nil {
		return fmt.Errorf("Error creating Dashboard: %s", err)
	}

	name, ok := res["name"]
	if !ok {
		return fmt.Errorf("Create response didn't contain critical fields. Create may not have succeeded.")
	}
	d.SetId(name.(string))

	return resourceMonitoringDashboardRead(d, config)
}

func resourceMonitoringDashboardRead(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	url := config.MonitoringBasePath + "v1/" + d.Id()

	project, err := getProject(d, config)
	if err != nil {
		return err
	}

	res, err := sendRequest(config, "GET", project, url, nil, isMonitoringConcurrentEditError)
	if err != nil {
		return handleNotFoundError(err, d, fmt.Sprintf("MonitoringDashboard %q", d.Id()))
	}

	if err := d.Set("project", project); err != nil {
		return fmt.Errorf("Error reading Dashboard: %s", err)
	}

	str, err := structure.FlattenJsonToString(res)
	if err != nil {
		return fmt.Errorf("Error reading Dashboard: %s", err)
	}
	if err = d.Set("dashboard_json", str); err != nil {
		return fmt.Errorf("Error reading Dashboard: %s", err)
	}

	return nil
}

func resourceMonitoringDashboardUpdate(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	o, n := d.GetChange("dashboard_json")
	oObj, err := structure.ExpandJsonFromString(o.(string))
	if err != nil {
		return err
	}
	nObj, err := structure.ExpandJsonFromString(n.(string))
	if err != nil {
		return err
	}

	nObj["etag"] = oObj["etag"]

	project, err := getProject(d, config)
	if err != nil {
		return err
	}

	url := config.MonitoringBasePath + "v1/" + d.Id()
	_, err = sendRequestWithTimeout(config, "PATCH", project, url, nObj, d.Timeout(schema.TimeoutUpdate), isMonitoringConcurrentEditError)
	if err != nil {
		return fmt.Errorf("Error updating Dashboard %q: %s", d.Id(), err)
	}

	return resourceMonitoringDashboardRead(d, config)
}

func resourceMonitoringDashboardDelete(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	url := config.MonitoringBasePath + "v1/" + d.Id()

	project, err := getProject(d, config)
	if err != nil {
		return err
	}

	_, err = sendRequestWithTimeout(config, "DELETE", project, url, nil, d.Timeout(schema.TimeoutDelete), isMonitoringConcurrentEditError)
	if err != nil {
		return handleNotFoundError(err, d, fmt.Sprintf("MonitoringDashboard %q", d.Id()))
	}

	return nil
}

func resourceMonitoringDashboardImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
	config := meta.(*Config)

	// current import_formats can't import fields with forward slashes in their value
	parts, err := getImportIdQualifiers([]string{"projects/(?P<project>[^/]+)/dashboards/(?P<id>[^/]+)", "(?P<id>[^/]+)"}, d, config, d.Id())
	if err != nil {
		return nil, err
	}

	d.Set("project", parts["project"])
	d.SetId(fmt.Sprintf("projects/%s/dashboards/%s", parts["project"], parts["id"]))

	return []*schema.ResourceData{d}, nil
}
<commit_msg>add desc to schema for google_monitoring_dashboard (#3677)<commit_after>package google

import (
	"fmt"
	"reflect"
	"time"

	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
	"github.com/hashicorp/terraform-plugin-sdk/helper/structure"
	"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
)

func monitoringDashboardDiffSuppress(k, old, new string, d *schema.ResourceData) bool {
	computedFields := []string{"etag", "name"}

	oldMap, err := structure.ExpandJsonFromString(old)
	if err != nil {
		return false
	}

	newMap, err := structure.ExpandJsonFromString(new)
	if err != nil {
		return false
	}

	for _, f := range computedFields {
		delete(oldMap, f)
		delete(newMap, f)
	}

	return reflect.DeepEqual(oldMap, newMap)
}

func resourceMonitoringDashboard() *schema.Resource {
	return &schema.Resource{
		Create: resourceMonitoringDashboardCreate,
		Read:   resourceMonitoringDashboardRead,
		Update: resourceMonitoringDashboardUpdate,
		Delete: resourceMonitoringDashboardDelete,

		Importer: &schema.ResourceImporter{
			State: resourceMonitoringDashboardImport,
		},

		Timeouts: &schema.ResourceTimeout{
			Create: schema.DefaultTimeout(4 * time.Minute),
			Update: schema.DefaultTimeout(4 * time.Minute),
			Delete: schema.DefaultTimeout(4 * time.Minute),
		},

		Schema: map[string]*schema.Schema{
			"dashboard_json": {
				Type:             schema.TypeString,
				Required:         true,
				ValidateFunc:     validation.ValidateJsonString,
				DiffSuppressFunc: monitoringDashboardDiffSuppress,
				StateFunc: func(v interface{}) string {
					json, _ := structure.NormalizeJsonString(v)
					return json
				},
				Description: `The JSON representation of a dashboard, following the format at https://cloud.google.com/monitoring/api/ref_v3/rest/v1/projects.dashboards.`,
			},
			"project": {
				Type:        schema.TypeString,
				Optional:    true,
				Computed:    true,
				ForceNew:    true,
				Description: `The ID of the project in which the resource belongs. If it is not provided, the provider project is used.`,
			},
		},
	}
}

func resourceMonitoringDashboardCreate(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	obj, err := structure.ExpandJsonFromString(d.Get("dashboard_json").(string))
	if err != nil {
		return err
	}

	project, err := getProject(d, config)
	if err != nil {
		return err
	}

	url, err := replaceVars(d, config, "{{MonitoringBasePath}}v1/projects/{{project}}/dashboards")
	if err != nil {
		return err
	}
	res, err := sendRequestWithTimeout(config, "POST", project, url, obj, d.Timeout(schema.TimeoutCreate), isMonitoringConcurrentEditError)
	if err != nil {
		return fmt.Errorf("Error creating Dashboard: %s", err)
	}

	name, ok := res["name"]
	if !ok {
		return fmt.Errorf("Create response didn't contain critical fields. Create may not have succeeded.")
	}
	d.SetId(name.(string))

	return resourceMonitoringDashboardRead(d, config)
}

func resourceMonitoringDashboardRead(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	url := config.MonitoringBasePath + "v1/" + d.Id()

	project, err := getProject(d, config)
	if err != nil {
		return err
	}

	res, err := sendRequest(config, "GET", project, url, nil, isMonitoringConcurrentEditError)
	if err != nil {
		return handleNotFoundError(err, d, fmt.Sprintf("MonitoringDashboard %q", d.Id()))
	}

	if err := d.Set("project", project); err != nil {
		return fmt.Errorf("Error reading Dashboard: %s", err)
	}

	str, err := structure.FlattenJsonToString(res)
	if err != nil {
		return fmt.Errorf("Error reading Dashboard: %s", err)
	}
	if err = d.Set("dashboard_json", str); err != nil {
		return fmt.Errorf("Error reading Dashboard: %s", err)
	}

	return nil
}

func resourceMonitoringDashboardUpdate(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	o, n := d.GetChange("dashboard_json")
	oObj, err := structure.ExpandJsonFromString(o.(string))
	if err != nil {
		return err
	}
	nObj, err := structure.ExpandJsonFromString(n.(string))
	if err != nil {
		return err
	}

	nObj["etag"] = oObj["etag"]

	project, err := getProject(d, config)
	if err != nil {
		return err
	}

	url := config.MonitoringBasePath + "v1/" + d.Id()
	_, err = sendRequestWithTimeout(config, "PATCH", project, url, nObj, d.Timeout(schema.TimeoutUpdate), isMonitoringConcurrentEditError)
	if err != nil {
		return fmt.Errorf("Error updating Dashboard %q: %s", d.Id(), err)
	}

	return resourceMonitoringDashboardRead(d, config)
}

func resourceMonitoringDashboardDelete(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)

	url := config.MonitoringBasePath + "v1/" + d.Id()

	project, err := getProject(d, config)
	if err != nil {
		return err
	}

	_, err = sendRequestWithTimeout(config, "DELETE", project, url, nil, d.Timeout(schema.TimeoutDelete), isMonitoringConcurrentEditError)
	if err != nil {
		return handleNotFoundError(err, d, fmt.Sprintf("MonitoringDashboard %q", d.Id()))
	}

	return nil
}

func resourceMonitoringDashboardImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
	config := meta.(*Config)

	// current import_formats can't import fields with forward slashes in their value
	parts, err := getImportIdQualifiers([]string{"projects/(?P<project>[^/]+)/dashboards/(?P<id>[^/]+)", "(?P<id>[^/]+)"}, d, config, d.Id())
	if err != nil {
		return nil, err
	}

	d.Set("project", parts["project"])
	d.SetId(fmt.Sprintf("projects/%s/dashboards/%s", parts["project"], parts["id"]))

	return []*schema.ResourceData{d}, nil
}
<|endoftext|>


<commit_before>package config

import (
	"fmt"
	"os"
	"strings"

	"github.com/caarlos0/env"
	iom "github.com/grokify/gotilla/io/ioutilmore"
	"github.com/joho/godotenv"
)

// EnvFileToJSONFile Converts an .env file to a JSON file using the definition
// provided in data.
func EnvFileToJSONFile(data interface{}, filepathENV, filepathJSON string, perm os.FileMode, pretty bool) error {
	err := godotenv.Load(filepathENV)
	if err != nil {
		return err
	}

	err = env.Parse(data)
	if err != nil {
		return err
	}

	return iom.WriteFileJSON(filepathJSON, data, perm, pretty)
}

// Return a merged environment var which is split into multiple
// vars. This is useful when the system has a size limit on
// environment variables, like AWS Lambda's limit at 256 characters.
func JoinEnvNumbered(prefix, delimiter string, startInt uint8, includeBase bool) string {
	vals := []string{}
	if includeBase {
		val := os.Getenv(prefix)
		if len(val) > 0 {
			vals = append(vals, val)
		}
	}
	i := startInt
	for {
		val := os.Getenv(fmt.Sprintf("%s_%d", prefix, i))
		if len(val) > 0 {
			vals = append(vals, val)
		} else {
			break
		}
		i++
	}
	return strings.Join(vals, delimiter)
}
<commit_msg>fix comment<commit_after>package config

import (
	"fmt"
	"os"
	"strings"

	"github.com/caarlos0/env"
	iom "github.com/grokify/gotilla/io/ioutilmore"
	"github.com/joho/godotenv"
)

// EnvFileToJSONFile Converts an .env file to a JSON file using the definition
// provided in data.
func EnvFileToJSONFile(data interface{}, filepathENV, filepathJSON string, perm os.FileMode, pretty bool) error {
	err := godotenv.Load(filepathENV)
	if err != nil {
		return err
	}

	err = env.Parse(data)
	if err != nil {
		return err
	}

	return iom.WriteFileJSON(filepathJSON, data, perm, pretty)
}

// Return a merged environment var which is split into multiple
// vars. This is useful when the system has a size limit on
// environment variables.
func JoinEnvNumbered(prefix, delimiter string, startInt uint8, includeBase bool) string {
	vals := []string{}
	if includeBase {
		val := os.Getenv(prefix)
		if len(val) > 0 {
			vals = append(vals, val)
		}
	}
	i := startInt
	for {
		val := os.Getenv(fmt.Sprintf("%s_%d", prefix, i))
		if len(val) > 0 {
			vals = append(vals, val)
		} else {
			break
		}
		i++
	}
	return strings.Join(vals, delimiter)
}
<|endoftext|>


<commit_before>package wallet

import (
	"time"

	"github.com/btcsuite/btcd/chaincfg/chainhash"
	"github.com/btcsuite/btcd/wire"
	"github.com/btcsuite/btcutil"
	"github.com/btcsuite/btcutil/hdkeychain"
	"github.com/btcsuite/btcwallet/waddrmgr"
	"github.com/btcsuite/btcwallet/walletdb"
	"github.com/btcsuite/btcwallet/wtxmgr"
)

// RecoveryManager maintains the state required to recover previously used
// addresses, and coordinates batched processing of the blocks to search.
type RecoveryManager struct {
	// recoveryWindow defines the key-derivation lookahead used when
	// attempting to recover the set of used addresses.
	recoveryWindow uint32

	// started is true after the first block has been added to the batch.
	started bool

	// blockBatch contains a list of blocks that have not yet been searched
	// for recovered addresses.
	blockBatch []wtxmgr.BlockMeta

	// state encapsulates and allocates the necessary recovery state for all
	// key scopes and subsidiary derivation paths.
	state *RecoveryState
}

// NewRecoveryManager initializes a new RecoveryManager with a derivation
// look-ahead of `recoveryWindow` child indexes, and pre-allocates a backing
// array for `batchSize` blocks to scan at once.
func NewRecoveryManager(recoveryWindow, batchSize uint32) *RecoveryManager {
	return &RecoveryManager{
		recoveryWindow: recoveryWindow,
		blockBatch:     make([]wtxmgr.BlockMeta, 0, batchSize),
		state:          NewRecoveryState(recoveryWindow),
	}
}

// Resurrect restores all known addresses for the provided scopes that can be
// found in the walletdb namespace, in addition to restoring all outpoints that
// have been previously found. This method ensures that the recovery state's
// horizons properly start from the last found address of a prior recovery
// attempt.
func (rm *RecoveryManager) Resurrect(ns walletdb.ReadBucket,
	scopedMgrs map[waddrmgr.KeyScope]*waddrmgr.ScopedKeyManager,
	credits []wtxmgr.Credit) error {

	// First, for each scope that we are recovering, rederive all of the
	// addresses up to the last found address known to each branch.
	for keyScope, scopedMgr := range scopedMgrs {
		// Load the current account properties for this scope, using the
		// the default account number.
		// TODO(conner): rescan for all created accounts if we allow
		// users to use non-default address
		scopeState := rm.state.StateForScope(keyScope)
		acctProperties, err := scopedMgr.AccountProperties(
			ns, waddrmgr.DefaultAccountNum,
		)
		if err != nil {
			return err
		}

		// Fetch the external key count, which bounds the indexes we
		// will need to rederive.
		externalCount := acctProperties.ExternalKeyCount

		// Walk through all indexes through the last external key,
		// deriving each address and adding it to the external branch
		// recovery state's set of addresses to look for.
		for i := uint32(0); i < externalCount; i++ {
			keyPath := externalKeyPath(i)
			addr, err := scopedMgr.DeriveFromKeyPath(ns, keyPath)
			if err != nil && err != hdkeychain.ErrInvalidChild {
				return err
			} else if err == hdkeychain.ErrInvalidChild {
				scopeState.ExternalBranch.MarkInvalidChild(i)
				continue
			}

			scopeState.ExternalBranch.AddAddr(i, addr.Address())
		}

		// Fetch the internal key count, which bounds the indexes we
		// will need to rederive.
		internalCount := acctProperties.InternalKeyCount

		// Walk through all indexes through the last internal key,
		// deriving each address and adding it to the internal branch
		// recovery state's set of addresses to look for.
		for i := uint32(0); i < internalCount; i++ {
			keyPath := internalKeyPath(i)
			addr, err := scopedMgr.DeriveFromKeyPath(ns, keyPath)
			if err != nil && err != hdkeychain.ErrInvalidChild {
				return err
			} else if err == hdkeychain.ErrInvalidChild {
				scopeState.InternalBranch.MarkInvalidChild(i)
				continue
			}

			scopeState.InternalBranch.AddAddr(i, addr.Address())
		}

		// The key counts will point to the next key that can be
		// derived, so we subtract one to point to last known key. If
		// the key count is zero, then no addresses have been found.
		if externalCount > 0 {
			scopeState.ExternalBranch.ReportFound(externalCount - 1)
		}
		if internalCount > 0 {
			scopeState.InternalBranch.ReportFound(internalCount - 1)
		}
	}

	// In addition, we will re-add any outpoints that are known the wallet
	// to our global set of watched outpoints, so that we can watch them for
	// spends.
	for _, credit := range credits {
		rm.state.AddWatchedOutPoint(&credit.OutPoint)
	}

	return nil
}

// AddToBlockBatch appends the block information, consisting of hash and height,
// to the batch of blocks to be searched.
func (rm *RecoveryManager) AddToBlockBatch(hash *chainhash.Hash, height int32,
	timestamp time.Time) {

	if !rm.started {
		log.Infof("Seed birthday surpassed, starting recovery "+
			"of wallet from height=%d hash=%v with "+
			"recovery-window=%d", height, *hash, rm.recoveryWindow)
		rm.started = true
	}

	block := wtxmgr.BlockMeta{
		Block: wtxmgr.Block{
			Hash:   *hash,
			Height: height,
		},
		Time: timestamp,
	}
	rm.blockBatch = append(rm.blockBatch, block)
}

// BlockBatch returns a buffer of blocks that have not yet been searched.
func (rm *RecoveryManager) BlockBatch() []wtxmgr.BlockMeta {
	return rm.blockBatch
}

// ResetBlockBatch resets the internal block buffer to conserve memory.
func (rm *RecoveryManager) ResetBlockBatch() {
	rm.blockBatch = rm.blockBatch[:0]
}

// State returns the current RecoveryState.
func (rm *RecoveryManager) State() *RecoveryState {
	return rm.state
}

// RecoveryState manages the initialization and lookup of ScopeRecoveryStates
// for any actively used key scopes.
//
// In order to ensure that all addresses are properly recovered, the window
// should be sized as the sum of maximum possible inter-block and intra-block
// gap between used addresses of a particular branch.
//
// These are defined as:
//   - Inter-Block Gap: The maximum difference between the derived child indexes
//       of the last addresses used in any block and the next address consumed
//       by a later block.
//   - Intra-Block Gap: The maximum difference between the derived child indexes
//       of the first address used in any block and the last address used in the
//       same block.
type RecoveryState struct {
	// recoveryWindow defines the key-derivation lookahead used when
	// attempting to recover the set of used addresses. This value will be
	// used to instantiate a new RecoveryState for each requested scope.
	recoveryWindow uint32

	// scopes maintains a map of each requested key scope to its active
	// RecoveryState.
	scopes map[waddrmgr.KeyScope]*ScopeRecoveryState

	// watchedOutPoints contains the set of all outpoints known to the
	// wallet. This is updated iteratively as new outpoints are found during
	// a rescan.
	watchedOutPoints map[wire.OutPoint]struct{}
}

// NewRecoveryState creates a new RecoveryState using the provided
// recoveryWindow. Each RecoveryState that is subsequently initialized for a
// particular key scope will receive the same recoveryWindow.
func NewRecoveryState(recoveryWindow uint32) *RecoveryState {
	scopes := make(map[waddrmgr.KeyScope]*ScopeRecoveryState)

	return &RecoveryState{
		recoveryWindow:   recoveryWindow,
		scopes:           scopes,
		watchedOutPoints: make(map[wire.OutPoint]struct{}),
	}
}

// StateForScope returns a ScopeRecoveryState for the provided key scope. If one
// does not already exist, a new one will be generated with the RecoveryState's
// recoveryWindow.
func (rs *RecoveryState) StateForScope(
	keyScope waddrmgr.KeyScope) *ScopeRecoveryState {

	// If the account recovery state already exists, return it.
	if scopeState, ok := rs.scopes[keyScope]; ok {
		return scopeState
	}

	// Otherwise, initialize the recovery state for this scope with the
	// chosen recovery window.
	rs.scopes[keyScope] = NewScopeRecoveryState(rs.recoveryWindow)

	return rs.scopes[keyScope]
}

// WatchedOutPoints returns the global set of outpoints that are known to belong
// to the wallet during recovery.
func (rs *RecoveryState) WatchedOutPoints() map[wire.OutPoint]struct{} {
	return rs.watchedOutPoints
}

// AddWatchedOutPoint updates the recovery state's set of known outpoints that
// we will monitor for spends during recovery.
func (rs *RecoveryState) AddWatchedOutPoint(outPoint *wire.OutPoint) {
	rs.watchedOutPoints[*outPoint] = struct{}{}
}

// ScopeRecoveryState is used to manage the recovery of addresses generated
// under a particular BIP32 account. Each account tracks both an external and
// internal branch recovery state, both of which use the same recovery window.
type ScopeRecoveryState struct {
	// ExternalBranch is the recovery state of addresses generated for
	// external use, i.e. receiving addresses.
	ExternalBranch *BranchRecoveryState

	// InternalBranch is the recovery state of addresses generated for
	// internal use, i.e. change addresses.
	InternalBranch *BranchRecoveryState
}

// NewScopeRecoveryState initializes an ScopeRecoveryState with the chosen
// recovery window.
func NewScopeRecoveryState(recoveryWindow uint32) *ScopeRecoveryState {
	return &ScopeRecoveryState{
		ExternalBranch: NewBranchRecoveryState(recoveryWindow),
		InternalBranch: NewBranchRecoveryState(recoveryWindow),
	}
}

// BranchRecoveryState maintains the required state in-order to properly
// recover addresses derived from a particular account's internal or external
// derivation branch.
//
// A branch recovery state supports operations for:
//  - Expanding the look-ahead horizon based on which indexes have been found.
//  - Registering derived addresses with indexes within the horizon.
//  - Reporting an invalid child index that falls into the horizon.
//  - Reporting that an address has been found.
//  - Retrieving all currently derived addresses for the branch.
//  - Looking up a particular address by its child index.
type BranchRecoveryState struct {
	// recoveryWindow defines the key-derivation lookahead used when
	// attempting to recover the set of addresses on this branch.
	recoveryWindow uint32

	// horizion records the highest child index watched by this branch.
	horizon uint32

	// nextUnfound maintains the child index of the successor to the highest
	// index that has been found during recovery of this branch.
	nextUnfound uint32

	// addresses is a map of child index to address for all actively watched
	// addresses belonging to this branch.
	addresses map[uint32]btcutil.Address

	// invalidChildren records the set of child indexes that derive to
	// invalid keys.
	invalidChildren map[uint32]struct{}
}

// NewBranchRecoveryState creates a new BranchRecoveryState that can be used to
// track either the external or internal branch of an account's derivation path.
func NewBranchRecoveryState(recoveryWindow uint32) *BranchRecoveryState {
	return &BranchRecoveryState{
		recoveryWindow:  recoveryWindow,
		addresses:       make(map[uint32]btcutil.Address),
		invalidChildren: make(map[uint32]struct{}),
	}
}

// ExtendHorizon returns the current horizon and the number of addresses that
// must be derived in order to maintain the desired recovery window.
func (brs *BranchRecoveryState) ExtendHorizon() (uint32, uint32) {

	// Compute the new horizon, which should surpass our last found address
	// by the recovery window.
	curHorizon := brs.horizon

	nInvalid := brs.NumInvalidInHorizon()
	minValidHorizon := brs.nextUnfound + brs.recoveryWindow + nInvalid

	// If the current horizon is sufficient, we will not have to derive any
	// new keys.
	if curHorizon >= minValidHorizon {
		return curHorizon, 0
	}

	// Otherwise, the number of addresses we should derive corresponds to
	// the delta of the two horizons, and we update our new horizon.
	delta := minValidHorizon - curHorizon
	brs.horizon = minValidHorizon

	return curHorizon, delta
}

// AddAddr adds a freshly derived address from our lookahead into the map of
// known addresses for this branch.
func (brs *BranchRecoveryState) AddAddr(index uint32, addr btcutil.Address) {
	brs.addresses[index] = addr
}

// GetAddr returns the address derived from a given child index.
func (brs *BranchRecoveryState) GetAddr(index uint32) btcutil.Address {
	return brs.addresses[index]
}

// ReportFound updates the last found index if the reported index exceeds the
// current value.
func (brs *BranchRecoveryState) ReportFound(index uint32) {
	if index >= brs.nextUnfound {
		brs.nextUnfound = index + 1

		// Prune all invalid child indexes that fall below our last
		// found index. We don't need to keep these entries any longer,
		// since they will not affect our required look-ahead.
		for childIndex := range brs.invalidChildren {
			if childIndex < index {
				delete(brs.invalidChildren, childIndex)
			}
		}
	}
}

// MarkInvalidChild records that a particular child index results in deriving an
// invalid address. In addition, the branch's horizon is increment, as we expect
// the caller to perform an additional derivation to replace the invalid child.
// This is used to ensure that we are always have the proper lookahead when an
// invalid child is encountered.
func (brs *BranchRecoveryState) MarkInvalidChild(index uint32) {
	brs.invalidChildren[index] = struct{}{}
	brs.horizon++
}

// NextUnfound returns the child index of the successor to the highest found
// child index.
func (brs *BranchRecoveryState) NextUnfound() uint32 {
	return brs.nextUnfound
}

// Addrs returns a map of all currently derived child indexes to the their
// corresponding addresses.
func (brs *BranchRecoveryState) Addrs() map[uint32]btcutil.Address {
	return brs.addresses
}

// NumInvalidInHorizon computes the number of invalid child indexes that lie
// between the last found and current horizon. This informs how many additional
// indexes to derive in order to maintain the proper number of valid addresses
// within our horizon.
func (brs *BranchRecoveryState) NumInvalidInHorizon() uint32 {
	var nInvalid uint32
	for childIndex := range brs.invalidChildren {
		if brs.nextUnfound <= childIndex && childIndex < brs.horizon {
			nInvalid++
		}
	}

	return nInvalid
}
<commit_msg>wallet: update HD recovery logic to map outpoints to addresses<commit_after>package wallet

import (
	"time"

	"github.com/btcsuite/btcd/chaincfg"
	"github.com/btcsuite/btcd/chaincfg/chainhash"
	"github.com/btcsuite/btcd/txscript"
	"github.com/btcsuite/btcd/wire"
	"github.com/btcsuite/btcutil"
	"github.com/btcsuite/btcutil/hdkeychain"
	"github.com/btcsuite/btcwallet/waddrmgr"
	"github.com/btcsuite/btcwallet/walletdb"
	"github.com/btcsuite/btcwallet/wtxmgr"
)

// RecoveryManager maintains the state required to recover previously used
// addresses, and coordinates batched processing of the blocks to search.
type RecoveryManager struct {
	// recoveryWindow defines the key-derivation lookahead used when
	// attempting to recover the set of used addresses.
	recoveryWindow uint32

	// started is true after the first block has been added to the batch.
	started bool

	// blockBatch contains a list of blocks that have not yet been searched
	// for recovered addresses.
	blockBatch []wtxmgr.BlockMeta

	// state encapsulates and allocates the necessary recovery state for all
	// key scopes and subsidiary derivation paths.
	state *RecoveryState

	// chainParams are the parameters that describe the chain we're trying
	// to recover funds on.
	chainParams *chaincfg.Params
}

// NewRecoveryManager initializes a new RecoveryManager with a derivation
// look-ahead of `recoveryWindow` child indexes, and pre-allocates a backing
// array for `batchSize` blocks to scan at once.
func NewRecoveryManager(recoveryWindow, batchSize uint32,
	chainParams *chaincfg.Params) *RecoveryManager {

	return &RecoveryManager{
		recoveryWindow: recoveryWindow,
		blockBatch:     make([]wtxmgr.BlockMeta, 0, batchSize),
		chainParams:    chainParams,
		state:          NewRecoveryState(recoveryWindow),
	}
}

// Resurrect restores all known addresses for the provided scopes that can be
// found in the walletdb namespace, in addition to restoring all outpoints that
// have been previously found. This method ensures that the recovery state's
// horizons properly start from the last found address of a prior recovery
// attempt.
func (rm *RecoveryManager) Resurrect(ns walletdb.ReadBucket,
	scopedMgrs map[waddrmgr.KeyScope]*waddrmgr.ScopedKeyManager,
	credits []wtxmgr.Credit) error {

	// First, for each scope that we are recovering, rederive all of the
	// addresses up to the last found address known to each branch.
	for keyScope, scopedMgr := range scopedMgrs {
		// Load the current account properties for this scope, using the
		// the default account number.
		// TODO(conner): rescan for all created accounts if we allow
		// users to use non-default address
		scopeState := rm.state.StateForScope(keyScope)
		acctProperties, err := scopedMgr.AccountProperties(
			ns, waddrmgr.DefaultAccountNum,
		)
		if err != nil {
			return err
		}

		// Fetch the external key count, which bounds the indexes we
		// will need to rederive.
		externalCount := acctProperties.ExternalKeyCount

		// Walk through all indexes through the last external key,
		// deriving each address and adding it to the external branch
		// recovery state's set of addresses to look for.
		for i := uint32(0); i < externalCount; i++ {
			keyPath := externalKeyPath(i)
			addr, err := scopedMgr.DeriveFromKeyPath(ns, keyPath)
			if err != nil && err != hdkeychain.ErrInvalidChild {
				return err
			} else if err == hdkeychain.ErrInvalidChild {
				scopeState.ExternalBranch.MarkInvalidChild(i)
				continue
			}

			scopeState.ExternalBranch.AddAddr(i, addr.Address())
		}

		// Fetch the internal key count, which bounds the indexes we
		// will need to rederive.
		internalCount := acctProperties.InternalKeyCount

		// Walk through all indexes through the last internal key,
		// deriving each address and adding it to the internal branch
		// recovery state's set of addresses to look for.
		for i := uint32(0); i < internalCount; i++ {
			keyPath := internalKeyPath(i)
			addr, err := scopedMgr.DeriveFromKeyPath(ns, keyPath)
			if err != nil && err != hdkeychain.ErrInvalidChild {
				return err
			} else if err == hdkeychain.ErrInvalidChild {
				scopeState.InternalBranch.MarkInvalidChild(i)
				continue
			}

			scopeState.InternalBranch.AddAddr(i, addr.Address())
		}

		// The key counts will point to the next key that can be
		// derived, so we subtract one to point to last known key. If
		// the key count is zero, then no addresses have been found.
		if externalCount > 0 {
			scopeState.ExternalBranch.ReportFound(externalCount - 1)
		}
		if internalCount > 0 {
			scopeState.InternalBranch.ReportFound(internalCount - 1)
		}
	}

	// In addition, we will re-add any outpoints that are known the wallet
	// to our global set of watched outpoints, so that we can watch them for
	// spends.
	for _, credit := range credits {
		_, addrs, _, err := txscript.ExtractPkScriptAddrs(
			credit.PkScript, rm.chainParams,
		)
		if err != nil {
			return err
		}

		rm.state.AddWatchedOutPoint(&credit.OutPoint, addrs[0])
	}

	return nil
}

// AddToBlockBatch appends the block information, consisting of hash and height,
// to the batch of blocks to be searched.
func (rm *RecoveryManager) AddToBlockBatch(hash *chainhash.Hash, height int32,
	timestamp time.Time) {

	if !rm.started {
		log.Infof("Seed birthday surpassed, starting recovery "+
			"of wallet from height=%d hash=%v with "+
			"recovery-window=%d", height, *hash, rm.recoveryWindow)
		rm.started = true
	}

	block := wtxmgr.BlockMeta{
		Block: wtxmgr.Block{
			Hash:   *hash,
			Height: height,
		},
		Time: timestamp,
	}
	rm.blockBatch = append(rm.blockBatch, block)
}

// BlockBatch returns a buffer of blocks that have not yet been searched.
func (rm *RecoveryManager) BlockBatch() []wtxmgr.BlockMeta {
	return rm.blockBatch
}

// ResetBlockBatch resets the internal block buffer to conserve memory.
func (rm *RecoveryManager) ResetBlockBatch() {
	rm.blockBatch = rm.blockBatch[:0]
}

// State returns the current RecoveryState.
func (rm *RecoveryManager) State() *RecoveryState {
	return rm.state
}

// RecoveryState manages the initialization and lookup of ScopeRecoveryStates
// for any actively used key scopes.
//
// In order to ensure that all addresses are properly recovered, the window
// should be sized as the sum of maximum possible inter-block and intra-block
// gap between used addresses of a particular branch.
//
// These are defined as:
//   - Inter-Block Gap: The maximum difference between the derived child indexes
//       of the last addresses used in any block and the next address consumed
//       by a later block.
//   - Intra-Block Gap: The maximum difference between the derived child indexes
//       of the first address used in any block and the last address used in the
//       same block.
type RecoveryState struct {
	// recoveryWindow defines the key-derivation lookahead used when
	// attempting to recover the set of used addresses. This value will be
	// used to instantiate a new RecoveryState for each requested scope.
	recoveryWindow uint32

	// scopes maintains a map of each requested key scope to its active
	// RecoveryState.
	scopes map[waddrmgr.KeyScope]*ScopeRecoveryState

	// watchedOutPoints contains the set of all outpoints known to the
	// wallet. This is updated iteratively as new outpoints are found during
	// a rescan.
	watchedOutPoints map[wire.OutPoint]btcutil.Address
}

// NewRecoveryState creates a new RecoveryState using the provided
// recoveryWindow. Each RecoveryState that is subsequently initialized for a
// particular key scope will receive the same recoveryWindow.
func NewRecoveryState(recoveryWindow uint32) *RecoveryState {
	scopes := make(map[waddrmgr.KeyScope]*ScopeRecoveryState)

	return &RecoveryState{
		recoveryWindow:   recoveryWindow,
		scopes:           scopes,
		watchedOutPoints: make(map[wire.OutPoint]btcutil.Address),
	}
}

// StateForScope returns a ScopeRecoveryState for the provided key scope. If one
// does not already exist, a new one will be generated with the RecoveryState's
// recoveryWindow.
func (rs *RecoveryState) StateForScope(
	keyScope waddrmgr.KeyScope) *ScopeRecoveryState {

	// If the account recovery state already exists, return it.
	if scopeState, ok := rs.scopes[keyScope]; ok {
		return scopeState
	}

	// Otherwise, initialize the recovery state for this scope with the
	// chosen recovery window.
	rs.scopes[keyScope] = NewScopeRecoveryState(rs.recoveryWindow)

	return rs.scopes[keyScope]
}

// WatchedOutPoints returns the global set of outpoints that are known to belong
// to the wallet during recovery.
func (rs *RecoveryState) WatchedOutPoints() map[wire.OutPoint]btcutil.Address {
	return rs.watchedOutPoints
}

// AddWatchedOutPoint updates the recovery state's set of known outpoints that
// we will monitor for spends during recovery.
func (rs *RecoveryState) AddWatchedOutPoint(outPoint *wire.OutPoint,
	addr btcutil.Address) {

	rs.watchedOutPoints[*outPoint] = addr
}

// ScopeRecoveryState is used to manage the recovery of addresses generated
// under a particular BIP32 account. Each account tracks both an external and
// internal branch recovery state, both of which use the same recovery window.
type ScopeRecoveryState struct {
	// ExternalBranch is the recovery state of addresses generated for
	// external use, i.e. receiving addresses.
	ExternalBranch *BranchRecoveryState

	// InternalBranch is the recovery state of addresses generated for
	// internal use, i.e. change addresses.
	InternalBranch *BranchRecoveryState
}

// NewScopeRecoveryState initializes an ScopeRecoveryState with the chosen
// recovery window.
func NewScopeRecoveryState(recoveryWindow uint32) *ScopeRecoveryState {
	return &ScopeRecoveryState{
		ExternalBranch: NewBranchRecoveryState(recoveryWindow),
		InternalBranch: NewBranchRecoveryState(recoveryWindow),
	}
}

// BranchRecoveryState maintains the required state in-order to properly
// recover addresses derived from a particular account's internal or external
// derivation branch.
//
// A branch recovery state supports operations for:
//  - Expanding the look-ahead horizon based on which indexes have been found.
//  - Registering derived addresses with indexes within the horizon.
//  - Reporting an invalid child index that falls into the horizon.
//  - Reporting that an address has been found.
//  - Retrieving all currently derived addresses for the branch.
//  - Looking up a particular address by its child index.
type BranchRecoveryState struct {
	// recoveryWindow defines the key-derivation lookahead used when
	// attempting to recover the set of addresses on this branch.
	recoveryWindow uint32

	// horizion records the highest child index watched by this branch.
	horizon uint32

	// nextUnfound maintains the child index of the successor to the highest
	// index that has been found during recovery of this branch.
	nextUnfound uint32

	// addresses is a map of child index to address for all actively watched
	// addresses belonging to this branch.
	addresses map[uint32]btcutil.Address

	// invalidChildren records the set of child indexes that derive to
	// invalid keys.
	invalidChildren map[uint32]struct{}
}

// NewBranchRecoveryState creates a new BranchRecoveryState that can be used to
// track either the external or internal branch of an account's derivation path.
func NewBranchRecoveryState(recoveryWindow uint32) *BranchRecoveryState {
	return &BranchRecoveryState{
		recoveryWindow:  recoveryWindow,
		addresses:       make(map[uint32]btcutil.Address),
		invalidChildren: make(map[uint32]struct{}),
	}
}

// ExtendHorizon returns the current horizon and the number of addresses that
// must be derived in order to maintain the desired recovery window.
func (brs *BranchRecoveryState) ExtendHorizon() (uint32, uint32) {

	// Compute the new horizon, which should surpass our last found address
	// by the recovery window.
	curHorizon := brs.horizon

	nInvalid := brs.NumInvalidInHorizon()
	minValidHorizon := brs.nextUnfound + brs.recoveryWindow + nInvalid

	// If the current horizon is sufficient, we will not have to derive any
	// new keys.
	if curHorizon >= minValidHorizon {
		return curHorizon, 0
	}

	// Otherwise, the number of addresses we should derive corresponds to
	// the delta of the two horizons, and we update our new horizon.
	delta := minValidHorizon - curHorizon
	brs.horizon = minValidHorizon

	return curHorizon, delta
}

// AddAddr adds a freshly derived address from our lookahead into the map of
// known addresses for this branch.
func (brs *BranchRecoveryState) AddAddr(index uint32, addr btcutil.Address) {
	brs.addresses[index] = addr
}

// GetAddr returns the address derived from a given child index.
func (brs *BranchRecoveryState) GetAddr(index uint32) btcutil.Address {
	return brs.addresses[index]
}

// ReportFound updates the last found index if the reported index exceeds the
// current value.
func (brs *BranchRecoveryState) ReportFound(index uint32) {
	if index >= brs.nextUnfound {
		brs.nextUnfound = index + 1

		// Prune all invalid child indexes that fall below our last
		// found index. We don't need to keep these entries any longer,
		// since they will not affect our required look-ahead.
		for childIndex := range brs.invalidChildren {
			if childIndex < index {
				delete(brs.invalidChildren, childIndex)
			}
		}
	}
}

// MarkInvalidChild records that a particular child index results in deriving an
// invalid address. In addition, the branch's horizon is increment, as we expect
// the caller to perform an additional derivation to replace the invalid child.
// This is used to ensure that we are always have the proper lookahead when an
// invalid child is encountered.
func (brs *BranchRecoveryState) MarkInvalidChild(index uint32) {
	brs.invalidChildren[index] = struct{}{}
	brs.horizon++
}

// NextUnfound returns the child index of the successor to the highest found
// child index.
func (brs *BranchRecoveryState) NextUnfound() uint32 {
	return brs.nextUnfound
}

// Addrs returns a map of all currently derived child indexes to the their
// corresponding addresses.
func (brs *BranchRecoveryState) Addrs() map[uint32]btcutil.Address {
	return brs.addresses
}

// NumInvalidInHorizon computes the number of invalid child indexes that lie
// between the last found and current horizon. This informs how many additional
// indexes to derive in order to maintain the proper number of valid addresses
// within our horizon.
func (brs *BranchRecoveryState) NumInvalidInHorizon() uint32 {
	var nInvalid uint32
	for childIndex := range brs.invalidChildren {
		if brs.nextUnfound <= childIndex && childIndex < brs.horizon {
			nInvalid++
		}
	}

	return nInvalid
}
<|endoftext|>


<commit_before>package walnut

import (
	"bytes"
	"regexp"
	"strconv"
	"time"
)

var (
	_TruthyRegexp = regexp.MustCompile(`^[ \t]*(true|yes|on)`)
	_FalsyRegexp  = regexp.MustCompile(`^[ \t]*(false|no|off)`)
	_IntRegexp    = regexp.MustCompile(`^[ \t]*([\+\-]?\d+)`)
	_FloatRegexp  = regexp.MustCompile(`^[ \t]*([\+\-]?\d+(?:\.\d+)?)`)
	_TimeRegexp   = regexp.MustCompile(
		`^[ \t]*(\d{4}\-\d{2}\-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)? [\-\+]\d{4})`)
)

// Attempts to extract a string literal from the beginning of `in`.
func readBool(in []byte) (bool, int) {
	if m := _TruthyRegexp.FindIndex(in); m != nil {
		return true, m[1]
	}
	if m := _FalsyRegexp.FindIndex(in); m != nil {
		return false, m[1]
	}

	return false, 0
}

// Attempts to extract a signed integer from the beginning of `in`.
func readInt64(in []byte) (int64, int) {
	m := _IntRegexp.FindSubmatchIndex(in)
	if m == nil {
		return 0, 0
	}

	num := string(in[m[2]:m[3]])
	v, err := strconv.ParseInt(num, 10, 64)
	if err != nil {
		return 0, 0
	}

	return v, m[3]
}

// Attempts to extract a floating point value from the beginning of `in`.
func readFloat64(in []byte) (float64, int) {
	m := _FloatRegexp.FindSubmatchIndex(in)
	if m == nil {
		return 0, 0
	}

	slice := string(in[m[2]:m[3]])
	v, err := strconv.ParseFloat(slice, 64)
	if err != nil {
		return 0, 0
	}

	return v, m[3]
}

// Attempts to extract a timestamp from the beginning of `in`.
func readString(in []byte) (string, int) {
	start := 0
	for start < len(in) && (in[start] == ' ' || in[start] == '\t') {
		start++
	}

	if len(in)-start < 2 || in[start] != '"' {
		return "", 0
	}

	i := start + 1 // jump the first double quote
	end := -1
	escaped := false

	for end == -1 {
		if i == len(in) {
			// end of input reached before finding a closing quote
			return "", 0
		}

		b := in[i]

		switch {
		case b <= 0x20:
			// control characters aren't inside a string literal
			return "", 0
		case escaped:
			escaped = false
		case b == '\\':
			escaped = true
		case b == '"':
			end = i
		}

		i++
	}

	v, err := strconv.Unquote(string(in[start : end+1]))
	if err != nil {
		return "", 0
	}

	return v, end + 1
}

// Attempts to extract a timestamp from the beginning of `in`.
func readTime(in []byte) (time.Time, int) {
	m := _TimeRegexp.FindSubmatchIndex(in)
	if m == nil {
		return time.Time{}, 0
	}

	slice := string(in[m[2]:m[3]])
	v, err := time.Parse("2006-01-02 15:04:05 -0700", slice)
	if err != nil {
		return time.Time{}, 0
	}

	return v, m[3]
}

// Attempts to extract a timestamp from the beginning of `in`.
func readDuration(in []byte) (time.Duration, int) {
	offset := 0
	total := time.Duration(0)

	for {
		v, n := readDurationPartial(in[offset:])
		if n == 0 {
			break
		}

		// guard against integer overflow
		if total+v <= total {
			return 0, 0
		}

		total += v
		offset += n
	}

	return total, offset
}

var timeUnits = []struct {
	name []byte
	dur  time.Duration
}{
	{[]byte("ns"), time.Nanosecond},
	{[]byte("μs"), time.Microsecond}, // \u03bc
	{[]byte("µs"), time.Microsecond}, // \u00b5
	{[]byte("us"), time.Microsecond},
	{[]byte("ms"), time.Millisecond},
	{[]byte("s"), time.Second},
	{[]byte("m"), time.Minute},
	{[]byte("h"), time.Hour},
	{[]byte("d"), 24 * time.Hour},
	{[]byte("w"), 7 * 24 * time.Hour},
}

func readDurationPartial(in []byte) (time.Duration, int) {
	i, end := 0, len(in)

	// skip whitespace
	for i < end && (in[i] == ' ' || in[i] == '\t') {
		i++
	}

	value := int64(0)
	start := i

	for ; i < end && ('0' <= in[i] && in[i] <= '9'); i++ {
		// guard against integer overflow
		next := (value * 10) + int64(in[i]-'0')
		if next <= value {
			return 0, 0
		} else {
			value = next
		}
	}

	// did we find any digits?
	if i == start {
		return 0, 0
	}

	for _, unit := range timeUnits {
		if bytes.HasPrefix(in[i:], unit.name) {
			return time.Duration(value) * unit.dur, i + len(unit.name)
		}
	}

	return 0, 0
}
<commit_msg>Float parsing should require at least one decimal point<commit_after>package walnut

import (
	"bytes"
	"regexp"
	"strconv"
	"time"
)

var (
	_TruthyRegexp = regexp.MustCompile(`^[ \t]*(true|yes|on)`)
	_FalsyRegexp  = regexp.MustCompile(`^[ \t]*(false|no|off)`)
	_IntRegexp    = regexp.MustCompile(`^[ \t]*([\+\-]?\d+)`)
	_FloatRegexp  = regexp.MustCompile(`^[ \t]*([\+\-]?\d+\.\d+)`)
	_TimeRegexp   = regexp.MustCompile(
		`^[ \t]*(\d{4}\-\d{2}\-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)? [\-\+]\d{4})`)
)

// Attempts to extract a string literal from the beginning of `in`.
func readBool(in []byte) (bool, int) {
	if m := _TruthyRegexp.FindIndex(in); m != nil {
		return true, m[1]
	}
	if m := _FalsyRegexp.FindIndex(in); m != nil {
		return false, m[1]
	}

	return false, 0
}

// Attempts to extract a signed integer from the beginning of `in`.
func readInt64(in []byte) (int64, int) {
	m := _IntRegexp.FindSubmatchIndex(in)
	if m == nil {
		return 0, 0
	}

	num := string(in[m[2]:m[3]])
	v, err := strconv.ParseInt(num, 10, 64)
	if err != nil {
		return 0, 0
	}

	return v, m[3]
}

// Attempts to extract a floating point value from the beginning of `in`.
func readFloat64(in []byte) (float64, int) {
	m := _FloatRegexp.FindSubmatchIndex(in)
	if m == nil {
		return 0, 0
	}

	slice := string(in[m[2]:m[3]])
	v, err := strconv.ParseFloat(slice, 64)
	if err != nil {
		return 0, 0
	}

	return v, m[3]
}

// Attempts to extract a timestamp from the beginning of `in`.
func readString(in []byte) (string, int) {
	start := 0
	for start < len(in) && (in[start] == ' ' || in[start] == '\t') {
		start++
	}

	if len(in)-start < 2 || in[start] != '"' {
		return "", 0
	}

	i := start + 1 // jump the first double quote
	end := -1
	escaped := false

	for end == -1 {
		if i == len(in) {
			// end of input reached before finding a closing quote
			return "", 0
		}

		b := in[i]

		switch {
		case b <= 0x20:
			// control characters aren't inside a string literal
			return "", 0
		case escaped:
			escaped = false
		case b == '\\':
			escaped = true
		case b == '"':
			end = i
		}

		i++
	}

	v, err := strconv.Unquote(string(in[start : end+1]))
	if err != nil {
		return "", 0
	}

	return v, end + 1
}

// Attempts to extract a timestamp from the beginning of `in`.
func readTime(in []byte) (time.Time, int) {
	m := _TimeRegexp.FindSubmatchIndex(in)
	if m == nil {
		return time.Time{}, 0
	}

	slice := string(in[m[2]:m[3]])
	v, err := time.Parse("2006-01-02 15:04:05 -0700", slice)
	if err != nil {
		return time.Time{}, 0
	}

	return v, m[3]
}

// Attempts to extract a timestamp from the beginning of `in`.
func readDuration(in []byte) (time.Duration, int) {
	offset := 0
	total := time.Duration(0)

	for {
		v, n := readDurationPartial(in[offset:])
		if n == 0 {
			break
		}

		// guard against integer overflow
		if total+v <= total {
			return 0, 0
		}

		total += v
		offset += n
	}

	return total, offset
}

var timeUnits = []struct {
	name []byte
	dur  time.Duration
}{
	{[]byte("ns"), time.Nanosecond},
	{[]byte("μs"), time.Microsecond}, // \u03bc
	{[]byte("µs"), time.Microsecond}, // \u00b5
	{[]byte("us"), time.Microsecond},
	{[]byte("ms"), time.Millisecond},
	{[]byte("s"), time.Second},
	{[]byte("m"), time.Minute},
	{[]byte("h"), time.Hour},
	{[]byte("d"), 24 * time.Hour},
	{[]byte("w"), 7 * 24 * time.Hour},
}

func readDurationPartial(in []byte) (time.Duration, int) {
	i, end := 0, len(in)

	// skip whitespace
	for i < end && (in[i] == ' ' || in[i] == '\t') {
		i++
	}

	value := int64(0)
	start := i

	for ; i < end && ('0' <= in[i] && in[i] <= '9'); i++ {
		// guard against integer overflow
		next := (value * 10) + int64(in[i]-'0')
		if next <= value {
			return 0, 0
		} else {
			value = next
		}
	}

	// did we find any digits?
	if i == start {
		return 0, 0
	}

	for _, unit := range timeUnits {
		if bytes.HasPrefix(in[i:], unit.name) {
			return time.Duration(value) * unit.dur, i + len(unit.name)
		}
	}

	return 0, 0
}
<|endoftext|>


<commit_before>package cl11

import (
	"unsafe"

	clw "github.com/rdwilliamson/clw11"
)

type Event struct {
	ID          clw.Event
	CommandType CommandType
}

func (c *Context) CreateUserEvent() (*Event, error) {
	event, err := clw.CreateUserEvent(c.ID)
	if err != nil {
		return nil, err
	}
	return &Event{ID: event}, nil
}

type CommandType int

const (
	CommandNDRangeKernel        = CommandType(clw.CommandNdrangeKernel)
	CommandTask                 = CommandType(clw.CommandTask)
	CommandNativeKernel         = CommandType(clw.CommandNativeKernel)
	CommandReadBuffer           = CommandType(clw.CommandReadBuffer)
	CommandWriteBuffer          = CommandType(clw.CommandWriteBuffer)
	CommandCopyBuffer           = CommandType(clw.CommandCopyBuffer)
	CommandReadImage            = CommandType(clw.CommandReadImage)
	CommandWriteImage           = CommandType(clw.CommandWriteImage)
	CommandCopyImage            = CommandType(clw.CommandCopyImage)
	CommandCopyImageToBuffer    = CommandType(clw.CommandCopyImageToBuffer)
	CommandCopyBufferToImage    = CommandType(clw.CommandCopyBufferToImage)
	CommandMapBuffer            = CommandType(clw.CommandMapBuffer)
	CommandMapImage             = CommandType(clw.CommandMapImage)
	CommandUnmapMemoryObject    = CommandType(clw.CommandUnmapMemoryObject)
	CommandMarker               = CommandType(clw.CommandMarker)
	CommandAcquireGlObjects     = CommandType(clw.CommandAcquireGlObjects)
	CommandReleaseGlObjects     = CommandType(clw.CommandReleaseGlObjects)
	CommandReadBufferRectangle  = CommandType(clw.CommandReadBufferRectangle)
	CommandWriteBufferRectangle = CommandType(clw.CommandWriteBufferRectangle)
	CommandCopyBufferRectangle  = CommandType(clw.CommandCopyBufferRectangle)
	CommandUser                 = CommandType(clw.CommandUser)
)

func (ct CommandType) String() string {
	switch ct {
	case CommandNDRangeKernel:
		return "ND range kernel"
	case CommandTask:
		return "task"
	case CommandNativeKernel:
		return "native kernel"
	case CommandReadBuffer:
		return "read buffer"
	case CommandWriteBuffer:
		return "write buffer"
	case CommandCopyBuffer:
		return "copy buffer"
	case CommandReadImage:
		return "read image"
	case CommandWriteImage:
		return "write image"
	case CommandCopyImage:
		return "copy image"
	case CommandCopyImageToBuffer:
		return "copy image to buffer"
	case CommandCopyBufferToImage:
		return "copy buffer to image"
	case CommandMapBuffer:
		return "map buffer"
	case CommandMapImage:
		return "map image"
	case CommandUnmapMemoryObject:
		return "unmap memory object"
	case CommandMarker:
		return "marker"
	case CommandAcquireGlObjects:
		return "acquire GL objects"
	case CommandReleaseGlObjects:
		return "release GL objects"
	case CommandReadBufferRectangle:
		return "read buffer rectangle"
	case CommandWriteBufferRectangle:
		return "write buffer rectangle"
	case CommandCopyBufferRectangle:
		return "copy buffer rectangle"
	case CommandUser:
		return "user"
	}
	panic("unknown command type")
}

type CommandExecutionStatus int8

const (
	Complete  = CommandExecutionStatus(clw.Complete)
	Running   = CommandExecutionStatus(clw.Running)
	Submitted = CommandExecutionStatus(clw.Submitted)
	Queued    = CommandExecutionStatus(clw.Queued)
)

func (ces CommandExecutionStatus) String() string {
	switch ces {
	case Complete:
		return "complete"
	case Running:
		return "running"
	case Submitted:
		return "submitted"
	case Queued:
		return "queued"
	}
	panic("unknown command execution status")
}

func toEvents(in []*Event) []clw.Event {

	if in == nil {
		return nil
	}

	// TODO avoid allocating memory.
	out := make([]clw.Event, len(in))
	for i := range in {
		out[i] = in[i].ID
	}
	return out
}

// Returns the events status, an error that caused the event to terminate, or an
// error that occurred trying to retrieve the event status.
func (e *Event) Status() (CommandExecutionStatus, error, error) {
	var status clw.CommandExecutionStatus
	err := clw.GetEventInfo(e.ID, clw.EventCommandExecutionStatus, clw.Size(unsafe.Sizeof(status)),
		unsafe.Pointer(&status), nil)
	if err != nil {
		return 0, nil, err
	}

	if status < 0 {
		return 0, clw.CodeToError(clw.Int(status)), nil
	}

	return CommandExecutionStatus(status), nil, nil
}
<commit_msg>Converted command type string lookup to a map (so GL or DirectX types can be added on appropriate platforms).<commit_after>package cl11

import (
	"unsafe"

	clw "github.com/rdwilliamson/clw11"
)

type Event struct {
	ID          clw.Event
	CommandType CommandType
}

func (c *Context) CreateUserEvent() (*Event, error) {
	event, err := clw.CreateUserEvent(c.ID)
	if err != nil {
		return nil, err
	}
	return &Event{ID: event}, nil
}

type CommandType int

const (
	CommandNDRangeKernel        = CommandType(clw.CommandNdrangeKernel)
	CommandTask                 = CommandType(clw.CommandTask)
	CommandNativeKernel         = CommandType(clw.CommandNativeKernel)
	CommandReadBuffer           = CommandType(clw.CommandReadBuffer)
	CommandWriteBuffer          = CommandType(clw.CommandWriteBuffer)
	CommandCopyBuffer           = CommandType(clw.CommandCopyBuffer)
	CommandReadImage            = CommandType(clw.CommandReadImage)
	CommandWriteImage           = CommandType(clw.CommandWriteImage)
	CommandCopyImage            = CommandType(clw.CommandCopyImage)
	CommandCopyImageToBuffer    = CommandType(clw.CommandCopyImageToBuffer)
	CommandCopyBufferToImage    = CommandType(clw.CommandCopyBufferToImage)
	CommandMapBuffer            = CommandType(clw.CommandMapBuffer)
	CommandMapImage             = CommandType(clw.CommandMapImage)
	CommandUnmapMemoryObject    = CommandType(clw.CommandUnmapMemoryObject)
	CommandMarker               = CommandType(clw.CommandMarker)
	CommandAcquireGlObjects     = CommandType(clw.CommandAcquireGlObjects)
	CommandReleaseGlObjects     = CommandType(clw.CommandReleaseGlObjects)
	CommandReadBufferRectangle  = CommandType(clw.CommandReadBufferRectangle)
	CommandWriteBufferRectangle = CommandType(clw.CommandWriteBufferRectangle)
	CommandCopyBufferRectangle  = CommandType(clw.CommandCopyBufferRectangle)
	CommandUser                 = CommandType(clw.CommandUser)
)

var commandTypeMap = map[CommandType]string{
	CommandNDRangeKernel:        "ND range kernel",
	CommandTask:                 "task",
	CommandNativeKernel:         "native kernel",
	CommandReadBuffer:           "read buffer",
	CommandWriteBuffer:          "write buffer",
	CommandCopyBuffer:           "copy buffer",
	CommandReadImage:            "read image",
	CommandWriteImage:           "write image",
	CommandCopyImage:            "copy image",
	CommandCopyImageToBuffer:    "copy image to buffer",
	CommandCopyBufferToImage:    "copy buffer to image",
	CommandMapBuffer:            "map buffer",
	CommandMapImage:             "map image",
	CommandUnmapMemoryObject:    "unmap memory object",
	CommandMarker:               "marker",
	CommandAcquireGlObjects:     "acquire GL objects",
	CommandReleaseGlObjects:     "release GL objects",
	CommandReadBufferRectangle:  "read buffer rectangle",
	CommandWriteBufferRectangle: "write buffer rectangle",
	CommandCopyBufferRectangle:  "copy buffer rectangle",
	CommandUser:                 "user",
}

func (ct CommandType) String() string {
	return commandTypeMap[ct]
}

type CommandExecutionStatus int8

const (
	Complete  = CommandExecutionStatus(clw.Complete)
	Running   = CommandExecutionStatus(clw.Running)
	Submitted = CommandExecutionStatus(clw.Submitted)
	Queued    = CommandExecutionStatus(clw.Queued)
)

func (ces CommandExecutionStatus) String() string {
	switch ces {
	case Complete:
		return "complete"
	case Running:
		return "running"
	case Submitted:
		return "submitted"
	case Queued:
		return "queued"
	}
	panic("unknown command execution status")
}

func toEvents(in []*Event) []clw.Event {

	if in == nil {
		return nil
	}

	// TODO avoid allocating memory.
	out := make([]clw.Event, len(in))
	for i := range in {
		out[i] = in[i].ID
	}
	return out
}

// Returns the events status, an error that caused the event to terminate, or an
// error that occurred trying to retrieve the event status.
func (e *Event) Status() (CommandExecutionStatus, error, error) {
	var status clw.CommandExecutionStatus
	err := clw.GetEventInfo(e.ID, clw.EventCommandExecutionStatus, clw.Size(unsafe.Sizeof(status)),
		unsafe.Pointer(&status), nil)
	if err != nil {
		return 0, nil, err
	}

	if status < 0 {
		return 0, clw.CodeToError(clw.Int(status)), nil
	}

	return CommandExecutionStatus(status), nil, nil
}
<|endoftext|>


<commit_before>package version

var (
	// GitCommit is the current HEAD set using ldflags.
	GitCommit string

	// Version is the built softwares version.
	Version string = TMCoreSemVer
)

func init() {
	if GitCommit != "" {
		Version += "-" + GitCommit
	}
}

const (
	// TMCoreSemVer is the current version of Tendermint Core.
	// It's the Semantic Version of the software.
	// Must be a string because scripts like dist.sh read this file.
	// XXX: Don't change the name of this variable or you will break
	// automation :)
	TMCoreSemVer = "0.32.4"

	// ABCISemVer is the semantic version of the ABCI library
	ABCISemVer  = "0.16.1"
	ABCIVersion = ABCISemVer
)

// Protocol is used for implementation agnostic versioning.
type Protocol uint64

// Uint64 returns the Protocol version as a uint64,
// eg. for compatibility with ABCI types.
func (p Protocol) Uint64() uint64 {
	return uint64(p)
}

var (
	// P2PProtocol versions all p2p behaviour and msgs.
	// This includes proposer selection.
	P2PProtocol Protocol = 7

	// BlockProtocol versions all block data structures and processing.
	// This includes validity of blocks and state updates.
	BlockProtocol Protocol = 10
)

//------------------------------------------------------------------------
// Version types

// App includes the protocol and software version for the application.
// This information is included in ResponseInfo. The App.Protocol can be
// updated in ResponseEndBlock.
type App struct {
	Protocol Protocol `json:"protocol"`
	Software string   `json:"software"`
}

// Consensus captures the consensus rules for processing a block in the blockchain,
// including all blockchain data structures and the rules of the application's
// state transition machine.
type Consensus struct {
	Block Protocol `json:"block"`
	App   Protocol `json:"app"`
}
<commit_msg>update version.go<commit_after>package version

var (
	// GitCommit is the current HEAD set using ldflags.
	GitCommit string

	// Version is the built softwares version.
	Version string = TMCoreSemVer
)

func init() {
	if GitCommit != "" {
		Version += "-" + GitCommit
	}
}

const (
	// TMCoreSemVer is the current version of Tendermint Core.
	// It's the Semantic Version of the software.
	// Must be a string because scripts like dist.sh read this file.
	// XXX: Don't change the name of this variable or you will break
	// automation :)
	TMCoreSemVer = "0.32.5"

	// ABCISemVer is the semantic version of the ABCI library
	ABCISemVer  = "0.16.1"
	ABCIVersion = ABCISemVer
)

// Protocol is used for implementation agnostic versioning.
type Protocol uint64

// Uint64 returns the Protocol version as a uint64,
// eg. for compatibility with ABCI types.
func (p Protocol) Uint64() uint64 {
	return uint64(p)
}

var (
	// P2PProtocol versions all p2p behaviour and msgs.
	// This includes proposer selection.
	P2PProtocol Protocol = 7

	// BlockProtocol versions all block data structures and processing.
	// This includes validity of blocks and state updates.
	BlockProtocol Protocol = 10
)

//------------------------------------------------------------------------
// Version types

// App includes the protocol and software version for the application.
// This information is included in ResponseInfo. The App.Protocol can be
// updated in ResponseEndBlock.
type App struct {
	Protocol Protocol `json:"protocol"`
	Software string   `json:"software"`
}

// Consensus captures the consensus rules for processing a block in the blockchain,
// including all blockchain data structures and the rules of the application's
// state transition machine.
type Consensus struct {
	Block Protocol `json:"block"`
	App   Protocol `json:"app"`
}
<|endoftext|>