mirror of https://github.com/poanetwork/gecko.git
Merge branch 'master' into fix-oversized-message
This commit is contained in:
commit
dde8e97590
|
@ -29,6 +29,7 @@ awscpu
|
|||
*.ava
|
||||
|
||||
db*
|
||||
|
||||
*cpu[0-9]*
|
||||
*mem[0-9]*
|
||||
*lock[0-9]*
|
||||
|
@ -46,3 +47,8 @@ bin/
|
|||
build/
|
||||
|
||||
keys/staker.*
|
||||
|
||||
!*.go
|
||||
!*.proto
|
||||
|
||||
plugins/
|
|
@ -6,10 +6,6 @@ RUN apt-get update && apt-get install -y libssl-dev libuv1-dev curl cmake
|
|||
|
||||
RUN mkdir -p /go/src/github.com/ava-labs
|
||||
|
||||
# Because downloading ethereum takes long it is done separately, so that the docker
|
||||
# layer, when cached can be re-used
|
||||
RUN go get -t -v github.com/ava-labs/go-ethereum
|
||||
|
||||
WORKDIR $GOPATH/src/github.com/ava-labs/
|
||||
COPY . gecko
|
||||
|
||||
|
|
|
@ -214,7 +214,12 @@ func (m *manager) ForceCreateChain(chain ChainParameters) {
|
|||
}
|
||||
|
||||
// Create the chain
|
||||
vm := vmFactory.New()
|
||||
vm, err := vmFactory.New()
|
||||
if err != nil {
|
||||
m.log.Error("error while creating vm: %s", err)
|
||||
return
|
||||
}
|
||||
// TODO: Shutdown VM if an error occurs
|
||||
|
||||
fxs := make([]*common.Fx, len(chain.FxAliases))
|
||||
for i, fxAlias := range chain.FxAliases {
|
||||
|
@ -231,10 +236,16 @@ func (m *manager) ForceCreateChain(chain ChainParameters) {
|
|||
return
|
||||
}
|
||||
|
||||
fx, err := fxFactory.New()
|
||||
if err != nil {
|
||||
m.log.Error("error while creating fx: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Create the fx
|
||||
fxs[i] = &common.Fx{
|
||||
ID: fxID,
|
||||
Fx: fxFactory.New(),
|
||||
Fx: fx,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,268 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package rpcdb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/ava-labs/gecko/database"
|
||||
"github.com/ava-labs/gecko/database/nodb"
|
||||
"github.com/ava-labs/gecko/database/rpcdb/proto"
|
||||
)
|
||||
|
||||
var (
|
||||
errClosed = fmt.Sprintf("rpc error: code = Unknown desc = %s", database.ErrClosed)
|
||||
errNotFound = fmt.Sprintf("rpc error: code = Unknown desc = %s", database.ErrNotFound)
|
||||
)
|
||||
|
||||
// DatabaseClient is an implementation of database that talks over RPC.
|
||||
type DatabaseClient struct{ client proto.DatabaseClient }
|
||||
|
||||
// NewClient returns a database instance connected to a remote database instance
|
||||
func NewClient(client proto.DatabaseClient) *DatabaseClient {
|
||||
return &DatabaseClient{client: client}
|
||||
}
|
||||
|
||||
// Has returns false, nil
|
||||
func (db *DatabaseClient) Has(key []byte) (bool, error) {
|
||||
resp, err := db.client.Has(context.Background(), &proto.HasRequest{
|
||||
Key: key,
|
||||
})
|
||||
if err != nil {
|
||||
return false, updateError(err)
|
||||
}
|
||||
return resp.Has, nil
|
||||
}
|
||||
|
||||
// Get returns nil, error
|
||||
func (db *DatabaseClient) Get(key []byte) ([]byte, error) {
|
||||
resp, err := db.client.Get(context.Background(), &proto.GetRequest{
|
||||
Key: key,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, updateError(err)
|
||||
}
|
||||
return resp.Value, nil
|
||||
}
|
||||
|
||||
// Put returns nil
|
||||
func (db *DatabaseClient) Put(key, value []byte) error {
|
||||
_, err := db.client.Put(context.Background(), &proto.PutRequest{
|
||||
Key: key,
|
||||
Value: value,
|
||||
})
|
||||
return updateError(err)
|
||||
}
|
||||
|
||||
// Delete returns nil
|
||||
func (db *DatabaseClient) Delete(key []byte) error {
|
||||
_, err := db.client.Delete(context.Background(), &proto.DeleteRequest{
|
||||
Key: key,
|
||||
})
|
||||
return updateError(err)
|
||||
}
|
||||
|
||||
// NewBatch returns a new batch
|
||||
func (db *DatabaseClient) NewBatch() database.Batch { return &batch{db: db} }
|
||||
|
||||
// NewIterator implements the Database interface
|
||||
func (db *DatabaseClient) NewIterator() database.Iterator {
|
||||
return db.NewIteratorWithStartAndPrefix(nil, nil)
|
||||
}
|
||||
|
||||
// NewIteratorWithStart implements the Database interface
|
||||
func (db *DatabaseClient) NewIteratorWithStart(start []byte) database.Iterator {
|
||||
return db.NewIteratorWithStartAndPrefix(start, nil)
|
||||
}
|
||||
|
||||
// NewIteratorWithPrefix implements the Database interface
|
||||
func (db *DatabaseClient) NewIteratorWithPrefix(prefix []byte) database.Iterator {
|
||||
return db.NewIteratorWithStartAndPrefix(nil, prefix)
|
||||
}
|
||||
|
||||
// NewIteratorWithStartAndPrefix returns a new empty iterator
|
||||
func (db *DatabaseClient) NewIteratorWithStartAndPrefix(start, prefix []byte) database.Iterator {
|
||||
resp, err := db.client.NewIteratorWithStartAndPrefix(context.Background(), &proto.NewIteratorWithStartAndPrefixRequest{
|
||||
Start: start,
|
||||
Prefix: prefix,
|
||||
})
|
||||
if err != nil {
|
||||
return &nodb.Iterator{Err: updateError(err)}
|
||||
}
|
||||
return &iterator{
|
||||
db: db,
|
||||
id: resp.Id,
|
||||
}
|
||||
}
|
||||
|
||||
// Stat returns an error
|
||||
func (db *DatabaseClient) Stat(property string) (string, error) {
|
||||
resp, err := db.client.Stat(context.Background(), &proto.StatRequest{
|
||||
Property: property,
|
||||
})
|
||||
if err != nil {
|
||||
return "", updateError(err)
|
||||
}
|
||||
return resp.Stat, nil
|
||||
}
|
||||
|
||||
// Compact returns nil
|
||||
func (db *DatabaseClient) Compact(start, limit []byte) error {
|
||||
_, err := db.client.Compact(context.Background(), &proto.CompactRequest{
|
||||
Start: start,
|
||||
Limit: limit,
|
||||
})
|
||||
return updateError(err)
|
||||
}
|
||||
|
||||
// Close returns nil
|
||||
func (db *DatabaseClient) Close() error {
|
||||
_, err := db.client.Close(context.Background(), &proto.CloseRequest{})
|
||||
return updateError(err)
|
||||
}
|
||||
|
||||
type keyValue struct {
|
||||
key []byte
|
||||
value []byte
|
||||
delete bool
|
||||
}
|
||||
|
||||
type batch struct {
|
||||
db *DatabaseClient
|
||||
writes []keyValue
|
||||
size int
|
||||
}
|
||||
|
||||
func (b *batch) Put(key, value []byte) error {
|
||||
b.writes = append(b.writes, keyValue{copyBytes(key), copyBytes(value), false})
|
||||
b.size += len(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *batch) Delete(key []byte) error {
|
||||
b.writes = append(b.writes, keyValue{copyBytes(key), nil, true})
|
||||
b.size++
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *batch) ValueSize() int { return b.size }
|
||||
|
||||
func (b *batch) Write() error {
|
||||
request := &proto.WriteBatchRequest{}
|
||||
|
||||
keySet := make(map[string]struct{}, len(b.writes))
|
||||
for i := len(b.writes) - 1; i >= 0; i-- {
|
||||
kv := b.writes[i]
|
||||
key := string(kv.key)
|
||||
if _, overwritten := keySet[key]; overwritten {
|
||||
continue
|
||||
}
|
||||
keySet[key] = struct{}{}
|
||||
|
||||
if kv.delete {
|
||||
request.Deletes = append(request.Deletes, &proto.DeleteRequest{
|
||||
Key: kv.key,
|
||||
})
|
||||
} else {
|
||||
request.Puts = append(request.Puts, &proto.PutRequest{
|
||||
Key: kv.key,
|
||||
Value: kv.value,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
_, err := b.db.client.WriteBatch(context.Background(), request)
|
||||
return updateError(err)
|
||||
}
|
||||
|
||||
func (b *batch) Reset() {
|
||||
b.writes = b.writes[:0]
|
||||
b.size = 0
|
||||
}
|
||||
|
||||
func (b *batch) Replay(w database.KeyValueWriter) error {
|
||||
for _, keyvalue := range b.writes {
|
||||
if keyvalue.delete {
|
||||
if err := w.Delete(keyvalue.key); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err := w.Put(keyvalue.key, keyvalue.value); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *batch) Inner() database.Batch { return b }
|
||||
|
||||
type iterator struct {
|
||||
db *DatabaseClient
|
||||
id uint64
|
||||
key []byte
|
||||
value []byte
|
||||
err error
|
||||
}
|
||||
|
||||
// Next returns false
|
||||
func (it *iterator) Next() bool {
|
||||
resp, err := it.db.client.IteratorNext(context.Background(), &proto.IteratorNextRequest{
|
||||
Id: it.id,
|
||||
})
|
||||
if err != nil {
|
||||
it.err = err
|
||||
return false
|
||||
}
|
||||
it.key = resp.Key
|
||||
it.value = resp.Value
|
||||
return resp.FoundNext
|
||||
}
|
||||
|
||||
// Error returns any errors
|
||||
func (it *iterator) Error() error {
|
||||
if it.err != nil {
|
||||
return it.err
|
||||
}
|
||||
|
||||
_, err := it.db.client.IteratorError(context.Background(), &proto.IteratorErrorRequest{
|
||||
Id: it.id,
|
||||
})
|
||||
it.err = updateError(err)
|
||||
return it.err
|
||||
}
|
||||
|
||||
// Key returns nil
|
||||
func (it *iterator) Key() []byte { return it.key }
|
||||
|
||||
// Value returns nil
|
||||
func (it *iterator) Value() []byte { return it.value }
|
||||
|
||||
// Release does nothing
|
||||
func (it *iterator) Release() {
|
||||
it.db.client.IteratorRelease(context.Background(), &proto.IteratorReleaseRequest{
|
||||
Id: it.id,
|
||||
})
|
||||
}
|
||||
|
||||
func copyBytes(bytes []byte) []byte {
|
||||
copiedBytes := make([]byte, len(bytes))
|
||||
copy(copiedBytes, bytes)
|
||||
return copiedBytes
|
||||
}
|
||||
|
||||
func updateError(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch err.Error() {
|
||||
case errClosed:
|
||||
return database.ErrClosed
|
||||
case errNotFound:
|
||||
return database.ErrNotFound
|
||||
default:
|
||||
return err
|
||||
}
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package rpcdb
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/ava-labs/gecko/database"
|
||||
"github.com/ava-labs/gecko/database/rpcdb/proto"
|
||||
)
|
||||
|
||||
var (
|
||||
errUnknownIterator = errors.New("unknown iterator")
|
||||
)
|
||||
|
||||
// DatabaseServer is a database that is managed over RPC.
|
||||
type DatabaseServer struct {
|
||||
db database.Database
|
||||
batch database.Batch
|
||||
|
||||
nextIteratorID uint64
|
||||
iterators map[uint64]database.Iterator
|
||||
}
|
||||
|
||||
// NewServer returns a database instance that is managed remotely
|
||||
func NewServer(db database.Database) *DatabaseServer {
|
||||
return &DatabaseServer{
|
||||
db: db,
|
||||
batch: db.NewBatch(),
|
||||
iterators: make(map[uint64]database.Iterator),
|
||||
}
|
||||
}
|
||||
|
||||
// Has ...
|
||||
func (db *DatabaseServer) Has(_ context.Context, req *proto.HasRequest) (*proto.HasResponse, error) {
|
||||
has, err := db.db.Has(req.Key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &proto.HasResponse{Has: has}, nil
|
||||
}
|
||||
|
||||
// Get ...
|
||||
func (db *DatabaseServer) Get(_ context.Context, req *proto.GetRequest) (*proto.GetResponse, error) {
|
||||
value, err := db.db.Get(req.Key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &proto.GetResponse{Value: value}, nil
|
||||
}
|
||||
|
||||
// Put ...
|
||||
func (db *DatabaseServer) Put(_ context.Context, req *proto.PutRequest) (*proto.PutResponse, error) {
|
||||
return &proto.PutResponse{}, db.db.Put(req.Key, req.Value)
|
||||
}
|
||||
|
||||
// Delete ...
|
||||
func (db *DatabaseServer) Delete(_ context.Context, req *proto.DeleteRequest) (*proto.DeleteResponse, error) {
|
||||
return &proto.DeleteResponse{}, db.db.Delete(req.Key)
|
||||
}
|
||||
|
||||
// Stat ...
|
||||
func (db *DatabaseServer) Stat(_ context.Context, req *proto.StatRequest) (*proto.StatResponse, error) {
|
||||
stat, err := db.db.Stat(req.Property)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &proto.StatResponse{Stat: stat}, nil
|
||||
}
|
||||
|
||||
// Compact ...
|
||||
func (db *DatabaseServer) Compact(_ context.Context, req *proto.CompactRequest) (*proto.CompactResponse, error) {
|
||||
return &proto.CompactResponse{}, db.db.Compact(req.Start, req.Limit)
|
||||
}
|
||||
|
||||
// Close ...
|
||||
func (db *DatabaseServer) Close(_ context.Context, _ *proto.CloseRequest) (*proto.CloseResponse, error) {
|
||||
return &proto.CloseResponse{}, db.db.Close()
|
||||
}
|
||||
|
||||
// WriteBatch ...
|
||||
func (db *DatabaseServer) WriteBatch(_ context.Context, req *proto.WriteBatchRequest) (*proto.WriteBatchResponse, error) {
|
||||
db.batch.Reset()
|
||||
|
||||
for _, put := range req.Puts {
|
||||
if err := db.batch.Put(put.Key, put.Value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
for _, del := range req.Deletes {
|
||||
if err := db.batch.Delete(del.Key); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &proto.WriteBatchResponse{}, db.batch.Write()
|
||||
}
|
||||
|
||||
// NewIteratorWithStartAndPrefix ...
|
||||
func (db *DatabaseServer) NewIteratorWithStartAndPrefix(_ context.Context, req *proto.NewIteratorWithStartAndPrefixRequest) (*proto.NewIteratorWithStartAndPrefixResponse, error) {
|
||||
id := db.nextIteratorID
|
||||
it := db.db.NewIteratorWithStartAndPrefix(req.Start, req.Prefix)
|
||||
db.iterators[id] = it
|
||||
|
||||
db.nextIteratorID++
|
||||
return &proto.NewIteratorWithStartAndPrefixResponse{Id: id}, nil
|
||||
}
|
||||
|
||||
// IteratorNext ...
|
||||
func (db *DatabaseServer) IteratorNext(_ context.Context, req *proto.IteratorNextRequest) (*proto.IteratorNextResponse, error) {
|
||||
it, exists := db.iterators[req.Id]
|
||||
if !exists {
|
||||
return nil, errUnknownIterator
|
||||
}
|
||||
return &proto.IteratorNextResponse{
|
||||
FoundNext: it.Next(),
|
||||
Key: it.Key(),
|
||||
Value: it.Value(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// IteratorError ...
|
||||
func (db *DatabaseServer) IteratorError(_ context.Context, req *proto.IteratorErrorRequest) (*proto.IteratorErrorResponse, error) {
|
||||
it, exists := db.iterators[req.Id]
|
||||
if !exists {
|
||||
return nil, errUnknownIterator
|
||||
}
|
||||
return &proto.IteratorErrorResponse{}, it.Error()
|
||||
}
|
||||
|
||||
// IteratorRelease ...
|
||||
func (db *DatabaseServer) IteratorRelease(_ context.Context, req *proto.IteratorReleaseRequest) (*proto.IteratorReleaseResponse, error) {
|
||||
it, exists := db.iterators[req.Id]
|
||||
if exists {
|
||||
delete(db.iterators, req.Id)
|
||||
it.Release()
|
||||
}
|
||||
return &proto.IteratorReleaseResponse{}, nil
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package rpcdb
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/test/bufconn"
|
||||
|
||||
"github.com/ava-labs/gecko/database"
|
||||
"github.com/ava-labs/gecko/database/memdb"
|
||||
"github.com/ava-labs/gecko/database/rpcdb/proto"
|
||||
)
|
||||
|
||||
const (
|
||||
bufSize = 1 << 20
|
||||
)
|
||||
|
||||
func TestInterface(t *testing.T) {
|
||||
for _, test := range database.Tests {
|
||||
listener := bufconn.Listen(bufSize)
|
||||
server := grpc.NewServer()
|
||||
proto.RegisterDatabaseServer(server, NewServer(memdb.New()))
|
||||
go func() {
|
||||
if err := server.Serve(listener); err != nil {
|
||||
log.Fatalf("Server exited with error: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
dialer := grpc.WithContextDialer(
|
||||
func(context.Context, string) (net.Conn, error) {
|
||||
return listener.Dial()
|
||||
})
|
||||
|
||||
ctx := context.Background()
|
||||
conn, err := grpc.DialContext(ctx, "", dialer, grpc.WithInsecure())
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to dial: %s", err)
|
||||
}
|
||||
|
||||
db := NewClient(proto.NewDatabaseClient(conn))
|
||||
test(t, db)
|
||||
conn.Close()
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,108 @@
|
|||
syntax = "proto3";
|
||||
package proto;
|
||||
|
||||
message HasRequest {
|
||||
bytes key = 1;
|
||||
}
|
||||
|
||||
message HasResponse {
|
||||
bool has = 1;
|
||||
}
|
||||
|
||||
message GetRequest {
|
||||
bytes key = 1;
|
||||
}
|
||||
|
||||
message GetResponse {
|
||||
bytes value = 1;
|
||||
}
|
||||
|
||||
message PutRequest {
|
||||
bytes key = 1;
|
||||
bytes value = 2;
|
||||
}
|
||||
|
||||
message PutResponse {}
|
||||
|
||||
message DeleteRequest {
|
||||
bytes key = 1;
|
||||
}
|
||||
|
||||
message DeleteResponse {}
|
||||
|
||||
message StatRequest {
|
||||
string property = 1;
|
||||
}
|
||||
|
||||
message StatResponse {
|
||||
string stat = 1;
|
||||
}
|
||||
|
||||
message CompactRequest {
|
||||
bytes start = 1;
|
||||
bytes limit = 2;
|
||||
}
|
||||
|
||||
message CompactResponse {}
|
||||
|
||||
message CloseRequest {}
|
||||
|
||||
message CloseResponse {}
|
||||
|
||||
message WriteBatchRequest {
|
||||
repeated PutRequest puts = 1;
|
||||
repeated DeleteRequest deletes = 2;
|
||||
}
|
||||
|
||||
message WriteBatchResponse {}
|
||||
|
||||
message NewIteratorRequest {}
|
||||
|
||||
message NewIteratorWithStartAndPrefixRequest {
|
||||
bytes start = 1;
|
||||
bytes prefix = 2;
|
||||
}
|
||||
|
||||
message NewIteratorWithStartAndPrefixResponse {
|
||||
uint64 id = 1;
|
||||
}
|
||||
|
||||
message IteratorNextRequest {
|
||||
uint64 id = 1;
|
||||
}
|
||||
|
||||
message IteratorNextResponse {
|
||||
bool foundNext = 1;
|
||||
bytes key = 2;
|
||||
bytes value = 3;
|
||||
}
|
||||
|
||||
message IteratorErrorRequest {
|
||||
uint64 id = 1;
|
||||
}
|
||||
|
||||
message IteratorErrorResponse {}
|
||||
|
||||
message IteratorReleaseRequest {
|
||||
uint64 id = 1;
|
||||
}
|
||||
|
||||
message IteratorReleaseResponse {}
|
||||
|
||||
service Database {
|
||||
rpc Has(HasRequest) returns (HasResponse);
|
||||
rpc Get(GetRequest) returns (GetResponse);
|
||||
rpc Put(PutRequest) returns (PutResponse);
|
||||
rpc Delete(DeleteRequest) returns (DeleteResponse);
|
||||
rpc Stat(StatRequest) returns (StatResponse);
|
||||
rpc Compact(CompactRequest) returns (CompactResponse);
|
||||
rpc Close(CloseRequest) returns (CloseResponse);
|
||||
|
||||
rpc WriteBatch(WriteBatchRequest) returns (WriteBatchResponse);
|
||||
|
||||
rpc NewIteratorWithStartAndPrefix(NewIteratorWithStartAndPrefixRequest) returns (NewIteratorWithStartAndPrefixResponse);
|
||||
|
||||
rpc IteratorNext(IteratorNextRequest) returns (IteratorNextResponse);
|
||||
rpc IteratorError(IteratorErrorRequest) returns (IteratorErrorResponse);
|
||||
rpc IteratorRelease(IteratorReleaseRequest) returns (IteratorReleaseResponse);
|
||||
}
|
|
@ -16,6 +16,8 @@ var (
|
|||
TestBatchPut,
|
||||
TestBatchDelete,
|
||||
TestBatchReset,
|
||||
TestBatchReuse,
|
||||
TestBatchRewrite,
|
||||
TestBatchReplay,
|
||||
TestBatchInner,
|
||||
TestIterator,
|
||||
|
@ -236,6 +238,105 @@ func TestBatchReset(t *testing.T, db Database) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestBatchReuse ...
|
||||
func TestBatchReuse(t *testing.T, db Database) {
|
||||
key1 := []byte("hello1")
|
||||
value1 := []byte("world1")
|
||||
|
||||
key2 := []byte("hello2")
|
||||
value2 := []byte("world2")
|
||||
|
||||
batch := db.NewBatch()
|
||||
if batch == nil {
|
||||
t.Fatalf("db.NewBatch returned nil")
|
||||
}
|
||||
|
||||
if err := batch.Put(key1, value1); err != nil {
|
||||
t.Fatalf("Unexpected error on batch.Put: %s", err)
|
||||
}
|
||||
|
||||
if err := batch.Write(); err != nil {
|
||||
t.Fatalf("Unexpected error on batch.Write: %s", err)
|
||||
}
|
||||
|
||||
if err := db.Delete(key1); err != nil {
|
||||
t.Fatalf("Unexpected error on database.Delete: %s", err)
|
||||
}
|
||||
|
||||
if has, err := db.Has(key1); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Has: %s", err)
|
||||
} else if has {
|
||||
t.Fatalf("db.Has unexpectedly returned true on key %s", key1)
|
||||
}
|
||||
|
||||
batch.Reset()
|
||||
|
||||
if err := batch.Put(key2, value2); err != nil {
|
||||
t.Fatalf("Unexpected error on batch.Put: %s", err)
|
||||
}
|
||||
|
||||
if err := batch.Write(); err != nil {
|
||||
t.Fatalf("Unexpected error on batch.Write: %s", err)
|
||||
}
|
||||
|
||||
if has, err := db.Has(key1); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Has: %s", err)
|
||||
} else if has {
|
||||
t.Fatalf("db.Has unexpectedly returned true on key %s", key1)
|
||||
} else if has, err := db.Has(key2); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Has: %s", err)
|
||||
} else if !has {
|
||||
t.Fatalf("db.Has unexpectedly returned false on key %s", key2)
|
||||
} else if v, err := db.Get(key2); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Get: %s", err)
|
||||
} else if !bytes.Equal(value2, v) {
|
||||
t.Fatalf("db.Get: Returned: 0x%x ; Expected: 0x%x", v, value2)
|
||||
}
|
||||
}
|
||||
|
||||
// TestBatchRewrite ...
|
||||
func TestBatchRewrite(t *testing.T, db Database) {
|
||||
key := []byte("hello1")
|
||||
value := []byte("world1")
|
||||
|
||||
batch := db.NewBatch()
|
||||
if batch == nil {
|
||||
t.Fatalf("db.NewBatch returned nil")
|
||||
}
|
||||
|
||||
if err := batch.Put(key, value); err != nil {
|
||||
t.Fatalf("Unexpected error on batch.Put: %s", err)
|
||||
}
|
||||
|
||||
if err := batch.Write(); err != nil {
|
||||
t.Fatalf("Unexpected error on batch.Write: %s", err)
|
||||
}
|
||||
|
||||
if err := db.Delete(key); err != nil {
|
||||
t.Fatalf("Unexpected error on database.Delete: %s", err)
|
||||
}
|
||||
|
||||
if has, err := db.Has(key); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Has: %s", err)
|
||||
} else if has {
|
||||
t.Fatalf("db.Has unexpectedly returned true on key %s", key)
|
||||
}
|
||||
|
||||
if err := batch.Write(); err != nil {
|
||||
t.Fatalf("Unexpected error on batch.Write: %s", err)
|
||||
}
|
||||
|
||||
if has, err := db.Has(key); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Has: %s", err)
|
||||
} else if !has {
|
||||
t.Fatalf("db.Has unexpectedly returned false on key %s", key)
|
||||
} else if v, err := db.Get(key); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Get: %s", err)
|
||||
} else if !bytes.Equal(value, v) {
|
||||
t.Fatalf("db.Get: Returned: 0x%x ; Expected: 0x%x", v, value)
|
||||
}
|
||||
}
|
||||
|
||||
// TestBatchReplay ...
|
||||
func TestBatchReplay(t *testing.T, db Database) {
|
||||
key1 := []byte("hello1")
|
||||
|
|
|
@ -6,7 +6,6 @@ package genesis
|
|||
import (
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/vms/avm"
|
||||
"github.com/ava-labs/gecko/vms/evm"
|
||||
"github.com/ava-labs/gecko/vms/nftfx"
|
||||
"github.com/ava-labs/gecko/vms/platformvm"
|
||||
"github.com/ava-labs/gecko/vms/propertyfx"
|
||||
|
@ -21,7 +20,7 @@ func Aliases(networkID uint32) (map[string][]string, map[[32]byte][]string, map[
|
|||
generalAliases := map[string][]string{
|
||||
"vm/" + platformvm.ID.String(): []string{"vm/platform"},
|
||||
"vm/" + avm.ID.String(): []string{"vm/avm"},
|
||||
"vm/" + evm.ID.String(): []string{"vm/evm"},
|
||||
"vm/" + EVMID.String(): []string{"vm/evm"},
|
||||
"vm/" + spdagvm.ID.String(): []string{"vm/spdag"},
|
||||
"vm/" + spchainvm.ID.String(): []string{"vm/spchain"},
|
||||
"vm/" + timestampvm.ID.String(): []string{"vm/timestamp"},
|
||||
|
@ -33,7 +32,7 @@ func Aliases(networkID uint32) (map[string][]string, map[[32]byte][]string, map[
|
|||
vmAliases := map[[32]byte][]string{
|
||||
platformvm.ID.Key(): []string{"platform"},
|
||||
avm.ID.Key(): []string{"avm"},
|
||||
evm.ID.Key(): []string{"evm"},
|
||||
EVMID.Key(): []string{"evm"},
|
||||
spdagvm.ID.Key(): []string{"spdag"},
|
||||
spchainvm.ID.Key(): []string{"spchain"},
|
||||
timestampvm.ID.Key(): []string{"timestamp"},
|
||||
|
@ -60,7 +59,7 @@ func Aliases(networkID uint32) (map[string][]string, map[[32]byte][]string, map[
|
|||
case avm.ID.Equals(chain.VMID):
|
||||
generalAliases["bc/"+chain.ID().String()] = []string{"X", "avm", "bc/X", "bc/avm"}
|
||||
chainAliases[chain.ID().Key()] = []string{"X", "avm"}
|
||||
case evm.ID.Equals(chain.VMID):
|
||||
case EVMID.Equals(chain.VMID):
|
||||
generalAliases["bc/"+chain.ID().String()] = []string{"C", "evm", "bc/C", "bc/evm"}
|
||||
chainAliases[chain.ID().Key()] = []string{"C", "evm"}
|
||||
case spdagvm.ID.Equals(chain.VMID):
|
||||
|
|
|
@ -5,7 +5,6 @@ package genesis
|
|||
|
||||
import (
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/vms/evm"
|
||||
)
|
||||
|
||||
// Note that since an AVA network has exactly one Platform Chain,
|
||||
|
@ -16,8 +15,9 @@ import (
|
|||
|
||||
// Config contains the genesis addresses used to construct a genesis
|
||||
type Config struct {
|
||||
MintAddresses, FundedAddresses, FundedEVMAddresses, StakerIDs []string
|
||||
ParsedMintAddresses, ParsedFundedAddresses, ParsedStakerIDs []ids.ShortID
|
||||
MintAddresses, FundedAddresses, StakerIDs []string
|
||||
ParsedMintAddresses, ParsedFundedAddresses, ParsedStakerIDs []ids.ShortID
|
||||
EVMBytes []byte
|
||||
}
|
||||
|
||||
func (c *Config) init() error {
|
||||
|
@ -66,9 +66,6 @@ var (
|
|||
"ZdhZv6oZrmXLyFDy6ovXAu6VxmbTsT2h",
|
||||
"6cesTteH62Y5mLoDBUASaBvCXuL2AthL",
|
||||
},
|
||||
FundedEVMAddresses: []string{
|
||||
"0x572f4D80f10f663B5049F789546f25f70Bb62a7F",
|
||||
},
|
||||
StakerIDs: []string{
|
||||
"NX4zVkuiRJZYe6Nzzav7GXN3TakUet3Co",
|
||||
"CMsa8cMw4eib1Hb8GG4xiUKAq5eE1BwUX",
|
||||
|
@ -76,6 +73,98 @@ var (
|
|||
"N86eodVZja3GEyZJTo3DFUPGpxEEvjGHs",
|
||||
"EkKeGSLUbHrrtuayBtbwgWDRUiAziC3ao",
|
||||
},
|
||||
EVMBytes: []byte{
|
||||
0x7b, 0x22, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x22, 0x3a, 0x7b, 0x22, 0x63, 0x68, 0x61, 0x69,
|
||||
0x6e, 0x49, 0x64, 0x22, 0x3a, 0x34, 0x33, 0x31,
|
||||
0x31, 0x30, 0x2c, 0x22, 0x68, 0x6f, 0x6d, 0x65,
|
||||
0x73, 0x74, 0x65, 0x61, 0x64, 0x42, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x64,
|
||||
0x61, 0x6f, 0x46, 0x6f, 0x72, 0x6b, 0x42, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22,
|
||||
0x64, 0x61, 0x6f, 0x46, 0x6f, 0x72, 0x6b, 0x53,
|
||||
0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x3a,
|
||||
0x74, 0x72, 0x75, 0x65, 0x2c, 0x22, 0x65, 0x69,
|
||||
0x70, 0x31, 0x35, 0x30, 0x42, 0x6c, 0x6f, 0x63,
|
||||
0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x65, 0x69,
|
||||
0x70, 0x31, 0x35, 0x30, 0x48, 0x61, 0x73, 0x68,
|
||||
0x22, 0x3a, 0x22, 0x30, 0x78, 0x32, 0x30, 0x38,
|
||||
0x36, 0x37, 0x39, 0x39, 0x61, 0x65, 0x65, 0x62,
|
||||
0x65, 0x61, 0x65, 0x31, 0x33, 0x35, 0x63, 0x32,
|
||||
0x34, 0x36, 0x63, 0x36, 0x35, 0x30, 0x32, 0x31,
|
||||
0x63, 0x38, 0x32, 0x62, 0x34, 0x65, 0x31, 0x35,
|
||||
0x61, 0x32, 0x63, 0x34, 0x35, 0x31, 0x33, 0x34,
|
||||
0x30, 0x39, 0x39, 0x33, 0x61, 0x61, 0x63, 0x66,
|
||||
0x64, 0x32, 0x37, 0x35, 0x31, 0x38, 0x38, 0x36,
|
||||
0x35, 0x31, 0x34, 0x66, 0x30, 0x22, 0x2c, 0x22,
|
||||
0x65, 0x69, 0x70, 0x31, 0x35, 0x35, 0x42, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22,
|
||||
0x65, 0x69, 0x70, 0x31, 0x35, 0x38, 0x42, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22,
|
||||
0x62, 0x79, 0x7a, 0x61, 0x6e, 0x74, 0x69, 0x75,
|
||||
0x6d, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3a,
|
||||
0x30, 0x2c, 0x22, 0x63, 0x6f, 0x6e, 0x73, 0x74,
|
||||
0x61, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x70, 0x6c,
|
||||
0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3a,
|
||||
0x30, 0x2c, 0x22, 0x70, 0x65, 0x74, 0x65, 0x72,
|
||||
0x73, 0x62, 0x75, 0x72, 0x67, 0x42, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x22, 0x3a, 0x30, 0x7d, 0x2c, 0x22,
|
||||
0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x22,
|
||||
0x30, 0x78, 0x30, 0x22, 0x2c, 0x22, 0x74, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22,
|
||||
0x3a, 0x22, 0x30, 0x78, 0x30, 0x22, 0x2c, 0x22,
|
||||
0x65, 0x78, 0x74, 0x72, 0x61, 0x44, 0x61, 0x74,
|
||||
0x61, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x30, 0x30,
|
||||
0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x4c, 0x69,
|
||||
0x6d, 0x69, 0x74, 0x22, 0x3a, 0x22, 0x30, 0x78,
|
||||
0x35, 0x66, 0x35, 0x65, 0x31, 0x30, 0x30, 0x22,
|
||||
0x2c, 0x22, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63,
|
||||
0x75, 0x6c, 0x74, 0x79, 0x22, 0x3a, 0x22, 0x30,
|
||||
0x78, 0x30, 0x22, 0x2c, 0x22, 0x6d, 0x69, 0x78,
|
||||
0x48, 0x61, 0x73, 0x68, 0x22, 0x3a, 0x22, 0x30,
|
||||
0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x22, 0x2c, 0x22, 0x63, 0x6f, 0x69, 0x6e,
|
||||
0x62, 0x61, 0x73, 0x65, 0x22, 0x3a, 0x22, 0x30,
|
||||
0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x22, 0x2c, 0x22, 0x61, 0x6c, 0x6c, 0x6f,
|
||||
0x63, 0x22, 0x3a, 0x7b, 0x22, 0x35, 0x37, 0x32,
|
||||
0x66, 0x34, 0x64, 0x38, 0x30, 0x66, 0x31, 0x30,
|
||||
0x66, 0x36, 0x36, 0x33, 0x62, 0x35, 0x30, 0x34,
|
||||
0x39, 0x66, 0x37, 0x38, 0x39, 0x35, 0x34, 0x36,
|
||||
0x66, 0x32, 0x35, 0x66, 0x37, 0x30, 0x62, 0x62,
|
||||
0x36, 0x32, 0x61, 0x37, 0x66, 0x22, 0x3a, 0x7b,
|
||||
0x22, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65,
|
||||
0x22, 0x3a, 0x22, 0x30, 0x78, 0x33, 0x33, 0x62,
|
||||
0x32, 0x65, 0x33, 0x63, 0x39, 0x66, 0x64, 0x30,
|
||||
0x38, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x22, 0x7d, 0x7d, 0x2c,
|
||||
0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22,
|
||||
0x3a, 0x22, 0x30, 0x78, 0x30, 0x22, 0x2c, 0x22,
|
||||
0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x22,
|
||||
0x3a, 0x22, 0x30, 0x78, 0x30, 0x22, 0x2c, 0x22,
|
||||
0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x61,
|
||||
0x73, 0x68, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22,
|
||||
0x7d,
|
||||
},
|
||||
}
|
||||
DefaultConfig = Config{
|
||||
MintAddresses: []string{},
|
||||
|
@ -83,10 +172,6 @@ var (
|
|||
// Private key: ewoqjP7PxY4yr3iLTpLisriqt94hdyDFNgchSxGGztUrTXtNN
|
||||
"6Y3kysjF9jnHnYkdS9yGAuoHyae2eNmeV",
|
||||
},
|
||||
FundedEVMAddresses: []string{
|
||||
// Private key: evm.GenesisTestKey
|
||||
evm.GenesisTestAddr,
|
||||
},
|
||||
StakerIDs: []string{
|
||||
"7Xhw2mDxuDS44j42TCB6U5579esbSt3Lg",
|
||||
"MFrZFVCXPv5iCn6M9K6XduxGTYp891xXZ",
|
||||
|
@ -94,6 +179,98 @@ var (
|
|||
"GWPcbFJZFfZreETSoWjPimr846mXEKCtu",
|
||||
"P7oB2McjBGgW2NXXWVYjV8JEDFoW9xDE5",
|
||||
},
|
||||
EVMBytes: []byte{
|
||||
0x7b, 0x22, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x22, 0x3a, 0x7b, 0x22, 0x63, 0x68, 0x61, 0x69,
|
||||
0x6e, 0x49, 0x64, 0x22, 0x3a, 0x34, 0x33, 0x31,
|
||||
0x31, 0x30, 0x2c, 0x22, 0x68, 0x6f, 0x6d, 0x65,
|
||||
0x73, 0x74, 0x65, 0x61, 0x64, 0x42, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x64,
|
||||
0x61, 0x6f, 0x46, 0x6f, 0x72, 0x6b, 0x42, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22,
|
||||
0x64, 0x61, 0x6f, 0x46, 0x6f, 0x72, 0x6b, 0x53,
|
||||
0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x3a,
|
||||
0x74, 0x72, 0x75, 0x65, 0x2c, 0x22, 0x65, 0x69,
|
||||
0x70, 0x31, 0x35, 0x30, 0x42, 0x6c, 0x6f, 0x63,
|
||||
0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x65, 0x69,
|
||||
0x70, 0x31, 0x35, 0x30, 0x48, 0x61, 0x73, 0x68,
|
||||
0x22, 0x3a, 0x22, 0x30, 0x78, 0x32, 0x30, 0x38,
|
||||
0x36, 0x37, 0x39, 0x39, 0x61, 0x65, 0x65, 0x62,
|
||||
0x65, 0x61, 0x65, 0x31, 0x33, 0x35, 0x63, 0x32,
|
||||
0x34, 0x36, 0x63, 0x36, 0x35, 0x30, 0x32, 0x31,
|
||||
0x63, 0x38, 0x32, 0x62, 0x34, 0x65, 0x31, 0x35,
|
||||
0x61, 0x32, 0x63, 0x34, 0x35, 0x31, 0x33, 0x34,
|
||||
0x30, 0x39, 0x39, 0x33, 0x61, 0x61, 0x63, 0x66,
|
||||
0x64, 0x32, 0x37, 0x35, 0x31, 0x38, 0x38, 0x36,
|
||||
0x35, 0x31, 0x34, 0x66, 0x30, 0x22, 0x2c, 0x22,
|
||||
0x65, 0x69, 0x70, 0x31, 0x35, 0x35, 0x42, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22,
|
||||
0x65, 0x69, 0x70, 0x31, 0x35, 0x38, 0x42, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22,
|
||||
0x62, 0x79, 0x7a, 0x61, 0x6e, 0x74, 0x69, 0x75,
|
||||
0x6d, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3a,
|
||||
0x30, 0x2c, 0x22, 0x63, 0x6f, 0x6e, 0x73, 0x74,
|
||||
0x61, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x70, 0x6c,
|
||||
0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3a,
|
||||
0x30, 0x2c, 0x22, 0x70, 0x65, 0x74, 0x65, 0x72,
|
||||
0x73, 0x62, 0x75, 0x72, 0x67, 0x42, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x22, 0x3a, 0x30, 0x7d, 0x2c, 0x22,
|
||||
0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x22,
|
||||
0x30, 0x78, 0x30, 0x22, 0x2c, 0x22, 0x74, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22,
|
||||
0x3a, 0x22, 0x30, 0x78, 0x30, 0x22, 0x2c, 0x22,
|
||||
0x65, 0x78, 0x74, 0x72, 0x61, 0x44, 0x61, 0x74,
|
||||
0x61, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x30, 0x30,
|
||||
0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x4c, 0x69,
|
||||
0x6d, 0x69, 0x74, 0x22, 0x3a, 0x22, 0x30, 0x78,
|
||||
0x35, 0x66, 0x35, 0x65, 0x31, 0x30, 0x30, 0x22,
|
||||
0x2c, 0x22, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63,
|
||||
0x75, 0x6c, 0x74, 0x79, 0x22, 0x3a, 0x22, 0x30,
|
||||
0x78, 0x30, 0x22, 0x2c, 0x22, 0x6d, 0x69, 0x78,
|
||||
0x48, 0x61, 0x73, 0x68, 0x22, 0x3a, 0x22, 0x30,
|
||||
0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x22, 0x2c, 0x22, 0x63, 0x6f, 0x69, 0x6e,
|
||||
0x62, 0x61, 0x73, 0x65, 0x22, 0x3a, 0x22, 0x30,
|
||||
0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x22, 0x2c, 0x22, 0x61, 0x6c, 0x6c, 0x6f,
|
||||
0x63, 0x22, 0x3a, 0x7b, 0x22, 0x37, 0x35, 0x31,
|
||||
0x61, 0x30, 0x62, 0x39, 0x36, 0x65, 0x31, 0x30,
|
||||
0x34, 0x32, 0x62, 0x65, 0x65, 0x37, 0x38, 0x39,
|
||||
0x34, 0x35, 0x32, 0x65, 0x63, 0x62, 0x32, 0x30,
|
||||
0x32, 0x35, 0x33, 0x66, 0x62, 0x61, 0x34, 0x30,
|
||||
0x64, 0x62, 0x65, 0x38, 0x35, 0x22, 0x3a, 0x7b,
|
||||
0x22, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65,
|
||||
0x22, 0x3a, 0x22, 0x30, 0x78, 0x33, 0x33, 0x62,
|
||||
0x32, 0x65, 0x33, 0x63, 0x39, 0x66, 0x64, 0x30,
|
||||
0x38, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x22, 0x7d, 0x7d, 0x2c,
|
||||
0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22,
|
||||
0x3a, 0x22, 0x30, 0x78, 0x30, 0x22, 0x2c, 0x22,
|
||||
0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x22,
|
||||
0x3a, 0x22, 0x30, 0x78, 0x30, 0x22, 0x2c, 0x22,
|
||||
0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x61,
|
||||
0x73, 0x68, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22,
|
||||
0x7d,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
@ -6,14 +6,8 @@ package genesis
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"time"
|
||||
|
||||
"github.com/ava-labs/coreth/core"
|
||||
|
||||
"github.com/ava-labs/go-ethereum/common"
|
||||
"github.com/ava-labs/go-ethereum/params"
|
||||
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/utils/formatting"
|
||||
"github.com/ava-labs/gecko/utils/json"
|
||||
|
@ -21,7 +15,6 @@ import (
|
|||
"github.com/ava-labs/gecko/utils/wrappers"
|
||||
"github.com/ava-labs/gecko/vms/avm"
|
||||
"github.com/ava-labs/gecko/vms/components/codec"
|
||||
"github.com/ava-labs/gecko/vms/evm"
|
||||
"github.com/ava-labs/gecko/vms/nftfx"
|
||||
"github.com/ava-labs/gecko/vms/platformvm"
|
||||
"github.com/ava-labs/gecko/vms/propertyfx"
|
||||
|
@ -31,6 +24,11 @@ import (
|
|||
"github.com/ava-labs/gecko/vms/timestampvm"
|
||||
)
|
||||
|
||||
// ID of the EVM VM
|
||||
var (
|
||||
EVMID = ids.NewID([32]byte{'e', 'v', 'm'})
|
||||
)
|
||||
|
||||
// Genesis returns the genesis data of the Platform Chain.
|
||||
// Since an AVA network has exactly one Platform Chain, and the Platform Chain
|
||||
// defines the genesis state of the network (who is staking, which chains exist,
|
||||
|
@ -76,50 +74,6 @@ func FromConfig(networkID uint32, config *Config) ([]byte, error) {
|
|||
|
||||
avmSS := avm.StaticService{}
|
||||
err := avmSS.BuildGenesis(nil, &avmArgs, &avmReply)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Specify the genesis state of Athereum (the built-in instance of the EVM)
|
||||
evmBalance, success := new(big.Int).SetString("33b2e3c9fd0804000000000", 16)
|
||||
if success != true {
|
||||
return nil, errors.New("problem creating evm genesis state")
|
||||
}
|
||||
|
||||
alloc := core.GenesisAlloc{}
|
||||
for _, addr := range config.FundedEVMAddresses {
|
||||
alloc[common.HexToAddress(addr)] = core.GenesisAccount{
|
||||
Balance: evmBalance,
|
||||
}
|
||||
}
|
||||
evmArgs := core.Genesis{
|
||||
Config: ¶ms.ChainConfig{
|
||||
ChainID: big.NewInt(43110),
|
||||
HomesteadBlock: big.NewInt(0),
|
||||
DAOForkBlock: big.NewInt(0),
|
||||
DAOForkSupport: true,
|
||||
EIP150Block: big.NewInt(0),
|
||||
EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"),
|
||||
EIP155Block: big.NewInt(0),
|
||||
EIP158Block: big.NewInt(0),
|
||||
ByzantiumBlock: big.NewInt(0),
|
||||
ConstantinopleBlock: big.NewInt(0),
|
||||
PetersburgBlock: big.NewInt(0),
|
||||
},
|
||||
Nonce: 0,
|
||||
Timestamp: 0,
|
||||
ExtraData: []byte{0},
|
||||
GasLimit: 100000000,
|
||||
Difficulty: big.NewInt(0),
|
||||
Mixhash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
Coinbase: common.HexToAddress("0x0000000000000000000000000000000000000000"),
|
||||
Alloc: alloc,
|
||||
Number: 0,
|
||||
GasUsed: 0,
|
||||
ParentHash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
}
|
||||
evmSS := evm.StaticService{}
|
||||
evmReply, err := evmSS.BuildGenesis(nil, &evmArgs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -214,9 +168,9 @@ func FromConfig(networkID uint32, config *Config) ([]byte, error) {
|
|||
Name: "X-Chain",
|
||||
},
|
||||
platformvm.APIChain{
|
||||
GenesisData: evmReply,
|
||||
GenesisData: formatting.CB58{Bytes: config.EVMBytes},
|
||||
SubnetID: platformvm.DefaultSubnetID,
|
||||
VMID: evm.ID,
|
||||
VMID: EVMID,
|
||||
Name: "C-Chain",
|
||||
},
|
||||
platformvm.APIChain{
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/vms/avm"
|
||||
"github.com/ava-labs/gecko/vms/evm"
|
||||
"github.com/ava-labs/gecko/vms/platformvm"
|
||||
"github.com/ava-labs/gecko/vms/spchainvm"
|
||||
"github.com/ava-labs/gecko/vms/spdagvm"
|
||||
|
@ -97,7 +96,7 @@ func TestAliases(t *testing.T) {
|
|||
t.Fatalf("Should have a custom alias from the vm")
|
||||
} else if _, exists := generalAliases["vm/"+avm.ID.String()]; !exists {
|
||||
t.Fatalf("Should have a custom alias from the vm")
|
||||
} else if _, exists := generalAliases["vm/"+evm.ID.String()]; !exists {
|
||||
} else if _, exists := generalAliases["vm/"+EVMID.String()]; !exists {
|
||||
t.Fatalf("Should have a custom alias from the vm")
|
||||
} else if _, exists := generalAliases["vm/"+spdagvm.ID.String()]; !exists {
|
||||
t.Fatalf("Should have a custom alias from the vm")
|
||||
|
@ -135,12 +134,12 @@ func TestVMGenesis(t *testing.T) {
|
|||
},
|
||||
{
|
||||
networkID: CascadeID,
|
||||
vmID: evm.ID,
|
||||
vmID: EVMID,
|
||||
expectedID: "2mUYSXfLrDtigwbzj1LxKVsHwELghc5sisoXrzJwLqAAQHF4i",
|
||||
},
|
||||
{
|
||||
networkID: LocalID,
|
||||
vmID: evm.ID,
|
||||
vmID: EVMID,
|
||||
expectedID: "tZGm6RCkeGpVETUTp11DW3UYFZmm69zfqxchpHrSF7wgy8rmw",
|
||||
},
|
||||
}
|
||||
|
|
25
main/main.go
25
main/main.go
|
@ -7,10 +7,10 @@ import (
|
|||
"fmt"
|
||||
"path"
|
||||
|
||||
"github.com/ava-labs/gecko/nat"
|
||||
"github.com/ava-labs/gecko/node"
|
||||
"github.com/ava-labs/gecko/utils/crypto"
|
||||
"github.com/ava-labs/gecko/utils/logging"
|
||||
"github.com/ava-labs/go-ethereum/p2p/nat"
|
||||
)
|
||||
|
||||
// main is the primary entry point to Ava. This can either create a CLI to an
|
||||
|
@ -61,26 +61,11 @@ func main() {
|
|||
log.Warn("assertions are enabled. This may slow down execution")
|
||||
}
|
||||
|
||||
natChan := make(chan struct{})
|
||||
defer close(natChan)
|
||||
mapper := nat.NewDefaultMapper(log, Config.Nat, nat.TCP, "gecko")
|
||||
defer mapper.UnmapAllPorts()
|
||||
|
||||
go nat.Map(
|
||||
/*nat=*/ Config.Nat,
|
||||
/*closeChannel=*/ natChan,
|
||||
/*protocol=*/ "TCP",
|
||||
/*internetPort=*/ int(Config.StakingIP.Port),
|
||||
/*localPort=*/ int(Config.StakingIP.Port),
|
||||
/*name=*/ "Gecko Staking Server",
|
||||
)
|
||||
|
||||
go nat.Map(
|
||||
/*nat=*/ Config.Nat,
|
||||
/*closeChannel=*/ natChan,
|
||||
/*protocol=*/ "TCP",
|
||||
/*internetPort=*/ int(Config.HTTPPort),
|
||||
/*localPort=*/ int(Config.HTTPPort),
|
||||
/*name=*/ "Gecko HTTP Server",
|
||||
)
|
||||
mapper.MapPort(Config.StakingIP.Port, Config.StakingIP.Port)
|
||||
mapper.MapPort(Config.HTTPPort, Config.HTTPPort)
|
||||
|
||||
log.Debug("initializing node state")
|
||||
// MainNode is a global variable in the node.go file
|
||||
|
|
|
@ -12,12 +12,11 @@ import (
|
|||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/ava-labs/go-ethereum/p2p/nat"
|
||||
|
||||
"github.com/ava-labs/gecko/database/leveldb"
|
||||
"github.com/ava-labs/gecko/database/memdb"
|
||||
"github.com/ava-labs/gecko/genesis"
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/nat"
|
||||
"github.com/ava-labs/gecko/node"
|
||||
"github.com/ava-labs/gecko/snow/networking/router"
|
||||
"github.com/ava-labs/gecko/utils"
|
||||
|
@ -90,6 +89,9 @@ func init() {
|
|||
fs.StringVar(&Config.StakingKeyFile, "staking-tls-key-file", "keys/staker.key", "TLS private key file for staking connections")
|
||||
fs.StringVar(&Config.StakingCertFile, "staking-tls-cert-file", "keys/staker.crt", "TLS certificate file for staking connections")
|
||||
|
||||
// Plugins:
|
||||
fs.StringVar(&Config.PluginDir, "plugin-dir", "./build/plugins", "Plugin directory for Ava VMs")
|
||||
|
||||
// Logging:
|
||||
logsDir := fs.String("log-dir", "", "Logging directory for Ava")
|
||||
logLevel := fs.String("log-level", "info", "The log level. Should be one of {verbo, debug, info, warn, error, fatal, off}")
|
||||
|
@ -141,12 +143,12 @@ func init() {
|
|||
Config.DB = memdb.New()
|
||||
}
|
||||
|
||||
Config.Nat = nat.Any()
|
||||
Config.Nat = nat.NewRouter()
|
||||
|
||||
var ip net.IP
|
||||
// If public IP is not specified, get it using shell command dig
|
||||
if *consensusIP == "" {
|
||||
ip, err = Config.Nat.ExternalIP()
|
||||
ip, err = Config.Nat.IP()
|
||||
errs.Add(fmt.Errorf(
|
||||
"%s\n"+
|
||||
"If you are trying to create a local network, try adding --public-ip=127.0.0.1\n"+
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package nat
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ava-labs/gecko/utils/logging"
|
||||
"github.com/ava-labs/gecko/utils/wrappers"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultMappingTimeout = 30 * time.Minute
|
||||
defaultMappingUpdateInterval = 3 * defaultMappingTimeout / 4
|
||||
)
|
||||
|
||||
// Mapper maps port
|
||||
type Mapper interface {
|
||||
MapPort(newInternalPort, newExternalPort uint16) error
|
||||
UnmapAllPorts() error
|
||||
}
|
||||
|
||||
type mapper struct {
|
||||
log logging.Logger
|
||||
router Router
|
||||
networkProtocol NetworkProtocol
|
||||
mappingNames string
|
||||
mappingTimeout time.Duration
|
||||
mappingUpdateInterval time.Duration
|
||||
|
||||
closer chan struct{}
|
||||
wg sync.WaitGroup
|
||||
errLock sync.Mutex
|
||||
errs wrappers.Errs
|
||||
}
|
||||
|
||||
// NewMapper returns a new mapper that can map ports on a router
|
||||
func NewMapper(
|
||||
log logging.Logger,
|
||||
router Router,
|
||||
networkProtocol NetworkProtocol,
|
||||
mappingNames string,
|
||||
mappingTimeout time.Duration,
|
||||
mappingUpdateInterval time.Duration,
|
||||
) Mapper {
|
||||
return &mapper{
|
||||
log: log,
|
||||
router: router,
|
||||
networkProtocol: networkProtocol,
|
||||
mappingNames: mappingNames,
|
||||
mappingTimeout: mappingTimeout,
|
||||
mappingUpdateInterval: mappingUpdateInterval,
|
||||
closer: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
// NewDefaultMapper returns a new mapper that can map ports on a router with
|
||||
// default settings
|
||||
func NewDefaultMapper(
|
||||
log logging.Logger,
|
||||
router Router,
|
||||
networkProtocol NetworkProtocol,
|
||||
mappingNames string,
|
||||
) Mapper {
|
||||
return NewMapper(
|
||||
log,
|
||||
router,
|
||||
networkProtocol,
|
||||
mappingNames,
|
||||
defaultMappingTimeout, // uses the default value
|
||||
defaultMappingUpdateInterval, // uses the default value
|
||||
)
|
||||
}
|
||||
|
||||
// MapPort maps a local port to a port on the router until UnmapAllPorts is
|
||||
// called.
|
||||
func (m *mapper) MapPort(newInternalPort, newExternalPort uint16) error {
|
||||
m.wg.Add(1)
|
||||
go m.mapPort(newInternalPort, newExternalPort)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mapper) mapPort(newInternalPort, newExternalPort uint16) {
|
||||
// duration is set to 0 here so that the select case will execute
|
||||
// immediately
|
||||
updateTimer := time.NewTimer(0)
|
||||
defer func() {
|
||||
updateTimer.Stop()
|
||||
|
||||
m.errLock.Lock()
|
||||
m.errs.Add(m.router.UnmapPort(
|
||||
m.networkProtocol,
|
||||
newInternalPort,
|
||||
newExternalPort))
|
||||
m.errLock.Unlock()
|
||||
|
||||
m.log.Debug("Unmapped external port %d to internal port %d",
|
||||
newExternalPort,
|
||||
newInternalPort)
|
||||
|
||||
m.wg.Done()
|
||||
}()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-updateTimer.C:
|
||||
err := m.router.MapPort(
|
||||
m.networkProtocol,
|
||||
newInternalPort,
|
||||
newExternalPort,
|
||||
m.mappingNames,
|
||||
m.mappingTimeout)
|
||||
|
||||
if err != nil {
|
||||
m.errLock.Lock()
|
||||
m.errs.Add(err)
|
||||
m.errLock.Unlock()
|
||||
|
||||
m.log.Debug("Failed to add mapping from external port %d to internal port %d due to %s",
|
||||
newExternalPort,
|
||||
newInternalPort,
|
||||
err)
|
||||
} else {
|
||||
m.log.Debug("Mapped external port %d to internal port %d",
|
||||
newExternalPort,
|
||||
newInternalPort)
|
||||
}
|
||||
|
||||
// remap the port in m.mappingUpdateInterval
|
||||
updateTimer.Reset(m.mappingUpdateInterval)
|
||||
case _, _ = <-m.closer:
|
||||
return // only return when all ports are unmapped
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *mapper) UnmapAllPorts() error {
|
||||
close(m.closer)
|
||||
m.wg.Wait()
|
||||
return m.errs.Err
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package nat
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
errNoRouter = errors.New("no nat enabled router was discovered")
|
||||
)
|
||||
|
||||
type noRouter struct{}
|
||||
|
||||
func (noRouter) MapPort(_ NetworkProtocol, _, _ uint16, _ string, _ time.Duration) error {
|
||||
return errNoRouter
|
||||
}
|
||||
|
||||
func (noRouter) UnmapPort(_ NetworkProtocol, _, _ uint16) error {
|
||||
return errNoRouter
|
||||
}
|
||||
|
||||
func (noRouter) IP() (net.IP, error) {
|
||||
return nil, errNoRouter
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package nat
|
||||
|
||||
import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/jackpal/gateway"
|
||||
"github.com/jackpal/go-nat-pmp"
|
||||
)
|
||||
|
||||
var (
|
||||
pmpClientTimeout = 500 * time.Millisecond
|
||||
)
|
||||
|
||||
// natPMPClient adapts the NAT-PMP protocol implementation so it conforms to
|
||||
// the common interface.
|
||||
type pmpClient struct {
|
||||
client *natpmp.Client
|
||||
}
|
||||
|
||||
func (pmp *pmpClient) MapPort(
|
||||
networkProtocol NetworkProtocol,
|
||||
newInternalPort uint16,
|
||||
newExternalPort uint16,
|
||||
mappingName string,
|
||||
mappingDuration time.Duration) error {
|
||||
protocol := string(networkProtocol)
|
||||
internalPort := int(newInternalPort)
|
||||
externalPort := int(newExternalPort)
|
||||
// go-nat-pmp uses seconds to denote their lifetime
|
||||
lifetime := int(mappingDuration / time.Second)
|
||||
|
||||
_, err := pmp.client.AddPortMapping(protocol, internalPort, externalPort, lifetime)
|
||||
return err
|
||||
}
|
||||
|
||||
func (pmp *pmpClient) UnmapPort(
|
||||
networkProtocol NetworkProtocol,
|
||||
internalPort uint16,
|
||||
_ uint16) error {
|
||||
protocol := string(networkProtocol)
|
||||
internalPortInt := int(internalPort)
|
||||
|
||||
_, err := pmp.client.AddPortMapping(protocol, internalPortInt, 0, 0)
|
||||
return err
|
||||
}
|
||||
|
||||
func (pmp *pmpClient) IP() (net.IP, error) {
|
||||
response, err := pmp.client.GetExternalAddress()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return response.ExternalIPAddress[:], nil
|
||||
}
|
||||
|
||||
func getPMPRouter() Router {
|
||||
gatewayIP, err := gateway.DiscoverGateway()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
pmp := &pmpClient{natpmp.NewClientWithTimeout(gatewayIP, pmpClientTimeout)}
|
||||
if _, err := pmp.IP(); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return pmp
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
// Package nat performs network address translation and provides helpers for
|
||||
// routing ports.
|
||||
package nat
|
||||
|
||||
import (
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
// NetworkProtocol is a protocol that will be used through a port
|
||||
type NetworkProtocol string
|
||||
|
||||
// Available protocol
|
||||
const (
|
||||
TCP NetworkProtocol = "TCP"
|
||||
UDP NetworkProtocol = "UDP"
|
||||
)
|
||||
|
||||
// Router provides a standard NAT router functions. Specifically, allowing the
|
||||
// fetching of public IPs and port forwarding to this computer.
|
||||
type Router interface {
|
||||
// mapPort creates a mapping between a port on the local computer to an
|
||||
// external port on the router.
|
||||
//
|
||||
// The mappingName is something displayed on the router, so it is included
|
||||
// for completeness.
|
||||
MapPort(
|
||||
networkProtocol NetworkProtocol,
|
||||
newInternalPort uint16,
|
||||
newExternalPort uint16,
|
||||
mappingName string,
|
||||
mappingDuration time.Duration) error
|
||||
|
||||
// UnmapPort clears a mapping that was previous made by a call to MapPort
|
||||
UnmapPort(
|
||||
networkProtocol NetworkProtocol,
|
||||
internalPort uint16,
|
||||
externalPort uint16) error
|
||||
|
||||
// Returns the routers IP address on the network the router considers
|
||||
// external
|
||||
IP() (net.IP, error)
|
||||
}
|
||||
|
||||
// NewRouter returns a new router discovered on the local network
|
||||
func NewRouter() Router {
|
||||
routers := make(chan Router)
|
||||
// Because getting a router can take a noticeable amount of time to error,
|
||||
// we run these requests in parallel
|
||||
go func() {
|
||||
routers <- getUPnPRouter()
|
||||
}()
|
||||
go func() {
|
||||
routers <- getPMPRouter()
|
||||
}()
|
||||
for i := 0; i < 2; i++ {
|
||||
if router := <-routers; router != nil {
|
||||
return router
|
||||
}
|
||||
}
|
||||
return noRouter{}
|
||||
}
|
|
@ -0,0 +1,253 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package nat
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/huin/goupnp"
|
||||
"github.com/huin/goupnp/dcps/internetgateway1"
|
||||
"github.com/huin/goupnp/dcps/internetgateway2"
|
||||
)
|
||||
|
||||
const (
|
||||
soapTimeout = time.Second
|
||||
)
|
||||
|
||||
var (
|
||||
errNoGateway = errors.New("Failed to connect to any avaliable gateways")
|
||||
)
|
||||
|
||||
// upnpClient is the interface used by goupnp for their client implementations
|
||||
type upnpClient interface {
|
||||
// attempts to map connection using the provided protocol from the external
|
||||
// port to the internal port for the lease duration.
|
||||
AddPortMapping(
|
||||
newRemoteHost string,
|
||||
newExternalPort uint16,
|
||||
newProtocol string,
|
||||
newInternalPort uint16,
|
||||
newInternalClient string,
|
||||
newEnabled bool,
|
||||
newPortMappingDescription string,
|
||||
newLeaseDuration uint32) error
|
||||
|
||||
// attempt to remove any mapping from the external port.
|
||||
DeletePortMapping(
|
||||
newRemoteHost string,
|
||||
newExternalPort uint16,
|
||||
newProtocol string) error
|
||||
|
||||
// attempts to return the external IP address, formatted as a string.
|
||||
GetExternalIPAddress() (ip string, err error)
|
||||
|
||||
// returns if there is rsip available, nat enabled, or an unexpected error.
|
||||
GetNATRSIPStatus() (newRSIPAvailable bool, natEnabled bool, err error)
|
||||
}
|
||||
|
||||
type upnpRouter struct {
|
||||
root *goupnp.RootDevice
|
||||
client upnpClient
|
||||
}
|
||||
|
||||
func (n *upnpRouter) MapPort(
|
||||
networkProtocol NetworkProtocol,
|
||||
newInternalPort uint16,
|
||||
newExternalPort uint16,
|
||||
mappingName string,
|
||||
mappingDuration time.Duration,
|
||||
) error {
|
||||
ip, err := n.localAddress()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
protocol := string(networkProtocol)
|
||||
// goupnp uses seconds to denote their lifetime
|
||||
lifetime := uint32(mappingDuration / time.Second)
|
||||
|
||||
// UnmapPort's error is intentionally dropped, because the mapping may not
|
||||
// exist.
|
||||
n.UnmapPort(networkProtocol, newInternalPort, newExternalPort)
|
||||
|
||||
return n.client.AddPortMapping(
|
||||
"", // newRemoteHost isn't used to limit the mapping to a host
|
||||
newExternalPort,
|
||||
protocol,
|
||||
newInternalPort,
|
||||
ip.String(), // newInternalClient is the client traffic should be sent to
|
||||
true, // newEnabled enables port mappings
|
||||
mappingName,
|
||||
lifetime,
|
||||
)
|
||||
}
|
||||
|
||||
func (n *upnpRouter) UnmapPort(networkProtocol NetworkProtocol, _, externalPort uint16) error {
|
||||
protocol := string(networkProtocol)
|
||||
return n.client.DeletePortMapping(
|
||||
"", // newRemoteHost isn't used to limit the mapping to a host
|
||||
externalPort,
|
||||
protocol)
|
||||
}
|
||||
|
||||
func (n *upnpRouter) IP() (net.IP, error) {
|
||||
ipStr, err := n.client.GetExternalIPAddress()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ip := net.ParseIP(ipStr)
|
||||
if ip == nil {
|
||||
return nil, fmt.Errorf("invalid IP %s", ipStr)
|
||||
}
|
||||
return ip, nil
|
||||
}
|
||||
|
||||
func (n *upnpRouter) localAddress() (net.IP, error) {
|
||||
// attempt to get an address on the router
|
||||
deviceAddr, err := net.ResolveUDPAddr("udp4", n.root.URLBase.Host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
deviceIP := deviceAddr.IP
|
||||
|
||||
netInterfaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// attempt to find one of my ips that the router would know about
|
||||
for _, netInterface := range netInterfaces {
|
||||
addrs, err := netInterface.Addrs()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, addr := range addrs {
|
||||
// this is pretty janky, but it seems to be the best way to get the
|
||||
// ip mask and properly check if the ip references the device we are
|
||||
// connected to
|
||||
ipNet, ok := addr.(*net.IPNet)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if ipNet.Contains(deviceIP) {
|
||||
return ipNet.IP, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("couldn't find the local address in the same network as %s", deviceIP)
|
||||
}
|
||||
|
||||
// getUPnPRouter searches for all Gateway Devices that have avaliable
|
||||
// connections in the goupnp library and returns the first connection it can
|
||||
// find.
|
||||
func getUPnPRouter() Router {
|
||||
routers := make(chan *upnpRouter)
|
||||
// Because DiscoverDevices takes a noticeable amount of time to error, we
|
||||
// run these requests in parallel
|
||||
go func() {
|
||||
routers <- connectToGateway(internetgateway1.URN_WANConnectionDevice_1, gateway1)
|
||||
}()
|
||||
go func() {
|
||||
routers <- connectToGateway(internetgateway2.URN_WANConnectionDevice_2, gateway2)
|
||||
}()
|
||||
for i := 0; i < 2; i++ {
|
||||
if router := <-routers; router != nil {
|
||||
return router
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func gateway1(client goupnp.ServiceClient) upnpClient {
|
||||
switch client.Service.ServiceType {
|
||||
case internetgateway1.URN_WANIPConnection_1:
|
||||
return &internetgateway1.WANIPConnection1{ServiceClient: client}
|
||||
case internetgateway1.URN_WANPPPConnection_1:
|
||||
return &internetgateway1.WANPPPConnection1{ServiceClient: client}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func gateway2(client goupnp.ServiceClient) upnpClient {
|
||||
switch client.Service.ServiceType {
|
||||
case internetgateway2.URN_WANIPConnection_1:
|
||||
return &internetgateway2.WANIPConnection1{ServiceClient: client}
|
||||
case internetgateway2.URN_WANIPConnection_2:
|
||||
return &internetgateway2.WANIPConnection2{ServiceClient: client}
|
||||
case internetgateway2.URN_WANPPPConnection_1:
|
||||
return &internetgateway2.WANPPPConnection1{ServiceClient: client}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func connectToGateway(deviceType string, toClient func(goupnp.ServiceClient) upnpClient) *upnpRouter {
|
||||
devs, err := goupnp.DiscoverDevices(deviceType)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
// we are iterating over all the network devices, acting a possible roots
|
||||
for i := range devs {
|
||||
dev := &devs[i]
|
||||
if dev.Root == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// the root device may be a router, so attempt to connect to that
|
||||
rootDevice := &dev.Root.Device
|
||||
if upnp := getRouter(dev, rootDevice, toClient); upnp != nil {
|
||||
return upnp
|
||||
}
|
||||
|
||||
// attempt to connect to any sub devices
|
||||
devices := rootDevice.Devices
|
||||
for i := range devices {
|
||||
if upnp := getRouter(dev, &devices[i], toClient); upnp != nil {
|
||||
return upnp
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getRouter(rootDevice *goupnp.MaybeRootDevice, device *goupnp.Device, toClient func(goupnp.ServiceClient) upnpClient) *upnpRouter {
|
||||
for i := range device.Services {
|
||||
service := &device.Services[i]
|
||||
|
||||
soapClient := service.NewSOAPClient()
|
||||
// make sure the client times out if needed
|
||||
soapClient.HTTPClient.Timeout = soapTimeout
|
||||
|
||||
// attempt to create a client connection
|
||||
serviceClient := goupnp.ServiceClient{
|
||||
SOAPClient: soapClient,
|
||||
RootDevice: rootDevice.Root,
|
||||
Location: rootDevice.Location,
|
||||
Service: service,
|
||||
}
|
||||
client := toClient(serviceClient)
|
||||
if client == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// check whether port mapping is enabled
|
||||
if _, nat, err := client.GetNATRSIPStatus(); err != nil || !nat {
|
||||
continue
|
||||
}
|
||||
|
||||
// we found a router!
|
||||
return &upnpRouter{
|
||||
root: rootDevice.Root,
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -4,9 +4,8 @@
|
|||
package node
|
||||
|
||||
import (
|
||||
"github.com/ava-labs/go-ethereum/p2p/nat"
|
||||
|
||||
"github.com/ava-labs/gecko/database"
|
||||
"github.com/ava-labs/gecko/nat"
|
||||
"github.com/ava-labs/gecko/snow/consensus/avalanche"
|
||||
"github.com/ava-labs/gecko/snow/networking/router"
|
||||
"github.com/ava-labs/gecko/utils"
|
||||
|
@ -16,7 +15,7 @@ import (
|
|||
// Config contains all of the configurations of an Ava node.
|
||||
type Config struct {
|
||||
// protocol to use for opening the network interface
|
||||
Nat nat.Interface
|
||||
Nat nat.Router
|
||||
|
||||
// ID of the network this node should connect to
|
||||
NetworkID uint32
|
||||
|
@ -56,6 +55,9 @@ type Config struct {
|
|||
// Logging configuration
|
||||
LoggingConfig logging.Config
|
||||
|
||||
// Plugin directory
|
||||
PluginDir string
|
||||
|
||||
// Consensus configuration
|
||||
ConsensusParams avalanche.Parameters
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
|
@ -39,10 +40,10 @@ import (
|
|||
"github.com/ava-labs/gecko/utils/wrappers"
|
||||
"github.com/ava-labs/gecko/vms"
|
||||
"github.com/ava-labs/gecko/vms/avm"
|
||||
"github.com/ava-labs/gecko/vms/evm"
|
||||
"github.com/ava-labs/gecko/vms/nftfx"
|
||||
"github.com/ava-labs/gecko/vms/platformvm"
|
||||
"github.com/ava-labs/gecko/vms/propertyfx"
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm"
|
||||
"github.com/ava-labs/gecko/vms/secp256k1fx"
|
||||
"github.com/ava-labs/gecko/vms/spchainvm"
|
||||
"github.com/ava-labs/gecko/vms/spdagvm"
|
||||
|
@ -360,7 +361,7 @@ func (n *Node) initNodeID() error {
|
|||
}
|
||||
|
||||
// Create the vmManager and register the following vms:
|
||||
// AVM, EVM, Simple Payments DAG, Simple Payments Chain
|
||||
// AVM, Simple Payments DAG, Simple Payments Chain
|
||||
// The Platform VM is registered in initStaking because
|
||||
// its factory needs to reference n.chainManager, which is nil right now
|
||||
func (n *Node) initVMManager() error {
|
||||
|
@ -377,7 +378,7 @@ func (n *Node) initVMManager() error {
|
|||
AVA: avaAssetID,
|
||||
Platform: ids.Empty,
|
||||
}),
|
||||
n.vmManager.RegisterVMFactory(evm.ID, &evm.Factory{}),
|
||||
n.vmManager.RegisterVMFactory(genesis.EVMID, &rpcchainvm.Factory{Path: path.Join(n.Config.PluginDir, "evm")}),
|
||||
n.vmManager.RegisterVMFactory(spdagvm.ID, &spdagvm.Factory{TxFee: n.Config.AvaTxFee}),
|
||||
n.vmManager.RegisterVMFactory(spchainvm.ID, &spchainvm.Factory{}),
|
||||
n.vmManager.RegisterVMFactory(timestampvm.ID, ×tampvm.Factory{}),
|
||||
|
|
|
@ -3,18 +3,31 @@
|
|||
# Ted: contact me when you make any changes
|
||||
|
||||
PREFIX="${PREFIX:-$(pwd)/build}"
|
||||
PLUGIN_PREFIX="$PREFIX/plugins"
|
||||
|
||||
SRC_DIR="$(dirname "${BASH_SOURCE[0]}")"
|
||||
source "$SRC_DIR/env.sh"
|
||||
|
||||
CORETH_PKG=github.com/ava-labs/coreth
|
||||
CORETH_PATH="$GOPATH/src/$CORETH_PKG"
|
||||
if [[ -d "$CORETH_PATH/.git" ]]; then
|
||||
cd "$CORETH_PATH"
|
||||
go get -t -v -d "./..."
|
||||
cd -
|
||||
else
|
||||
go get -t -v -d "$CORETH_PKG/..."
|
||||
fi
|
||||
|
||||
GECKO_PKG=github.com/ava-labs/gecko
|
||||
GECKO_PATH="$GOPATH/src/$GECKO_PKG"
|
||||
if [[ -d "$GECKO_PATH/.git" ]]; then
|
||||
cd "$GECKO_PATH"
|
||||
go get -t -v "./..."
|
||||
go get -t -v -d "./..."
|
||||
cd -
|
||||
else
|
||||
go get -t -v "$GECKO_PKG/..."
|
||||
go get -t -v -d "$GECKO_PKG/..."
|
||||
fi
|
||||
|
||||
go build -o "$PREFIX/ava" "$GECKO_PATH/main/"*.go
|
||||
go build -o "$PREFIX/xputtest" "$GECKO_PATH/xputtest/"*.go
|
||||
go build -o "$PLUGIN_PREFIX/evm" "$CORETH_PATH/plugin/"*.go
|
||||
|
|
|
@ -17,8 +17,6 @@ fi
|
|||
if [[ ! -d "$WORKPREFIX" ]]; then
|
||||
mkdir -p "$WORKPREFIX"
|
||||
git config --global credential.helper cache
|
||||
git clone https://github.com/ava-labs/coreth.git "$WORKPREFIX/coreth"
|
||||
git clone --depth 1 https://github.com/ava-labs/go-ethereum.git "$WORKPREFIX/go-ethereum"
|
||||
git clone https://github.com/ava-labs/gecko.git "$WORKPREFIX/gecko"
|
||||
fi
|
||||
GECKO_COMMIT="$(git --git-dir="$WORKPREFIX/gecko/.git" rev-parse --short HEAD)"
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
)
|
||||
|
||||
// LockOption allows the vm to specify their lock option based on their endpoint
|
||||
type LockOption int
|
||||
type LockOption uint32
|
||||
|
||||
// List of all allowed options
|
||||
const (
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
// TODO: Consider renaming Message to, say, VMMessage
|
||||
|
||||
// Message is an enum of the message types that vms can send to consensus
|
||||
type Message int
|
||||
type Message uint32
|
||||
|
||||
const (
|
||||
// PendingTxs notifies a consensus engine that
|
||||
|
|
|
@ -41,7 +41,7 @@ func init() {
|
|||
RSA: &FactoryRSA{},
|
||||
RSAPSS: &FactoryRSAPSS{},
|
||||
ED25519: &FactoryED25519{},
|
||||
SECP256K1: &FactorySECP256K1{},
|
||||
SECP256K1: &FactorySECP256K1R{},
|
||||
}
|
||||
for _, f := range factories {
|
||||
fKeys := []PublicKey{}
|
||||
|
|
|
@ -1,149 +0,0 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/rand"
|
||||
"math/big"
|
||||
|
||||
"github.com/ava-labs/go-ethereum/crypto"
|
||||
"github.com/ava-labs/go-ethereum/crypto/secp256k1"
|
||||
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/utils/hashing"
|
||||
)
|
||||
|
||||
const (
|
||||
// SECP256K1SigLen is the number of bytes in a secp2561k signature
|
||||
SECP256K1SigLen = 64
|
||||
|
||||
// SECP256K1SKLen is the number of bytes in a secp2561k private key
|
||||
SECP256K1SKLen = 32
|
||||
|
||||
// SECP256K1PKLen is the number of bytes in a secp2561k public key
|
||||
SECP256K1PKLen = 33
|
||||
)
|
||||
|
||||
// FactorySECP256K1 ...
|
||||
type FactorySECP256K1 struct{}
|
||||
|
||||
// NewPrivateKey implements the Factory interface
|
||||
func (*FactorySECP256K1) NewPrivateKey() (PrivateKey, error) {
|
||||
k, err := ecdsa.GenerateKey(secp256k1.S256(), rand.Reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &PrivateKeySECP256K1{sk: k}, nil
|
||||
}
|
||||
|
||||
// ToPublicKey implements the Factory interface
|
||||
func (*FactorySECP256K1) ToPublicKey(b []byte) (PublicKey, error) {
|
||||
key, err := crypto.DecompressPubkey(b)
|
||||
return &PublicKeySECP256K1{
|
||||
pk: key,
|
||||
bytes: b,
|
||||
}, err
|
||||
}
|
||||
|
||||
// ToPrivateKey implements the Factory interface
|
||||
func (*FactorySECP256K1) ToPrivateKey(b []byte) (PrivateKey, error) {
|
||||
key, err := crypto.ToECDSA(b)
|
||||
return &PrivateKeySECP256K1{
|
||||
sk: key,
|
||||
bytes: b,
|
||||
}, err
|
||||
}
|
||||
|
||||
// PublicKeySECP256K1 ...
|
||||
type PublicKeySECP256K1 struct {
|
||||
pk *ecdsa.PublicKey
|
||||
addr ids.ShortID
|
||||
bytes []byte
|
||||
}
|
||||
|
||||
// Verify implements the PublicKey interface
|
||||
func (k *PublicKeySECP256K1) Verify(msg, sig []byte) bool {
|
||||
return k.VerifyHash(hashing.ComputeHash256(msg), sig)
|
||||
}
|
||||
|
||||
// VerifyHash implements the PublicKey interface
|
||||
func (k *PublicKeySECP256K1) VerifyHash(hash, sig []byte) bool {
|
||||
if verifySECP256K1SignatureFormat(sig) != nil {
|
||||
return false
|
||||
}
|
||||
return crypto.VerifySignature(k.Bytes(), hash, sig)
|
||||
}
|
||||
|
||||
// Address implements the PublicKey interface
|
||||
func (k *PublicKeySECP256K1) Address() ids.ShortID {
|
||||
if k.addr.IsZero() {
|
||||
addr, err := ids.ToShortID(hashing.PubkeyBytesToAddress(k.Bytes()))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
k.addr = addr
|
||||
}
|
||||
return k.addr
|
||||
}
|
||||
|
||||
// Bytes implements the PublicKey interface
|
||||
func (k *PublicKeySECP256K1) Bytes() []byte {
|
||||
if k.bytes == nil {
|
||||
k.bytes = crypto.CompressPubkey(k.pk)
|
||||
}
|
||||
return k.bytes
|
||||
}
|
||||
|
||||
// PrivateKeySECP256K1 ...
|
||||
type PrivateKeySECP256K1 struct {
|
||||
sk *ecdsa.PrivateKey
|
||||
pk *PublicKeySECP256K1
|
||||
bytes []byte
|
||||
}
|
||||
|
||||
// PublicKey implements the PrivateKey interface
|
||||
func (k *PrivateKeySECP256K1) PublicKey() PublicKey {
|
||||
if k.pk == nil {
|
||||
k.pk = &PublicKeySECP256K1{pk: (*ecdsa.PublicKey)(&k.sk.PublicKey)}
|
||||
}
|
||||
return k.pk
|
||||
}
|
||||
|
||||
// Sign implements the PrivateKey interface
|
||||
func (k *PrivateKeySECP256K1) Sign(msg []byte) ([]byte, error) {
|
||||
return k.SignHash(hashing.ComputeHash256(msg))
|
||||
}
|
||||
|
||||
// SignHash implements the PrivateKey interface
|
||||
func (k *PrivateKeySECP256K1) SignHash(hash []byte) ([]byte, error) {
|
||||
sig, err := crypto.Sign(hash, k.sk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return sig[:len(sig)-1], err
|
||||
}
|
||||
|
||||
// Bytes implements the PrivateKey interface
|
||||
func (k *PrivateKeySECP256K1) Bytes() []byte {
|
||||
if k.bytes == nil {
|
||||
k.bytes = make([]byte, SECP256K1SKLen)
|
||||
bytes := k.sk.D.Bytes()
|
||||
copy(k.bytes[SECP256K1SKLen-len(bytes):], bytes)
|
||||
}
|
||||
return k.bytes
|
||||
}
|
||||
|
||||
func verifySECP256K1SignatureFormat(sig []byte) error {
|
||||
if len(sig) != SECP256K1SigLen {
|
||||
return errInvalidSigLen
|
||||
}
|
||||
var r, s big.Int
|
||||
r.SetBytes(sig[:32])
|
||||
s.SetBytes(sig[32:])
|
||||
if !crypto.ValidateSignatureValues(0, &r, &s, true) {
|
||||
return errMutatedSig
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
package crypto
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ava-labs/gecko/utils/hashing"
|
||||
)
|
||||
|
||||
// NumRecoveries is the number of recoveries to run per operation
|
||||
const NumRecoveries = 1
|
||||
|
||||
var (
|
||||
secpSigs [][]byte
|
||||
)
|
||||
|
||||
func init() {
|
||||
factory := FactorySECP256K1R{}
|
||||
|
||||
hash := hashing.ComputeHash256(nil)
|
||||
for i := byte(0); i < NumRecoveries; i++ {
|
||||
key, err := factory.NewPrivateKey()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
sig, err := key.SignHash(hash)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
secpSigs = append(secpSigs, sig)
|
||||
}
|
||||
}
|
||||
|
||||
func recover() {
|
||||
factory := FactorySECP256K1R{}
|
||||
hash := hashing.ComputeHash256(nil)
|
||||
for _, sig := range secpSigs {
|
||||
if _, err := factory.RecoverHashPublicKey(hash, sig); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BenchmarkSecp256k1RecoverVerify runs the benchmark with secp sig
|
||||
func BenchmarkSecp256k1RecoverVerify(b *testing.B) {
|
||||
for n := 0; n < b.N; n++ {
|
||||
recover()
|
||||
}
|
||||
}
|
|
@ -5,13 +5,11 @@ package crypto
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
"crypto/rand"
|
||||
"math/big"
|
||||
"errors"
|
||||
"sort"
|
||||
|
||||
"github.com/ava-labs/go-ethereum/crypto"
|
||||
"github.com/ava-labs/go-ethereum/crypto/secp256k1"
|
||||
"github.com/decred/dcrd/dcrec/secp256k1"
|
||||
"github.com/decred/dcrd/dcrec/secp256k1/ecdsa"
|
||||
|
||||
"github.com/ava-labs/gecko/cache"
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
|
@ -31,6 +29,14 @@ const (
|
|||
// SECP256K1RPKLen is the number of bytes in a secp2561k recoverable public
|
||||
// key
|
||||
SECP256K1RPKLen = 33
|
||||
|
||||
// from the decred library:
|
||||
// compactSigMagicOffset is a value used when creating the compact signature
|
||||
// recovery code inherited from Bitcoin and has no meaning, but has been
|
||||
// retained for compatibility. For historical purposes, it was originally
|
||||
// picked to avoid a binary representation that would allow compact
|
||||
// signatures to be mistaken for other components.
|
||||
compactSigMagicOffset = 27
|
||||
)
|
||||
|
||||
// FactorySECP256K1R ...
|
||||
|
@ -38,16 +44,13 @@ type FactorySECP256K1R struct{ Cache cache.LRU }
|
|||
|
||||
// NewPrivateKey implements the Factory interface
|
||||
func (*FactorySECP256K1R) NewPrivateKey() (PrivateKey, error) {
|
||||
k, err := ecdsa.GenerateKey(secp256k1.S256(), rand.Reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &PrivateKeySECP256K1R{sk: k}, nil
|
||||
k, err := secp256k1.GeneratePrivateKey()
|
||||
return &PrivateKeySECP256K1R{sk: k}, err
|
||||
}
|
||||
|
||||
// ToPublicKey implements the Factory interface
|
||||
func (*FactorySECP256K1R) ToPublicKey(b []byte) (PublicKey, error) {
|
||||
key, err := crypto.DecompressPubkey(b)
|
||||
key, err := secp256k1.ParsePubKey(b)
|
||||
return &PublicKeySECP256K1R{
|
||||
pk: key,
|
||||
bytes: b,
|
||||
|
@ -56,11 +59,10 @@ func (*FactorySECP256K1R) ToPublicKey(b []byte) (PublicKey, error) {
|
|||
|
||||
// ToPrivateKey implements the Factory interface
|
||||
func (*FactorySECP256K1R) ToPrivateKey(b []byte) (PrivateKey, error) {
|
||||
key, err := crypto.ToECDSA(b)
|
||||
return &PrivateKeySECP256K1R{
|
||||
sk: key,
|
||||
sk: secp256k1.PrivKeyFromBytes(b),
|
||||
bytes: b,
|
||||
}, err
|
||||
}, nil
|
||||
}
|
||||
|
||||
// RecoverPublicKey returns the public key from a 65 byte signature
|
||||
|
@ -75,25 +77,35 @@ func (f *FactorySECP256K1R) RecoverHashPublicKey(hash, sig []byte) (PublicKey, e
|
|||
copy(cacheBytes[len(hash):], sig)
|
||||
id := ids.NewID(hashing.ComputeHash256Array(cacheBytes))
|
||||
if cachedPublicKey, ok := f.Cache.Get(id); ok {
|
||||
return cachedPublicKey.(*PublicKeySECP256K1), nil
|
||||
return cachedPublicKey.(*PublicKeySECP256K1R), nil
|
||||
}
|
||||
|
||||
if err := verifySECP256K1RSignatureFormat(sig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rawPubkey, err := crypto.SigToPub(hash, sig)
|
||||
sig, err := sigToRawSig(sig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pubkey := &PublicKeySECP256K1{pk: rawPubkey}
|
||||
|
||||
rawPubkey, compressed, err := ecdsa.RecoverCompact(sig, hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if compressed {
|
||||
return nil, errors.New("wasn't expecting a compresses key")
|
||||
}
|
||||
|
||||
pubkey := &PublicKeySECP256K1R{pk: rawPubkey}
|
||||
f.Cache.Put(id, pubkey)
|
||||
return pubkey, nil
|
||||
}
|
||||
|
||||
// PublicKeySECP256K1R ...
|
||||
type PublicKeySECP256K1R struct {
|
||||
pk *ecdsa.PublicKey
|
||||
pk *secp256k1.PublicKey
|
||||
addr ids.ShortID
|
||||
bytes []byte
|
||||
}
|
||||
|
@ -105,10 +117,12 @@ func (k *PublicKeySECP256K1R) Verify(msg, sig []byte) bool {
|
|||
|
||||
// VerifyHash implements the PublicKey interface
|
||||
func (k *PublicKeySECP256K1R) VerifyHash(hash, sig []byte) bool {
|
||||
if verifySECP256K1RSignatureFormat(sig) != nil {
|
||||
factory := FactorySECP256K1R{}
|
||||
pk, err := factory.RecoverHashPublicKey(hash, sig)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return crypto.VerifySignature(k.Bytes(), hash, sig[:SECP256K1RSigLen-1])
|
||||
return k.Address().Equals(pk.Address())
|
||||
}
|
||||
|
||||
// Address implements the PublicKey interface
|
||||
|
@ -126,14 +140,14 @@ func (k *PublicKeySECP256K1R) Address() ids.ShortID {
|
|||
// Bytes implements the PublicKey interface
|
||||
func (k *PublicKeySECP256K1R) Bytes() []byte {
|
||||
if k.bytes == nil {
|
||||
k.bytes = crypto.CompressPubkey(k.pk)
|
||||
k.bytes = k.pk.SerializeCompressed()
|
||||
}
|
||||
return k.bytes
|
||||
}
|
||||
|
||||
// PrivateKeySECP256K1R ...
|
||||
type PrivateKeySECP256K1R struct {
|
||||
sk *ecdsa.PrivateKey
|
||||
sk *secp256k1.PrivateKey
|
||||
pk *PublicKeySECP256K1R
|
||||
bytes []byte
|
||||
}
|
||||
|
@ -141,7 +155,7 @@ type PrivateKeySECP256K1R struct {
|
|||
// PublicKey implements the PrivateKey interface
|
||||
func (k *PrivateKeySECP256K1R) PublicKey() PublicKey {
|
||||
if k.pk == nil {
|
||||
k.pk = &PublicKeySECP256K1R{pk: (*ecdsa.PublicKey)(&k.sk.PublicKey)}
|
||||
k.pk = &PublicKeySECP256K1R{pk: k.sk.PubKey()}
|
||||
}
|
||||
return k.pk
|
||||
}
|
||||
|
@ -153,27 +167,49 @@ func (k *PrivateKeySECP256K1R) Sign(msg []byte) ([]byte, error) {
|
|||
|
||||
// SignHash implements the PrivateKey interface
|
||||
func (k *PrivateKeySECP256K1R) SignHash(hash []byte) ([]byte, error) {
|
||||
return crypto.Sign(hash, k.sk)
|
||||
sig := ecdsa.SignCompact(k.sk, hash, false) // returns [v || r || s]
|
||||
return rawSigToSig(sig)
|
||||
}
|
||||
|
||||
// Bytes implements the PrivateKey interface
|
||||
func (k *PrivateKeySECP256K1R) Bytes() []byte {
|
||||
if k.bytes == nil {
|
||||
k.bytes = make([]byte, SECP256K1RSKLen)
|
||||
bytes := k.sk.D.Bytes()
|
||||
copy(k.bytes[SECP256K1RSKLen-len(bytes):], bytes)
|
||||
k.bytes = k.sk.Serialize()
|
||||
}
|
||||
return k.bytes
|
||||
}
|
||||
|
||||
// raw sig has format [v || r || s] whereas the sig has format [r || s || v]
|
||||
func rawSigToSig(sig []byte) ([]byte, error) {
|
||||
if len(sig) != SECP256K1RSigLen {
|
||||
return nil, errInvalidSigLen
|
||||
}
|
||||
recCode := sig[0]
|
||||
copy(sig, sig[1:])
|
||||
sig[SECP256K1RSigLen-1] = recCode - compactSigMagicOffset
|
||||
return sig, nil
|
||||
}
|
||||
|
||||
// sig has format [r || s || v] whereas the raw sig has format [v || r || s]
|
||||
func sigToRawSig(sig []byte) ([]byte, error) {
|
||||
if len(sig) != SECP256K1RSigLen {
|
||||
return nil, errInvalidSigLen
|
||||
}
|
||||
newSig := make([]byte, SECP256K1RSigLen)
|
||||
newSig[0] = sig[SECP256K1RSigLen-1] + compactSigMagicOffset
|
||||
copy(newSig[1:], sig)
|
||||
return newSig, nil
|
||||
}
|
||||
|
||||
// verifies the signature format in format [r || s || v]
|
||||
func verifySECP256K1RSignatureFormat(sig []byte) error {
|
||||
if len(sig) != SECP256K1RSigLen {
|
||||
return errInvalidSigLen
|
||||
}
|
||||
var r, s big.Int
|
||||
r.SetBytes(sig[:32])
|
||||
s.SetBytes(sig[32:64])
|
||||
if !crypto.ValidateSignatureValues(sig[64], &r, &s, true) {
|
||||
|
||||
var s secp256k1.ModNScalar
|
||||
s.SetByteSlice(sig[32:64])
|
||||
if s.IsOverHalfOrder() {
|
||||
return errMutatedSig
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -10,6 +10,8 @@ import (
|
|||
"github.com/ava-labs/gecko/cache"
|
||||
"github.com/ava-labs/gecko/utils/formatting"
|
||||
"github.com/ava-labs/gecko/utils/hashing"
|
||||
"github.com/decred/dcrd/dcrec/secp256k1"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestRecover(t *testing.T) {
|
||||
|
@ -73,3 +75,24 @@ func TestGenRecreate(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyMutatedSignature(t *testing.T) {
|
||||
factory := FactorySECP256K1R{}
|
||||
|
||||
sk, err := factory.NewPrivateKey()
|
||||
assert.NoError(t, err)
|
||||
|
||||
msg := []byte{'h', 'e', 'l', 'l', 'o'}
|
||||
|
||||
sig, err := sk.Sign(msg)
|
||||
assert.NoError(t, err)
|
||||
|
||||
var s secp256k1.ModNScalar
|
||||
s.SetByteSlice(sig[32:64])
|
||||
s.Negate()
|
||||
newSBytes := s.Bytes()
|
||||
copy(sig[32:], newSBytes[:])
|
||||
|
||||
_, err = factory.RecoverPublicKey(msg, sig)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
|
|
@ -19,9 +19,9 @@ type Factory struct {
|
|||
}
|
||||
|
||||
// New ...
|
||||
func (f *Factory) New() interface{} {
|
||||
func (f *Factory) New() (interface{}, error) {
|
||||
return &VM{
|
||||
ava: f.AVA,
|
||||
platform: f.Platform,
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -198,6 +198,10 @@ func (vm *VM) Initialize(
|
|||
|
||||
// Shutdown implements the avalanche.DAGVM interface
|
||||
func (vm *VM) Shutdown() {
|
||||
if vm.timer == nil {
|
||||
return
|
||||
}
|
||||
|
||||
vm.timer.Stop()
|
||||
if err := vm.baseDB.Close(); err != nil {
|
||||
vm.ctx.Log.Error("Closing the database failed with %s", err)
|
||||
|
|
|
@ -83,6 +83,10 @@ func (svm *SnowmanVM) GetBlock(ID ids.ID) (snowman.Block, error) {
|
|||
|
||||
// Shutdown this vm
|
||||
func (svm *SnowmanVM) Shutdown() {
|
||||
if svm.DB == nil {
|
||||
return
|
||||
}
|
||||
|
||||
svm.DB.Commit() // Flush DB
|
||||
svm.DB.GetDatabase().Close() // close underlying database
|
||||
svm.DB.Close() // close versionDB
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package evm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ava-labs/go-ethereum/core/types"
|
||||
"github.com/ava-labs/go-ethereum/rlp"
|
||||
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/snow/choices"
|
||||
"github.com/ava-labs/gecko/snow/consensus/snowman"
|
||||
)
|
||||
|
||||
// Block implements the snowman.Block interface
|
||||
type Block struct {
|
||||
id ids.ID
|
||||
ethBlock *types.Block
|
||||
vm *VM
|
||||
}
|
||||
|
||||
// ID implements the snowman.Block interface
|
||||
func (b *Block) ID() ids.ID { return b.id }
|
||||
|
||||
// Accept implements the snowman.Block interface
|
||||
func (b *Block) Accept() {
|
||||
b.vm.ctx.Log.Verbo("Block %s is accepted", b.ID())
|
||||
b.vm.updateStatus(b.ID(), choices.Accepted)
|
||||
}
|
||||
|
||||
// Reject implements the snowman.Block interface
|
||||
func (b *Block) Reject() {
|
||||
b.vm.ctx.Log.Verbo("Block %s is rejected", b.ID())
|
||||
b.vm.updateStatus(b.ID(), choices.Rejected)
|
||||
}
|
||||
|
||||
// Status implements the snowman.Block interface
|
||||
func (b *Block) Status() choices.Status {
|
||||
status := b.vm.getCachedStatus(b.ID())
|
||||
if status == choices.Unknown && b.ethBlock != nil {
|
||||
return choices.Processing
|
||||
}
|
||||
return status
|
||||
}
|
||||
|
||||
// Parent implements the snowman.Block interface
|
||||
func (b *Block) Parent() snowman.Block {
|
||||
parentID := ids.NewID(b.ethBlock.ParentHash())
|
||||
block := &Block{
|
||||
id: parentID,
|
||||
ethBlock: b.vm.getCachedBlock(parentID),
|
||||
vm: b.vm,
|
||||
}
|
||||
b.vm.ctx.Log.Verbo("Parent(%s) has status: %s", block.ID(), block.Status())
|
||||
return block
|
||||
}
|
||||
|
||||
// Verify implements the snowman.Block interface
|
||||
func (b *Block) Verify() error {
|
||||
_, err := b.vm.chain.InsertChain([]*types.Block{b.ethBlock})
|
||||
return err
|
||||
}
|
||||
|
||||
// Bytes implements the snowman.Block interface
|
||||
func (b *Block) Bytes() []byte {
|
||||
res, err := rlp.EncodeToBytes(b.ethBlock)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (b *Block) String() string { return fmt.Sprintf("EVM block, ID = %s", b.ID()) }
|
|
@ -1,66 +0,0 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package evm
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/ava-labs/go-ethereum/ethdb"
|
||||
|
||||
"github.com/ava-labs/gecko/database"
|
||||
)
|
||||
|
||||
var (
|
||||
errOpNotSupported = errors.New("this operation is not supported")
|
||||
)
|
||||
|
||||
// Database implements ethdb.Database
|
||||
type Database struct{ database.Database }
|
||||
|
||||
// HasAncient returns an error as we don't have a backing chain freezer.
|
||||
func (db Database) HasAncient(kind string, number uint64) (bool, error) {
|
||||
return false, errOpNotSupported
|
||||
}
|
||||
|
||||
// Ancient returns an error as we don't have a backing chain freezer.
|
||||
func (db Database) Ancient(kind string, number uint64) ([]byte, error) { return nil, errOpNotSupported }
|
||||
|
||||
// Ancients returns an error as we don't have a backing chain freezer.
|
||||
func (db Database) Ancients() (uint64, error) { return 0, errOpNotSupported }
|
||||
|
||||
// AncientSize returns an error as we don't have a backing chain freezer.
|
||||
func (db Database) AncientSize(kind string) (uint64, error) { return 0, errOpNotSupported }
|
||||
|
||||
// AppendAncient returns an error as we don't have a backing chain freezer.
|
||||
func (db Database) AppendAncient(number uint64, hash, header, body, receipts, td []byte) error {
|
||||
return errOpNotSupported
|
||||
}
|
||||
|
||||
// TruncateAncients returns an error as we don't have a backing chain freezer.
|
||||
func (db Database) TruncateAncients(items uint64) error { return errOpNotSupported }
|
||||
|
||||
// Sync returns an error as we don't have a backing chain freezer.
|
||||
func (db Database) Sync() error { return errOpNotSupported }
|
||||
|
||||
// NewBatch implements ethdb.Database
|
||||
func (db Database) NewBatch() ethdb.Batch { return Batch{db.Database.NewBatch()} }
|
||||
|
||||
// NewIterator implements ethdb.Database
|
||||
func (db Database) NewIterator() ethdb.Iterator { return db.Database.NewIterator() }
|
||||
|
||||
// NewIteratorWithPrefix implements ethdb.Database
|
||||
func (db Database) NewIteratorWithPrefix(prefix []byte) ethdb.Iterator {
|
||||
return db.NewIteratorWithPrefix(prefix)
|
||||
}
|
||||
|
||||
// NewIteratorWithStart implements ethdb.Database
|
||||
func (db Database) NewIteratorWithStart(start []byte) ethdb.Iterator {
|
||||
return db.NewIteratorWithStart(start)
|
||||
}
|
||||
|
||||
// Batch implements ethdb.Batch
|
||||
type Batch struct{ database.Batch }
|
||||
|
||||
// Replay implements ethdb.Batch
|
||||
func (batch Batch) Replay(w ethdb.KeyValueWriter) error { return batch.Batch.Replay(w) }
|
|
@ -1,19 +0,0 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package evm
|
||||
|
||||
import (
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
)
|
||||
|
||||
// ID this VM should be referenced by
|
||||
var (
|
||||
ID = ids.NewID([32]byte{'e', 'v', 'm'})
|
||||
)
|
||||
|
||||
// Factory ...
|
||||
type Factory struct{}
|
||||
|
||||
// New ...
|
||||
func (f *Factory) New() interface{} { return &VM{} }
|
|
@ -1,122 +0,0 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package evm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/ava-labs/coreth"
|
||||
|
||||
"github.com/ava-labs/go-ethereum/common"
|
||||
"github.com/ava-labs/go-ethereum/common/hexutil"
|
||||
"github.com/ava-labs/go-ethereum/core/types"
|
||||
"github.com/ava-labs/go-ethereum/crypto"
|
||||
)
|
||||
|
||||
const (
|
||||
version = "Athereum 1.0"
|
||||
)
|
||||
|
||||
// test constants
|
||||
const (
|
||||
GenesisTestAddr = "0x751a0b96e1042bee789452ecb20253fba40dbe85"
|
||||
GenesisTestKey = "0xabd71b35d559563fea757f0f5edbde286fb8c043105b15abb7cd57189306d7d1"
|
||||
)
|
||||
|
||||
// DebugAPI introduces helper functions for debuging
|
||||
type DebugAPI struct{ vm *VM }
|
||||
|
||||
// SnowmanAPI introduces snowman specific functionality to the evm
|
||||
type SnowmanAPI struct{ vm *VM }
|
||||
|
||||
// NetAPI offers network related API methods
|
||||
type NetAPI struct{ vm *VM }
|
||||
|
||||
// NewNetAPI creates a new net API instance.
|
||||
func NewNetAPI(vm *VM) *NetAPI { return &NetAPI{vm} }
|
||||
|
||||
// Listening returns an indication if the node is listening for network connections.
|
||||
func (s *NetAPI) Listening() bool { return true } // always listening
|
||||
|
||||
// PeerCount returns the number of connected peers
|
||||
func (s *NetAPI) PeerCount() hexutil.Uint { return hexutil.Uint(0) } // TODO: report number of connected peers
|
||||
|
||||
// Version returns the current ethereum protocol version.
|
||||
func (s *NetAPI) Version() string { return fmt.Sprintf("%d", s.vm.networkID) }
|
||||
|
||||
// Web3API offers helper API methods
|
||||
type Web3API struct{}
|
||||
|
||||
// ClientVersion returns the version of the vm running
|
||||
func (s *Web3API) ClientVersion() string { return version }
|
||||
|
||||
// Sha3 returns the bytes returned by hashing [input] with Keccak256
|
||||
func (s *Web3API) Sha3(input hexutil.Bytes) hexutil.Bytes { return crypto.Keccak256(input) }
|
||||
|
||||
// GetAcceptedFrontReply defines the reply that will be sent from the
|
||||
// GetAcceptedFront API call
|
||||
type GetAcceptedFrontReply struct {
|
||||
Hash common.Hash `json:"hash"`
|
||||
Number *big.Int `json:"number"`
|
||||
}
|
||||
|
||||
// GetAcceptedFront returns the last accepted block's hash and height
|
||||
func (api *SnowmanAPI) GetAcceptedFront(ctx context.Context) (*GetAcceptedFrontReply, error) {
|
||||
blk := api.vm.getLastAccepted().ethBlock
|
||||
return &GetAcceptedFrontReply{
|
||||
Hash: blk.Hash(),
|
||||
Number: blk.Number(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetGenesisBalance returns the current funds in the genesis
|
||||
func (api *DebugAPI) GetGenesisBalance(ctx context.Context) (*hexutil.Big, error) {
|
||||
lastAccepted := api.vm.getLastAccepted()
|
||||
api.vm.ctx.Log.Verbo("Currently accepted block front: %s", lastAccepted.ethBlock.Hash().Hex())
|
||||
state, err := api.vm.chain.BlockState(lastAccepted.ethBlock)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return (*hexutil.Big)(state.GetBalance(common.HexToAddress(GenesisTestAddr))), nil
|
||||
}
|
||||
|
||||
// SpendGenesis funds
|
||||
func (api *DebugAPI) SpendGenesis(ctx context.Context, nonce uint64) error {
|
||||
api.vm.ctx.Log.Info("Spending the genesis")
|
||||
|
||||
value := big.NewInt(1000000000000)
|
||||
gasLimit := 21000
|
||||
gasPrice := big.NewInt(1000000000)
|
||||
|
||||
genPrivateKey, err := crypto.HexToECDSA(GenesisTestKey[2:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bob, err := coreth.NewKey(rand.Reader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tx := types.NewTransaction(nonce, bob.Address, value, uint64(gasLimit), gasPrice, nil)
|
||||
signedTx, err := types.SignTx(tx, types.NewEIP155Signer(api.vm.chainID), genPrivateKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := api.vm.issueRemoteTxs([]*types.Transaction{signedTx}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// IssueBlock to the chain
|
||||
func (api *DebugAPI) IssueBlock(ctx context.Context) error {
|
||||
api.vm.ctx.Log.Info("Issuing a new block")
|
||||
|
||||
return api.vm.tryBlockGen()
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package evm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/ava-labs/coreth/core"
|
||||
"github.com/ava-labs/gecko/utils/formatting"
|
||||
)
|
||||
|
||||
// StaticService defines the static API services exposed by the evm
|
||||
type StaticService struct{}
|
||||
|
||||
// BuildGenesis returns the UTXOs such that at least one address in [args.Addresses] is
|
||||
// referenced in the UTXO.
|
||||
func (*StaticService) BuildGenesis(_ context.Context, args *core.Genesis) (formatting.CB58, error) {
|
||||
bytes, err := json.Marshal(args)
|
||||
return formatting.CB58{Bytes: bytes}, err
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package evm
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/ava-labs/go-ethereum/common"
|
||||
"github.com/ava-labs/go-ethereum/params"
|
||||
|
||||
"github.com/ava-labs/coreth/core"
|
||||
)
|
||||
|
||||
func TestBuildGenesis(t *testing.T) {
|
||||
expected := "3wP629bGfSGj9trh1UNBp5qGRGCcma5d8ezLeSmd9hnUJjSMUJesHHoxbZNcVUC9CjH7PEGNA96htNTd1saZCMt1Mf1dZFG7JDhcYNok6RS4TZufejXdxbVVgquohSa7nCCcrXpiVeiRFwzLJAxyQbXzYRhaCRtcDDfCcqfaVdtkFsPbNeQ49pDTbEC5hVkmfopeQ2Zz8tAG5QXKBdbYBCukR3xNHJ4xDxeixmEwPr1odb42yQRYrL7xREKNn2LFoFwAWUjBTsCkf5GPNgY2GvvN9o8wFWXTroW5fp754DhpdxHYxkMTfuE9DGyNWHTyrEbrUHutUdsfitcSHVj5ctFtkN2wGCs3cyv1eRRNvFFMggWTbarjne6AYaeCrJ631qAu3CbrUtrTH5N2E6G2yQKX4sT4Sk3qWPJdsGXuT95iKKcgNn1u5QRHHw9DXXuGPpJjkcKQRGUCuqpXy61iF5RNPEwAwKDa8f2Y25WMmNgWynUuLj8iSAyePj7USPWk54QFUr86ApVzqAdzzdD1qSVScpmudGnGbz9UNXdzHqSot6XLrNTYsgkabiu6TGntFm7qywbCRmtNdBuT9aznGQdUVimjt5QzUz68HXhUxBzTkrz7yXfVGV5JcWxVHQXYS4oc41U5yu83mH3A7WBrZLVq6UyNrvQVbim5nDxeKKbALPxwzVwywjgY5cp39AvzGnY8CX2AtuBNnKmZaAvG8JWAkx3yxjnJrwWhLgpDQYcCvRp2jg1EPBqN8FKJxSPE6eedjDHDJfB57mNzyEtmg22BPnem3eLdiovX8awkhBUHdE7uPrapNSVprnS85u1saW2Kwza3FsS2jAM3LckGW8KdtfPTpHBTRKAUo49zZLuPsyGL5WduedGyAdaM3a2KPoyXuz4UbexTVUWFNypFvvgyoDS8FMxDCNoMMaD7y4yVnoDpSpVFEVZD6EuSGHe9U8Ew57xLPbjhepDx6"
|
||||
|
||||
balance, success := new(big.Int).SetString("33b2e3c9fd0804000000000", 16)
|
||||
if !success {
|
||||
t.Fatal("Failed to initialize balance")
|
||||
}
|
||||
|
||||
args := core.Genesis{
|
||||
Config: ¶ms.ChainConfig{
|
||||
ChainID: big.NewInt(43110),
|
||||
HomesteadBlock: big.NewInt(0),
|
||||
DAOForkBlock: big.NewInt(0),
|
||||
DAOForkSupport: true,
|
||||
EIP150Block: big.NewInt(0),
|
||||
EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"),
|
||||
EIP155Block: big.NewInt(0),
|
||||
EIP158Block: big.NewInt(0),
|
||||
ByzantiumBlock: big.NewInt(0),
|
||||
ConstantinopleBlock: big.NewInt(0),
|
||||
PetersburgBlock: big.NewInt(0),
|
||||
},
|
||||
Nonce: 0,
|
||||
Timestamp: 0,
|
||||
ExtraData: []byte{},
|
||||
GasLimit: 100000000,
|
||||
Difficulty: big.NewInt(0),
|
||||
Mixhash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
Coinbase: common.HexToAddress("0x0000000000000000000000000000000000000000"),
|
||||
Alloc: core.GenesisAlloc{
|
||||
common.HexToAddress("751a0b96e1042bee789452ecb20253fba40dbe85"): core.GenesisAccount{
|
||||
Balance: balance,
|
||||
},
|
||||
},
|
||||
Number: 0,
|
||||
GasUsed: 0,
|
||||
ParentHash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
}
|
||||
|
||||
ss := StaticService{}
|
||||
result, err := ss.BuildGenesis(nil, &args)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if result.String() != expected {
|
||||
t.Fatalf("StaticService.BuildGenesis:\nReturned: %s\nExpected: %s", result, expected)
|
||||
}
|
||||
}
|
498
vms/evm/vm.go
498
vms/evm/vm.go
|
@ -1,498 +0,0 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package evm
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/ava-labs/coreth"
|
||||
"github.com/ava-labs/coreth/core"
|
||||
"github.com/ava-labs/coreth/eth"
|
||||
"github.com/ava-labs/coreth/node"
|
||||
|
||||
"github.com/ava-labs/go-ethereum/common"
|
||||
"github.com/ava-labs/go-ethereum/core/types"
|
||||
"github.com/ava-labs/go-ethereum/rlp"
|
||||
"github.com/ava-labs/go-ethereum/rpc"
|
||||
|
||||
"github.com/ava-labs/gecko/cache"
|
||||
"github.com/ava-labs/gecko/database"
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/snow"
|
||||
"github.com/ava-labs/gecko/snow/choices"
|
||||
"github.com/ava-labs/gecko/snow/consensus/snowman"
|
||||
"github.com/ava-labs/gecko/utils/timer"
|
||||
|
||||
commonEng "github.com/ava-labs/gecko/snow/engine/common"
|
||||
)
|
||||
|
||||
const (
|
||||
lastAcceptedKey = "snowman_lastAccepted"
|
||||
)
|
||||
|
||||
const (
|
||||
minBlockTime = 250 * time.Millisecond
|
||||
maxBlockTime = 1000 * time.Millisecond
|
||||
batchSize = 250
|
||||
)
|
||||
|
||||
const (
|
||||
bdTimerStateMin = iota
|
||||
bdTimerStateMax
|
||||
bdTimerStateLong
|
||||
)
|
||||
|
||||
var (
|
||||
errEmptyBlock = errors.New("empty block")
|
||||
errCreateBlock = errors.New("couldn't create block")
|
||||
errUnknownBlock = errors.New("unknown block")
|
||||
errBlockFrequency = errors.New("too frequent block issuance")
|
||||
errUnsupportedFXs = errors.New("unsupported feature extensions")
|
||||
)
|
||||
|
||||
func maxDuration(x, y time.Duration) time.Duration {
|
||||
if x > y {
|
||||
return x
|
||||
}
|
||||
return y
|
||||
}
|
||||
|
||||
// VM implements the snowman.ChainVM interface
|
||||
type VM struct {
|
||||
ctx *snow.Context
|
||||
|
||||
chainID *big.Int
|
||||
networkID uint64
|
||||
chain *coreth.ETHChain
|
||||
chaindb Database
|
||||
newBlockChan chan *Block
|
||||
networkChan chan<- commonEng.Message
|
||||
newTxPoolHeadChan chan core.NewTxPoolHeadEvent
|
||||
|
||||
txPoolStabilizedHead common.Hash
|
||||
txPoolStabilizedOk chan struct{}
|
||||
txPoolStabilizedLock sync.Mutex
|
||||
|
||||
metalock sync.Mutex
|
||||
blockCache, blockStatusCache cache.LRU
|
||||
lastAccepted *Block
|
||||
writingMetadata uint32
|
||||
|
||||
bdlock sync.Mutex
|
||||
blockDelayTimer *timer.Timer
|
||||
bdTimerState int8
|
||||
bdGenWaitFlag bool
|
||||
bdGenFlag bool
|
||||
|
||||
genlock sync.Mutex
|
||||
txSubmitChan <-chan struct{}
|
||||
}
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
********************************* Snowman API ********************************
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
// Initialize implements the snowman.ChainVM interface
|
||||
func (vm *VM) Initialize(
|
||||
ctx *snow.Context,
|
||||
db database.Database,
|
||||
b []byte,
|
||||
toEngine chan<- commonEng.Message,
|
||||
fxs []*commonEng.Fx,
|
||||
) error {
|
||||
if len(fxs) > 0 {
|
||||
return errUnsupportedFXs
|
||||
}
|
||||
|
||||
vm.ctx = ctx
|
||||
vm.chaindb = Database{db}
|
||||
g := new(core.Genesis)
|
||||
err := json.Unmarshal(b, g)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
vm.chainID = g.Config.ChainID
|
||||
|
||||
config := eth.DefaultConfig
|
||||
config.ManualCanonical = true
|
||||
config.Genesis = g
|
||||
config.Miner.ManualMining = true
|
||||
config.Miner.DisableUncle = true
|
||||
if err := config.SetGCMode("archive"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
nodecfg := node.Config{NoUSB: true}
|
||||
chain := coreth.NewETHChain(&config, &nodecfg, nil, vm.chaindb)
|
||||
vm.chain = chain
|
||||
vm.networkID = config.NetworkId
|
||||
chain.SetOnHeaderNew(func(header *types.Header) {
|
||||
hid := make([]byte, 32)
|
||||
_, err := rand.Read(hid)
|
||||
if err != nil {
|
||||
panic("cannot generate hid")
|
||||
}
|
||||
header.Extra = append(header.Extra, hid...)
|
||||
})
|
||||
chain.SetOnSeal(func(block *types.Block) error {
|
||||
if len(block.Transactions()) == 0 {
|
||||
// this could happen due to the async logic of geth tx pool
|
||||
vm.newBlockChan <- nil
|
||||
return errEmptyBlock
|
||||
}
|
||||
return nil
|
||||
})
|
||||
chain.SetOnSealFinish(func(block *types.Block) error {
|
||||
vm.ctx.Log.Verbo("EVM sealed a block")
|
||||
|
||||
blk := &Block{
|
||||
id: ids.NewID(block.Hash()),
|
||||
ethBlock: block,
|
||||
vm: vm,
|
||||
}
|
||||
vm.newBlockChan <- blk
|
||||
vm.updateStatus(ids.NewID(block.Hash()), choices.Processing)
|
||||
vm.txPoolStabilizedLock.Lock()
|
||||
vm.txPoolStabilizedHead = block.Hash()
|
||||
vm.txPoolStabilizedLock.Unlock()
|
||||
return nil
|
||||
})
|
||||
chain.SetOnQueryAcceptedBlock(func() *types.Block {
|
||||
return vm.getLastAccepted().ethBlock
|
||||
})
|
||||
vm.blockCache = cache.LRU{Size: 2048}
|
||||
vm.blockStatusCache = cache.LRU{Size: 1024}
|
||||
vm.newBlockChan = make(chan *Block)
|
||||
vm.networkChan = toEngine
|
||||
vm.blockDelayTimer = timer.NewTimer(func() {
|
||||
vm.bdlock.Lock()
|
||||
switch vm.bdTimerState {
|
||||
case bdTimerStateMin:
|
||||
vm.bdTimerState = bdTimerStateMax
|
||||
vm.blockDelayTimer.SetTimeoutIn(maxDuration(maxBlockTime-minBlockTime, 0))
|
||||
case bdTimerStateMax:
|
||||
vm.bdTimerState = bdTimerStateLong
|
||||
}
|
||||
tryAgain := vm.bdGenWaitFlag
|
||||
vm.bdlock.Unlock()
|
||||
if tryAgain {
|
||||
vm.tryBlockGen()
|
||||
}
|
||||
})
|
||||
go ctx.Log.RecoverAndPanic(vm.blockDelayTimer.Dispatch)
|
||||
|
||||
vm.bdTimerState = bdTimerStateLong
|
||||
vm.bdGenWaitFlag = true
|
||||
vm.newTxPoolHeadChan = make(chan core.NewTxPoolHeadEvent, 1)
|
||||
vm.txPoolStabilizedOk = make(chan struct{}, 1)
|
||||
chain.GetTxPool().SubscribeNewHeadEvent(vm.newTxPoolHeadChan)
|
||||
// TODO: shutdown this go routine
|
||||
go ctx.Log.RecoverAndPanic(func() {
|
||||
for {
|
||||
select {
|
||||
case h := <-vm.newTxPoolHeadChan:
|
||||
vm.txPoolStabilizedLock.Lock()
|
||||
if vm.txPoolStabilizedHead == h.Block.Hash() {
|
||||
vm.txPoolStabilizedOk <- struct{}{}
|
||||
vm.txPoolStabilizedHead = common.Hash{}
|
||||
}
|
||||
vm.txPoolStabilizedLock.Unlock()
|
||||
}
|
||||
}
|
||||
})
|
||||
chain.Start()
|
||||
|
||||
var lastAccepted *types.Block
|
||||
if b, err := vm.chaindb.Get([]byte(lastAcceptedKey)); err == nil {
|
||||
var hash common.Hash
|
||||
if err = rlp.DecodeBytes(b, &hash); err == nil {
|
||||
if block := chain.GetBlockByHash(hash); block == nil {
|
||||
vm.ctx.Log.Debug("lastAccepted block not found in chaindb")
|
||||
} else {
|
||||
lastAccepted = block
|
||||
}
|
||||
}
|
||||
}
|
||||
if lastAccepted == nil {
|
||||
vm.ctx.Log.Debug("lastAccepted is unavailable, setting to the genesis block")
|
||||
lastAccepted = chain.GetGenesisBlock()
|
||||
}
|
||||
vm.lastAccepted = &Block{
|
||||
id: ids.NewID(lastAccepted.Hash()),
|
||||
ethBlock: lastAccepted,
|
||||
vm: vm,
|
||||
}
|
||||
vm.ctx.Log.Info(fmt.Sprintf("lastAccepted = %s", vm.lastAccepted.ethBlock.Hash().Hex()))
|
||||
|
||||
// TODO: shutdown this go routine
|
||||
go vm.ctx.Log.RecoverAndPanic(func() {
|
||||
vm.txSubmitChan = vm.chain.GetTxSubmitCh()
|
||||
for {
|
||||
select {
|
||||
case <-vm.txSubmitChan:
|
||||
vm.ctx.Log.Verbo("New tx detected, trying to generate a block")
|
||||
vm.tryBlockGen()
|
||||
case <-time.After(5 * time.Second):
|
||||
vm.tryBlockGen()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Shutdown implements the snowman.ChainVM interface
|
||||
func (vm *VM) Shutdown() {
|
||||
vm.writeBackMetadata()
|
||||
vm.chain.Stop()
|
||||
}
|
||||
|
||||
// BuildBlock implements the snowman.ChainVM interface
|
||||
func (vm *VM) BuildBlock() (snowman.Block, error) {
|
||||
vm.chain.GenBlock()
|
||||
block := <-vm.newBlockChan
|
||||
if block == nil {
|
||||
return nil, errCreateBlock
|
||||
}
|
||||
// reset the min block time timer
|
||||
vm.bdlock.Lock()
|
||||
vm.bdTimerState = bdTimerStateMin
|
||||
vm.bdGenWaitFlag = false
|
||||
vm.bdGenFlag = false
|
||||
vm.blockDelayTimer.SetTimeoutIn(minBlockTime)
|
||||
vm.bdlock.Unlock()
|
||||
|
||||
vm.ctx.Log.Debug("built block 0x%x", block.ID().Bytes())
|
||||
// make sure Tx Pool is updated
|
||||
<-vm.txPoolStabilizedOk
|
||||
return block, nil
|
||||
}
|
||||
|
||||
// ParseBlock implements the snowman.ChainVM interface
|
||||
func (vm *VM) ParseBlock(b []byte) (snowman.Block, error) {
|
||||
vm.metalock.Lock()
|
||||
defer vm.metalock.Unlock()
|
||||
|
||||
ethBlock := new(types.Block)
|
||||
if err := rlp.DecodeBytes(b, ethBlock); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
block := &Block{
|
||||
id: ids.NewID(ethBlock.Hash()),
|
||||
ethBlock: ethBlock,
|
||||
vm: vm,
|
||||
}
|
||||
vm.blockCache.Put(block.ID(), block)
|
||||
return block, nil
|
||||
}
|
||||
|
||||
// GetBlock implements the snowman.ChainVM interface
|
||||
func (vm *VM) GetBlock(id ids.ID) (snowman.Block, error) {
|
||||
vm.metalock.Lock()
|
||||
defer vm.metalock.Unlock()
|
||||
|
||||
block := vm.getBlock(id)
|
||||
if block == nil {
|
||||
return nil, errUnknownBlock
|
||||
}
|
||||
return block, nil
|
||||
}
|
||||
|
||||
// SetPreference sets what the current tail of the chain is
|
||||
func (vm *VM) SetPreference(blkID ids.ID) {
|
||||
err := vm.chain.SetTail(blkID.Key())
|
||||
vm.ctx.Log.AssertNoError(err)
|
||||
}
|
||||
|
||||
// LastAccepted returns the ID of the block that was last accepted
|
||||
func (vm *VM) LastAccepted() ids.ID {
|
||||
vm.metalock.Lock()
|
||||
defer vm.metalock.Unlock()
|
||||
|
||||
return vm.lastAccepted.ID()
|
||||
}
|
||||
|
||||
// CreateHandlers makes new http handlers that can handle API calls
|
||||
func (vm *VM) CreateHandlers() map[string]*commonEng.HTTPHandler {
|
||||
handler := vm.chain.NewRPCHandler()
|
||||
vm.chain.AttachEthService(handler, []string{"eth", "personal", "txpool"})
|
||||
handler.RegisterName("net", &NetAPI{vm})
|
||||
handler.RegisterName("snowman", &SnowmanAPI{vm})
|
||||
handler.RegisterName("web3", &Web3API{})
|
||||
handler.RegisterName("debug", &DebugAPI{vm})
|
||||
|
||||
return map[string]*commonEng.HTTPHandler{
|
||||
"/rpc": &commonEng.HTTPHandler{LockOptions: commonEng.NoLock, Handler: handler},
|
||||
"/ws": &commonEng.HTTPHandler{LockOptions: commonEng.NoLock, Handler: handler.WebsocketHandler([]string{"*"})},
|
||||
}
|
||||
}
|
||||
|
||||
// CreateStaticHandlers makes new http handlers that can handle API calls
|
||||
func (vm *VM) CreateStaticHandlers() map[string]*commonEng.HTTPHandler {
|
||||
handler := rpc.NewServer()
|
||||
handler.RegisterName("static", &StaticService{})
|
||||
return map[string]*commonEng.HTTPHandler{
|
||||
"/rpc": &commonEng.HTTPHandler{LockOptions: commonEng.NoLock, Handler: handler},
|
||||
"/ws": &commonEng.HTTPHandler{LockOptions: commonEng.NoLock, Handler: handler.WebsocketHandler([]string{"*"})},
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
*********************************** Helpers **********************************
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
func (vm *VM) updateStatus(blockID ids.ID, status choices.Status) {
|
||||
vm.metalock.Lock()
|
||||
defer vm.metalock.Unlock()
|
||||
|
||||
if status == choices.Accepted {
|
||||
vm.lastAccepted = vm.getBlock(blockID)
|
||||
// TODO: improve this naive implementation
|
||||
if atomic.SwapUint32(&vm.writingMetadata, 1) == 0 {
|
||||
go vm.ctx.Log.RecoverAndPanic(vm.writeBackMetadata)
|
||||
}
|
||||
}
|
||||
vm.blockStatusCache.Put(blockID, status)
|
||||
}
|
||||
|
||||
func (vm *VM) getCachedBlock(blockID ids.ID) *types.Block {
|
||||
return vm.chain.GetBlockByHash(blockID.Key())
|
||||
}
|
||||
|
||||
func (vm *VM) tryBlockGen() error {
|
||||
vm.bdlock.Lock()
|
||||
defer vm.bdlock.Unlock()
|
||||
if vm.bdGenFlag {
|
||||
// skip if one call already generates a block in this round
|
||||
return nil
|
||||
}
|
||||
vm.bdGenWaitFlag = true
|
||||
|
||||
vm.genlock.Lock()
|
||||
defer vm.genlock.Unlock()
|
||||
// get pending size
|
||||
size, err := vm.chain.PendingSize()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if size == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch vm.bdTimerState {
|
||||
case bdTimerStateMin:
|
||||
return nil
|
||||
case bdTimerStateMax:
|
||||
if size < batchSize {
|
||||
return nil
|
||||
}
|
||||
case bdTimerStateLong:
|
||||
// timeout; go ahead and generate a new block anyway
|
||||
}
|
||||
select {
|
||||
case vm.networkChan <- commonEng.PendingTxs:
|
||||
// successfully push out the notification; this round ends
|
||||
vm.bdGenFlag = true
|
||||
default:
|
||||
return errBlockFrequency
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (vm *VM) getCachedStatus(blockID ids.ID) choices.Status {
|
||||
vm.metalock.Lock()
|
||||
defer vm.metalock.Unlock()
|
||||
status := choices.Processing
|
||||
|
||||
if statusIntf, ok := vm.blockStatusCache.Get(blockID); ok {
|
||||
status = statusIntf.(choices.Status)
|
||||
} else {
|
||||
blk := vm.chain.GetBlockByHash(blockID.Key())
|
||||
if blk == nil {
|
||||
return choices.Unknown
|
||||
}
|
||||
acceptedBlk := vm.lastAccepted.ethBlock
|
||||
|
||||
// TODO: There must be a better way of doing this.
|
||||
// Traverse up the chain from the lower block until the indices match
|
||||
highBlock := blk
|
||||
lowBlock := acceptedBlk
|
||||
if highBlock.Number().Cmp(lowBlock.Number()) < 0 {
|
||||
highBlock, lowBlock = lowBlock, highBlock
|
||||
}
|
||||
for highBlock.Number().Cmp(lowBlock.Number()) > 0 {
|
||||
highBlock = vm.chain.GetBlockByHash(highBlock.ParentHash())
|
||||
}
|
||||
|
||||
if highBlock.Hash() == lowBlock.Hash() { // on the same branch
|
||||
if blk.Number().Cmp(acceptedBlk.Number()) <= 0 {
|
||||
status = choices.Accepted
|
||||
}
|
||||
} else { // on different branches
|
||||
status = choices.Rejected
|
||||
}
|
||||
}
|
||||
|
||||
vm.blockStatusCache.Put(blockID, status)
|
||||
return status
|
||||
}
|
||||
|
||||
func (vm *VM) getBlock(id ids.ID) *Block {
|
||||
if blockIntf, ok := vm.blockCache.Get(id); ok {
|
||||
return blockIntf.(*Block)
|
||||
}
|
||||
ethBlock := vm.getCachedBlock(id)
|
||||
if ethBlock == nil {
|
||||
return nil
|
||||
}
|
||||
block := &Block{
|
||||
id: ids.NewID(ethBlock.Hash()),
|
||||
ethBlock: ethBlock,
|
||||
vm: vm,
|
||||
}
|
||||
vm.blockCache.Put(id, block)
|
||||
return block
|
||||
}
|
||||
|
||||
func (vm *VM) issueRemoteTxs(txs []*types.Transaction) error {
|
||||
errs := vm.chain.AddRemoteTxs(txs)
|
||||
for _, err := range errs {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return vm.tryBlockGen()
|
||||
}
|
||||
|
||||
func (vm *VM) writeBackMetadata() {
|
||||
vm.metalock.Lock()
|
||||
defer vm.metalock.Unlock()
|
||||
|
||||
b, err := rlp.EncodeToBytes(vm.lastAccepted.ethBlock.Hash())
|
||||
if err != nil {
|
||||
vm.ctx.Log.Error("snowman-eth: error while writing back metadata")
|
||||
return
|
||||
}
|
||||
vm.ctx.Log.Debug("writing back metadata")
|
||||
vm.chaindb.Put([]byte(lastAcceptedKey), b)
|
||||
atomic.StoreUint32(&vm.writingMetadata, 0)
|
||||
}
|
||||
|
||||
func (vm *VM) getLastAccepted() *Block {
|
||||
vm.metalock.Lock()
|
||||
defer vm.metalock.Unlock()
|
||||
|
||||
return vm.lastAccepted
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package evm
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/ava-labs/coreth/core"
|
||||
)
|
||||
|
||||
func TestParseGenesis(t *testing.T) {
|
||||
genesis := []byte(`{"config":{"chainId":43110,"homesteadBlock":0,"daoForkBlock":0,"daoForkSupport":true,"eip150Block":0,"eip150Hash":"0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0","eip155Block":0,"eip158Block":0,"byzantiumBlock":0,"constantinopleBlock":0,"petersburgBlock":0},"nonce":"0x0","timestamp":"0x0","extraData":"0x00","gasLimit":"0x5f5e100","difficulty":"0x0","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","coinbase":"0x0000000000000000000000000000000000000000","alloc":{"751a0b96e1042bee789452ecb20253fba40dbe85":{"balance":"0x33b2e3c9fd0804000000000"}},"number":"0x0","gasUsed":"0x0","parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000"}`)
|
||||
|
||||
genesisBlock := new(core.Genesis)
|
||||
err := json.Unmarshal(genesis, genesisBlock)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
marshalledBytes, err := json.Marshal(genesisBlock)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
secondGenesisBlock := new(core.Genesis)
|
||||
err = json.Unmarshal(marshalledBytes, secondGenesisBlock)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
|
@ -16,7 +16,7 @@ import (
|
|||
|
||||
// A VMFactory creates new instances of a VM
|
||||
type VMFactory interface {
|
||||
New() interface{}
|
||||
New() (interface{}, error)
|
||||
}
|
||||
|
||||
// Manager is a VM manager.
|
||||
|
@ -110,10 +110,17 @@ func (m *manager) addStaticAPIEndpoints(vmID ids.ID) {
|
|||
vmFactory, err := m.GetVMFactory(vmID)
|
||||
m.log.AssertNoError(err)
|
||||
m.log.Debug("adding static API for VM with ID %s", vmID)
|
||||
vm := vmFactory.New()
|
||||
vm, err := vmFactory.New()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
staticVM, ok := vm.(common.StaticVM)
|
||||
if !ok {
|
||||
staticVM, ok := vm.(common.VM)
|
||||
if ok {
|
||||
staticVM.Shutdown()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -13,4 +13,4 @@ var (
|
|||
type Factory struct{}
|
||||
|
||||
// New ...
|
||||
func (f *Factory) New() interface{} { return &Fx{} }
|
||||
func (f *Factory) New() (interface{}, error) { return &Fx{}, nil }
|
||||
|
|
|
@ -6,7 +6,9 @@ import (
|
|||
|
||||
func TestFactory(t *testing.T) {
|
||||
factory := Factory{}
|
||||
if fx := factory.New(); fx == nil {
|
||||
if fx, err := factory.New(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if fx == nil {
|
||||
t.Fatalf("Factory.New returned nil")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,12 +24,12 @@ type Factory struct {
|
|||
}
|
||||
|
||||
// New returns a new instance of the Platform Chain
|
||||
func (f *Factory) New() interface{} {
|
||||
func (f *Factory) New() (interface{}, error) {
|
||||
return &VM{
|
||||
chainManager: f.ChainManager,
|
||||
validators: f.Validators,
|
||||
stakingEnabled: f.StakingEnabled,
|
||||
ava: f.AVA,
|
||||
avm: f.AVM,
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -382,6 +382,10 @@ func (vm *VM) createChain(tx *CreateChainTx) {
|
|||
|
||||
// Shutdown this blockchain
|
||||
func (vm *VM) Shutdown() {
|
||||
if vm.timer == nil {
|
||||
return
|
||||
}
|
||||
|
||||
vm.timer.Stop()
|
||||
if err := vm.DB.Close(); err != nil {
|
||||
vm.Ctx.Log.Error("Closing the database failed with %s", err)
|
||||
|
|
|
@ -13,4 +13,4 @@ var (
|
|||
type Factory struct{}
|
||||
|
||||
// New ...
|
||||
func (f *Factory) New() interface{} { return &Fx{} }
|
||||
func (f *Factory) New() (interface{}, error) { return &Fx{}, nil }
|
||||
|
|
|
@ -6,7 +6,9 @@ import (
|
|||
|
||||
func TestFactory(t *testing.T) {
|
||||
factory := Factory{}
|
||||
if fx := factory.New(); fx == nil {
|
||||
if fx, err := factory.New(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if fx == nil {
|
||||
t.Fatalf("Factory.New returned nil")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package rpcchainvm
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os/exec"
|
||||
|
||||
"github.com/hashicorp/go-plugin"
|
||||
)
|
||||
|
||||
var (
|
||||
errWrongVM = errors.New("wrong vm type")
|
||||
)
|
||||
|
||||
// Factory ...
|
||||
type Factory struct {
|
||||
Path string
|
||||
}
|
||||
|
||||
// New ...
|
||||
func (f *Factory) New() (interface{}, error) {
|
||||
client := plugin.NewClient(&plugin.ClientConfig{
|
||||
HandshakeConfig: Handshake,
|
||||
Plugins: PluginMap,
|
||||
Cmd: exec.Command("sh", "-c", f.Path),
|
||||
AllowedProtocols: []plugin.Protocol{
|
||||
plugin.ProtocolNetRPC,
|
||||
plugin.ProtocolGRPC,
|
||||
},
|
||||
})
|
||||
|
||||
rpcClient, err := client.Client()
|
||||
if err != nil {
|
||||
client.Kill()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
raw, err := rpcClient.Dispense("vm")
|
||||
if err != nil {
|
||||
client.Kill()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vm, ok := raw.(*VMClient)
|
||||
if !ok {
|
||||
client.Kill()
|
||||
return nil, errWrongVM
|
||||
}
|
||||
|
||||
vm.SetProcess(client)
|
||||
return vm, nil
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package gconn
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/ava-labs/gecko/utils/wrappers"
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/gconn/proto"
|
||||
)
|
||||
|
||||
// Client is an implementation of a messenger channel that talks over RPC.
|
||||
type Client struct {
|
||||
client proto.ConnClient
|
||||
local net.Addr
|
||||
remote net.Addr
|
||||
toClose []io.Closer
|
||||
}
|
||||
|
||||
// NewClient returns a database instance connected to a remote database instance
|
||||
func NewClient(client proto.ConnClient, local, remote net.Addr, toClose ...io.Closer) *Client {
|
||||
return &Client{
|
||||
client: client,
|
||||
local: local,
|
||||
remote: remote,
|
||||
toClose: toClose,
|
||||
}
|
||||
}
|
||||
|
||||
// Read ...
|
||||
func (c *Client) Read(p []byte) (int, error) {
|
||||
resp, err := c.client.Read(context.Background(), &proto.ReadRequest{
|
||||
Length: int32(len(p)),
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
copy(p, resp.Read)
|
||||
|
||||
if resp.Errored {
|
||||
err = errors.New(resp.Error)
|
||||
}
|
||||
return len(resp.Read), err
|
||||
}
|
||||
|
||||
// Write ...
|
||||
func (c *Client) Write(b []byte) (int, error) {
|
||||
resp, err := c.client.Write(context.Background(), &proto.WriteRequest{
|
||||
Payload: b,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if resp.Errored {
|
||||
err = errors.New(resp.Error)
|
||||
}
|
||||
return int(resp.Length), err
|
||||
}
|
||||
|
||||
// Close ...
|
||||
func (c *Client) Close() error {
|
||||
_, err := c.client.Close(context.Background(), &proto.CloseRequest{})
|
||||
errs := wrappers.Errs{}
|
||||
errs.Add(err)
|
||||
for _, toClose := range c.toClose {
|
||||
errs.Add(toClose.Close())
|
||||
}
|
||||
return errs.Err
|
||||
}
|
||||
|
||||
// LocalAddr ...
|
||||
func (c *Client) LocalAddr() net.Addr { return c.local }
|
||||
|
||||
// RemoteAddr ...
|
||||
func (c *Client) RemoteAddr() net.Addr { return c.remote }
|
||||
|
||||
// SetDeadline ...
|
||||
func (c *Client) SetDeadline(t time.Time) error {
|
||||
bytes, err := t.MarshalBinary()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = c.client.SetDeadline(context.Background(), &proto.SetDeadlineRequest{
|
||||
Time: bytes,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// SetReadDeadline ...
|
||||
func (c *Client) SetReadDeadline(t time.Time) error {
|
||||
bytes, err := t.MarshalBinary()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = c.client.SetReadDeadline(context.Background(), &proto.SetReadDeadlineRequest{
|
||||
Time: bytes,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// SetWriteDeadline ...
|
||||
func (c *Client) SetWriteDeadline(t time.Time) error {
|
||||
bytes, err := t.MarshalBinary()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = c.client.SetWriteDeadline(context.Background(), &proto.SetWriteDeadlineRequest{
|
||||
Time: bytes,
|
||||
})
|
||||
return err
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package gconn
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/gconn/proto"
|
||||
)
|
||||
|
||||
// Server is a http.Handler that is managed over RPC.
|
||||
type Server struct{ conn net.Conn }
|
||||
|
||||
// NewServer returns a http.Handler instance manage remotely
|
||||
func NewServer(conn net.Conn) *Server {
|
||||
return &Server{conn: conn}
|
||||
}
|
||||
|
||||
// Read ...
|
||||
func (s *Server) Read(ctx context.Context, req *proto.ReadRequest) (*proto.ReadResponse, error) {
|
||||
buf := make([]byte, int(req.Length))
|
||||
n, err := s.conn.Read(buf)
|
||||
resp := &proto.ReadResponse{
|
||||
Read: buf[:n],
|
||||
}
|
||||
if err != nil {
|
||||
resp.Errored = true
|
||||
resp.Error = err.Error()
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Write ...
|
||||
func (s *Server) Write(ctx context.Context, req *proto.WriteRequest) (*proto.WriteResponse, error) {
|
||||
n, err := s.conn.Write(req.Payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &proto.WriteResponse{
|
||||
Length: int32(n),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Close ...
|
||||
func (s *Server) Close(ctx context.Context, req *proto.CloseRequest) (*proto.CloseResponse, error) {
|
||||
return &proto.CloseResponse{}, s.conn.Close()
|
||||
}
|
||||
|
||||
// SetDeadline ...
|
||||
func (s *Server) SetDeadline(ctx context.Context, req *proto.SetDeadlineRequest) (*proto.SetDeadlineResponse, error) {
|
||||
deadline := time.Time{}
|
||||
err := deadline.UnmarshalBinary(req.Time)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &proto.SetDeadlineResponse{}, s.conn.SetDeadline(deadline)
|
||||
}
|
||||
|
||||
// SetReadDeadline ...
|
||||
func (s *Server) SetReadDeadline(ctx context.Context, req *proto.SetReadDeadlineRequest) (*proto.SetReadDeadlineResponse, error) {
|
||||
deadline := time.Time{}
|
||||
err := deadline.UnmarshalBinary(req.Time)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &proto.SetReadDeadlineResponse{}, s.conn.SetReadDeadline(deadline)
|
||||
}
|
||||
|
||||
// SetWriteDeadline ...
|
||||
func (s *Server) SetWriteDeadline(ctx context.Context, req *proto.SetWriteDeadlineRequest) (*proto.SetWriteDeadlineResponse, error) {
|
||||
deadline := time.Time{}
|
||||
err := deadline.UnmarshalBinary(req.Time)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &proto.SetWriteDeadlineResponse{}, s.conn.SetWriteDeadline(deadline)
|
||||
}
|
|
@ -0,0 +1,788 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: conn.proto
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
type ReadRequest struct {
|
||||
Length int32 `protobuf:"varint,1,opt,name=length,proto3" json:"length,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ReadRequest) Reset() { *m = ReadRequest{} }
|
||||
func (m *ReadRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ReadRequest) ProtoMessage() {}
|
||||
func (*ReadRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f401a58c1fc7ceef, []int{0}
|
||||
}
|
||||
|
||||
func (m *ReadRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ReadRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ReadRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ReadRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ReadRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ReadRequest.Merge(m, src)
|
||||
}
|
||||
func (m *ReadRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_ReadRequest.Size(m)
|
||||
}
|
||||
func (m *ReadRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ReadRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ReadRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *ReadRequest) GetLength() int32 {
|
||||
if m != nil {
|
||||
return m.Length
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type ReadResponse struct {
|
||||
Read []byte `protobuf:"bytes,1,opt,name=read,proto3" json:"read,omitempty"`
|
||||
Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"`
|
||||
Errored bool `protobuf:"varint,3,opt,name=errored,proto3" json:"errored,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ReadResponse) Reset() { *m = ReadResponse{} }
|
||||
func (m *ReadResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ReadResponse) ProtoMessage() {}
|
||||
func (*ReadResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f401a58c1fc7ceef, []int{1}
|
||||
}
|
||||
|
||||
func (m *ReadResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ReadResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ReadResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ReadResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ReadResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ReadResponse.Merge(m, src)
|
||||
}
|
||||
func (m *ReadResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_ReadResponse.Size(m)
|
||||
}
|
||||
func (m *ReadResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ReadResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ReadResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *ReadResponse) GetRead() []byte {
|
||||
if m != nil {
|
||||
return m.Read
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ReadResponse) GetError() string {
|
||||
if m != nil {
|
||||
return m.Error
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *ReadResponse) GetErrored() bool {
|
||||
if m != nil {
|
||||
return m.Errored
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type WriteRequest struct {
|
||||
Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *WriteRequest) Reset() { *m = WriteRequest{} }
|
||||
func (m *WriteRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*WriteRequest) ProtoMessage() {}
|
||||
func (*WriteRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f401a58c1fc7ceef, []int{2}
|
||||
}
|
||||
|
||||
func (m *WriteRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_WriteRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *WriteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_WriteRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *WriteRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_WriteRequest.Merge(m, src)
|
||||
}
|
||||
func (m *WriteRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_WriteRequest.Size(m)
|
||||
}
|
||||
func (m *WriteRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_WriteRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_WriteRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *WriteRequest) GetPayload() []byte {
|
||||
if m != nil {
|
||||
return m.Payload
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type WriteResponse struct {
|
||||
Length int32 `protobuf:"varint,1,opt,name=length,proto3" json:"length,omitempty"`
|
||||
Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"`
|
||||
Errored bool `protobuf:"varint,3,opt,name=errored,proto3" json:"errored,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *WriteResponse) Reset() { *m = WriteResponse{} }
|
||||
func (m *WriteResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*WriteResponse) ProtoMessage() {}
|
||||
func (*WriteResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f401a58c1fc7ceef, []int{3}
|
||||
}
|
||||
|
||||
func (m *WriteResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_WriteResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *WriteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_WriteResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *WriteResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_WriteResponse.Merge(m, src)
|
||||
}
|
||||
func (m *WriteResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_WriteResponse.Size(m)
|
||||
}
|
||||
func (m *WriteResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_WriteResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_WriteResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *WriteResponse) GetLength() int32 {
|
||||
if m != nil {
|
||||
return m.Length
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *WriteResponse) GetError() string {
|
||||
if m != nil {
|
||||
return m.Error
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *WriteResponse) GetErrored() bool {
|
||||
if m != nil {
|
||||
return m.Errored
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type CloseRequest struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *CloseRequest) Reset() { *m = CloseRequest{} }
|
||||
func (m *CloseRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*CloseRequest) ProtoMessage() {}
|
||||
func (*CloseRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f401a58c1fc7ceef, []int{4}
|
||||
}
|
||||
|
||||
func (m *CloseRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_CloseRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *CloseRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_CloseRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *CloseRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_CloseRequest.Merge(m, src)
|
||||
}
|
||||
func (m *CloseRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_CloseRequest.Size(m)
|
||||
}
|
||||
func (m *CloseRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_CloseRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_CloseRequest proto.InternalMessageInfo
|
||||
|
||||
type CloseResponse struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *CloseResponse) Reset() { *m = CloseResponse{} }
|
||||
func (m *CloseResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*CloseResponse) ProtoMessage() {}
|
||||
func (*CloseResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f401a58c1fc7ceef, []int{5}
|
||||
}
|
||||
|
||||
func (m *CloseResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_CloseResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *CloseResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_CloseResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *CloseResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_CloseResponse.Merge(m, src)
|
||||
}
|
||||
func (m *CloseResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_CloseResponse.Size(m)
|
||||
}
|
||||
func (m *CloseResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_CloseResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_CloseResponse proto.InternalMessageInfo
|
||||
|
||||
type SetDeadlineRequest struct {
|
||||
Time []byte `protobuf:"bytes,1,opt,name=time,proto3" json:"time,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *SetDeadlineRequest) Reset() { *m = SetDeadlineRequest{} }
|
||||
func (m *SetDeadlineRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*SetDeadlineRequest) ProtoMessage() {}
|
||||
func (*SetDeadlineRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f401a58c1fc7ceef, []int{6}
|
||||
}
|
||||
|
||||
func (m *SetDeadlineRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_SetDeadlineRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *SetDeadlineRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_SetDeadlineRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *SetDeadlineRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_SetDeadlineRequest.Merge(m, src)
|
||||
}
|
||||
func (m *SetDeadlineRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_SetDeadlineRequest.Size(m)
|
||||
}
|
||||
func (m *SetDeadlineRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_SetDeadlineRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_SetDeadlineRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *SetDeadlineRequest) GetTime() []byte {
|
||||
if m != nil {
|
||||
return m.Time
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type SetDeadlineResponse struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *SetDeadlineResponse) Reset() { *m = SetDeadlineResponse{} }
|
||||
func (m *SetDeadlineResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*SetDeadlineResponse) ProtoMessage() {}
|
||||
func (*SetDeadlineResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f401a58c1fc7ceef, []int{7}
|
||||
}
|
||||
|
||||
func (m *SetDeadlineResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_SetDeadlineResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *SetDeadlineResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_SetDeadlineResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *SetDeadlineResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_SetDeadlineResponse.Merge(m, src)
|
||||
}
|
||||
func (m *SetDeadlineResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_SetDeadlineResponse.Size(m)
|
||||
}
|
||||
func (m *SetDeadlineResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_SetDeadlineResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_SetDeadlineResponse proto.InternalMessageInfo
|
||||
|
||||
type SetReadDeadlineRequest struct {
|
||||
Time []byte `protobuf:"bytes,1,opt,name=time,proto3" json:"time,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *SetReadDeadlineRequest) Reset() { *m = SetReadDeadlineRequest{} }
|
||||
func (m *SetReadDeadlineRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*SetReadDeadlineRequest) ProtoMessage() {}
|
||||
func (*SetReadDeadlineRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f401a58c1fc7ceef, []int{8}
|
||||
}
|
||||
|
||||
func (m *SetReadDeadlineRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_SetReadDeadlineRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *SetReadDeadlineRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_SetReadDeadlineRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *SetReadDeadlineRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_SetReadDeadlineRequest.Merge(m, src)
|
||||
}
|
||||
func (m *SetReadDeadlineRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_SetReadDeadlineRequest.Size(m)
|
||||
}
|
||||
func (m *SetReadDeadlineRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_SetReadDeadlineRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_SetReadDeadlineRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *SetReadDeadlineRequest) GetTime() []byte {
|
||||
if m != nil {
|
||||
return m.Time
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type SetReadDeadlineResponse struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *SetReadDeadlineResponse) Reset() { *m = SetReadDeadlineResponse{} }
|
||||
func (m *SetReadDeadlineResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*SetReadDeadlineResponse) ProtoMessage() {}
|
||||
func (*SetReadDeadlineResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f401a58c1fc7ceef, []int{9}
|
||||
}
|
||||
|
||||
func (m *SetReadDeadlineResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_SetReadDeadlineResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *SetReadDeadlineResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_SetReadDeadlineResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *SetReadDeadlineResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_SetReadDeadlineResponse.Merge(m, src)
|
||||
}
|
||||
func (m *SetReadDeadlineResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_SetReadDeadlineResponse.Size(m)
|
||||
}
|
||||
func (m *SetReadDeadlineResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_SetReadDeadlineResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_SetReadDeadlineResponse proto.InternalMessageInfo
|
||||
|
||||
type SetWriteDeadlineRequest struct {
|
||||
Time []byte `protobuf:"bytes,1,opt,name=time,proto3" json:"time,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *SetWriteDeadlineRequest) Reset() { *m = SetWriteDeadlineRequest{} }
|
||||
func (m *SetWriteDeadlineRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*SetWriteDeadlineRequest) ProtoMessage() {}
|
||||
func (*SetWriteDeadlineRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f401a58c1fc7ceef, []int{10}
|
||||
}
|
||||
|
||||
func (m *SetWriteDeadlineRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_SetWriteDeadlineRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *SetWriteDeadlineRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_SetWriteDeadlineRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *SetWriteDeadlineRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_SetWriteDeadlineRequest.Merge(m, src)
|
||||
}
|
||||
func (m *SetWriteDeadlineRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_SetWriteDeadlineRequest.Size(m)
|
||||
}
|
||||
func (m *SetWriteDeadlineRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_SetWriteDeadlineRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_SetWriteDeadlineRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *SetWriteDeadlineRequest) GetTime() []byte {
|
||||
if m != nil {
|
||||
return m.Time
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type SetWriteDeadlineResponse struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *SetWriteDeadlineResponse) Reset() { *m = SetWriteDeadlineResponse{} }
|
||||
func (m *SetWriteDeadlineResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*SetWriteDeadlineResponse) ProtoMessage() {}
|
||||
func (*SetWriteDeadlineResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f401a58c1fc7ceef, []int{11}
|
||||
}
|
||||
|
||||
func (m *SetWriteDeadlineResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_SetWriteDeadlineResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *SetWriteDeadlineResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_SetWriteDeadlineResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *SetWriteDeadlineResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_SetWriteDeadlineResponse.Merge(m, src)
|
||||
}
|
||||
func (m *SetWriteDeadlineResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_SetWriteDeadlineResponse.Size(m)
|
||||
}
|
||||
func (m *SetWriteDeadlineResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_SetWriteDeadlineResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_SetWriteDeadlineResponse proto.InternalMessageInfo
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*ReadRequest)(nil), "proto.ReadRequest")
|
||||
proto.RegisterType((*ReadResponse)(nil), "proto.ReadResponse")
|
||||
proto.RegisterType((*WriteRequest)(nil), "proto.WriteRequest")
|
||||
proto.RegisterType((*WriteResponse)(nil), "proto.WriteResponse")
|
||||
proto.RegisterType((*CloseRequest)(nil), "proto.CloseRequest")
|
||||
proto.RegisterType((*CloseResponse)(nil), "proto.CloseResponse")
|
||||
proto.RegisterType((*SetDeadlineRequest)(nil), "proto.SetDeadlineRequest")
|
||||
proto.RegisterType((*SetDeadlineResponse)(nil), "proto.SetDeadlineResponse")
|
||||
proto.RegisterType((*SetReadDeadlineRequest)(nil), "proto.SetReadDeadlineRequest")
|
||||
proto.RegisterType((*SetReadDeadlineResponse)(nil), "proto.SetReadDeadlineResponse")
|
||||
proto.RegisterType((*SetWriteDeadlineRequest)(nil), "proto.SetWriteDeadlineRequest")
|
||||
proto.RegisterType((*SetWriteDeadlineResponse)(nil), "proto.SetWriteDeadlineResponse")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("conn.proto", fileDescriptor_f401a58c1fc7ceef) }
|
||||
|
||||
var fileDescriptor_f401a58c1fc7ceef = []byte{
|
||||
// 351 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x52, 0xd1, 0x4e, 0xea, 0x40,
|
||||
0x10, 0x4d, 0x2f, 0x2d, 0x5c, 0x87, 0x22, 0x66, 0x40, 0x2c, 0x9b, 0xa8, 0x64, 0x13, 0x93, 0x3e,
|
||||
0x28, 0x26, 0xf8, 0x09, 0xf0, 0x01, 0x66, 0x79, 0xe0, 0xb9, 0xda, 0x89, 0x92, 0xd4, 0x5d, 0x6c,
|
||||
0xd7, 0x07, 0xff, 0xc1, 0x8f, 0x36, 0x6c, 0xb7, 0xa5, 0x05, 0x9a, 0xe0, 0x53, 0xf7, 0xec, 0x39,
|
||||
0x73, 0x66, 0x7a, 0x66, 0x01, 0x5e, 0x95, 0x94, 0xd3, 0x4d, 0xaa, 0xb4, 0x42, 0xcf, 0x7c, 0xf8,
|
||||
0x1d, 0x74, 0x05, 0x45, 0xb1, 0xa0, 0xcf, 0x2f, 0xca, 0x34, 0x8e, 0xa0, 0x9d, 0x90, 0x7c, 0xd3,
|
||||
0xef, 0x81, 0x33, 0x71, 0x42, 0x4f, 0x58, 0xc4, 0x05, 0xf8, 0xb9, 0x2c, 0xdb, 0x28, 0x99, 0x11,
|
||||
0x22, 0xb8, 0x29, 0x45, 0xb1, 0x51, 0xf9, 0xc2, 0x9c, 0x71, 0x08, 0x1e, 0xa5, 0xa9, 0x4a, 0x83,
|
||||
0x7f, 0x13, 0x27, 0x3c, 0x13, 0x39, 0xc0, 0x00, 0x3a, 0xe6, 0x40, 0x71, 0xd0, 0x9a, 0x38, 0xe1,
|
||||
0x7f, 0x51, 0x40, 0x1e, 0x82, 0xbf, 0x4a, 0xd7, 0x9a, 0x8a, 0xde, 0x01, 0x74, 0x36, 0xd1, 0x77,
|
||||
0xa2, 0x4a, 0xdb, 0x02, 0xf2, 0x15, 0xf4, 0xac, 0xd2, 0xb6, 0x6f, 0x18, 0xf3, 0xcf, 0x23, 0x9c,
|
||||
0x83, 0x3f, 0x4f, 0x54, 0x56, 0x8c, 0xc0, 0xfb, 0xd0, 0xb3, 0x38, 0x6f, 0xc4, 0x43, 0xc0, 0x25,
|
||||
0xe9, 0x05, 0x45, 0x71, 0xb2, 0x96, 0xe5, 0xa4, 0x08, 0xae, 0x5e, 0x7f, 0x50, 0xf1, 0xf7, 0xdb,
|
||||
0x33, 0xbf, 0x84, 0x41, 0x4d, 0x69, 0x0d, 0xee, 0x61, 0xb4, 0x24, 0xbd, 0xcd, 0xee, 0x14, 0x93,
|
||||
0x31, 0x5c, 0x1d, 0xa8, 0xad, 0xd1, 0x83, 0xa1, 0x4c, 0x0c, 0xa7, 0x38, 0x31, 0x08, 0x0e, 0xe5,
|
||||
0xb9, 0xd5, 0xec, 0xa7, 0x05, 0xee, 0x5c, 0x49, 0x89, 0x8f, 0xe0, 0x6e, 0x7b, 0x21, 0xe6, 0x6f,
|
||||
0x62, 0x5a, 0x79, 0x09, 0x6c, 0x50, 0xbb, 0xb3, 0xb9, 0xcf, 0xc0, 0x33, 0x96, 0x58, 0xb0, 0xd5,
|
||||
0x05, 0xb2, 0x61, 0xfd, 0x72, 0x57, 0x63, 0x32, 0x2d, 0x6b, 0xaa, 0x89, 0x97, 0x35, 0xb5, 0xd8,
|
||||
0x71, 0x01, 0xdd, 0x4a, 0x98, 0x38, 0xb6, 0xa2, 0xc3, 0x55, 0x30, 0x76, 0x8c, 0xb2, 0x2e, 0xcf,
|
||||
0xd0, 0xdf, 0x4b, 0x13, 0xaf, 0x77, 0xf2, 0x23, 0x3b, 0x61, 0x37, 0x4d, 0xb4, 0x75, 0x5c, 0xc2,
|
||||
0xc5, 0x7e, 0xaa, 0x58, 0xa9, 0x39, 0xb6, 0x1d, 0x76, 0xdb, 0xc8, 0xe7, 0xa6, 0x2f, 0x6d, 0xc3,
|
||||
0x3f, 0xfd, 0x06, 0x00, 0x00, 0xff, 0xff, 0xe3, 0x73, 0x4d, 0x43, 0x9e, 0x03, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ grpc.ClientConnInterface
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc.SupportPackageIsVersion6
|
||||
|
||||
// ConnClient is the client API for Conn service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type ConnClient interface {
|
||||
Read(ctx context.Context, in *ReadRequest, opts ...grpc.CallOption) (*ReadResponse, error)
|
||||
Write(ctx context.Context, in *WriteRequest, opts ...grpc.CallOption) (*WriteResponse, error)
|
||||
Close(ctx context.Context, in *CloseRequest, opts ...grpc.CallOption) (*CloseResponse, error)
|
||||
SetDeadline(ctx context.Context, in *SetDeadlineRequest, opts ...grpc.CallOption) (*SetDeadlineResponse, error)
|
||||
SetReadDeadline(ctx context.Context, in *SetReadDeadlineRequest, opts ...grpc.CallOption) (*SetReadDeadlineResponse, error)
|
||||
SetWriteDeadline(ctx context.Context, in *SetWriteDeadlineRequest, opts ...grpc.CallOption) (*SetWriteDeadlineResponse, error)
|
||||
}
|
||||
|
||||
type connClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewConnClient(cc grpc.ClientConnInterface) ConnClient {
|
||||
return &connClient{cc}
|
||||
}
|
||||
|
||||
func (c *connClient) Read(ctx context.Context, in *ReadRequest, opts ...grpc.CallOption) (*ReadResponse, error) {
|
||||
out := new(ReadResponse)
|
||||
err := c.cc.Invoke(ctx, "/proto.Conn/Read", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *connClient) Write(ctx context.Context, in *WriteRequest, opts ...grpc.CallOption) (*WriteResponse, error) {
|
||||
out := new(WriteResponse)
|
||||
err := c.cc.Invoke(ctx, "/proto.Conn/Write", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *connClient) Close(ctx context.Context, in *CloseRequest, opts ...grpc.CallOption) (*CloseResponse, error) {
|
||||
out := new(CloseResponse)
|
||||
err := c.cc.Invoke(ctx, "/proto.Conn/Close", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *connClient) SetDeadline(ctx context.Context, in *SetDeadlineRequest, opts ...grpc.CallOption) (*SetDeadlineResponse, error) {
|
||||
out := new(SetDeadlineResponse)
|
||||
err := c.cc.Invoke(ctx, "/proto.Conn/SetDeadline", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *connClient) SetReadDeadline(ctx context.Context, in *SetReadDeadlineRequest, opts ...grpc.CallOption) (*SetReadDeadlineResponse, error) {
|
||||
out := new(SetReadDeadlineResponse)
|
||||
err := c.cc.Invoke(ctx, "/proto.Conn/SetReadDeadline", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *connClient) SetWriteDeadline(ctx context.Context, in *SetWriteDeadlineRequest, opts ...grpc.CallOption) (*SetWriteDeadlineResponse, error) {
|
||||
out := new(SetWriteDeadlineResponse)
|
||||
err := c.cc.Invoke(ctx, "/proto.Conn/SetWriteDeadline", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ConnServer is the server API for Conn service.
|
||||
type ConnServer interface {
|
||||
Read(context.Context, *ReadRequest) (*ReadResponse, error)
|
||||
Write(context.Context, *WriteRequest) (*WriteResponse, error)
|
||||
Close(context.Context, *CloseRequest) (*CloseResponse, error)
|
||||
SetDeadline(context.Context, *SetDeadlineRequest) (*SetDeadlineResponse, error)
|
||||
SetReadDeadline(context.Context, *SetReadDeadlineRequest) (*SetReadDeadlineResponse, error)
|
||||
SetWriteDeadline(context.Context, *SetWriteDeadlineRequest) (*SetWriteDeadlineResponse, error)
|
||||
}
|
||||
|
||||
// UnimplementedConnServer can be embedded to have forward compatible implementations.
|
||||
type UnimplementedConnServer struct {
|
||||
}
|
||||
|
||||
func (*UnimplementedConnServer) Read(ctx context.Context, req *ReadRequest) (*ReadResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Read not implemented")
|
||||
}
|
||||
func (*UnimplementedConnServer) Write(ctx context.Context, req *WriteRequest) (*WriteResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Write not implemented")
|
||||
}
|
||||
func (*UnimplementedConnServer) Close(ctx context.Context, req *CloseRequest) (*CloseResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Close not implemented")
|
||||
}
|
||||
func (*UnimplementedConnServer) SetDeadline(ctx context.Context, req *SetDeadlineRequest) (*SetDeadlineResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method SetDeadline not implemented")
|
||||
}
|
||||
func (*UnimplementedConnServer) SetReadDeadline(ctx context.Context, req *SetReadDeadlineRequest) (*SetReadDeadlineResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method SetReadDeadline not implemented")
|
||||
}
|
||||
func (*UnimplementedConnServer) SetWriteDeadline(ctx context.Context, req *SetWriteDeadlineRequest) (*SetWriteDeadlineResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method SetWriteDeadline not implemented")
|
||||
}
|
||||
|
||||
func RegisterConnServer(s *grpc.Server, srv ConnServer) {
|
||||
s.RegisterService(&_Conn_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _Conn_Read_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ReadRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ConnServer).Read(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/proto.Conn/Read",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ConnServer).Read(ctx, req.(*ReadRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Conn_Write_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(WriteRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ConnServer).Write(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/proto.Conn/Write",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ConnServer).Write(ctx, req.(*WriteRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Conn_Close_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CloseRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ConnServer).Close(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/proto.Conn/Close",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ConnServer).Close(ctx, req.(*CloseRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Conn_SetDeadline_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(SetDeadlineRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ConnServer).SetDeadline(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/proto.Conn/SetDeadline",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ConnServer).SetDeadline(ctx, req.(*SetDeadlineRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Conn_SetReadDeadline_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(SetReadDeadlineRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ConnServer).SetReadDeadline(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/proto.Conn/SetReadDeadline",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ConnServer).SetReadDeadline(ctx, req.(*SetReadDeadlineRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Conn_SetWriteDeadline_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(SetWriteDeadlineRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ConnServer).SetWriteDeadline(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/proto.Conn/SetWriteDeadline",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ConnServer).SetWriteDeadline(ctx, req.(*SetWriteDeadlineRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _Conn_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "proto.Conn",
|
||||
HandlerType: (*ConnServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Read",
|
||||
Handler: _Conn_Read_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Write",
|
||||
Handler: _Conn_Write_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Close",
|
||||
Handler: _Conn_Close_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "SetDeadline",
|
||||
Handler: _Conn_SetDeadline_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "SetReadDeadline",
|
||||
Handler: _Conn_SetReadDeadline_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "SetWriteDeadline",
|
||||
Handler: _Conn_SetWriteDeadline_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "conn.proto",
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
syntax = "proto3";
|
||||
package proto;
|
||||
|
||||
message ReadRequest {
|
||||
int32 length = 1;
|
||||
}
|
||||
|
||||
message ReadResponse {
|
||||
bytes read = 1;
|
||||
string error = 2;
|
||||
bool errored = 3;
|
||||
}
|
||||
|
||||
message WriteRequest {
|
||||
bytes payload = 1;
|
||||
}
|
||||
|
||||
message WriteResponse {
|
||||
int32 length = 1;
|
||||
string error = 2;
|
||||
bool errored = 3;
|
||||
}
|
||||
|
||||
message CloseRequest {}
|
||||
|
||||
message CloseResponse {}
|
||||
|
||||
message SetDeadlineRequest {
|
||||
bytes time = 1;
|
||||
}
|
||||
|
||||
message SetDeadlineResponse {}
|
||||
|
||||
message SetReadDeadlineRequest {
|
||||
bytes time = 1;
|
||||
}
|
||||
|
||||
message SetReadDeadlineResponse {}
|
||||
|
||||
message SetWriteDeadlineRequest {
|
||||
bytes time = 1;
|
||||
}
|
||||
|
||||
message SetWriteDeadlineResponse {}
|
||||
|
||||
service Conn {
|
||||
rpc Read(ReadRequest) returns (ReadResponse);
|
||||
rpc Write(WriteRequest) returns (WriteResponse);
|
||||
rpc Close(CloseRequest) returns (CloseResponse);
|
||||
rpc SetDeadline(SetDeadlineRequest) returns (SetDeadlineResponse);
|
||||
rpc SetReadDeadline(SetReadDeadlineRequest) returns (SetReadDeadlineResponse);
|
||||
rpc SetWriteDeadline(SetWriteDeadlineRequest) returns (SetWriteDeadlineResponse);
|
||||
}
|
|
@ -0,0 +1,323 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: reader.proto
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
type ReadRequest struct {
|
||||
Length int32 `protobuf:"varint,1,opt,name=length,proto3" json:"length,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ReadRequest) Reset() { *m = ReadRequest{} }
|
||||
func (m *ReadRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ReadRequest) ProtoMessage() {}
|
||||
func (*ReadRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f534e48276761a43, []int{0}
|
||||
}
|
||||
|
||||
func (m *ReadRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ReadRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ReadRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ReadRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ReadRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ReadRequest.Merge(m, src)
|
||||
}
|
||||
func (m *ReadRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_ReadRequest.Size(m)
|
||||
}
|
||||
func (m *ReadRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ReadRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ReadRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *ReadRequest) GetLength() int32 {
|
||||
if m != nil {
|
||||
return m.Length
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type ReadResponse struct {
|
||||
Read []byte `protobuf:"bytes,1,opt,name=read,proto3" json:"read,omitempty"`
|
||||
Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"`
|
||||
Errored bool `protobuf:"varint,3,opt,name=errored,proto3" json:"errored,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ReadResponse) Reset() { *m = ReadResponse{} }
|
||||
func (m *ReadResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ReadResponse) ProtoMessage() {}
|
||||
func (*ReadResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f534e48276761a43, []int{1}
|
||||
}
|
||||
|
||||
func (m *ReadResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ReadResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ReadResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ReadResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ReadResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ReadResponse.Merge(m, src)
|
||||
}
|
||||
func (m *ReadResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_ReadResponse.Size(m)
|
||||
}
|
||||
func (m *ReadResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ReadResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ReadResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *ReadResponse) GetRead() []byte {
|
||||
if m != nil {
|
||||
return m.Read
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ReadResponse) GetError() string {
|
||||
if m != nil {
|
||||
return m.Error
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *ReadResponse) GetErrored() bool {
|
||||
if m != nil {
|
||||
return m.Errored
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type CloseRequest struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *CloseRequest) Reset() { *m = CloseRequest{} }
|
||||
func (m *CloseRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*CloseRequest) ProtoMessage() {}
|
||||
func (*CloseRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f534e48276761a43, []int{2}
|
||||
}
|
||||
|
||||
func (m *CloseRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_CloseRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *CloseRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_CloseRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *CloseRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_CloseRequest.Merge(m, src)
|
||||
}
|
||||
func (m *CloseRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_CloseRequest.Size(m)
|
||||
}
|
||||
func (m *CloseRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_CloseRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_CloseRequest proto.InternalMessageInfo
|
||||
|
||||
type CloseResponse struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *CloseResponse) Reset() { *m = CloseResponse{} }
|
||||
func (m *CloseResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*CloseResponse) ProtoMessage() {}
|
||||
func (*CloseResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f534e48276761a43, []int{3}
|
||||
}
|
||||
|
||||
func (m *CloseResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_CloseResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *CloseResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_CloseResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *CloseResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_CloseResponse.Merge(m, src)
|
||||
}
|
||||
func (m *CloseResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_CloseResponse.Size(m)
|
||||
}
|
||||
func (m *CloseResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_CloseResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_CloseResponse proto.InternalMessageInfo
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*ReadRequest)(nil), "proto.ReadRequest")
|
||||
proto.RegisterType((*ReadResponse)(nil), "proto.ReadResponse")
|
||||
proto.RegisterType((*CloseRequest)(nil), "proto.CloseRequest")
|
||||
proto.RegisterType((*CloseResponse)(nil), "proto.CloseResponse")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("reader.proto", fileDescriptor_f534e48276761a43) }
|
||||
|
||||
var fileDescriptor_f534e48276761a43 = []byte{
|
||||
// 195 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x8e, 0xd1, 0x6a, 0x84, 0x30,
|
||||
0x10, 0x45, 0x49, 0x6b, 0x6c, 0x3b, 0x4d, 0x5b, 0x98, 0x4a, 0x09, 0x3e, 0x49, 0xa0, 0xe0, 0x93,
|
||||
0x0b, 0xee, 0x27, 0xec, 0x1f, 0xcc, 0x1f, 0xb8, 0x38, 0xec, 0x3e, 0xb8, 0xc6, 0x4d, 0xdc, 0xff,
|
||||
0x5f, 0x4c, 0x22, 0xe8, 0x53, 0xee, 0xbd, 0x99, 0x99, 0x7b, 0x40, 0x39, 0xee, 0x7a, 0x76, 0xcd,
|
||||
0xe4, 0xec, 0x6c, 0x51, 0x86, 0xc7, 0xfc, 0xc3, 0x27, 0x71, 0xd7, 0x13, 0xdf, 0x1f, 0xec, 0x67,
|
||||
0xfc, 0x83, 0x7c, 0xe0, 0xf1, 0x32, 0x5f, 0xb5, 0xa8, 0x44, 0x2d, 0x29, 0x39, 0x43, 0xa0, 0xe2,
|
||||
0x98, 0x9f, 0xec, 0xe8, 0x19, 0x11, 0xb2, 0xe5, 0x5a, 0x98, 0x52, 0x14, 0x34, 0x16, 0x20, 0xd9,
|
||||
0x39, 0xeb, 0xf4, 0x4b, 0x25, 0xea, 0x0f, 0x8a, 0x06, 0x35, 0xbc, 0x05, 0xc1, 0xbd, 0x7e, 0xad,
|
||||
0x44, 0xfd, 0x4e, 0xab, 0x35, 0xdf, 0xa0, 0x4e, 0x83, 0xf5, 0x9c, 0xba, 0xcd, 0x0f, 0x7c, 0x25,
|
||||
0x1f, 0x4b, 0xda, 0x1b, 0xe4, 0x14, 0x90, 0xf1, 0x00, 0xd9, 0xa2, 0x10, 0x23, 0x7c, 0xb3, 0x41,
|
||||
0x2e, 0x7f, 0x77, 0x59, 0xe2, 0x6b, 0x41, 0x86, 0x5b, 0xb8, 0xfe, 0x6e, 0x9b, 0xca, 0x62, 0x1f,
|
||||
0xc6, 0x9d, 0x73, 0x1e, 0xc2, 0xe3, 0x33, 0x00, 0x00, 0xff, 0xff, 0x47, 0x74, 0x81, 0x61, 0x28,
|
||||
0x01, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ grpc.ClientConnInterface
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc.SupportPackageIsVersion6
|
||||
|
||||
// ReaderClient is the client API for Reader service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type ReaderClient interface {
|
||||
Read(ctx context.Context, in *ReadRequest, opts ...grpc.CallOption) (*ReadResponse, error)
|
||||
Close(ctx context.Context, in *CloseRequest, opts ...grpc.CallOption) (*CloseResponse, error)
|
||||
}
|
||||
|
||||
type readerClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewReaderClient(cc grpc.ClientConnInterface) ReaderClient {
|
||||
return &readerClient{cc}
|
||||
}
|
||||
|
||||
func (c *readerClient) Read(ctx context.Context, in *ReadRequest, opts ...grpc.CallOption) (*ReadResponse, error) {
|
||||
out := new(ReadResponse)
|
||||
err := c.cc.Invoke(ctx, "/proto.Reader/Read", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *readerClient) Close(ctx context.Context, in *CloseRequest, opts ...grpc.CallOption) (*CloseResponse, error) {
|
||||
out := new(CloseResponse)
|
||||
err := c.cc.Invoke(ctx, "/proto.Reader/Close", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ReaderServer is the server API for Reader service.
|
||||
type ReaderServer interface {
|
||||
Read(context.Context, *ReadRequest) (*ReadResponse, error)
|
||||
Close(context.Context, *CloseRequest) (*CloseResponse, error)
|
||||
}
|
||||
|
||||
// UnimplementedReaderServer can be embedded to have forward compatible implementations.
|
||||
type UnimplementedReaderServer struct {
|
||||
}
|
||||
|
||||
func (*UnimplementedReaderServer) Read(ctx context.Context, req *ReadRequest) (*ReadResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Read not implemented")
|
||||
}
|
||||
func (*UnimplementedReaderServer) Close(ctx context.Context, req *CloseRequest) (*CloseResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Close not implemented")
|
||||
}
|
||||
|
||||
func RegisterReaderServer(s *grpc.Server, srv ReaderServer) {
|
||||
s.RegisterService(&_Reader_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _Reader_Read_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ReadRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ReaderServer).Read(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/proto.Reader/Read",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ReaderServer).Read(ctx, req.(*ReadRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Reader_Close_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CloseRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ReaderServer).Close(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/proto.Reader/Close",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ReaderServer).Close(ctx, req.(*CloseRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _Reader_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "proto.Reader",
|
||||
HandlerType: (*ReaderServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Read",
|
||||
Handler: _Reader_Read_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Close",
|
||||
Handler: _Reader_Close_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "reader.proto",
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
syntax = "proto3";
|
||||
package proto;
|
||||
|
||||
message ReadRequest {
|
||||
int32 length = 1;
|
||||
}
|
||||
|
||||
message ReadResponse {
|
||||
bytes read = 1;
|
||||
string error = 2;
|
||||
bool errored = 3;
|
||||
}
|
||||
|
||||
message CloseRequest {}
|
||||
|
||||
message CloseResponse {}
|
||||
|
||||
service Reader {
|
||||
rpc Read(ReadRequest) returns (ReadResponse);
|
||||
rpc Close(CloseRequest) returns (CloseResponse);
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package greadcloser
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/greadcloser/proto"
|
||||
)
|
||||
|
||||
// Client is an implementation of a messenger channel that talks over RPC.
|
||||
type Client struct{ client proto.ReaderClient }
|
||||
|
||||
// NewClient returns a database instance connected to a remote database instance
|
||||
func NewClient(client proto.ReaderClient) *Client {
|
||||
return &Client{client: client}
|
||||
}
|
||||
|
||||
// Read ...
|
||||
func (c *Client) Read(p []byte) (int, error) {
|
||||
resp, err := c.client.Read(context.Background(), &proto.ReadRequest{
|
||||
Length: int32(len(p)),
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
copy(p, resp.Read)
|
||||
|
||||
if resp.Errored {
|
||||
err = errors.New(resp.Error)
|
||||
}
|
||||
return len(resp.Read), err
|
||||
}
|
||||
|
||||
// Close ...
|
||||
func (c *Client) Close() error {
|
||||
_, err := c.client.Close(context.Background(), &proto.CloseRequest{})
|
||||
return err
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package greadcloser
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/greadcloser/proto"
|
||||
)
|
||||
|
||||
// Server is a http.Handler that is managed over RPC.
|
||||
type Server struct{ readCloser io.ReadCloser }
|
||||
|
||||
// NewServer returns a http.Handler instance manage remotely
|
||||
func NewServer(readCloser io.ReadCloser) *Server {
|
||||
return &Server{readCloser: readCloser}
|
||||
}
|
||||
|
||||
// Read ...
|
||||
func (s *Server) Read(ctx context.Context, req *proto.ReadRequest) (*proto.ReadResponse, error) {
|
||||
buf := make([]byte, int(req.Length))
|
||||
n, err := s.readCloser.Read(buf)
|
||||
resp := &proto.ReadResponse{
|
||||
Read: buf[:n],
|
||||
}
|
||||
if err != nil {
|
||||
resp.Errored = true
|
||||
resp.Error = err.Error()
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Close ...
|
||||
func (s *Server) Close(ctx context.Context, req *proto.CloseRequest) (*proto.CloseResponse, error) {
|
||||
return &proto.CloseResponse{}, s.readCloser.Close()
|
||||
}
|
|
@ -0,0 +1,221 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: reader.proto
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
type ReadRequest struct {
|
||||
Length int32 `protobuf:"varint,1,opt,name=length,proto3" json:"length,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ReadRequest) Reset() { *m = ReadRequest{} }
|
||||
func (m *ReadRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ReadRequest) ProtoMessage() {}
|
||||
func (*ReadRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f534e48276761a43, []int{0}
|
||||
}
|
||||
|
||||
func (m *ReadRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ReadRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ReadRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ReadRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ReadRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ReadRequest.Merge(m, src)
|
||||
}
|
||||
func (m *ReadRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_ReadRequest.Size(m)
|
||||
}
|
||||
func (m *ReadRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ReadRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ReadRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *ReadRequest) GetLength() int32 {
|
||||
if m != nil {
|
||||
return m.Length
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type ReadResponse struct {
|
||||
Read []byte `protobuf:"bytes,1,opt,name=read,proto3" json:"read,omitempty"`
|
||||
Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"`
|
||||
Errored bool `protobuf:"varint,3,opt,name=errored,proto3" json:"errored,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ReadResponse) Reset() { *m = ReadResponse{} }
|
||||
func (m *ReadResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ReadResponse) ProtoMessage() {}
|
||||
func (*ReadResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f534e48276761a43, []int{1}
|
||||
}
|
||||
|
||||
func (m *ReadResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ReadResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ReadResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ReadResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ReadResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ReadResponse.Merge(m, src)
|
||||
}
|
||||
func (m *ReadResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_ReadResponse.Size(m)
|
||||
}
|
||||
func (m *ReadResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ReadResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ReadResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *ReadResponse) GetRead() []byte {
|
||||
if m != nil {
|
||||
return m.Read
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ReadResponse) GetError() string {
|
||||
if m != nil {
|
||||
return m.Error
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *ReadResponse) GetErrored() bool {
|
||||
if m != nil {
|
||||
return m.Errored
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*ReadRequest)(nil), "proto.ReadRequest")
|
||||
proto.RegisterType((*ReadResponse)(nil), "proto.ReadResponse")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("reader.proto", fileDescriptor_f534e48276761a43) }
|
||||
|
||||
var fileDescriptor_f534e48276761a43 = []byte{
|
||||
// 162 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x54, 0x8e, 0x41, 0x0a, 0xc2, 0x30,
|
||||
0x10, 0x45, 0x89, 0xb6, 0x55, 0xc7, 0xae, 0x46, 0x91, 0xe0, 0xaa, 0x14, 0x84, 0xac, 0x2a, 0xe8,
|
||||
0xca, 0x6b, 0xcc, 0x0d, 0x2a, 0x19, 0x74, 0x21, 0x4d, 0x9d, 0xc4, 0xfb, 0x4b, 0x27, 0x0a, 0xba,
|
||||
0xca, 0x7f, 0x9f, 0x4f, 0xe6, 0x41, 0x2d, 0xdc, 0x7b, 0x96, 0x6e, 0x94, 0x90, 0x02, 0x96, 0xfa,
|
||||
0xb4, 0x07, 0x58, 0x13, 0xf7, 0x9e, 0xf8, 0xf9, 0xe2, 0x98, 0x70, 0x07, 0xd5, 0x83, 0x87, 0x5b,
|
||||
0xba, 0x5b, 0xd3, 0x18, 0x57, 0xd2, 0x87, 0x5a, 0x82, 0x3a, 0xcf, 0xe2, 0x18, 0x86, 0xc8, 0x88,
|
||||
0x50, 0x4c, 0xbf, 0xe9, 0xaa, 0x26, 0xcd, 0xb8, 0x85, 0x92, 0x45, 0x82, 0xd8, 0x59, 0x63, 0xdc,
|
||||
0x8a, 0x32, 0xa0, 0x85, 0x85, 0x06, 0xf6, 0x76, 0xde, 0x18, 0xb7, 0xa4, 0x2f, 0x9e, 0x2e, 0x50,
|
||||
0x91, 0x1a, 0xe1, 0x11, 0x8a, 0x29, 0x21, 0x66, 0xb7, 0xee, 0xc7, 0x68, 0xbf, 0xf9, 0xeb, 0xf2,
|
||||
0xf9, 0x6b, 0xa5, 0xdd, 0xf9, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x06, 0x11, 0x6f, 0x5d, 0xd3, 0x00,
|
||||
0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ grpc.ClientConnInterface
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc.SupportPackageIsVersion6
|
||||
|
||||
// ReaderClient is the client API for Reader service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type ReaderClient interface {
|
||||
Read(ctx context.Context, in *ReadRequest, opts ...grpc.CallOption) (*ReadResponse, error)
|
||||
}
|
||||
|
||||
type readerClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewReaderClient(cc grpc.ClientConnInterface) ReaderClient {
|
||||
return &readerClient{cc}
|
||||
}
|
||||
|
||||
func (c *readerClient) Read(ctx context.Context, in *ReadRequest, opts ...grpc.CallOption) (*ReadResponse, error) {
|
||||
out := new(ReadResponse)
|
||||
err := c.cc.Invoke(ctx, "/proto.Reader/Read", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ReaderServer is the server API for Reader service.
|
||||
type ReaderServer interface {
|
||||
Read(context.Context, *ReadRequest) (*ReadResponse, error)
|
||||
}
|
||||
|
||||
// UnimplementedReaderServer can be embedded to have forward compatible implementations.
|
||||
type UnimplementedReaderServer struct {
|
||||
}
|
||||
|
||||
func (*UnimplementedReaderServer) Read(ctx context.Context, req *ReadRequest) (*ReadResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Read not implemented")
|
||||
}
|
||||
|
||||
func RegisterReaderServer(s *grpc.Server, srv ReaderServer) {
|
||||
s.RegisterService(&_Reader_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _Reader_Read_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ReadRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ReaderServer).Read(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/proto.Reader/Read",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ReaderServer).Read(ctx, req.(*ReadRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _Reader_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "proto.Reader",
|
||||
HandlerType: (*ReaderServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Read",
|
||||
Handler: _Reader_Read_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "reader.proto",
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
syntax = "proto3";
|
||||
package proto;
|
||||
|
||||
message ReadRequest {
|
||||
int32 length = 1;
|
||||
}
|
||||
|
||||
message ReadResponse {
|
||||
bytes read = 1;
|
||||
string error = 2;
|
||||
bool errored = 3;
|
||||
}
|
||||
|
||||
service Reader {
|
||||
rpc Read(ReadRequest) returns (ReadResponse);
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package greader
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/greader/proto"
|
||||
)
|
||||
|
||||
// Client is an implementation of a messenger channel that talks over RPC.
|
||||
type Client struct{ client proto.ReaderClient }
|
||||
|
||||
// NewClient returns a database instance connected to a remote database instance
|
||||
func NewClient(client proto.ReaderClient) *Client {
|
||||
return &Client{client: client}
|
||||
}
|
||||
|
||||
// Read ...
|
||||
func (c *Client) Read(p []byte) (int, error) {
|
||||
resp, err := c.client.Read(context.Background(), &proto.ReadRequest{
|
||||
Length: int32(len(p)),
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
copy(p, resp.Read)
|
||||
|
||||
if resp.Errored {
|
||||
err = errors.New(resp.Error)
|
||||
}
|
||||
return len(resp.Read), err
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package greader
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/greader/proto"
|
||||
)
|
||||
|
||||
// Server is a http.Handler that is managed over RPC.
|
||||
type Server struct{ reader io.Reader }
|
||||
|
||||
// NewServer returns a http.Handler instance manage remotely
|
||||
func NewServer(reader io.Reader) *Server {
|
||||
return &Server{reader: reader}
|
||||
}
|
||||
|
||||
// Read ...
|
||||
func (s *Server) Read(ctx context.Context, req *proto.ReadRequest) (*proto.ReadResponse, error) {
|
||||
buf := make([]byte, int(req.Length))
|
||||
n, err := s.reader.Read(buf)
|
||||
resp := &proto.ReadResponse{
|
||||
Read: buf[:n],
|
||||
}
|
||||
if err != nil {
|
||||
resp.Errored = true
|
||||
resp.Error = err.Error()
|
||||
}
|
||||
return resp, nil
|
||||
}
|
|
@ -0,0 +1,648 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: writer.proto
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
type Header struct {
|
||||
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
|
||||
Values []string `protobuf:"bytes,2,rep,name=values,proto3" json:"values,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Header) Reset() { *m = Header{} }
|
||||
func (m *Header) String() string { return proto.CompactTextString(m) }
|
||||
func (*Header) ProtoMessage() {}
|
||||
func (*Header) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_ea6fbe89c42e6759, []int{0}
|
||||
}
|
||||
|
||||
func (m *Header) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Header.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Header) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Header.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Header) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Header.Merge(m, src)
|
||||
}
|
||||
func (m *Header) XXX_Size() int {
|
||||
return xxx_messageInfo_Header.Size(m)
|
||||
}
|
||||
func (m *Header) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Header.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Header proto.InternalMessageInfo
|
||||
|
||||
func (m *Header) GetKey() string {
|
||||
if m != nil {
|
||||
return m.Key
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Header) GetValues() []string {
|
||||
if m != nil {
|
||||
return m.Values
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type WriteRequest struct {
|
||||
Headers []*Header `protobuf:"bytes,1,rep,name=headers,proto3" json:"headers,omitempty"`
|
||||
Payload []byte `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *WriteRequest) Reset() { *m = WriteRequest{} }
|
||||
func (m *WriteRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*WriteRequest) ProtoMessage() {}
|
||||
func (*WriteRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_ea6fbe89c42e6759, []int{1}
|
||||
}
|
||||
|
||||
func (m *WriteRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_WriteRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *WriteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_WriteRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *WriteRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_WriteRequest.Merge(m, src)
|
||||
}
|
||||
func (m *WriteRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_WriteRequest.Size(m)
|
||||
}
|
||||
func (m *WriteRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_WriteRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_WriteRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *WriteRequest) GetHeaders() []*Header {
|
||||
if m != nil {
|
||||
return m.Headers
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *WriteRequest) GetPayload() []byte {
|
||||
if m != nil {
|
||||
return m.Payload
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type WriteResponse struct {
|
||||
Written int32 `protobuf:"varint,1,opt,name=written,proto3" json:"written,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *WriteResponse) Reset() { *m = WriteResponse{} }
|
||||
func (m *WriteResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*WriteResponse) ProtoMessage() {}
|
||||
func (*WriteResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_ea6fbe89c42e6759, []int{2}
|
||||
}
|
||||
|
||||
func (m *WriteResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_WriteResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *WriteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_WriteResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *WriteResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_WriteResponse.Merge(m, src)
|
||||
}
|
||||
func (m *WriteResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_WriteResponse.Size(m)
|
||||
}
|
||||
func (m *WriteResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_WriteResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_WriteResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *WriteResponse) GetWritten() int32 {
|
||||
if m != nil {
|
||||
return m.Written
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type WriteHeaderRequest struct {
|
||||
Headers []*Header `protobuf:"bytes,1,rep,name=headers,proto3" json:"headers,omitempty"`
|
||||
StatusCode int32 `protobuf:"varint,2,opt,name=statusCode,proto3" json:"statusCode,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *WriteHeaderRequest) Reset() { *m = WriteHeaderRequest{} }
|
||||
func (m *WriteHeaderRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*WriteHeaderRequest) ProtoMessage() {}
|
||||
func (*WriteHeaderRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_ea6fbe89c42e6759, []int{3}
|
||||
}
|
||||
|
||||
func (m *WriteHeaderRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_WriteHeaderRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *WriteHeaderRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_WriteHeaderRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *WriteHeaderRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_WriteHeaderRequest.Merge(m, src)
|
||||
}
|
||||
func (m *WriteHeaderRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_WriteHeaderRequest.Size(m)
|
||||
}
|
||||
func (m *WriteHeaderRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_WriteHeaderRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_WriteHeaderRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *WriteHeaderRequest) GetHeaders() []*Header {
|
||||
if m != nil {
|
||||
return m.Headers
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *WriteHeaderRequest) GetStatusCode() int32 {
|
||||
if m != nil {
|
||||
return m.StatusCode
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type WriteHeaderResponse struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *WriteHeaderResponse) Reset() { *m = WriteHeaderResponse{} }
|
||||
func (m *WriteHeaderResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*WriteHeaderResponse) ProtoMessage() {}
|
||||
func (*WriteHeaderResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_ea6fbe89c42e6759, []int{4}
|
||||
}
|
||||
|
||||
func (m *WriteHeaderResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_WriteHeaderResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *WriteHeaderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_WriteHeaderResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *WriteHeaderResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_WriteHeaderResponse.Merge(m, src)
|
||||
}
|
||||
func (m *WriteHeaderResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_WriteHeaderResponse.Size(m)
|
||||
}
|
||||
func (m *WriteHeaderResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_WriteHeaderResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_WriteHeaderResponse proto.InternalMessageInfo
|
||||
|
||||
type FlushRequest struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *FlushRequest) Reset() { *m = FlushRequest{} }
|
||||
func (m *FlushRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*FlushRequest) ProtoMessage() {}
|
||||
func (*FlushRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_ea6fbe89c42e6759, []int{5}
|
||||
}
|
||||
|
||||
func (m *FlushRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_FlushRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *FlushRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_FlushRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *FlushRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_FlushRequest.Merge(m, src)
|
||||
}
|
||||
func (m *FlushRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_FlushRequest.Size(m)
|
||||
}
|
||||
func (m *FlushRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_FlushRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_FlushRequest proto.InternalMessageInfo
|
||||
|
||||
type FlushResponse struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *FlushResponse) Reset() { *m = FlushResponse{} }
|
||||
func (m *FlushResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*FlushResponse) ProtoMessage() {}
|
||||
func (*FlushResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_ea6fbe89c42e6759, []int{6}
|
||||
}
|
||||
|
||||
func (m *FlushResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_FlushResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *FlushResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_FlushResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *FlushResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_FlushResponse.Merge(m, src)
|
||||
}
|
||||
func (m *FlushResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_FlushResponse.Size(m)
|
||||
}
|
||||
func (m *FlushResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_FlushResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_FlushResponse proto.InternalMessageInfo
|
||||
|
||||
type HijackRequest struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *HijackRequest) Reset() { *m = HijackRequest{} }
|
||||
func (m *HijackRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*HijackRequest) ProtoMessage() {}
|
||||
func (*HijackRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_ea6fbe89c42e6759, []int{7}
|
||||
}
|
||||
|
||||
func (m *HijackRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_HijackRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *HijackRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_HijackRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *HijackRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_HijackRequest.Merge(m, src)
|
||||
}
|
||||
func (m *HijackRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_HijackRequest.Size(m)
|
||||
}
|
||||
func (m *HijackRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_HijackRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_HijackRequest proto.InternalMessageInfo
|
||||
|
||||
type HijackResponse struct {
|
||||
ConnServer uint32 `protobuf:"varint,1,opt,name=connServer,proto3" json:"connServer,omitempty"`
|
||||
LocalNetwork string `protobuf:"bytes,2,opt,name=localNetwork,proto3" json:"localNetwork,omitempty"`
|
||||
LocalString string `protobuf:"bytes,3,opt,name=localString,proto3" json:"localString,omitempty"`
|
||||
RemoteNetwork string `protobuf:"bytes,4,opt,name=remoteNetwork,proto3" json:"remoteNetwork,omitempty"`
|
||||
RemoteString string `protobuf:"bytes,5,opt,name=remoteString,proto3" json:"remoteString,omitempty"`
|
||||
ReaderServer uint32 `protobuf:"varint,6,opt,name=readerServer,proto3" json:"readerServer,omitempty"`
|
||||
WriterServer uint32 `protobuf:"varint,7,opt,name=writerServer,proto3" json:"writerServer,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *HijackResponse) Reset() { *m = HijackResponse{} }
|
||||
func (m *HijackResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*HijackResponse) ProtoMessage() {}
|
||||
func (*HijackResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_ea6fbe89c42e6759, []int{8}
|
||||
}
|
||||
|
||||
func (m *HijackResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_HijackResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *HijackResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_HijackResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *HijackResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_HijackResponse.Merge(m, src)
|
||||
}
|
||||
func (m *HijackResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_HijackResponse.Size(m)
|
||||
}
|
||||
func (m *HijackResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_HijackResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_HijackResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *HijackResponse) GetConnServer() uint32 {
|
||||
if m != nil {
|
||||
return m.ConnServer
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *HijackResponse) GetLocalNetwork() string {
|
||||
if m != nil {
|
||||
return m.LocalNetwork
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *HijackResponse) GetLocalString() string {
|
||||
if m != nil {
|
||||
return m.LocalString
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *HijackResponse) GetRemoteNetwork() string {
|
||||
if m != nil {
|
||||
return m.RemoteNetwork
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *HijackResponse) GetRemoteString() string {
|
||||
if m != nil {
|
||||
return m.RemoteString
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *HijackResponse) GetReaderServer() uint32 {
|
||||
if m != nil {
|
||||
return m.ReaderServer
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *HijackResponse) GetWriterServer() uint32 {
|
||||
if m != nil {
|
||||
return m.WriterServer
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Header)(nil), "proto.Header")
|
||||
proto.RegisterType((*WriteRequest)(nil), "proto.WriteRequest")
|
||||
proto.RegisterType((*WriteResponse)(nil), "proto.WriteResponse")
|
||||
proto.RegisterType((*WriteHeaderRequest)(nil), "proto.WriteHeaderRequest")
|
||||
proto.RegisterType((*WriteHeaderResponse)(nil), "proto.WriteHeaderResponse")
|
||||
proto.RegisterType((*FlushRequest)(nil), "proto.FlushRequest")
|
||||
proto.RegisterType((*FlushResponse)(nil), "proto.FlushResponse")
|
||||
proto.RegisterType((*HijackRequest)(nil), "proto.HijackRequest")
|
||||
proto.RegisterType((*HijackResponse)(nil), "proto.HijackResponse")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("writer.proto", fileDescriptor_ea6fbe89c42e6759) }
|
||||
|
||||
var fileDescriptor_ea6fbe89c42e6759 = []byte{
|
||||
// 408 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x92, 0x41, 0x6e, 0xe2, 0x30,
|
||||
0x14, 0x86, 0x15, 0x32, 0x09, 0xe2, 0x91, 0xc0, 0xc8, 0x0c, 0xa3, 0x4c, 0x16, 0x28, 0xb2, 0x46,
|
||||
0x9a, 0xcc, 0x86, 0x45, 0xaa, 0x9e, 0xa0, 0x55, 0xc5, 0xaa, 0x52, 0xcd, 0xa2, 0xab, 0x2e, 0x52,
|
||||
0xb0, 0x0a, 0x25, 0x8d, 0xa9, 0xed, 0x80, 0xb8, 0x41, 0x2f, 0xdb, 0x3b, 0x54, 0xb1, 0x1d, 0x64,
|
||||
0x57, 0xdd, 0x74, 0x15, 0xbf, 0xcf, 0x7f, 0xfe, 0xf7, 0xdb, 0xcf, 0x10, 0x1d, 0xf9, 0x56, 0x52,
|
||||
0x3e, 0xdf, 0x73, 0x26, 0x19, 0x0a, 0xd4, 0x07, 0x17, 0x10, 0x2e, 0x68, 0xb9, 0xa6, 0x1c, 0xfd,
|
||||
0x04, 0x7f, 0x47, 0x4f, 0x89, 0x97, 0x79, 0xf9, 0x80, 0xb4, 0x4b, 0xf4, 0x1b, 0xc2, 0x43, 0x59,
|
||||
0x35, 0x54, 0x24, 0xbd, 0xcc, 0xcf, 0x07, 0xc4, 0x54, 0xf8, 0x0e, 0xa2, 0xfb, 0xd6, 0x8a, 0xd0,
|
||||
0xd7, 0x86, 0x0a, 0x89, 0xfe, 0x41, 0x7f, 0xa3, 0x3c, 0x44, 0xe2, 0x65, 0x7e, 0x3e, 0x2c, 0x62,
|
||||
0xdd, 0x63, 0xae, 0x9d, 0x49, 0xb7, 0x8b, 0x12, 0xe8, 0xef, 0xcb, 0x53, 0xc5, 0xca, 0x75, 0xd2,
|
||||
0xcb, 0xbc, 0x3c, 0x22, 0x5d, 0x89, 0xff, 0x43, 0x6c, 0x2c, 0xc5, 0x9e, 0xd5, 0x82, 0xb6, 0xd2,
|
||||
0x36, 0xae, 0xa4, 0xb5, 0x4a, 0x14, 0x90, 0xae, 0xc4, 0x0f, 0x80, 0x94, 0xd4, 0x98, 0x7f, 0x37,
|
||||
0xc3, 0x0c, 0x40, 0xc8, 0x52, 0x36, 0xe2, 0x8a, 0xad, 0xa9, 0x8a, 0x11, 0x10, 0x8b, 0xe0, 0x29,
|
||||
0x4c, 0x1c, 0x7b, 0x9d, 0x07, 0x8f, 0x20, 0xba, 0xa9, 0x1a, 0xb1, 0x31, 0xfd, 0xf0, 0x18, 0x62,
|
||||
0x53, 0x1b, 0xc1, 0x18, 0xe2, 0xc5, 0xf6, 0xb9, 0x5c, 0xed, 0x3a, 0xc5, 0x5b, 0x0f, 0x46, 0x1d,
|
||||
0x31, 0x87, 0x9a, 0x01, 0xac, 0x58, 0x5d, 0x2f, 0x29, 0x3f, 0x50, 0xae, 0xce, 0x15, 0x13, 0x8b,
|
||||
0x20, 0x0c, 0x51, 0xc5, 0x56, 0x65, 0x75, 0x4b, 0xe5, 0x91, 0xf1, 0x9d, 0x4a, 0x37, 0x20, 0x0e,
|
||||
0x43, 0x19, 0x0c, 0x55, 0xbd, 0x94, 0x7c, 0x5b, 0x3f, 0x25, 0xbe, 0x92, 0xd8, 0x08, 0xfd, 0x85,
|
||||
0x98, 0xd3, 0x17, 0x26, 0x69, 0x67, 0xf3, 0x43, 0x69, 0x5c, 0xd8, 0xf6, 0xd2, 0xc0, 0x18, 0x05,
|
||||
0xba, 0x97, 0xcd, 0xb4, 0xa6, 0xbd, 0x06, 0x93, 0x38, 0x54, 0x89, 0x1d, 0xd6, 0x6a, 0xf4, 0xbb,
|
||||
0x32, 0x9a, 0xbe, 0xd6, 0xd8, 0xac, 0x78, 0xf7, 0x20, 0x54, 0x97, 0xca, 0x51, 0x01, 0x81, 0x5a,
|
||||
0xa1, 0x89, 0x99, 0x8f, 0xfd, 0x92, 0xd2, 0x5f, 0x2e, 0x34, 0xd7, 0x76, 0x0d, 0x43, 0x6b, 0x24,
|
||||
0xe8, 0x8f, 0x2d, 0x72, 0x5e, 0x41, 0x9a, 0x7e, 0xb5, 0x65, 0x5c, 0x0a, 0x08, 0xd4, 0xc4, 0xce,
|
||||
0x9d, 0xed, 0x79, 0x9e, 0x3b, 0x3b, 0x43, 0x45, 0x97, 0x10, 0xea, 0x11, 0xa2, 0x6e, 0xdf, 0x99,
|
||||
0x71, 0x3a, 0xfd, 0x44, 0xf5, 0x6f, 0x8f, 0xa1, 0xa2, 0x17, 0x1f, 0x01, 0x00, 0x00, 0xff, 0xff,
|
||||
0x6f, 0xbe, 0x4a, 0x4f, 0x72, 0x03, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ grpc.ClientConnInterface
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc.SupportPackageIsVersion6
|
||||
|
||||
// WriterClient is the client API for Writer service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type WriterClient interface {
|
||||
Write(ctx context.Context, in *WriteRequest, opts ...grpc.CallOption) (*WriteResponse, error)
|
||||
WriteHeader(ctx context.Context, in *WriteHeaderRequest, opts ...grpc.CallOption) (*WriteHeaderResponse, error)
|
||||
Flush(ctx context.Context, in *FlushRequest, opts ...grpc.CallOption) (*FlushResponse, error)
|
||||
Hijack(ctx context.Context, in *HijackRequest, opts ...grpc.CallOption) (*HijackResponse, error)
|
||||
}
|
||||
|
||||
type writerClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewWriterClient(cc grpc.ClientConnInterface) WriterClient {
|
||||
return &writerClient{cc}
|
||||
}
|
||||
|
||||
func (c *writerClient) Write(ctx context.Context, in *WriteRequest, opts ...grpc.CallOption) (*WriteResponse, error) {
|
||||
out := new(WriteResponse)
|
||||
err := c.cc.Invoke(ctx, "/proto.Writer/Write", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *writerClient) WriteHeader(ctx context.Context, in *WriteHeaderRequest, opts ...grpc.CallOption) (*WriteHeaderResponse, error) {
|
||||
out := new(WriteHeaderResponse)
|
||||
err := c.cc.Invoke(ctx, "/proto.Writer/WriteHeader", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *writerClient) Flush(ctx context.Context, in *FlushRequest, opts ...grpc.CallOption) (*FlushResponse, error) {
|
||||
out := new(FlushResponse)
|
||||
err := c.cc.Invoke(ctx, "/proto.Writer/Flush", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *writerClient) Hijack(ctx context.Context, in *HijackRequest, opts ...grpc.CallOption) (*HijackResponse, error) {
|
||||
out := new(HijackResponse)
|
||||
err := c.cc.Invoke(ctx, "/proto.Writer/Hijack", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// WriterServer is the server API for Writer service.
|
||||
type WriterServer interface {
|
||||
Write(context.Context, *WriteRequest) (*WriteResponse, error)
|
||||
WriteHeader(context.Context, *WriteHeaderRequest) (*WriteHeaderResponse, error)
|
||||
Flush(context.Context, *FlushRequest) (*FlushResponse, error)
|
||||
Hijack(context.Context, *HijackRequest) (*HijackResponse, error)
|
||||
}
|
||||
|
||||
// UnimplementedWriterServer can be embedded to have forward compatible implementations.
|
||||
type UnimplementedWriterServer struct {
|
||||
}
|
||||
|
||||
func (*UnimplementedWriterServer) Write(ctx context.Context, req *WriteRequest) (*WriteResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Write not implemented")
|
||||
}
|
||||
func (*UnimplementedWriterServer) WriteHeader(ctx context.Context, req *WriteHeaderRequest) (*WriteHeaderResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method WriteHeader not implemented")
|
||||
}
|
||||
func (*UnimplementedWriterServer) Flush(ctx context.Context, req *FlushRequest) (*FlushResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Flush not implemented")
|
||||
}
|
||||
func (*UnimplementedWriterServer) Hijack(ctx context.Context, req *HijackRequest) (*HijackResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Hijack not implemented")
|
||||
}
|
||||
|
||||
func RegisterWriterServer(s *grpc.Server, srv WriterServer) {
|
||||
s.RegisterService(&_Writer_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _Writer_Write_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(WriteRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(WriterServer).Write(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/proto.Writer/Write",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(WriterServer).Write(ctx, req.(*WriteRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Writer_WriteHeader_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(WriteHeaderRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(WriterServer).WriteHeader(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/proto.Writer/WriteHeader",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(WriterServer).WriteHeader(ctx, req.(*WriteHeaderRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Writer_Flush_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(FlushRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(WriterServer).Flush(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/proto.Writer/Flush",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(WriterServer).Flush(ctx, req.(*FlushRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Writer_Hijack_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(HijackRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(WriterServer).Hijack(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/proto.Writer/Hijack",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(WriterServer).Hijack(ctx, req.(*HijackRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _Writer_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "proto.Writer",
|
||||
HandlerType: (*WriterServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Write",
|
||||
Handler: _Writer_Write_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "WriteHeader",
|
||||
Handler: _Writer_WriteHeader_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Flush",
|
||||
Handler: _Writer_Flush_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Hijack",
|
||||
Handler: _Writer_Hijack_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "writer.proto",
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
syntax = "proto3";
|
||||
package proto;
|
||||
|
||||
message Header {
|
||||
string key = 1;
|
||||
repeated string values = 2;
|
||||
}
|
||||
|
||||
message WriteRequest {
|
||||
repeated Header headers = 1;
|
||||
bytes payload = 2;
|
||||
}
|
||||
|
||||
message WriteResponse {
|
||||
int32 written = 1;
|
||||
}
|
||||
|
||||
message WriteHeaderRequest {
|
||||
repeated Header headers = 1;
|
||||
int32 statusCode = 2;
|
||||
}
|
||||
|
||||
message WriteHeaderResponse {}
|
||||
|
||||
message FlushRequest {}
|
||||
|
||||
message FlushResponse {}
|
||||
|
||||
message HijackRequest {}
|
||||
|
||||
message HijackResponse {
|
||||
uint32 connServer = 1;
|
||||
string localNetwork = 2;
|
||||
string localString = 3;
|
||||
string remoteNetwork = 4;
|
||||
string remoteString = 5;
|
||||
uint32 readerServer = 6;
|
||||
uint32 writerServer = 7;
|
||||
}
|
||||
|
||||
service Writer {
|
||||
rpc Write(WriteRequest) returns (WriteResponse);
|
||||
rpc WriteHeader(WriteHeaderRequest) returns (WriteHeaderResponse);
|
||||
rpc Flush(FlushRequest) returns (FlushResponse);
|
||||
rpc Hijack(HijackRequest) returns (HijackResponse);
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package gresponsewriter
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/hashicorp/go-plugin"
|
||||
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/gconn"
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/greader"
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/gwriter"
|
||||
|
||||
connproto "github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/gconn/proto"
|
||||
readerproto "github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/greader/proto"
|
||||
responsewriterproto "github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/gresponsewriter/proto"
|
||||
writerproto "github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/gwriter/proto"
|
||||
)
|
||||
|
||||
// Client is an implementation of a messenger channel that talks over RPC.
|
||||
type Client struct {
|
||||
client responsewriterproto.WriterClient
|
||||
header http.Header
|
||||
broker *plugin.GRPCBroker
|
||||
}
|
||||
|
||||
// NewClient returns a database instance connected to a remote database instance
|
||||
func NewClient(client responsewriterproto.WriterClient, broker *plugin.GRPCBroker) *Client {
|
||||
return &Client{
|
||||
client: client,
|
||||
header: make(http.Header),
|
||||
broker: broker,
|
||||
}
|
||||
}
|
||||
|
||||
// Header ...
|
||||
func (c *Client) Header() http.Header { return c.header }
|
||||
|
||||
// Write ...
|
||||
func (c *Client) Write(payload []byte) (int, error) {
|
||||
req := &responsewriterproto.WriteRequest{
|
||||
Headers: make([]*responsewriterproto.Header, 0, len(c.header)),
|
||||
Payload: payload,
|
||||
}
|
||||
for key, values := range c.header {
|
||||
req.Headers = append(req.Headers, &responsewriterproto.Header{
|
||||
Key: key,
|
||||
Values: values,
|
||||
})
|
||||
}
|
||||
resp, err := c.client.Write(context.Background(), req)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(resp.Written), nil
|
||||
}
|
||||
|
||||
// WriteHeader ...
|
||||
func (c *Client) WriteHeader(statusCode int) {
|
||||
req := &responsewriterproto.WriteHeaderRequest{
|
||||
Headers: make([]*responsewriterproto.Header, 0, len(c.header)),
|
||||
StatusCode: int32(statusCode),
|
||||
}
|
||||
for key, values := range c.header {
|
||||
req.Headers = append(req.Headers, &responsewriterproto.Header{
|
||||
Key: key,
|
||||
Values: values,
|
||||
})
|
||||
}
|
||||
// TODO: How should we handle an error here?
|
||||
c.client.WriteHeader(context.Background(), req)
|
||||
}
|
||||
|
||||
// Flush ...
|
||||
func (c *Client) Flush() {
|
||||
// TODO: How should we handle an error here?
|
||||
c.client.Flush(context.Background(), &responsewriterproto.FlushRequest{})
|
||||
}
|
||||
|
||||
type addr struct {
|
||||
network string
|
||||
str string
|
||||
}
|
||||
|
||||
func (a *addr) Network() string { return a.network }
|
||||
func (a *addr) String() string { return a.str }
|
||||
|
||||
// Hijack ...
|
||||
func (c *Client) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||
resp, err := c.client.Hijack(context.Background(), &responsewriterproto.HijackRequest{})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
connConn, err := c.broker.Dial(resp.ConnServer)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
readerConn, err := c.broker.Dial(resp.ReaderServer)
|
||||
if err != nil {
|
||||
connConn.Close()
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
writerConn, err := c.broker.Dial(resp.WriterServer)
|
||||
if err != nil {
|
||||
connConn.Close()
|
||||
readerConn.Close()
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
conn := gconn.NewClient(connproto.NewConnClient(connConn), &addr{
|
||||
network: resp.LocalNetwork,
|
||||
str: resp.LocalString,
|
||||
}, &addr{
|
||||
network: resp.RemoteNetwork,
|
||||
str: resp.RemoteString,
|
||||
}, connConn, readerConn, writerConn)
|
||||
|
||||
reader := greader.NewClient(readerproto.NewReaderClient(readerConn))
|
||||
writer := gwriter.NewClient(writerproto.NewWriterClient(writerConn))
|
||||
|
||||
readWriter := bufio.NewReadWriter(
|
||||
bufio.NewReader(reader),
|
||||
bufio.NewWriter(writer),
|
||||
)
|
||||
|
||||
return conn, readWriter, nil
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package gresponsewriter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/gconn"
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/greader"
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/gwriter"
|
||||
|
||||
"github.com/hashicorp/go-plugin"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
connproto "github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/gconn/proto"
|
||||
readerproto "github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/greader/proto"
|
||||
responsewriterproto "github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/gresponsewriter/proto"
|
||||
writerproto "github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/gwriter/proto"
|
||||
)
|
||||
|
||||
// Server is a http.Handler that is managed over RPC.
|
||||
type Server struct {
|
||||
writer http.ResponseWriter
|
||||
broker *plugin.GRPCBroker
|
||||
}
|
||||
|
||||
// NewServer returns a http.Handler instance manage remotely
|
||||
func NewServer(writer http.ResponseWriter, broker *plugin.GRPCBroker) *Server {
|
||||
return &Server{
|
||||
writer: writer,
|
||||
broker: broker,
|
||||
}
|
||||
}
|
||||
|
||||
// Write ...
|
||||
func (s *Server) Write(ctx context.Context, req *responsewriterproto.WriteRequest) (*responsewriterproto.WriteResponse, error) {
|
||||
headers := s.writer.Header()
|
||||
for key := range headers {
|
||||
delete(headers, key)
|
||||
}
|
||||
for _, header := range req.Headers {
|
||||
headers[header.Key] = header.Values
|
||||
}
|
||||
|
||||
n, err := s.writer.Write(req.Payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &responsewriterproto.WriteResponse{
|
||||
Written: int32(n),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// WriteHeader ...
|
||||
func (s *Server) WriteHeader(ctx context.Context, req *responsewriterproto.WriteHeaderRequest) (*responsewriterproto.WriteHeaderResponse, error) {
|
||||
headers := s.writer.Header()
|
||||
for key := range headers {
|
||||
delete(headers, key)
|
||||
}
|
||||
for _, header := range req.Headers {
|
||||
headers[header.Key] = header.Values
|
||||
}
|
||||
s.writer.WriteHeader(int(req.StatusCode))
|
||||
return &responsewriterproto.WriteHeaderResponse{}, nil
|
||||
}
|
||||
|
||||
// Flush ...
|
||||
func (s *Server) Flush(ctx context.Context, req *responsewriterproto.FlushRequest) (*responsewriterproto.FlushResponse, error) {
|
||||
flusher, ok := s.writer.(http.Flusher)
|
||||
if !ok {
|
||||
return nil, errors.New("response writer doesn't support flushing")
|
||||
}
|
||||
flusher.Flush()
|
||||
return &responsewriterproto.FlushResponse{}, nil
|
||||
}
|
||||
|
||||
// Hijack ...
|
||||
func (s *Server) Hijack(ctx context.Context, req *responsewriterproto.HijackRequest) (*responsewriterproto.HijackResponse, error) {
|
||||
hijacker, ok := s.writer.(http.Hijacker)
|
||||
if !ok {
|
||||
return nil, errors.New("response writer doesn't support hijacking")
|
||||
}
|
||||
conn, readWriter, err := hijacker.Hijack()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
connID := s.broker.NextId()
|
||||
readerID := s.broker.NextId()
|
||||
writerID := s.broker.NextId()
|
||||
|
||||
go s.broker.AcceptAndServe(connID, func(opts []grpc.ServerOption) *grpc.Server {
|
||||
connServer := grpc.NewServer(opts...)
|
||||
connproto.RegisterConnServer(connServer, gconn.NewServer(conn))
|
||||
return connServer
|
||||
})
|
||||
go s.broker.AcceptAndServe(readerID, func(opts []grpc.ServerOption) *grpc.Server {
|
||||
readerServer := grpc.NewServer(opts...)
|
||||
readerproto.RegisterReaderServer(readerServer, greader.NewServer(readWriter))
|
||||
return readerServer
|
||||
})
|
||||
go s.broker.AcceptAndServe(writerID, func(opts []grpc.ServerOption) *grpc.Server {
|
||||
writerServer := grpc.NewServer(opts...)
|
||||
writerproto.RegisterWriterServer(writerServer, gwriter.NewServer(readWriter))
|
||||
return writerServer
|
||||
})
|
||||
|
||||
local := conn.LocalAddr()
|
||||
remote := conn.RemoteAddr()
|
||||
|
||||
return &responsewriterproto.HijackResponse{
|
||||
ConnServer: connID,
|
||||
LocalNetwork: local.Network(),
|
||||
LocalString: local.String(),
|
||||
RemoteNetwork: remote.Network(),
|
||||
RemoteString: remote.String(),
|
||||
ReaderServer: readerID,
|
||||
WriterServer: writerID,
|
||||
}, nil
|
||||
}
|
|
@ -0,0 +1,221 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: writer.proto
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
type WriteRequest struct {
|
||||
Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *WriteRequest) Reset() { *m = WriteRequest{} }
|
||||
func (m *WriteRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*WriteRequest) ProtoMessage() {}
|
||||
func (*WriteRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_ea6fbe89c42e6759, []int{0}
|
||||
}
|
||||
|
||||
func (m *WriteRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_WriteRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *WriteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_WriteRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *WriteRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_WriteRequest.Merge(m, src)
|
||||
}
|
||||
func (m *WriteRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_WriteRequest.Size(m)
|
||||
}
|
||||
func (m *WriteRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_WriteRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_WriteRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *WriteRequest) GetPayload() []byte {
|
||||
if m != nil {
|
||||
return m.Payload
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type WriteResponse struct {
|
||||
Written int32 `protobuf:"varint,1,opt,name=written,proto3" json:"written,omitempty"`
|
||||
Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"`
|
||||
Errored bool `protobuf:"varint,3,opt,name=errored,proto3" json:"errored,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *WriteResponse) Reset() { *m = WriteResponse{} }
|
||||
func (m *WriteResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*WriteResponse) ProtoMessage() {}
|
||||
func (*WriteResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_ea6fbe89c42e6759, []int{1}
|
||||
}
|
||||
|
||||
func (m *WriteResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_WriteResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *WriteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_WriteResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *WriteResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_WriteResponse.Merge(m, src)
|
||||
}
|
||||
func (m *WriteResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_WriteResponse.Size(m)
|
||||
}
|
||||
func (m *WriteResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_WriteResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_WriteResponse proto.InternalMessageInfo
|
||||
|
||||
func (m *WriteResponse) GetWritten() int32 {
|
||||
if m != nil {
|
||||
return m.Written
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *WriteResponse) GetError() string {
|
||||
if m != nil {
|
||||
return m.Error
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *WriteResponse) GetErrored() bool {
|
||||
if m != nil {
|
||||
return m.Errored
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*WriteRequest)(nil), "proto.WriteRequest")
|
||||
proto.RegisterType((*WriteResponse)(nil), "proto.WriteResponse")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("writer.proto", fileDescriptor_ea6fbe89c42e6759) }
|
||||
|
||||
var fileDescriptor_ea6fbe89c42e6759 = []byte{
|
||||
// 164 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0x2f, 0xca, 0x2c,
|
||||
0x49, 0x2d, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x05, 0x53, 0x4a, 0x1a, 0x5c, 0x3c,
|
||||
0xe1, 0x20, 0xe1, 0xa0, 0xd4, 0xc2, 0xd2, 0xd4, 0xe2, 0x12, 0x21, 0x09, 0x2e, 0xf6, 0x82, 0xc4,
|
||||
0xca, 0x9c, 0xfc, 0xc4, 0x14, 0x09, 0x46, 0x05, 0x46, 0x0d, 0x9e, 0x20, 0x18, 0x57, 0x29, 0x92,
|
||||
0x8b, 0x17, 0xaa, 0xb2, 0xb8, 0x20, 0x3f, 0xaf, 0x38, 0x15, 0xa4, 0x14, 0x64, 0x62, 0x49, 0x6a,
|
||||
0x1e, 0x58, 0x29, 0x6b, 0x10, 0x8c, 0x2b, 0x24, 0xc2, 0xc5, 0x9a, 0x5a, 0x54, 0x94, 0x5f, 0x24,
|
||||
0xc1, 0xa4, 0xc0, 0xa8, 0xc1, 0x19, 0x04, 0xe1, 0x80, 0xd4, 0x83, 0x19, 0xa9, 0x29, 0x12, 0xcc,
|
||||
0x0a, 0x8c, 0x1a, 0x1c, 0x41, 0x30, 0xae, 0x91, 0x0d, 0x17, 0x1b, 0xd8, 0xe8, 0x22, 0x21, 0x23,
|
||||
0x2e, 0x56, 0x30, 0x4b, 0x48, 0x18, 0xe2, 0x4c, 0x3d, 0x64, 0xc7, 0x49, 0x89, 0xa0, 0x0a, 0x42,
|
||||
0xdc, 0x91, 0xc4, 0x06, 0x16, 0x34, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x3e, 0x3f, 0xbb, 0x2f,
|
||||
0xe0, 0x00, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ grpc.ClientConnInterface
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc.SupportPackageIsVersion6
|
||||
|
||||
// WriterClient is the client API for Writer service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type WriterClient interface {
|
||||
Write(ctx context.Context, in *WriteRequest, opts ...grpc.CallOption) (*WriteResponse, error)
|
||||
}
|
||||
|
||||
type writerClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewWriterClient(cc grpc.ClientConnInterface) WriterClient {
|
||||
return &writerClient{cc}
|
||||
}
|
||||
|
||||
func (c *writerClient) Write(ctx context.Context, in *WriteRequest, opts ...grpc.CallOption) (*WriteResponse, error) {
|
||||
out := new(WriteResponse)
|
||||
err := c.cc.Invoke(ctx, "/proto.Writer/Write", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// WriterServer is the server API for Writer service.
|
||||
type WriterServer interface {
|
||||
Write(context.Context, *WriteRequest) (*WriteResponse, error)
|
||||
}
|
||||
|
||||
// UnimplementedWriterServer can be embedded to have forward compatible implementations.
|
||||
type UnimplementedWriterServer struct {
|
||||
}
|
||||
|
||||
func (*UnimplementedWriterServer) Write(ctx context.Context, req *WriteRequest) (*WriteResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Write not implemented")
|
||||
}
|
||||
|
||||
func RegisterWriterServer(s *grpc.Server, srv WriterServer) {
|
||||
s.RegisterService(&_Writer_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _Writer_Write_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(WriteRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(WriterServer).Write(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/proto.Writer/Write",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(WriterServer).Write(ctx, req.(*WriteRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _Writer_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "proto.Writer",
|
||||
HandlerType: (*WriterServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Write",
|
||||
Handler: _Writer_Write_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "writer.proto",
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
syntax = "proto3";
|
||||
package proto;
|
||||
|
||||
message WriteRequest {
|
||||
bytes payload = 1;
|
||||
}
|
||||
|
||||
message WriteResponse {
|
||||
int32 written = 1;
|
||||
string error = 2;
|
||||
bool errored = 3;
|
||||
}
|
||||
|
||||
service Writer {
|
||||
rpc Write(WriteRequest) returns (WriteResponse);
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package gwriter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/gwriter/proto"
|
||||
)
|
||||
|
||||
// Client is an implementation of a messenger channel that talks over RPC.
|
||||
type Client struct{ client proto.WriterClient }
|
||||
|
||||
// NewClient returns a database instance connected to a remote database instance
|
||||
func NewClient(client proto.WriterClient) *Client {
|
||||
return &Client{client: client}
|
||||
}
|
||||
|
||||
// Write ...
|
||||
func (c *Client) Write(p []byte) (int, error) {
|
||||
resp, err := c.client.Write(context.Background(), &proto.WriteRequest{
|
||||
Payload: p,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if resp.Errored {
|
||||
err = errors.New(resp.Error)
|
||||
}
|
||||
return int(resp.Written), err
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package gwriter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/gwriter/proto"
|
||||
)
|
||||
|
||||
// Server is a http.Handler that is managed over RPC.
|
||||
type Server struct{ writer io.Writer }
|
||||
|
||||
// NewServer returns a http.Handler instance manage remotely
|
||||
func NewServer(writer io.Writer) *Server {
|
||||
return &Server{writer: writer}
|
||||
}
|
||||
|
||||
// Write ...
|
||||
func (s *Server) Write(ctx context.Context, req *proto.WriteRequest) (*proto.WriteResponse, error) {
|
||||
n, err := s.writer.Write(req.Payload)
|
||||
resp := &proto.WriteResponse{
|
||||
Written: int32(n),
|
||||
}
|
||||
if err != nil {
|
||||
resp.Errored = true
|
||||
resp.Error = err.Error()
|
||||
}
|
||||
return resp, nil
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package ghttp
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/hashicorp/go-plugin"
|
||||
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/greadcloser"
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/gresponsewriter"
|
||||
|
||||
readcloserproto "github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/greadcloser/proto"
|
||||
responsewriterproto "github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/gresponsewriter/proto"
|
||||
httpproto "github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/proto"
|
||||
)
|
||||
|
||||
// Client is an implementation of a messenger channel that talks over RPC.
|
||||
type Client struct {
|
||||
client httpproto.HTTPClient
|
||||
broker *plugin.GRPCBroker
|
||||
}
|
||||
|
||||
// NewClient returns a database instance connected to a remote database instance
|
||||
func NewClient(client httpproto.HTTPClient, broker *plugin.GRPCBroker) *Client {
|
||||
return &Client{
|
||||
client: client,
|
||||
broker: broker,
|
||||
}
|
||||
}
|
||||
|
||||
// Handle ...
|
||||
func (c *Client) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
var reader *grpc.Server
|
||||
var writer *grpc.Server
|
||||
|
||||
readerID := c.broker.NextId()
|
||||
go c.broker.AcceptAndServe(readerID, func(opts []grpc.ServerOption) *grpc.Server {
|
||||
reader = grpc.NewServer(opts...)
|
||||
readcloserproto.RegisterReaderServer(reader, greadcloser.NewServer(r.Body))
|
||||
|
||||
return reader
|
||||
})
|
||||
writerID := c.broker.NextId()
|
||||
go c.broker.AcceptAndServe(writerID, func(opts []grpc.ServerOption) *grpc.Server {
|
||||
writer = grpc.NewServer(opts...)
|
||||
responsewriterproto.RegisterWriterServer(writer, gresponsewriter.NewServer(w, c.broker))
|
||||
|
||||
return writer
|
||||
})
|
||||
|
||||
req := &httpproto.HTTPRequest{
|
||||
ResponseWriter: writerID,
|
||||
Request: &httpproto.Request{
|
||||
Method: r.Method,
|
||||
Proto: r.Proto,
|
||||
ProtoMajor: int32(r.ProtoMajor),
|
||||
ProtoMinor: int32(r.ProtoMinor),
|
||||
Body: readerID,
|
||||
ContentLength: r.ContentLength,
|
||||
TransferEncoding: r.TransferEncoding,
|
||||
Host: r.Host,
|
||||
RemoteAddr: r.RemoteAddr,
|
||||
RequestURI: r.RequestURI,
|
||||
},
|
||||
}
|
||||
req.Request.Header = make([]*httpproto.Element, 0, len(r.Header))
|
||||
for key, values := range r.Header {
|
||||
req.Request.Header = append(req.Request.Header, &httpproto.Element{
|
||||
Key: key,
|
||||
Values: values,
|
||||
})
|
||||
}
|
||||
|
||||
req.Request.Form = make([]*httpproto.Element, 0, len(r.Form))
|
||||
for key, values := range r.Form {
|
||||
req.Request.Form = append(req.Request.Form, &httpproto.Element{
|
||||
Key: key,
|
||||
Values: values,
|
||||
})
|
||||
}
|
||||
|
||||
req.Request.PostForm = make([]*httpproto.Element, 0, len(r.PostForm))
|
||||
for key, values := range r.PostForm {
|
||||
req.Request.PostForm = append(req.Request.PostForm, &httpproto.Element{
|
||||
Key: key,
|
||||
Values: values,
|
||||
})
|
||||
}
|
||||
|
||||
if r.URL != nil {
|
||||
req.Request.Url = &httpproto.URL{
|
||||
Scheme: r.URL.Scheme,
|
||||
Opaque: r.URL.Opaque,
|
||||
Host: r.URL.Host,
|
||||
Path: r.URL.Path,
|
||||
RawPath: r.URL.RawPath,
|
||||
ForceQuery: r.URL.ForceQuery,
|
||||
RawQuery: r.URL.RawQuery,
|
||||
Fragment: r.URL.Fragment,
|
||||
}
|
||||
|
||||
if r.URL.User != nil {
|
||||
req.Request.Url.User = &httpproto.Userinfo{
|
||||
Username: r.URL.User.Username(),
|
||||
}
|
||||
pwd, set := r.URL.User.Password()
|
||||
req.Request.Url.User.Password = pwd
|
||||
req.Request.Url.User.PasswordSet = set
|
||||
}
|
||||
}
|
||||
|
||||
if r.TLS != nil {
|
||||
req.Request.Tls = &httpproto.ConnectionState{
|
||||
Version: uint32(r.TLS.Version),
|
||||
HandshakeComplete: r.TLS.HandshakeComplete,
|
||||
DidResume: r.TLS.DidResume,
|
||||
CipherSuite: uint32(r.TLS.CipherSuite),
|
||||
NegotiatedProtocol: r.TLS.NegotiatedProtocol,
|
||||
NegotiatedProtocolIsMutual: r.TLS.NegotiatedProtocolIsMutual,
|
||||
ServerName: r.TLS.ServerName,
|
||||
SignedCertificateTimestamps: r.TLS.SignedCertificateTimestamps,
|
||||
OcspResponse: r.TLS.OCSPResponse,
|
||||
TlsUnique: r.TLS.TLSUnique,
|
||||
}
|
||||
|
||||
req.Request.Tls.PeerCertificates = &httpproto.Certificates{
|
||||
Cert: make([][]byte, len(r.TLS.PeerCertificates)),
|
||||
}
|
||||
for i, cert := range r.TLS.PeerCertificates {
|
||||
req.Request.Tls.PeerCertificates.Cert[i] = cert.Raw
|
||||
}
|
||||
|
||||
req.Request.Tls.VerifiedChains = make([]*httpproto.Certificates, len(r.TLS.VerifiedChains))
|
||||
for i, chain := range r.TLS.VerifiedChains {
|
||||
req.Request.Tls.VerifiedChains[i] = &httpproto.Certificates{
|
||||
Cert: make([][]byte, len(chain)),
|
||||
}
|
||||
for j, cert := range chain {
|
||||
req.Request.Tls.VerifiedChains[i].Cert[j] = cert.Raw
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c.client.Handle(r.Context(), req)
|
||||
|
||||
reader.Stop()
|
||||
writer.Stop()
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package ghttp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/hashicorp/go-plugin"
|
||||
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/greadcloser"
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/gresponsewriter"
|
||||
|
||||
readcloserproto "github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/greadcloser/proto"
|
||||
responsewriterproto "github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/gresponsewriter/proto"
|
||||
httpproto "github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/proto"
|
||||
)
|
||||
|
||||
// Server is a http.Handler that is managed over RPC.
|
||||
type Server struct {
|
||||
handler http.Handler
|
||||
broker *plugin.GRPCBroker
|
||||
}
|
||||
|
||||
// NewServer returns a http.Handler instance manage remotely
|
||||
func NewServer(handler http.Handler, broker *plugin.GRPCBroker) *Server {
|
||||
return &Server{
|
||||
handler: handler,
|
||||
broker: broker,
|
||||
}
|
||||
}
|
||||
|
||||
// Handle ...
|
||||
func (s *Server) Handle(ctx context.Context, req *httpproto.HTTPRequest) (*httpproto.HTTPResponse, error) {
|
||||
writerConn, err := s.broker.Dial(req.ResponseWriter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer writerConn.Close()
|
||||
|
||||
readerConn, err := s.broker.Dial(req.Request.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer readerConn.Close()
|
||||
|
||||
writer := gresponsewriter.NewClient(responsewriterproto.NewWriterClient(writerConn), s.broker)
|
||||
reader := greadcloser.NewClient(readcloserproto.NewReaderClient(readerConn))
|
||||
|
||||
// create the request with the current context
|
||||
request, err := http.NewRequestWithContext(
|
||||
ctx,
|
||||
req.Request.Method,
|
||||
req.Request.RequestURI,
|
||||
reader,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if req.Request.Url != nil {
|
||||
request.URL = &url.URL{
|
||||
Scheme: req.Request.Url.Scheme,
|
||||
Opaque: req.Request.Url.Opaque,
|
||||
Host: req.Request.Url.Host,
|
||||
Path: req.Request.Url.Path,
|
||||
RawPath: req.Request.Url.RawPath,
|
||||
ForceQuery: req.Request.Url.ForceQuery,
|
||||
RawQuery: req.Request.Url.RawQuery,
|
||||
Fragment: req.Request.Url.Fragment,
|
||||
}
|
||||
if req.Request.Url.User != nil {
|
||||
if req.Request.Url.User.PasswordSet {
|
||||
request.URL.User = url.UserPassword(req.Request.Url.User.Username, req.Request.Url.User.Password)
|
||||
} else {
|
||||
request.URL.User = url.User(req.Request.Url.User.Username)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
request.Proto = req.Request.Proto
|
||||
request.ProtoMajor = int(req.Request.ProtoMajor)
|
||||
request.ProtoMinor = int(req.Request.ProtoMinor)
|
||||
request.Header = make(http.Header, len(req.Request.Header))
|
||||
for _, elem := range req.Request.Header {
|
||||
request.Header[elem.Key] = elem.Values
|
||||
}
|
||||
request.ContentLength = req.Request.ContentLength
|
||||
request.TransferEncoding = req.Request.TransferEncoding
|
||||
request.Host = req.Request.Host
|
||||
request.Form = make(url.Values, len(req.Request.Form))
|
||||
for _, elem := range req.Request.Form {
|
||||
request.Form[elem.Key] = elem.Values
|
||||
}
|
||||
request.PostForm = make(url.Values, len(req.Request.PostForm))
|
||||
for _, elem := range req.Request.PostForm {
|
||||
request.PostForm[elem.Key] = elem.Values
|
||||
}
|
||||
request.Trailer = make(http.Header)
|
||||
request.RemoteAddr = req.Request.RemoteAddr
|
||||
request.RequestURI = req.Request.RequestURI
|
||||
|
||||
if req.Request.Tls != nil {
|
||||
request.TLS = &tls.ConnectionState{
|
||||
Version: uint16(req.Request.Tls.Version),
|
||||
HandshakeComplete: req.Request.Tls.HandshakeComplete,
|
||||
DidResume: req.Request.Tls.DidResume,
|
||||
CipherSuite: uint16(req.Request.Tls.CipherSuite),
|
||||
NegotiatedProtocol: req.Request.Tls.NegotiatedProtocol,
|
||||
NegotiatedProtocolIsMutual: req.Request.Tls.NegotiatedProtocolIsMutual,
|
||||
ServerName: req.Request.Tls.ServerName,
|
||||
SignedCertificateTimestamps: req.Request.Tls.SignedCertificateTimestamps,
|
||||
OCSPResponse: req.Request.Tls.OcspResponse,
|
||||
TLSUnique: req.Request.Tls.TlsUnique,
|
||||
}
|
||||
|
||||
request.TLS.PeerCertificates = make([]*x509.Certificate, len(req.Request.Tls.PeerCertificates.Cert))
|
||||
for i, certBytes := range req.Request.Tls.PeerCertificates.Cert {
|
||||
cert, err := x509.ParseCertificate(certBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
request.TLS.PeerCertificates[i] = cert
|
||||
}
|
||||
|
||||
request.TLS.VerifiedChains = make([][]*x509.Certificate, len(req.Request.Tls.VerifiedChains))
|
||||
for i, chain := range req.Request.Tls.VerifiedChains {
|
||||
request.TLS.VerifiedChains[i] = make([]*x509.Certificate, len(chain.Cert))
|
||||
for j, certBytes := range chain.Cert {
|
||||
cert, err := x509.ParseCertificate(certBytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
request.TLS.VerifiedChains[i][j] = cert
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s.handler.ServeHTTP(writer, request)
|
||||
|
||||
// return the response
|
||||
return &httpproto.HTTPResponse{}, nil
|
||||
}
|
|
@ -0,0 +1,781 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: http.proto
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
type Userinfo struct {
|
||||
Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"`
|
||||
Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`
|
||||
PasswordSet bool `protobuf:"varint,3,opt,name=passwordSet,proto3" json:"passwordSet,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Userinfo) Reset() { *m = Userinfo{} }
|
||||
func (m *Userinfo) String() string { return proto.CompactTextString(m) }
|
||||
func (*Userinfo) ProtoMessage() {}
|
||||
func (*Userinfo) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_11b04836674e6f94, []int{0}
|
||||
}
|
||||
|
||||
func (m *Userinfo) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Userinfo.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Userinfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Userinfo.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Userinfo) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Userinfo.Merge(m, src)
|
||||
}
|
||||
func (m *Userinfo) XXX_Size() int {
|
||||
return xxx_messageInfo_Userinfo.Size(m)
|
||||
}
|
||||
func (m *Userinfo) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Userinfo.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Userinfo proto.InternalMessageInfo
|
||||
|
||||
func (m *Userinfo) GetUsername() string {
|
||||
if m != nil {
|
||||
return m.Username
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Userinfo) GetPassword() string {
|
||||
if m != nil {
|
||||
return m.Password
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Userinfo) GetPasswordSet() bool {
|
||||
if m != nil {
|
||||
return m.PasswordSet
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type URL struct {
|
||||
Scheme string `protobuf:"bytes,1,opt,name=scheme,proto3" json:"scheme,omitempty"`
|
||||
Opaque string `protobuf:"bytes,2,opt,name=opaque,proto3" json:"opaque,omitempty"`
|
||||
User *Userinfo `protobuf:"bytes,3,opt,name=user,proto3" json:"user,omitempty"`
|
||||
Host string `protobuf:"bytes,4,opt,name=host,proto3" json:"host,omitempty"`
|
||||
Path string `protobuf:"bytes,5,opt,name=path,proto3" json:"path,omitempty"`
|
||||
RawPath string `protobuf:"bytes,6,opt,name=rawPath,proto3" json:"rawPath,omitempty"`
|
||||
ForceQuery bool `protobuf:"varint,7,opt,name=forceQuery,proto3" json:"forceQuery,omitempty"`
|
||||
RawQuery string `protobuf:"bytes,8,opt,name=rawQuery,proto3" json:"rawQuery,omitempty"`
|
||||
Fragment string `protobuf:"bytes,9,opt,name=fragment,proto3" json:"fragment,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *URL) Reset() { *m = URL{} }
|
||||
func (m *URL) String() string { return proto.CompactTextString(m) }
|
||||
func (*URL) ProtoMessage() {}
|
||||
func (*URL) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_11b04836674e6f94, []int{1}
|
||||
}
|
||||
|
||||
func (m *URL) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_URL.Unmarshal(m, b)
|
||||
}
|
||||
func (m *URL) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_URL.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *URL) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_URL.Merge(m, src)
|
||||
}
|
||||
func (m *URL) XXX_Size() int {
|
||||
return xxx_messageInfo_URL.Size(m)
|
||||
}
|
||||
func (m *URL) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_URL.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_URL proto.InternalMessageInfo
|
||||
|
||||
func (m *URL) GetScheme() string {
|
||||
if m != nil {
|
||||
return m.Scheme
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *URL) GetOpaque() string {
|
||||
if m != nil {
|
||||
return m.Opaque
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *URL) GetUser() *Userinfo {
|
||||
if m != nil {
|
||||
return m.User
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *URL) GetHost() string {
|
||||
if m != nil {
|
||||
return m.Host
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *URL) GetPath() string {
|
||||
if m != nil {
|
||||
return m.Path
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *URL) GetRawPath() string {
|
||||
if m != nil {
|
||||
return m.RawPath
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *URL) GetForceQuery() bool {
|
||||
if m != nil {
|
||||
return m.ForceQuery
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *URL) GetRawQuery() string {
|
||||
if m != nil {
|
||||
return m.RawQuery
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *URL) GetFragment() string {
|
||||
if m != nil {
|
||||
return m.Fragment
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Element struct {
|
||||
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
|
||||
Values []string `protobuf:"bytes,2,rep,name=values,proto3" json:"values,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Element) Reset() { *m = Element{} }
|
||||
func (m *Element) String() string { return proto.CompactTextString(m) }
|
||||
func (*Element) ProtoMessage() {}
|
||||
func (*Element) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_11b04836674e6f94, []int{2}
|
||||
}
|
||||
|
||||
func (m *Element) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Element.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Element) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Element.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Element) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Element.Merge(m, src)
|
||||
}
|
||||
func (m *Element) XXX_Size() int {
|
||||
return xxx_messageInfo_Element.Size(m)
|
||||
}
|
||||
func (m *Element) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Element.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Element proto.InternalMessageInfo
|
||||
|
||||
func (m *Element) GetKey() string {
|
||||
if m != nil {
|
||||
return m.Key
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Element) GetValues() []string {
|
||||
if m != nil {
|
||||
return m.Values
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Certificates struct {
|
||||
Cert [][]byte `protobuf:"bytes,1,rep,name=cert,proto3" json:"cert,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Certificates) Reset() { *m = Certificates{} }
|
||||
func (m *Certificates) String() string { return proto.CompactTextString(m) }
|
||||
func (*Certificates) ProtoMessage() {}
|
||||
func (*Certificates) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_11b04836674e6f94, []int{3}
|
||||
}
|
||||
|
||||
func (m *Certificates) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Certificates.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Certificates) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Certificates.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Certificates) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Certificates.Merge(m, src)
|
||||
}
|
||||
func (m *Certificates) XXX_Size() int {
|
||||
return xxx_messageInfo_Certificates.Size(m)
|
||||
}
|
||||
func (m *Certificates) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Certificates.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Certificates proto.InternalMessageInfo
|
||||
|
||||
func (m *Certificates) GetCert() [][]byte {
|
||||
if m != nil {
|
||||
return m.Cert
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ConnectionState struct {
|
||||
Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"`
|
||||
HandshakeComplete bool `protobuf:"varint,2,opt,name=handshakeComplete,proto3" json:"handshakeComplete,omitempty"`
|
||||
DidResume bool `protobuf:"varint,3,opt,name=didResume,proto3" json:"didResume,omitempty"`
|
||||
CipherSuite uint32 `protobuf:"varint,4,opt,name=cipherSuite,proto3" json:"cipherSuite,omitempty"`
|
||||
NegotiatedProtocol string `protobuf:"bytes,5,opt,name=negotiatedProtocol,proto3" json:"negotiatedProtocol,omitempty"`
|
||||
NegotiatedProtocolIsMutual bool `protobuf:"varint,6,opt,name=negotiatedProtocolIsMutual,proto3" json:"negotiatedProtocolIsMutual,omitempty"`
|
||||
ServerName string `protobuf:"bytes,7,opt,name=serverName,proto3" json:"serverName,omitempty"`
|
||||
PeerCertificates *Certificates `protobuf:"bytes,8,opt,name=peerCertificates,proto3" json:"peerCertificates,omitempty"`
|
||||
VerifiedChains []*Certificates `protobuf:"bytes,9,rep,name=verifiedChains,proto3" json:"verifiedChains,omitempty"`
|
||||
SignedCertificateTimestamps [][]byte `protobuf:"bytes,10,rep,name=signedCertificateTimestamps,proto3" json:"signedCertificateTimestamps,omitempty"`
|
||||
OcspResponse []byte `protobuf:"bytes,11,opt,name=ocspResponse,proto3" json:"ocspResponse,omitempty"`
|
||||
TlsUnique []byte `protobuf:"bytes,12,opt,name=tlsUnique,proto3" json:"tlsUnique,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ConnectionState) Reset() { *m = ConnectionState{} }
|
||||
func (m *ConnectionState) String() string { return proto.CompactTextString(m) }
|
||||
func (*ConnectionState) ProtoMessage() {}
|
||||
func (*ConnectionState) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_11b04836674e6f94, []int{4}
|
||||
}
|
||||
|
||||
func (m *ConnectionState) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ConnectionState.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ConnectionState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ConnectionState.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ConnectionState) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ConnectionState.Merge(m, src)
|
||||
}
|
||||
func (m *ConnectionState) XXX_Size() int {
|
||||
return xxx_messageInfo_ConnectionState.Size(m)
|
||||
}
|
||||
func (m *ConnectionState) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ConnectionState.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ConnectionState proto.InternalMessageInfo
|
||||
|
||||
func (m *ConnectionState) GetVersion() uint32 {
|
||||
if m != nil {
|
||||
return m.Version
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *ConnectionState) GetHandshakeComplete() bool {
|
||||
if m != nil {
|
||||
return m.HandshakeComplete
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *ConnectionState) GetDidResume() bool {
|
||||
if m != nil {
|
||||
return m.DidResume
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *ConnectionState) GetCipherSuite() uint32 {
|
||||
if m != nil {
|
||||
return m.CipherSuite
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *ConnectionState) GetNegotiatedProtocol() string {
|
||||
if m != nil {
|
||||
return m.NegotiatedProtocol
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *ConnectionState) GetNegotiatedProtocolIsMutual() bool {
|
||||
if m != nil {
|
||||
return m.NegotiatedProtocolIsMutual
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *ConnectionState) GetServerName() string {
|
||||
if m != nil {
|
||||
return m.ServerName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *ConnectionState) GetPeerCertificates() *Certificates {
|
||||
if m != nil {
|
||||
return m.PeerCertificates
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ConnectionState) GetVerifiedChains() []*Certificates {
|
||||
if m != nil {
|
||||
return m.VerifiedChains
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ConnectionState) GetSignedCertificateTimestamps() [][]byte {
|
||||
if m != nil {
|
||||
return m.SignedCertificateTimestamps
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ConnectionState) GetOcspResponse() []byte {
|
||||
if m != nil {
|
||||
return m.OcspResponse
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ConnectionState) GetTlsUnique() []byte {
|
||||
if m != nil {
|
||||
return m.TlsUnique
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Request struct {
|
||||
Method string `protobuf:"bytes,1,opt,name=method,proto3" json:"method,omitempty"`
|
||||
Url *URL `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"`
|
||||
Proto string `protobuf:"bytes,3,opt,name=proto,proto3" json:"proto,omitempty"`
|
||||
ProtoMajor int32 `protobuf:"varint,4,opt,name=protoMajor,proto3" json:"protoMajor,omitempty"`
|
||||
ProtoMinor int32 `protobuf:"varint,5,opt,name=protoMinor,proto3" json:"protoMinor,omitempty"`
|
||||
Header []*Element `protobuf:"bytes,6,rep,name=header,proto3" json:"header,omitempty"`
|
||||
Body uint32 `protobuf:"varint,7,opt,name=body,proto3" json:"body,omitempty"`
|
||||
ContentLength int64 `protobuf:"varint,8,opt,name=contentLength,proto3" json:"contentLength,omitempty"`
|
||||
TransferEncoding []string `protobuf:"bytes,9,rep,name=transferEncoding,proto3" json:"transferEncoding,omitempty"`
|
||||
Host string `protobuf:"bytes,10,opt,name=host,proto3" json:"host,omitempty"`
|
||||
Form []*Element `protobuf:"bytes,11,rep,name=form,proto3" json:"form,omitempty"`
|
||||
PostForm []*Element `protobuf:"bytes,12,rep,name=postForm,proto3" json:"postForm,omitempty"`
|
||||
TrailerKeys []string `protobuf:"bytes,13,rep,name=trailerKeys,proto3" json:"trailerKeys,omitempty"`
|
||||
RemoteAddr string `protobuf:"bytes,14,opt,name=remoteAddr,proto3" json:"remoteAddr,omitempty"`
|
||||
RequestURI string `protobuf:"bytes,15,opt,name=requestURI,proto3" json:"requestURI,omitempty"`
|
||||
Tls *ConnectionState `protobuf:"bytes,16,opt,name=tls,proto3" json:"tls,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Request) Reset() { *m = Request{} }
|
||||
func (m *Request) String() string { return proto.CompactTextString(m) }
|
||||
func (*Request) ProtoMessage() {}
|
||||
func (*Request) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_11b04836674e6f94, []int{5}
|
||||
}
|
||||
|
||||
func (m *Request) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Request.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Request) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Request.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Request) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Request.Merge(m, src)
|
||||
}
|
||||
func (m *Request) XXX_Size() int {
|
||||
return xxx_messageInfo_Request.Size(m)
|
||||
}
|
||||
func (m *Request) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Request.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Request proto.InternalMessageInfo
|
||||
|
||||
func (m *Request) GetMethod() string {
|
||||
if m != nil {
|
||||
return m.Method
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Request) GetUrl() *URL {
|
||||
if m != nil {
|
||||
return m.Url
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Request) GetProto() string {
|
||||
if m != nil {
|
||||
return m.Proto
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Request) GetProtoMajor() int32 {
|
||||
if m != nil {
|
||||
return m.ProtoMajor
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Request) GetProtoMinor() int32 {
|
||||
if m != nil {
|
||||
return m.ProtoMinor
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Request) GetHeader() []*Element {
|
||||
if m != nil {
|
||||
return m.Header
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Request) GetBody() uint32 {
|
||||
if m != nil {
|
||||
return m.Body
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Request) GetContentLength() int64 {
|
||||
if m != nil {
|
||||
return m.ContentLength
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *Request) GetTransferEncoding() []string {
|
||||
if m != nil {
|
||||
return m.TransferEncoding
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Request) GetHost() string {
|
||||
if m != nil {
|
||||
return m.Host
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Request) GetForm() []*Element {
|
||||
if m != nil {
|
||||
return m.Form
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Request) GetPostForm() []*Element {
|
||||
if m != nil {
|
||||
return m.PostForm
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Request) GetTrailerKeys() []string {
|
||||
if m != nil {
|
||||
return m.TrailerKeys
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Request) GetRemoteAddr() string {
|
||||
if m != nil {
|
||||
return m.RemoteAddr
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Request) GetRequestURI() string {
|
||||
if m != nil {
|
||||
return m.RequestURI
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Request) GetTls() *ConnectionState {
|
||||
if m != nil {
|
||||
return m.Tls
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type HTTPRequest struct {
|
||||
ResponseWriter uint32 `protobuf:"varint,1,opt,name=responseWriter,proto3" json:"responseWriter,omitempty"`
|
||||
Request *Request `protobuf:"bytes,2,opt,name=request,proto3" json:"request,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *HTTPRequest) Reset() { *m = HTTPRequest{} }
|
||||
func (m *HTTPRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*HTTPRequest) ProtoMessage() {}
|
||||
func (*HTTPRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_11b04836674e6f94, []int{6}
|
||||
}
|
||||
|
||||
func (m *HTTPRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_HTTPRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *HTTPRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_HTTPRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *HTTPRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_HTTPRequest.Merge(m, src)
|
||||
}
|
||||
func (m *HTTPRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_HTTPRequest.Size(m)
|
||||
}
|
||||
func (m *HTTPRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_HTTPRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_HTTPRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *HTTPRequest) GetResponseWriter() uint32 {
|
||||
if m != nil {
|
||||
return m.ResponseWriter
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *HTTPRequest) GetRequest() *Request {
|
||||
if m != nil {
|
||||
return m.Request
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type HTTPResponse struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *HTTPResponse) Reset() { *m = HTTPResponse{} }
|
||||
func (m *HTTPResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*HTTPResponse) ProtoMessage() {}
|
||||
func (*HTTPResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_11b04836674e6f94, []int{7}
|
||||
}
|
||||
|
||||
func (m *HTTPResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_HTTPResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *HTTPResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_HTTPResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *HTTPResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_HTTPResponse.Merge(m, src)
|
||||
}
|
||||
func (m *HTTPResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_HTTPResponse.Size(m)
|
||||
}
|
||||
func (m *HTTPResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_HTTPResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_HTTPResponse proto.InternalMessageInfo
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Userinfo)(nil), "proto.Userinfo")
|
||||
proto.RegisterType((*URL)(nil), "proto.URL")
|
||||
proto.RegisterType((*Element)(nil), "proto.Element")
|
||||
proto.RegisterType((*Certificates)(nil), "proto.Certificates")
|
||||
proto.RegisterType((*ConnectionState)(nil), "proto.ConnectionState")
|
||||
proto.RegisterType((*Request)(nil), "proto.Request")
|
||||
proto.RegisterType((*HTTPRequest)(nil), "proto.HTTPRequest")
|
||||
proto.RegisterType((*HTTPResponse)(nil), "proto.HTTPResponse")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("http.proto", fileDescriptor_11b04836674e6f94) }
|
||||
|
||||
var fileDescriptor_11b04836674e6f94 = []byte{
|
||||
// 816 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x54, 0xdb, 0x6e, 0x1b, 0x37,
|
||||
0x10, 0x85, 0xb2, 0xb2, 0x2e, 0xa3, 0x8b, 0x5d, 0xa6, 0x08, 0x08, 0x37, 0x28, 0x84, 0x6d, 0x11,
|
||||
0x08, 0x41, 0x61, 0xa0, 0xce, 0x53, 0x51, 0xa0, 0x17, 0x18, 0x29, 0x12, 0xd4, 0x29, 0x5c, 0xda,
|
||||
0x46, 0x1f, 0x0b, 0x66, 0x77, 0xa4, 0x65, 0xb3, 0x4b, 0x6e, 0x48, 0xae, 0x0c, 0x7f, 0x47, 0x3f,
|
||||
0xa3, 0xbf, 0xd7, 0x0f, 0x28, 0x78, 0x59, 0x69, 0x15, 0xb9, 0x7e, 0xda, 0x99, 0x73, 0x86, 0xcb,
|
||||
0x99, 0x39, 0x33, 0x04, 0x28, 0xac, 0xad, 0xcf, 0x6a, 0xad, 0xac, 0x22, 0x47, 0xfe, 0x93, 0xe6,
|
||||
0x30, 0xba, 0x35, 0xa8, 0x85, 0x5c, 0x29, 0x72, 0x0a, 0xa3, 0xc6, 0xa0, 0x96, 0xbc, 0x42, 0xda,
|
||||
0x5b, 0xf4, 0x96, 0x63, 0xb6, 0xf5, 0x1d, 0x57, 0x73, 0x63, 0xee, 0x94, 0xce, 0xe9, 0x93, 0xc0,
|
||||
0xb5, 0x3e, 0x59, 0xc0, 0xa4, 0xb5, 0xaf, 0xd1, 0xd2, 0x64, 0xd1, 0x5b, 0x8e, 0x58, 0x17, 0x4a,
|
||||
0xff, 0xed, 0x41, 0x72, 0xcb, 0x2e, 0xc9, 0x33, 0x18, 0x98, 0xac, 0xc0, 0xed, 0xff, 0xa3, 0xe7,
|
||||
0x70, 0x55, 0xf3, 0x8f, 0x0d, 0xc6, 0x7f, 0x47, 0x8f, 0x7c, 0x05, 0x7d, 0x97, 0x81, 0xff, 0xe5,
|
||||
0xe4, 0xfc, 0x38, 0xa4, 0x7e, 0xd6, 0x26, 0xcc, 0x3c, 0x49, 0x08, 0xf4, 0x0b, 0x65, 0x2c, 0xed,
|
||||
0xfb, 0xa3, 0xde, 0x76, 0x58, 0xcd, 0x6d, 0x41, 0x8f, 0x02, 0xe6, 0x6c, 0x42, 0x61, 0xa8, 0xf9,
|
||||
0xdd, 0x95, 0x83, 0x07, 0x1e, 0x6e, 0x5d, 0xf2, 0x25, 0xc0, 0x4a, 0xe9, 0x0c, 0x7f, 0x6f, 0x50,
|
||||
0xdf, 0xd3, 0xa1, 0xcf, 0xbf, 0x83, 0xb8, 0xe2, 0x35, 0xbf, 0x0b, 0xec, 0x28, 0x14, 0xdf, 0xfa,
|
||||
0x8e, 0x5b, 0x69, 0xbe, 0xae, 0x50, 0x5a, 0x3a, 0x0e, 0x5c, 0xeb, 0xa7, 0xaf, 0x60, 0xf8, 0xba,
|
||||
0x44, 0x67, 0x92, 0x13, 0x48, 0x3e, 0xe0, 0x7d, 0x2c, 0xdb, 0x99, 0xae, 0xe6, 0x0d, 0x2f, 0x1b,
|
||||
0x34, 0xf4, 0xc9, 0x22, 0x71, 0x35, 0x07, 0x2f, 0x4d, 0x61, 0x7a, 0x81, 0xda, 0x8a, 0x95, 0xc8,
|
||||
0xb8, 0x45, 0xe3, 0x4a, 0xc9, 0x50, 0x5b, 0xda, 0x5b, 0x24, 0xcb, 0x29, 0xf3, 0x76, 0xfa, 0x4f,
|
||||
0x1f, 0x8e, 0x2f, 0x94, 0x94, 0x98, 0x59, 0xa1, 0xe4, 0xb5, 0xe5, 0x16, 0x5d, 0x79, 0x1b, 0xd4,
|
||||
0x46, 0x28, 0xe9, 0x6f, 0x99, 0xb1, 0xd6, 0x25, 0xdf, 0xc0, 0x67, 0x05, 0x97, 0xb9, 0x29, 0xf8,
|
||||
0x07, 0xbc, 0x50, 0x55, 0x5d, 0xa2, 0x0d, 0x8d, 0x1e, 0xb1, 0x43, 0x82, 0x3c, 0x87, 0x71, 0x2e,
|
||||
0x72, 0x86, 0xa6, 0xa9, 0x30, 0x6a, 0xb9, 0x03, 0x9c, 0xd6, 0x99, 0xa8, 0x0b, 0xd4, 0xd7, 0x8d,
|
||||
0xb0, 0xe8, 0x7b, 0x3e, 0x63, 0x5d, 0x88, 0x9c, 0x01, 0x91, 0xb8, 0x56, 0x56, 0x70, 0x8b, 0xf9,
|
||||
0x95, 0x13, 0x2c, 0x53, 0x65, 0x14, 0xe2, 0x01, 0x86, 0xfc, 0x00, 0xa7, 0x87, 0xe8, 0x5b, 0xf3,
|
||||
0xae, 0xb1, 0x0d, 0x2f, 0xbd, 0x52, 0x23, 0xf6, 0x48, 0x84, 0x13, 0xcf, 0xa0, 0xde, 0xa0, 0xfe,
|
||||
0xcd, 0xcd, 0xed, 0xd0, 0xdf, 0xd3, 0x41, 0xc8, 0x8f, 0x70, 0x52, 0x23, 0xea, 0x6e, 0x4f, 0xbd,
|
||||
0x88, 0x93, 0xf3, 0xa7, 0x71, 0x9e, 0xba, 0x14, 0x3b, 0x08, 0x26, 0xdf, 0xc3, 0x7c, 0x83, 0x5a,
|
||||
0xac, 0x04, 0xe6, 0x17, 0x05, 0x17, 0xd2, 0xd0, 0xf1, 0x22, 0xf9, 0xbf, 0xe3, 0x9f, 0x84, 0x92,
|
||||
0x9f, 0xe0, 0x0b, 0x23, 0xd6, 0x12, 0xf3, 0x4e, 0xd4, 0x8d, 0xa8, 0xd0, 0x58, 0x5e, 0xd5, 0x86,
|
||||
0x82, 0x17, 0xf5, 0xb1, 0x10, 0x92, 0xc2, 0x54, 0x65, 0xa6, 0x66, 0x68, 0x6a, 0x25, 0x0d, 0xd2,
|
||||
0xc9, 0xa2, 0xb7, 0x9c, 0xb2, 0x3d, 0xcc, 0x69, 0x66, 0x4b, 0x73, 0x2b, 0x85, 0x5b, 0xa1, 0xa9,
|
||||
0x0f, 0xd8, 0x01, 0xe9, 0xdf, 0x7d, 0x18, 0x32, 0xfc, 0xd8, 0xa0, 0xb1, 0x6e, 0xea, 0x2a, 0xb4,
|
||||
0x85, 0xca, 0xdb, 0x0d, 0x0c, 0x1e, 0x79, 0x0e, 0x49, 0xa3, 0x4b, 0x3f, 0x15, 0x93, 0x73, 0x68,
|
||||
0x17, 0x8d, 0x5d, 0x32, 0x07, 0x93, 0xcf, 0x21, 0x3c, 0x17, 0x7e, 0x1e, 0xc6, 0x2c, 0x38, 0xae,
|
||||
0xf3, 0xde, 0x78, 0xc7, 0xff, 0x52, 0xda, 0x8f, 0xc2, 0x11, 0xeb, 0x20, 0x3b, 0x5e, 0x48, 0xa5,
|
||||
0xfd, 0x04, 0x6c, 0x79, 0x87, 0x90, 0x17, 0x30, 0x28, 0x90, 0xe7, 0xa8, 0xe9, 0xc0, 0x37, 0x74,
|
||||
0x1e, 0xaf, 0x8d, 0x3b, 0xc3, 0x22, 0xeb, 0x36, 0xe0, 0xbd, 0xca, 0xc3, 0x62, 0xce, 0x98, 0xb7,
|
||||
0xc9, 0xd7, 0x30, 0xcb, 0x94, 0xb4, 0x28, 0xed, 0x25, 0xca, 0xb5, 0x2d, 0xbc, 0xa4, 0x09, 0xdb,
|
||||
0x07, 0xc9, 0x4b, 0x38, 0xb1, 0x9a, 0x4b, 0xb3, 0x42, 0xfd, 0x5a, 0x66, 0x2a, 0x17, 0x72, 0xed,
|
||||
0xc5, 0x1b, 0xb3, 0x03, 0x7c, 0xfb, 0x8c, 0x40, 0xe7, 0x19, 0x49, 0xa1, 0xbf, 0x52, 0xba, 0xa2,
|
||||
0x93, 0x07, 0xf3, 0xf3, 0x1c, 0x79, 0x09, 0xa3, 0x5a, 0x19, 0xfb, 0x8b, 0x8b, 0x9b, 0x3e, 0x18,
|
||||
0xb7, 0xe5, 0xdd, 0xf6, 0x58, 0xcd, 0x45, 0x89, 0xfa, 0x57, 0xbc, 0x37, 0x74, 0xe6, 0x53, 0xe9,
|
||||
0x42, 0xae, 0x67, 0x1a, 0x2b, 0x65, 0xf1, 0xe7, 0x3c, 0xd7, 0x74, 0x1e, 0xa6, 0x79, 0x87, 0x04,
|
||||
0xde, 0x4b, 0x79, 0xcb, 0xde, 0xd2, 0xe3, 0x96, 0x6f, 0x11, 0xb2, 0x84, 0xc4, 0x96, 0x86, 0x9e,
|
||||
0x78, 0x1d, 0x9f, 0xb5, 0x13, 0xba, 0xff, 0x54, 0x30, 0x17, 0x92, 0xfe, 0x09, 0x93, 0x37, 0x37,
|
||||
0x37, 0x57, 0xed, 0x60, 0xbc, 0x80, 0xb9, 0x8e, 0xe3, 0xf4, 0x87, 0x16, 0x16, 0x75, 0x7c, 0x45,
|
||||
0x3e, 0x41, 0xc9, 0x12, 0x86, 0xf1, 0xba, 0x38, 0x2c, 0x6d, 0xb5, 0xf1, 0x47, 0xac, 0xa5, 0xd3,
|
||||
0x39, 0x4c, 0xc3, 0x05, 0xe1, 0xfc, 0xf9, 0x77, 0xd0, 0x77, 0x3e, 0xf9, 0x16, 0x06, 0x6f, 0xb8,
|
||||
0xcc, 0x4b, 0x24, 0x24, 0x1e, 0xed, 0xe4, 0x71, 0xfa, 0x74, 0x0f, 0x0b, 0x47, 0xdf, 0x0f, 0x3c,
|
||||
0xf6, 0xea, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xbf, 0x29, 0xb2, 0xd4, 0xc1, 0x06, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ grpc.ClientConnInterface
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc.SupportPackageIsVersion6
|
||||
|
||||
// HTTPClient is the client API for HTTP service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type HTTPClient interface {
|
||||
Handle(ctx context.Context, in *HTTPRequest, opts ...grpc.CallOption) (*HTTPResponse, error)
|
||||
}
|
||||
|
||||
type hTTPClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewHTTPClient(cc grpc.ClientConnInterface) HTTPClient {
|
||||
return &hTTPClient{cc}
|
||||
}
|
||||
|
||||
func (c *hTTPClient) Handle(ctx context.Context, in *HTTPRequest, opts ...grpc.CallOption) (*HTTPResponse, error) {
|
||||
out := new(HTTPResponse)
|
||||
err := c.cc.Invoke(ctx, "/proto.HTTP/Handle", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// HTTPServer is the server API for HTTP service.
|
||||
type HTTPServer interface {
|
||||
Handle(context.Context, *HTTPRequest) (*HTTPResponse, error)
|
||||
}
|
||||
|
||||
// UnimplementedHTTPServer can be embedded to have forward compatible implementations.
|
||||
type UnimplementedHTTPServer struct {
|
||||
}
|
||||
|
||||
func (*UnimplementedHTTPServer) Handle(ctx context.Context, req *HTTPRequest) (*HTTPResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Handle not implemented")
|
||||
}
|
||||
|
||||
func RegisterHTTPServer(s *grpc.Server, srv HTTPServer) {
|
||||
s.RegisterService(&_HTTP_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _HTTP_Handle_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(HTTPRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(HTTPServer).Handle(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/proto.HTTP/Handle",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(HTTPServer).Handle(ctx, req.(*HTTPRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _HTTP_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "proto.HTTP",
|
||||
HandlerType: (*HTTPServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Handle",
|
||||
Handler: _HTTP_Handle_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "http.proto",
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
syntax = "proto3";
|
||||
package proto;
|
||||
|
||||
|
||||
message Userinfo {
|
||||
string username = 1;
|
||||
string password = 2;
|
||||
bool passwordSet = 3;
|
||||
}
|
||||
|
||||
message URL {
|
||||
string scheme = 1;
|
||||
string opaque = 2;
|
||||
Userinfo user = 3;
|
||||
string host = 4;
|
||||
string path = 5;
|
||||
string rawPath = 6;
|
||||
bool forceQuery = 7;
|
||||
string rawQuery = 8;
|
||||
string fragment = 9;
|
||||
}
|
||||
|
||||
message Element {
|
||||
string key = 1;
|
||||
repeated string values = 2;
|
||||
}
|
||||
|
||||
message Certificates {
|
||||
repeated bytes cert = 1;
|
||||
}
|
||||
|
||||
message ConnectionState {
|
||||
uint32 version = 1;
|
||||
bool handshakeComplete = 2;
|
||||
bool didResume = 3;
|
||||
uint32 cipherSuite = 4;
|
||||
string negotiatedProtocol = 5;
|
||||
bool negotiatedProtocolIsMutual = 6;
|
||||
string serverName = 7;
|
||||
Certificates peerCertificates = 8;
|
||||
repeated Certificates verifiedChains = 9;
|
||||
repeated bytes signedCertificateTimestamps = 10;
|
||||
bytes ocspResponse = 11;
|
||||
bytes tlsUnique = 12;
|
||||
}
|
||||
|
||||
message Request {
|
||||
string method = 1;
|
||||
URL url = 2;
|
||||
string proto = 3;
|
||||
int32 protoMajor = 4;
|
||||
int32 protoMinor = 5;
|
||||
repeated Element header = 6;
|
||||
uint32 body = 7; // server ID
|
||||
int64 contentLength = 8;
|
||||
repeated string transferEncoding = 9;
|
||||
string host = 10;
|
||||
repeated Element form = 11;
|
||||
repeated Element postForm = 12;
|
||||
repeated string trailerKeys = 13;
|
||||
string remoteAddr = 14;
|
||||
string requestURI = 15;
|
||||
ConnectionState tls = 16;
|
||||
}
|
||||
|
||||
message HTTPRequest {
|
||||
uint32 responseWriter = 1; // server ID
|
||||
Request request = 2;
|
||||
}
|
||||
|
||||
message HTTPResponse {}
|
||||
|
||||
service HTTP {
|
||||
rpc Handle(HTTPRequest) returns (HTTPResponse);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package messenger
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/ava-labs/gecko/snow/engine/common"
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/messenger/proto"
|
||||
)
|
||||
|
||||
// Client is an implementation of a messenger channel that talks over RPC.
|
||||
type Client struct{ client proto.MessengerClient }
|
||||
|
||||
// NewClient returns a database instance connected to a remote database instance
|
||||
func NewClient(client proto.MessengerClient) *Client {
|
||||
return &Client{client: client}
|
||||
}
|
||||
|
||||
// Notify ...
|
||||
func (c *Client) Notify(msg common.Message) error {
|
||||
_, err := c.client.Notify(context.Background(), &proto.NotifyRequest{
|
||||
Message: uint32(msg),
|
||||
})
|
||||
return err
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package messenger
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/ava-labs/gecko/snow/engine/common"
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/messenger/proto"
|
||||
)
|
||||
|
||||
var (
|
||||
errFullQueue = errors.New("full message queue")
|
||||
)
|
||||
|
||||
// Server is a messenger that is managed over RPC.
|
||||
type Server struct {
|
||||
messenger chan<- common.Message
|
||||
}
|
||||
|
||||
// NewServer returns a vm instance connected to a remote vm instance
|
||||
func NewServer(messenger chan<- common.Message) *Server {
|
||||
return &Server{messenger: messenger}
|
||||
}
|
||||
|
||||
// Notify ...
|
||||
func (s *Server) Notify(_ context.Context, req *proto.NotifyRequest) (*proto.NotifyResponse, error) {
|
||||
msg := common.Message(req.Message)
|
||||
select {
|
||||
case s.messenger <- msg:
|
||||
return &proto.NotifyResponse{}, nil
|
||||
default:
|
||||
return nil, errFullQueue
|
||||
}
|
||||
}
|
|
@ -0,0 +1,194 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: messenger.proto
|
||||
|
||||
package proto
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
type NotifyRequest struct {
|
||||
Message uint32 `protobuf:"varint,1,opt,name=message,proto3" json:"message,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *NotifyRequest) Reset() { *m = NotifyRequest{} }
|
||||
func (m *NotifyRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*NotifyRequest) ProtoMessage() {}
|
||||
func (*NotifyRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_b99aba0cbf4e4b91, []int{0}
|
||||
}
|
||||
|
||||
func (m *NotifyRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_NotifyRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *NotifyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_NotifyRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *NotifyRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_NotifyRequest.Merge(m, src)
|
||||
}
|
||||
func (m *NotifyRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_NotifyRequest.Size(m)
|
||||
}
|
||||
func (m *NotifyRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_NotifyRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_NotifyRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *NotifyRequest) GetMessage() uint32 {
|
||||
if m != nil {
|
||||
return m.Message
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type NotifyResponse struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *NotifyResponse) Reset() { *m = NotifyResponse{} }
|
||||
func (m *NotifyResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*NotifyResponse) ProtoMessage() {}
|
||||
func (*NotifyResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_b99aba0cbf4e4b91, []int{1}
|
||||
}
|
||||
|
||||
func (m *NotifyResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_NotifyResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *NotifyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_NotifyResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *NotifyResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_NotifyResponse.Merge(m, src)
|
||||
}
|
||||
func (m *NotifyResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_NotifyResponse.Size(m)
|
||||
}
|
||||
func (m *NotifyResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_NotifyResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_NotifyResponse proto.InternalMessageInfo
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*NotifyRequest)(nil), "proto.NotifyRequest")
|
||||
proto.RegisterType((*NotifyResponse)(nil), "proto.NotifyResponse")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("messenger.proto", fileDescriptor_b99aba0cbf4e4b91) }
|
||||
|
||||
var fileDescriptor_b99aba0cbf4e4b91 = []byte{
|
||||
// 123 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xcf, 0x4d, 0x2d, 0x2e,
|
||||
0x4e, 0xcd, 0x4b, 0x4f, 0x2d, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x05, 0x53, 0x4a,
|
||||
0x9a, 0x5c, 0xbc, 0x7e, 0xf9, 0x25, 0x99, 0x69, 0x95, 0x41, 0xa9, 0x85, 0xa5, 0xa9, 0xc5, 0x25,
|
||||
0x42, 0x12, 0x5c, 0xec, 0x20, 0xa5, 0x89, 0xe9, 0xa9, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0xbc, 0x41,
|
||||
0x30, 0xae, 0x92, 0x00, 0x17, 0x1f, 0x4c, 0x69, 0x71, 0x41, 0x7e, 0x5e, 0x71, 0xaa, 0x91, 0x13,
|
||||
0x17, 0xa7, 0x2f, 0xcc, 0x58, 0x21, 0x53, 0x2e, 0x36, 0x88, 0xb4, 0x90, 0x08, 0xc4, 0x0a, 0x3d,
|
||||
0x14, 0x83, 0xa5, 0x44, 0xd1, 0x44, 0x21, 0x66, 0x24, 0xb1, 0x81, 0x45, 0x8d, 0x01, 0x01, 0x00,
|
||||
0x00, 0xff, 0xff, 0x39, 0x03, 0x19, 0x97, 0xa1, 0x00, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ grpc.ClientConnInterface
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc.SupportPackageIsVersion6
|
||||
|
||||
// MessengerClient is the client API for Messenger service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type MessengerClient interface {
|
||||
Notify(ctx context.Context, in *NotifyRequest, opts ...grpc.CallOption) (*NotifyResponse, error)
|
||||
}
|
||||
|
||||
type messengerClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewMessengerClient(cc grpc.ClientConnInterface) MessengerClient {
|
||||
return &messengerClient{cc}
|
||||
}
|
||||
|
||||
func (c *messengerClient) Notify(ctx context.Context, in *NotifyRequest, opts ...grpc.CallOption) (*NotifyResponse, error) {
|
||||
out := new(NotifyResponse)
|
||||
err := c.cc.Invoke(ctx, "/proto.Messenger/Notify", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// MessengerServer is the server API for Messenger service.
|
||||
type MessengerServer interface {
|
||||
Notify(context.Context, *NotifyRequest) (*NotifyResponse, error)
|
||||
}
|
||||
|
||||
// UnimplementedMessengerServer can be embedded to have forward compatible implementations.
|
||||
type UnimplementedMessengerServer struct {
|
||||
}
|
||||
|
||||
func (*UnimplementedMessengerServer) Notify(ctx context.Context, req *NotifyRequest) (*NotifyResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Notify not implemented")
|
||||
}
|
||||
|
||||
func RegisterMessengerServer(s *grpc.Server, srv MessengerServer) {
|
||||
s.RegisterService(&_Messenger_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _Messenger_Notify_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(NotifyRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(MessengerServer).Notify(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/proto.Messenger/Notify",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(MessengerServer).Notify(ctx, req.(*NotifyRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _Messenger_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "proto.Messenger",
|
||||
HandlerType: (*MessengerServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Notify",
|
||||
Handler: _Messenger_Notify_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "messenger.proto",
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
syntax = "proto3";
|
||||
package proto;
|
||||
|
||||
message NotifyRequest {
|
||||
uint32 message = 1;
|
||||
}
|
||||
|
||||
message NotifyResponse {}
|
||||
|
||||
service Messenger {
|
||||
rpc Notify(NotifyRequest) returns (NotifyResponse);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,100 @@
|
|||
syntax = "proto3";
|
||||
package proto;
|
||||
|
||||
message InitializeRequest {
|
||||
uint32 dbServer = 1;
|
||||
bytes genesisBytes = 2;
|
||||
uint32 engineServer = 3;
|
||||
}
|
||||
|
||||
message InitializeResponse {}
|
||||
|
||||
message ShutdownRequest {}
|
||||
|
||||
message ShutdownResponse {}
|
||||
|
||||
message CreateHandlersRequest {}
|
||||
|
||||
message CreateHandlersResponse {
|
||||
repeated Handler handlers = 1;
|
||||
}
|
||||
|
||||
message Handler {
|
||||
string prefix = 1;
|
||||
uint32 lockOptions = 2;
|
||||
uint32 server = 3;
|
||||
}
|
||||
|
||||
message BuildBlockRequest {}
|
||||
|
||||
message BuildBlockResponse {
|
||||
bytes id = 1;
|
||||
bytes parentID = 2;
|
||||
bytes bytes = 3;
|
||||
// status is always processing
|
||||
}
|
||||
|
||||
message ParseBlockRequest {
|
||||
bytes bytes = 1;
|
||||
}
|
||||
|
||||
message ParseBlockResponse {
|
||||
bytes id = 1;
|
||||
bytes parentID = 2;
|
||||
uint32 status = 3;
|
||||
}
|
||||
|
||||
message GetBlockRequest {
|
||||
bytes id = 1;
|
||||
}
|
||||
|
||||
message GetBlockResponse {
|
||||
bytes parentID = 1;
|
||||
bytes bytes = 2;
|
||||
uint32 status = 3;
|
||||
}
|
||||
|
||||
message SetPreferenceRequest {
|
||||
bytes id = 1;
|
||||
}
|
||||
|
||||
message SetPreferenceResponse {}
|
||||
|
||||
message LastAcceptedRequest {}
|
||||
|
||||
message LastAcceptedResponse {
|
||||
bytes id = 1;
|
||||
}
|
||||
|
||||
message BlockVerifyRequest {
|
||||
bytes id = 1;
|
||||
}
|
||||
|
||||
message BlockVerifyResponse {}
|
||||
|
||||
message BlockAcceptRequest {
|
||||
bytes id = 1;
|
||||
}
|
||||
|
||||
message BlockAcceptResponse {}
|
||||
|
||||
message BlockRejectRequest {
|
||||
bytes id = 1;
|
||||
}
|
||||
|
||||
message BlockRejectResponse {}
|
||||
|
||||
service VM {
|
||||
rpc Initialize(InitializeRequest) returns (InitializeResponse);
|
||||
rpc Shutdown(ShutdownRequest) returns (ShutdownResponse);
|
||||
rpc CreateHandlers(CreateHandlersRequest) returns (CreateHandlersResponse);
|
||||
rpc BuildBlock(BuildBlockRequest) returns (BuildBlockResponse);
|
||||
rpc ParseBlock(ParseBlockRequest) returns (ParseBlockResponse);
|
||||
rpc GetBlock(GetBlockRequest) returns (GetBlockResponse);
|
||||
rpc SetPreference(SetPreferenceRequest) returns (SetPreferenceResponse);
|
||||
rpc LastAccepted(LastAcceptedRequest) returns (LastAcceptedResponse);
|
||||
|
||||
rpc BlockVerify(BlockVerifyRequest) returns (BlockVerifyResponse);
|
||||
rpc BlockAccept(BlockAcceptRequest) returns (BlockAcceptResponse);
|
||||
rpc BlockReject(BlockRejectRequest) returns (BlockRejectResponse);
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package rpcchainvm
|
||||
|
||||
import (
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/hashicorp/go-plugin"
|
||||
|
||||
"github.com/ava-labs/gecko/snow/engine/snowman"
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/proto"
|
||||
)
|
||||
|
||||
// Handshake is a common handshake that is shared by plugin and host.
|
||||
var Handshake = plugin.HandshakeConfig{
|
||||
ProtocolVersion: 1,
|
||||
MagicCookieKey: "VM_PLUGIN",
|
||||
MagicCookieValue: "dynamic",
|
||||
}
|
||||
|
||||
// PluginMap is the map of plugins we can dispense.
|
||||
var PluginMap = map[string]plugin.Plugin{
|
||||
"vm": &Plugin{},
|
||||
}
|
||||
|
||||
// Plugin is the implementation of plugin.Plugin so we can serve/consume this.
|
||||
// We also implement GRPCPlugin so that this plugin can be served over gRPC.
|
||||
type Plugin struct {
|
||||
plugin.NetRPCUnsupportedPlugin
|
||||
// Concrete implementation, written in Go. This is only used for plugins
|
||||
// that are written in Go.
|
||||
vm snowman.ChainVM
|
||||
}
|
||||
|
||||
// New ...
|
||||
func New(vm snowman.ChainVM) *Plugin { return &Plugin{vm: vm} }
|
||||
|
||||
// GRPCServer ...
|
||||
func (p *Plugin) GRPCServer(broker *plugin.GRPCBroker, s *grpc.Server) error {
|
||||
proto.RegisterVMServer(s, NewServer(p.vm, broker))
|
||||
return nil
|
||||
}
|
||||
|
||||
// GRPCClient ...
|
||||
func (p *Plugin) GRPCClient(ctx context.Context, broker *plugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) {
|
||||
return NewClient(proto.NewVMClient(c), broker), nil
|
||||
}
|
|
@ -0,0 +1,336 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package rpcchainvm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"sync"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/hashicorp/go-plugin"
|
||||
|
||||
"github.com/ava-labs/gecko/database"
|
||||
"github.com/ava-labs/gecko/database/rpcdb"
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/snow"
|
||||
"github.com/ava-labs/gecko/snow/choices"
|
||||
"github.com/ava-labs/gecko/snow/consensus/snowman"
|
||||
"github.com/ava-labs/gecko/snow/engine/common"
|
||||
"github.com/ava-labs/gecko/vms/components/missing"
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/ghttp"
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/messenger"
|
||||
|
||||
dbproto "github.com/ava-labs/gecko/database/rpcdb/proto"
|
||||
httpproto "github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/proto"
|
||||
msgproto "github.com/ava-labs/gecko/vms/rpcchainvm/messenger/proto"
|
||||
vmproto "github.com/ava-labs/gecko/vms/rpcchainvm/proto"
|
||||
)
|
||||
|
||||
var (
|
||||
errUnsupportedFXs = errors.New("unsupported feature extensions")
|
||||
)
|
||||
|
||||
// VMClient is an implementation of VM that talks over RPC.
|
||||
type VMClient struct {
|
||||
client vmproto.VMClient
|
||||
broker *plugin.GRPCBroker
|
||||
proc *plugin.Client
|
||||
|
||||
db *rpcdb.DatabaseServer
|
||||
messenger *messenger.Server
|
||||
|
||||
lock sync.Mutex
|
||||
closed bool
|
||||
servers []*grpc.Server
|
||||
conns []*grpc.ClientConn
|
||||
|
||||
ctx *snow.Context
|
||||
blks map[[32]byte]*BlockClient
|
||||
}
|
||||
|
||||
// NewClient returns a database instance connected to a remote database instance
|
||||
func NewClient(client vmproto.VMClient, broker *plugin.GRPCBroker) *VMClient {
|
||||
return &VMClient{
|
||||
client: client,
|
||||
broker: broker,
|
||||
}
|
||||
}
|
||||
|
||||
// SetProcess ...
|
||||
func (vm *VMClient) SetProcess(proc *plugin.Client) {
|
||||
vm.proc = proc
|
||||
}
|
||||
|
||||
// Initialize ...
|
||||
func (vm *VMClient) Initialize(
|
||||
ctx *snow.Context,
|
||||
db database.Database,
|
||||
genesisBytes []byte,
|
||||
toEngine chan<- common.Message,
|
||||
fxs []*common.Fx,
|
||||
) error {
|
||||
if len(fxs) != 0 {
|
||||
return errUnsupportedFXs
|
||||
}
|
||||
|
||||
vm.ctx = ctx
|
||||
|
||||
vm.db = rpcdb.NewServer(db)
|
||||
vm.messenger = messenger.NewServer(toEngine)
|
||||
|
||||
// start the db server
|
||||
dbBrokerID := vm.broker.NextId()
|
||||
go vm.broker.AcceptAndServe(dbBrokerID, vm.startDBServer)
|
||||
|
||||
// start the messenger server
|
||||
messengerBrokerID := vm.broker.NextId()
|
||||
go vm.broker.AcceptAndServe(messengerBrokerID, vm.startMessengerServer)
|
||||
|
||||
_, err := vm.client.Initialize(context.Background(), &vmproto.InitializeRequest{
|
||||
DbServer: dbBrokerID,
|
||||
GenesisBytes: genesisBytes,
|
||||
EngineServer: messengerBrokerID,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (vm *VMClient) startDBServer(opts []grpc.ServerOption) *grpc.Server {
|
||||
vm.lock.Lock()
|
||||
defer vm.lock.Unlock()
|
||||
|
||||
server := grpc.NewServer(opts...)
|
||||
|
||||
if vm.closed {
|
||||
server.Stop()
|
||||
} else {
|
||||
vm.servers = append(vm.servers, server)
|
||||
}
|
||||
|
||||
dbproto.RegisterDatabaseServer(server, vm.db)
|
||||
return server
|
||||
}
|
||||
|
||||
func (vm *VMClient) startMessengerServer(opts []grpc.ServerOption) *grpc.Server {
|
||||
vm.lock.Lock()
|
||||
defer vm.lock.Unlock()
|
||||
|
||||
server := grpc.NewServer(opts...)
|
||||
|
||||
if vm.closed {
|
||||
server.Stop()
|
||||
} else {
|
||||
vm.servers = append(vm.servers, server)
|
||||
}
|
||||
|
||||
msgproto.RegisterMessengerServer(server, vm.messenger)
|
||||
return server
|
||||
}
|
||||
|
||||
// Shutdown ...
|
||||
func (vm *VMClient) Shutdown() {
|
||||
vm.lock.Lock()
|
||||
defer vm.lock.Unlock()
|
||||
|
||||
if vm.closed {
|
||||
return
|
||||
}
|
||||
|
||||
vm.closed = true
|
||||
|
||||
vm.client.Shutdown(context.Background(), &vmproto.ShutdownRequest{})
|
||||
|
||||
for _, server := range vm.servers {
|
||||
server.Stop()
|
||||
}
|
||||
for _, conn := range vm.conns {
|
||||
conn.Close()
|
||||
}
|
||||
|
||||
vm.proc.Kill()
|
||||
}
|
||||
|
||||
// CreateHandlers ...
|
||||
func (vm *VMClient) CreateHandlers() map[string]*common.HTTPHandler {
|
||||
vm.lock.Lock()
|
||||
defer vm.lock.Unlock()
|
||||
|
||||
if vm.closed {
|
||||
return nil
|
||||
}
|
||||
|
||||
resp, err := vm.client.CreateHandlers(context.Background(), &vmproto.CreateHandlersRequest{})
|
||||
vm.ctx.Log.AssertNoError(err)
|
||||
|
||||
handlers := make(map[string]*common.HTTPHandler, len(resp.Handlers))
|
||||
for _, handler := range resp.Handlers {
|
||||
conn, err := vm.broker.Dial(handler.Server)
|
||||
vm.ctx.Log.AssertNoError(err)
|
||||
|
||||
vm.conns = append(vm.conns, conn)
|
||||
handlers[handler.Prefix] = &common.HTTPHandler{
|
||||
LockOptions: common.LockOption(handler.LockOptions),
|
||||
Handler: ghttp.NewClient(httpproto.NewHTTPClient(conn), vm.broker),
|
||||
}
|
||||
}
|
||||
return handlers
|
||||
}
|
||||
|
||||
// BuildBlock ...
|
||||
func (vm *VMClient) BuildBlock() (snowman.Block, error) {
|
||||
resp, err := vm.client.BuildBlock(context.Background(), &vmproto.BuildBlockRequest{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
id, err := ids.ToID(resp.Id)
|
||||
vm.ctx.Log.AssertNoError(err)
|
||||
parentID, err := ids.ToID(resp.ParentID)
|
||||
vm.ctx.Log.AssertNoError(err)
|
||||
|
||||
return &BlockClient{
|
||||
vm: vm,
|
||||
id: id,
|
||||
parentID: parentID,
|
||||
status: choices.Processing,
|
||||
bytes: resp.Bytes,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ParseBlock ...
|
||||
func (vm *VMClient) ParseBlock(bytes []byte) (snowman.Block, error) {
|
||||
resp, err := vm.client.ParseBlock(context.Background(), &vmproto.ParseBlockRequest{
|
||||
Bytes: bytes,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
id, err := ids.ToID(resp.Id)
|
||||
vm.ctx.Log.AssertNoError(err)
|
||||
|
||||
if blk, cached := vm.blks[id.Key()]; cached {
|
||||
return blk, nil
|
||||
}
|
||||
|
||||
parentID, err := ids.ToID(resp.ParentID)
|
||||
vm.ctx.Log.AssertNoError(err)
|
||||
status := choices.Status(resp.Status)
|
||||
vm.ctx.Log.AssertDeferredNoError(status.Valid)
|
||||
|
||||
return &BlockClient{
|
||||
vm: vm,
|
||||
id: id,
|
||||
parentID: parentID,
|
||||
status: status,
|
||||
bytes: bytes,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetBlock ...
|
||||
func (vm *VMClient) GetBlock(id ids.ID) (snowman.Block, error) {
|
||||
if blk, cached := vm.blks[id.Key()]; cached {
|
||||
return blk, nil
|
||||
}
|
||||
|
||||
resp, err := vm.client.GetBlock(context.Background(), &vmproto.GetBlockRequest{
|
||||
Id: id.Bytes(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
parentID, err := ids.ToID(resp.ParentID)
|
||||
vm.ctx.Log.AssertNoError(err)
|
||||
status := choices.Status(resp.Status)
|
||||
vm.ctx.Log.AssertDeferredNoError(status.Valid)
|
||||
|
||||
return &BlockClient{
|
||||
vm: vm,
|
||||
id: id,
|
||||
parentID: parentID,
|
||||
status: status,
|
||||
bytes: resp.Bytes,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SetPreference ...
|
||||
func (vm *VMClient) SetPreference(id ids.ID) {
|
||||
_, err := vm.client.SetPreference(context.Background(), &vmproto.SetPreferenceRequest{
|
||||
Id: id.Bytes(),
|
||||
})
|
||||
vm.ctx.Log.AssertNoError(err)
|
||||
}
|
||||
|
||||
// LastAccepted ...
|
||||
func (vm *VMClient) LastAccepted() ids.ID {
|
||||
resp, err := vm.client.LastAccepted(context.Background(), &vmproto.LastAcceptedRequest{})
|
||||
vm.ctx.Log.AssertNoError(err)
|
||||
|
||||
id, err := ids.ToID(resp.Id)
|
||||
vm.ctx.Log.AssertNoError(err)
|
||||
|
||||
return id
|
||||
}
|
||||
|
||||
// BlockClient is an implementation of Block that talks over RPC.
|
||||
type BlockClient struct {
|
||||
vm *VMClient
|
||||
|
||||
id ids.ID
|
||||
parentID ids.ID
|
||||
status choices.Status
|
||||
bytes []byte
|
||||
}
|
||||
|
||||
// ID ...
|
||||
func (b *BlockClient) ID() ids.ID { return b.id }
|
||||
|
||||
// Accept ...
|
||||
func (b *BlockClient) Accept() {
|
||||
delete(b.vm.blks, b.id.Key())
|
||||
b.status = choices.Accepted
|
||||
_, err := b.vm.client.BlockAccept(context.Background(), &vmproto.BlockAcceptRequest{
|
||||
Id: b.id.Bytes(),
|
||||
})
|
||||
b.vm.ctx.Log.AssertNoError(err)
|
||||
}
|
||||
|
||||
// Reject ...
|
||||
func (b *BlockClient) Reject() {
|
||||
delete(b.vm.blks, b.id.Key())
|
||||
b.status = choices.Rejected
|
||||
_, err := b.vm.client.BlockReject(context.Background(), &vmproto.BlockRejectRequest{
|
||||
Id: b.id.Bytes(),
|
||||
})
|
||||
b.vm.ctx.Log.AssertNoError(err)
|
||||
}
|
||||
|
||||
// Status ...
|
||||
func (b *BlockClient) Status() choices.Status { return b.status }
|
||||
|
||||
// Parent ...
|
||||
func (b *BlockClient) Parent() snowman.Block {
|
||||
if parent, err := b.vm.GetBlock(b.parentID); err == nil {
|
||||
return parent
|
||||
}
|
||||
return &missing.Block{BlkID: b.parentID}
|
||||
}
|
||||
|
||||
// Verify ...
|
||||
func (b *BlockClient) Verify() error {
|
||||
_, err := b.vm.client.BlockVerify(context.Background(), &vmproto.BlockVerifyRequest{
|
||||
Id: b.id.Bytes(),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b.vm.blks[b.id.Key()] = b
|
||||
return nil
|
||||
}
|
||||
|
||||
// Bytes ...
|
||||
func (b *BlockClient) Bytes() []byte { return b.bytes }
|
|
@ -0,0 +1,240 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package rpcchainvm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/hashicorp/go-plugin"
|
||||
|
||||
"github.com/ava-labs/gecko/database/rpcdb"
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/snow"
|
||||
"github.com/ava-labs/gecko/snow/engine/common"
|
||||
"github.com/ava-labs/gecko/snow/engine/snowman"
|
||||
"github.com/ava-labs/gecko/utils/wrappers"
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/ghttp"
|
||||
"github.com/ava-labs/gecko/vms/rpcchainvm/messenger"
|
||||
|
||||
dbproto "github.com/ava-labs/gecko/database/rpcdb/proto"
|
||||
httpproto "github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/proto"
|
||||
msgproto "github.com/ava-labs/gecko/vms/rpcchainvm/messenger/proto"
|
||||
vmproto "github.com/ava-labs/gecko/vms/rpcchainvm/proto"
|
||||
)
|
||||
|
||||
// VMServer is a VM that is managed over RPC.
|
||||
type VMServer struct {
|
||||
vm snowman.ChainVM
|
||||
broker *plugin.GRPCBroker
|
||||
|
||||
lock sync.Mutex
|
||||
closed bool
|
||||
servers []*grpc.Server
|
||||
conns []*grpc.ClientConn
|
||||
|
||||
toEngine chan common.Message
|
||||
}
|
||||
|
||||
// NewServer returns a vm instance connected to a remote vm instance
|
||||
func NewServer(vm snowman.ChainVM, broker *plugin.GRPCBroker) *VMServer {
|
||||
return &VMServer{
|
||||
vm: vm,
|
||||
broker: broker,
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize ...
|
||||
func (vm *VMServer) Initialize(_ context.Context, req *vmproto.InitializeRequest) (*vmproto.InitializeResponse, error) {
|
||||
dbConn, err := vm.broker.Dial(req.DbServer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
msgConn, err := vm.broker.Dial(req.EngineServer)
|
||||
if err != nil {
|
||||
dbConn.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dbClient := rpcdb.NewClient(dbproto.NewDatabaseClient(dbConn))
|
||||
msgClient := messenger.NewClient(msgproto.NewMessengerClient(msgConn))
|
||||
|
||||
toEngine := make(chan common.Message, 1)
|
||||
go func() {
|
||||
for msg := range toEngine {
|
||||
msgClient.Notify(msg)
|
||||
}
|
||||
}()
|
||||
|
||||
// TODO: Needs to populate a real context
|
||||
ctx := snow.DefaultContextTest()
|
||||
|
||||
if err := vm.vm.Initialize(ctx, dbClient, req.GenesisBytes, toEngine, nil); err != nil {
|
||||
dbConn.Close()
|
||||
msgConn.Close()
|
||||
close(toEngine)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vm.conns = append(vm.conns, dbConn)
|
||||
vm.conns = append(vm.conns, msgConn)
|
||||
vm.toEngine = toEngine
|
||||
return &vmproto.InitializeResponse{}, nil
|
||||
}
|
||||
|
||||
// Shutdown ...
|
||||
func (vm *VMServer) Shutdown(_ context.Context, _ *vmproto.ShutdownRequest) (*vmproto.ShutdownResponse, error) {
|
||||
vm.lock.Lock()
|
||||
defer vm.lock.Unlock()
|
||||
|
||||
if vm.closed || vm.toEngine == nil {
|
||||
return &vmproto.ShutdownResponse{}, nil
|
||||
}
|
||||
|
||||
vm.closed = true
|
||||
|
||||
vm.vm.Shutdown()
|
||||
close(vm.toEngine)
|
||||
|
||||
errs := wrappers.Errs{}
|
||||
for _, conn := range vm.conns {
|
||||
errs.Add(conn.Close())
|
||||
}
|
||||
return &vmproto.ShutdownResponse{}, errs.Err
|
||||
}
|
||||
|
||||
// CreateHandlers ...
|
||||
func (vm *VMServer) CreateHandlers(_ context.Context, req *vmproto.CreateHandlersRequest) (*vmproto.CreateHandlersResponse, error) {
|
||||
handlers := vm.vm.CreateHandlers()
|
||||
resp := &vmproto.CreateHandlersResponse{}
|
||||
for prefix, h := range handlers {
|
||||
handler := h
|
||||
|
||||
// start the messenger server
|
||||
serverID := vm.broker.NextId()
|
||||
go vm.broker.AcceptAndServe(serverID, func(opts []grpc.ServerOption) *grpc.Server {
|
||||
vm.lock.Lock()
|
||||
defer vm.lock.Unlock()
|
||||
|
||||
server := grpc.NewServer(opts...)
|
||||
|
||||
if vm.closed {
|
||||
server.Stop()
|
||||
} else {
|
||||
vm.servers = append(vm.servers, server)
|
||||
}
|
||||
|
||||
httpproto.RegisterHTTPServer(server, ghttp.NewServer(handler.Handler, vm.broker))
|
||||
return server
|
||||
})
|
||||
|
||||
resp.Handlers = append(resp.Handlers, &vmproto.Handler{
|
||||
Prefix: prefix,
|
||||
LockOptions: uint32(handler.LockOptions),
|
||||
Server: serverID,
|
||||
})
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// BuildBlock ...
|
||||
func (vm *VMServer) BuildBlock(_ context.Context, _ *vmproto.BuildBlockRequest) (*vmproto.BuildBlockResponse, error) {
|
||||
blk, err := vm.vm.BuildBlock()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &vmproto.BuildBlockResponse{
|
||||
Id: blk.ID().Bytes(),
|
||||
ParentID: blk.Parent().ID().Bytes(),
|
||||
Bytes: blk.Bytes(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ParseBlock ...
|
||||
func (vm *VMServer) ParseBlock(_ context.Context, req *vmproto.ParseBlockRequest) (*vmproto.ParseBlockResponse, error) {
|
||||
blk, err := vm.vm.ParseBlock(req.Bytes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &vmproto.ParseBlockResponse{
|
||||
Id: blk.ID().Bytes(),
|
||||
ParentID: blk.Parent().ID().Bytes(),
|
||||
Status: uint32(blk.Status()),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetBlock ...
|
||||
func (vm *VMServer) GetBlock(_ context.Context, req *vmproto.GetBlockRequest) (*vmproto.GetBlockResponse, error) {
|
||||
id, err := ids.ToID(req.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blk, err := vm.vm.GetBlock(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &vmproto.GetBlockResponse{
|
||||
ParentID: blk.Parent().ID().Bytes(),
|
||||
Bytes: blk.Bytes(),
|
||||
Status: uint32(blk.Status()),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SetPreference ...
|
||||
func (vm *VMServer) SetPreference(_ context.Context, req *vmproto.SetPreferenceRequest) (*vmproto.SetPreferenceResponse, error) {
|
||||
id, err := ids.ToID(req.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vm.vm.SetPreference(id)
|
||||
return &vmproto.SetPreferenceResponse{}, nil
|
||||
}
|
||||
|
||||
// LastAccepted ...
|
||||
func (vm *VMServer) LastAccepted(_ context.Context, _ *vmproto.LastAcceptedRequest) (*vmproto.LastAcceptedResponse, error) {
|
||||
return &vmproto.LastAcceptedResponse{Id: vm.vm.LastAccepted().Bytes()}, nil
|
||||
}
|
||||
|
||||
// BlockVerify ...
|
||||
func (vm *VMServer) BlockVerify(_ context.Context, req *vmproto.BlockVerifyRequest) (*vmproto.BlockVerifyResponse, error) {
|
||||
id, err := ids.ToID(req.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blk, err := vm.vm.GetBlock(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &vmproto.BlockVerifyResponse{}, blk.Verify()
|
||||
}
|
||||
|
||||
// BlockAccept ...
|
||||
func (vm *VMServer) BlockAccept(_ context.Context, req *vmproto.BlockAcceptRequest) (*vmproto.BlockAcceptResponse, error) {
|
||||
id, err := ids.ToID(req.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blk, err := vm.vm.GetBlock(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blk.Accept()
|
||||
return &vmproto.BlockAcceptResponse{}, nil
|
||||
}
|
||||
|
||||
// BlockReject ...
|
||||
func (vm *VMServer) BlockReject(_ context.Context, req *vmproto.BlockRejectRequest) (*vmproto.BlockRejectResponse, error) {
|
||||
id, err := ids.ToID(req.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blk, err := vm.vm.GetBlock(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blk.Reject()
|
||||
return &vmproto.BlockRejectResponse{}, nil
|
||||
}
|
|
@ -16,4 +16,4 @@ var (
|
|||
type Factory struct{}
|
||||
|
||||
// New ...
|
||||
func (f *Factory) New() interface{} { return &Fx{} }
|
||||
func (f *Factory) New() (interface{}, error) { return &Fx{}, nil }
|
||||
|
|
|
@ -9,7 +9,9 @@ import (
|
|||
|
||||
func TestFactory(t *testing.T) {
|
||||
factory := Factory{}
|
||||
if fx := factory.New(); fx == nil {
|
||||
if fx, err := factory.New(); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if fx == nil {
|
||||
t.Fatalf("Factory.New returned nil")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,4 +16,4 @@ var (
|
|||
type Factory struct{}
|
||||
|
||||
// New ...
|
||||
func (f *Factory) New() interface{} { return &VM{} }
|
||||
func (f *Factory) New() (interface{}, error) { return &VM{}, nil }
|
||||
|
|
|
@ -118,6 +118,10 @@ func (vm *VM) Initialize(
|
|||
|
||||
// Shutdown implements the snowman.ChainVM interface
|
||||
func (vm *VM) Shutdown() {
|
||||
if vm.timer == nil {
|
||||
return
|
||||
}
|
||||
|
||||
vm.timer.Stop()
|
||||
if err := vm.baseDB.Close(); err != nil {
|
||||
vm.ctx.Log.Error("Closing the database failed with %s", err)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue