diff --git a/.gitignore b/.gitignore index 6b1e28c..f8a87c9 100644 --- a/.gitignore +++ b/.gitignore @@ -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/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index b24a23f..13ef1e7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -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 diff --git a/chains/manager.go b/chains/manager.go index aef8064..3f7d48d 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -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, } } diff --git a/database/encdb/encdb.go b/database/encdb/db.go similarity index 100% rename from database/encdb/encdb.go rename to database/encdb/db.go diff --git a/database/encdb/encdb_test.go b/database/encdb/db_test.go similarity index 100% rename from database/encdb/encdb_test.go rename to database/encdb/db_test.go diff --git a/database/leveldb/leveldb.go b/database/leveldb/db.go similarity index 100% rename from database/leveldb/leveldb.go rename to database/leveldb/db.go diff --git a/database/leveldb/leveldb_test.go b/database/leveldb/db_test.go similarity index 100% rename from database/leveldb/leveldb_test.go rename to database/leveldb/db_test.go diff --git a/database/memdb/memdb.go b/database/memdb/db.go similarity index 100% rename from database/memdb/memdb.go rename to database/memdb/db.go diff --git a/database/memdb/memdb_test.go b/database/memdb/db_test.go similarity index 100% rename from database/memdb/memdb_test.go rename to database/memdb/db_test.go diff --git a/database/mockdb/mockdb.go b/database/mockdb/db.go similarity index 100% rename from database/mockdb/mockdb.go rename to database/mockdb/db.go diff --git a/database/mockdb/mockdb_test.go b/database/mockdb/db_test.go similarity index 100% rename from database/mockdb/mockdb_test.go rename to database/mockdb/db_test.go diff --git a/database/nodb/nodb.go b/database/nodb/db.go similarity index 100% rename from database/nodb/nodb.go rename to database/nodb/db.go diff --git a/database/prefixdb/prefixdb.go b/database/prefixdb/db.go similarity index 100% rename from database/prefixdb/prefixdb.go rename to database/prefixdb/db.go diff --git a/database/prefixdb/prefixdb_test.go b/database/prefixdb/db_test.go similarity index 100% rename from database/prefixdb/prefixdb_test.go rename to database/prefixdb/db_test.go diff --git a/database/rpcdb/db_client.go b/database/rpcdb/db_client.go new file mode 100644 index 0000000..8d23049 --- /dev/null +++ b/database/rpcdb/db_client.go @@ -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 + } +} diff --git a/database/rpcdb/db_server.go b/database/rpcdb/db_server.go new file mode 100644 index 0000000..5abc3be --- /dev/null +++ b/database/rpcdb/db_server.go @@ -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 +} diff --git a/database/rpcdb/db_test.go b/database/rpcdb/db_test.go new file mode 100644 index 0000000..ae833d5 --- /dev/null +++ b/database/rpcdb/db_test.go @@ -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() + } +} diff --git a/database/rpcdb/proto/db.pb.go b/database/rpcdb/proto/db.pb.go new file mode 100644 index 0000000..452bad7 --- /dev/null +++ b/database/rpcdb/proto/db.pb.go @@ -0,0 +1,1526 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: db.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 HasRequest struct { + Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *HasRequest) Reset() { *m = HasRequest{} } +func (m *HasRequest) String() string { return proto.CompactTextString(m) } +func (*HasRequest) ProtoMessage() {} +func (*HasRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_8817812184a13374, []int{0} +} + +func (m *HasRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_HasRequest.Unmarshal(m, b) +} +func (m *HasRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_HasRequest.Marshal(b, m, deterministic) +} +func (m *HasRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_HasRequest.Merge(m, src) +} +func (m *HasRequest) XXX_Size() int { + return xxx_messageInfo_HasRequest.Size(m) +} +func (m *HasRequest) XXX_DiscardUnknown() { + xxx_messageInfo_HasRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_HasRequest proto.InternalMessageInfo + +func (m *HasRequest) GetKey() []byte { + if m != nil { + return m.Key + } + return nil +} + +type HasResponse struct { + Has bool `protobuf:"varint,1,opt,name=has,proto3" json:"has,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *HasResponse) Reset() { *m = HasResponse{} } +func (m *HasResponse) String() string { return proto.CompactTextString(m) } +func (*HasResponse) ProtoMessage() {} +func (*HasResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_8817812184a13374, []int{1} +} + +func (m *HasResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_HasResponse.Unmarshal(m, b) +} +func (m *HasResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_HasResponse.Marshal(b, m, deterministic) +} +func (m *HasResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_HasResponse.Merge(m, src) +} +func (m *HasResponse) XXX_Size() int { + return xxx_messageInfo_HasResponse.Size(m) +} +func (m *HasResponse) XXX_DiscardUnknown() { + xxx_messageInfo_HasResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_HasResponse proto.InternalMessageInfo + +func (m *HasResponse) GetHas() bool { + if m != nil { + return m.Has + } + return false +} + +type GetRequest struct { + Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetRequest) Reset() { *m = GetRequest{} } +func (m *GetRequest) String() string { return proto.CompactTextString(m) } +func (*GetRequest) ProtoMessage() {} +func (*GetRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_8817812184a13374, []int{2} +} + +func (m *GetRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetRequest.Unmarshal(m, b) +} +func (m *GetRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetRequest.Marshal(b, m, deterministic) +} +func (m *GetRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetRequest.Merge(m, src) +} +func (m *GetRequest) XXX_Size() int { + return xxx_messageInfo_GetRequest.Size(m) +} +func (m *GetRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetRequest proto.InternalMessageInfo + +func (m *GetRequest) GetKey() []byte { + if m != nil { + return m.Key + } + return nil +} + +type GetResponse struct { + Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetResponse) Reset() { *m = GetResponse{} } +func (m *GetResponse) String() string { return proto.CompactTextString(m) } +func (*GetResponse) ProtoMessage() {} +func (*GetResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_8817812184a13374, []int{3} +} + +func (m *GetResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetResponse.Unmarshal(m, b) +} +func (m *GetResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetResponse.Marshal(b, m, deterministic) +} +func (m *GetResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetResponse.Merge(m, src) +} +func (m *GetResponse) XXX_Size() int { + return xxx_messageInfo_GetResponse.Size(m) +} +func (m *GetResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetResponse proto.InternalMessageInfo + +func (m *GetResponse) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +type PutRequest struct { + Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PutRequest) Reset() { *m = PutRequest{} } +func (m *PutRequest) String() string { return proto.CompactTextString(m) } +func (*PutRequest) ProtoMessage() {} +func (*PutRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_8817812184a13374, []int{4} +} + +func (m *PutRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PutRequest.Unmarshal(m, b) +} +func (m *PutRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PutRequest.Marshal(b, m, deterministic) +} +func (m *PutRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PutRequest.Merge(m, src) +} +func (m *PutRequest) XXX_Size() int { + return xxx_messageInfo_PutRequest.Size(m) +} +func (m *PutRequest) XXX_DiscardUnknown() { + xxx_messageInfo_PutRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_PutRequest proto.InternalMessageInfo + +func (m *PutRequest) GetKey() []byte { + if m != nil { + return m.Key + } + return nil +} + +func (m *PutRequest) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +type PutResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PutResponse) Reset() { *m = PutResponse{} } +func (m *PutResponse) String() string { return proto.CompactTextString(m) } +func (*PutResponse) ProtoMessage() {} +func (*PutResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_8817812184a13374, []int{5} +} + +func (m *PutResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PutResponse.Unmarshal(m, b) +} +func (m *PutResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PutResponse.Marshal(b, m, deterministic) +} +func (m *PutResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_PutResponse.Merge(m, src) +} +func (m *PutResponse) XXX_Size() int { + return xxx_messageInfo_PutResponse.Size(m) +} +func (m *PutResponse) XXX_DiscardUnknown() { + xxx_messageInfo_PutResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_PutResponse proto.InternalMessageInfo + +type DeleteRequest struct { + Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeleteRequest) Reset() { *m = DeleteRequest{} } +func (m *DeleteRequest) String() string { return proto.CompactTextString(m) } +func (*DeleteRequest) ProtoMessage() {} +func (*DeleteRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_8817812184a13374, []int{6} +} + +func (m *DeleteRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DeleteRequest.Unmarshal(m, b) +} +func (m *DeleteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DeleteRequest.Marshal(b, m, deterministic) +} +func (m *DeleteRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeleteRequest.Merge(m, src) +} +func (m *DeleteRequest) XXX_Size() int { + return xxx_messageInfo_DeleteRequest.Size(m) +} +func (m *DeleteRequest) XXX_DiscardUnknown() { + xxx_messageInfo_DeleteRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_DeleteRequest proto.InternalMessageInfo + +func (m *DeleteRequest) GetKey() []byte { + if m != nil { + return m.Key + } + return nil +} + +type DeleteResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeleteResponse) Reset() { *m = DeleteResponse{} } +func (m *DeleteResponse) String() string { return proto.CompactTextString(m) } +func (*DeleteResponse) ProtoMessage() {} +func (*DeleteResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_8817812184a13374, []int{7} +} + +func (m *DeleteResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DeleteResponse.Unmarshal(m, b) +} +func (m *DeleteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DeleteResponse.Marshal(b, m, deterministic) +} +func (m *DeleteResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeleteResponse.Merge(m, src) +} +func (m *DeleteResponse) XXX_Size() int { + return xxx_messageInfo_DeleteResponse.Size(m) +} +func (m *DeleteResponse) XXX_DiscardUnknown() { + xxx_messageInfo_DeleteResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_DeleteResponse proto.InternalMessageInfo + +type StatRequest struct { + Property string `protobuf:"bytes,1,opt,name=property,proto3" json:"property,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StatRequest) Reset() { *m = StatRequest{} } +func (m *StatRequest) String() string { return proto.CompactTextString(m) } +func (*StatRequest) ProtoMessage() {} +func (*StatRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_8817812184a13374, []int{8} +} + +func (m *StatRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_StatRequest.Unmarshal(m, b) +} +func (m *StatRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_StatRequest.Marshal(b, m, deterministic) +} +func (m *StatRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_StatRequest.Merge(m, src) +} +func (m *StatRequest) XXX_Size() int { + return xxx_messageInfo_StatRequest.Size(m) +} +func (m *StatRequest) XXX_DiscardUnknown() { + xxx_messageInfo_StatRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_StatRequest proto.InternalMessageInfo + +func (m *StatRequest) GetProperty() string { + if m != nil { + return m.Property + } + return "" +} + +type StatResponse struct { + Stat string `protobuf:"bytes,1,opt,name=stat,proto3" json:"stat,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *StatResponse) Reset() { *m = StatResponse{} } +func (m *StatResponse) String() string { return proto.CompactTextString(m) } +func (*StatResponse) ProtoMessage() {} +func (*StatResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_8817812184a13374, []int{9} +} + +func (m *StatResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_StatResponse.Unmarshal(m, b) +} +func (m *StatResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_StatResponse.Marshal(b, m, deterministic) +} +func (m *StatResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_StatResponse.Merge(m, src) +} +func (m *StatResponse) XXX_Size() int { + return xxx_messageInfo_StatResponse.Size(m) +} +func (m *StatResponse) XXX_DiscardUnknown() { + xxx_messageInfo_StatResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_StatResponse proto.InternalMessageInfo + +func (m *StatResponse) GetStat() string { + if m != nil { + return m.Stat + } + return "" +} + +type CompactRequest struct { + Start []byte `protobuf:"bytes,1,opt,name=start,proto3" json:"start,omitempty"` + Limit []byte `protobuf:"bytes,2,opt,name=limit,proto3" json:"limit,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CompactRequest) Reset() { *m = CompactRequest{} } +func (m *CompactRequest) String() string { return proto.CompactTextString(m) } +func (*CompactRequest) ProtoMessage() {} +func (*CompactRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_8817812184a13374, []int{10} +} + +func (m *CompactRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CompactRequest.Unmarshal(m, b) +} +func (m *CompactRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CompactRequest.Marshal(b, m, deterministic) +} +func (m *CompactRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_CompactRequest.Merge(m, src) +} +func (m *CompactRequest) XXX_Size() int { + return xxx_messageInfo_CompactRequest.Size(m) +} +func (m *CompactRequest) XXX_DiscardUnknown() { + xxx_messageInfo_CompactRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_CompactRequest proto.InternalMessageInfo + +func (m *CompactRequest) GetStart() []byte { + if m != nil { + return m.Start + } + return nil +} + +func (m *CompactRequest) GetLimit() []byte { + if m != nil { + return m.Limit + } + return nil +} + +type CompactResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CompactResponse) Reset() { *m = CompactResponse{} } +func (m *CompactResponse) String() string { return proto.CompactTextString(m) } +func (*CompactResponse) ProtoMessage() {} +func (*CompactResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_8817812184a13374, []int{11} +} + +func (m *CompactResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CompactResponse.Unmarshal(m, b) +} +func (m *CompactResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CompactResponse.Marshal(b, m, deterministic) +} +func (m *CompactResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_CompactResponse.Merge(m, src) +} +func (m *CompactResponse) XXX_Size() int { + return xxx_messageInfo_CompactResponse.Size(m) +} +func (m *CompactResponse) XXX_DiscardUnknown() { + xxx_messageInfo_CompactResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_CompactResponse proto.InternalMessageInfo + +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_8817812184a13374, []int{12} +} + +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_8817812184a13374, []int{13} +} + +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 WriteBatchRequest struct { + Puts []*PutRequest `protobuf:"bytes,1,rep,name=puts,proto3" json:"puts,omitempty"` + Deletes []*DeleteRequest `protobuf:"bytes,2,rep,name=deletes,proto3" json:"deletes,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *WriteBatchRequest) Reset() { *m = WriteBatchRequest{} } +func (m *WriteBatchRequest) String() string { return proto.CompactTextString(m) } +func (*WriteBatchRequest) ProtoMessage() {} +func (*WriteBatchRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_8817812184a13374, []int{14} +} + +func (m *WriteBatchRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_WriteBatchRequest.Unmarshal(m, b) +} +func (m *WriteBatchRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_WriteBatchRequest.Marshal(b, m, deterministic) +} +func (m *WriteBatchRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_WriteBatchRequest.Merge(m, src) +} +func (m *WriteBatchRequest) XXX_Size() int { + return xxx_messageInfo_WriteBatchRequest.Size(m) +} +func (m *WriteBatchRequest) XXX_DiscardUnknown() { + xxx_messageInfo_WriteBatchRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_WriteBatchRequest proto.InternalMessageInfo + +func (m *WriteBatchRequest) GetPuts() []*PutRequest { + if m != nil { + return m.Puts + } + return nil +} + +func (m *WriteBatchRequest) GetDeletes() []*DeleteRequest { + if m != nil { + return m.Deletes + } + return nil +} + +type WriteBatchResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *WriteBatchResponse) Reset() { *m = WriteBatchResponse{} } +func (m *WriteBatchResponse) String() string { return proto.CompactTextString(m) } +func (*WriteBatchResponse) ProtoMessage() {} +func (*WriteBatchResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_8817812184a13374, []int{15} +} + +func (m *WriteBatchResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_WriteBatchResponse.Unmarshal(m, b) +} +func (m *WriteBatchResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_WriteBatchResponse.Marshal(b, m, deterministic) +} +func (m *WriteBatchResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_WriteBatchResponse.Merge(m, src) +} +func (m *WriteBatchResponse) XXX_Size() int { + return xxx_messageInfo_WriteBatchResponse.Size(m) +} +func (m *WriteBatchResponse) XXX_DiscardUnknown() { + xxx_messageInfo_WriteBatchResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_WriteBatchResponse proto.InternalMessageInfo + +type NewIteratorRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *NewIteratorRequest) Reset() { *m = NewIteratorRequest{} } +func (m *NewIteratorRequest) String() string { return proto.CompactTextString(m) } +func (*NewIteratorRequest) ProtoMessage() {} +func (*NewIteratorRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_8817812184a13374, []int{16} +} + +func (m *NewIteratorRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_NewIteratorRequest.Unmarshal(m, b) +} +func (m *NewIteratorRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_NewIteratorRequest.Marshal(b, m, deterministic) +} +func (m *NewIteratorRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_NewIteratorRequest.Merge(m, src) +} +func (m *NewIteratorRequest) XXX_Size() int { + return xxx_messageInfo_NewIteratorRequest.Size(m) +} +func (m *NewIteratorRequest) XXX_DiscardUnknown() { + xxx_messageInfo_NewIteratorRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_NewIteratorRequest proto.InternalMessageInfo + +type NewIteratorWithStartAndPrefixRequest struct { + Start []byte `protobuf:"bytes,1,opt,name=start,proto3" json:"start,omitempty"` + Prefix []byte `protobuf:"bytes,2,opt,name=prefix,proto3" json:"prefix,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *NewIteratorWithStartAndPrefixRequest) Reset() { *m = NewIteratorWithStartAndPrefixRequest{} } +func (m *NewIteratorWithStartAndPrefixRequest) String() string { return proto.CompactTextString(m) } +func (*NewIteratorWithStartAndPrefixRequest) ProtoMessage() {} +func (*NewIteratorWithStartAndPrefixRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_8817812184a13374, []int{17} +} + +func (m *NewIteratorWithStartAndPrefixRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_NewIteratorWithStartAndPrefixRequest.Unmarshal(m, b) +} +func (m *NewIteratorWithStartAndPrefixRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_NewIteratorWithStartAndPrefixRequest.Marshal(b, m, deterministic) +} +func (m *NewIteratorWithStartAndPrefixRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_NewIteratorWithStartAndPrefixRequest.Merge(m, src) +} +func (m *NewIteratorWithStartAndPrefixRequest) XXX_Size() int { + return xxx_messageInfo_NewIteratorWithStartAndPrefixRequest.Size(m) +} +func (m *NewIteratorWithStartAndPrefixRequest) XXX_DiscardUnknown() { + xxx_messageInfo_NewIteratorWithStartAndPrefixRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_NewIteratorWithStartAndPrefixRequest proto.InternalMessageInfo + +func (m *NewIteratorWithStartAndPrefixRequest) GetStart() []byte { + if m != nil { + return m.Start + } + return nil +} + +func (m *NewIteratorWithStartAndPrefixRequest) GetPrefix() []byte { + if m != nil { + return m.Prefix + } + return nil +} + +type NewIteratorWithStartAndPrefixResponse struct { + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *NewIteratorWithStartAndPrefixResponse) Reset() { *m = NewIteratorWithStartAndPrefixResponse{} } +func (m *NewIteratorWithStartAndPrefixResponse) String() string { return proto.CompactTextString(m) } +func (*NewIteratorWithStartAndPrefixResponse) ProtoMessage() {} +func (*NewIteratorWithStartAndPrefixResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_8817812184a13374, []int{18} +} + +func (m *NewIteratorWithStartAndPrefixResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_NewIteratorWithStartAndPrefixResponse.Unmarshal(m, b) +} +func (m *NewIteratorWithStartAndPrefixResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_NewIteratorWithStartAndPrefixResponse.Marshal(b, m, deterministic) +} +func (m *NewIteratorWithStartAndPrefixResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_NewIteratorWithStartAndPrefixResponse.Merge(m, src) +} +func (m *NewIteratorWithStartAndPrefixResponse) XXX_Size() int { + return xxx_messageInfo_NewIteratorWithStartAndPrefixResponse.Size(m) +} +func (m *NewIteratorWithStartAndPrefixResponse) XXX_DiscardUnknown() { + xxx_messageInfo_NewIteratorWithStartAndPrefixResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_NewIteratorWithStartAndPrefixResponse proto.InternalMessageInfo + +func (m *NewIteratorWithStartAndPrefixResponse) GetId() uint64 { + if m != nil { + return m.Id + } + return 0 +} + +type IteratorNextRequest struct { + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *IteratorNextRequest) Reset() { *m = IteratorNextRequest{} } +func (m *IteratorNextRequest) String() string { return proto.CompactTextString(m) } +func (*IteratorNextRequest) ProtoMessage() {} +func (*IteratorNextRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_8817812184a13374, []int{19} +} + +func (m *IteratorNextRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_IteratorNextRequest.Unmarshal(m, b) +} +func (m *IteratorNextRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_IteratorNextRequest.Marshal(b, m, deterministic) +} +func (m *IteratorNextRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_IteratorNextRequest.Merge(m, src) +} +func (m *IteratorNextRequest) XXX_Size() int { + return xxx_messageInfo_IteratorNextRequest.Size(m) +} +func (m *IteratorNextRequest) XXX_DiscardUnknown() { + xxx_messageInfo_IteratorNextRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_IteratorNextRequest proto.InternalMessageInfo + +func (m *IteratorNextRequest) GetId() uint64 { + if m != nil { + return m.Id + } + return 0 +} + +type IteratorNextResponse struct { + FoundNext bool `protobuf:"varint,1,opt,name=foundNext,proto3" json:"foundNext,omitempty"` + Key []byte `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` + Value []byte `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *IteratorNextResponse) Reset() { *m = IteratorNextResponse{} } +func (m *IteratorNextResponse) String() string { return proto.CompactTextString(m) } +func (*IteratorNextResponse) ProtoMessage() {} +func (*IteratorNextResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_8817812184a13374, []int{20} +} + +func (m *IteratorNextResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_IteratorNextResponse.Unmarshal(m, b) +} +func (m *IteratorNextResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_IteratorNextResponse.Marshal(b, m, deterministic) +} +func (m *IteratorNextResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_IteratorNextResponse.Merge(m, src) +} +func (m *IteratorNextResponse) XXX_Size() int { + return xxx_messageInfo_IteratorNextResponse.Size(m) +} +func (m *IteratorNextResponse) XXX_DiscardUnknown() { + xxx_messageInfo_IteratorNextResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_IteratorNextResponse proto.InternalMessageInfo + +func (m *IteratorNextResponse) GetFoundNext() bool { + if m != nil { + return m.FoundNext + } + return false +} + +func (m *IteratorNextResponse) GetKey() []byte { + if m != nil { + return m.Key + } + return nil +} + +func (m *IteratorNextResponse) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +type IteratorErrorRequest struct { + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *IteratorErrorRequest) Reset() { *m = IteratorErrorRequest{} } +func (m *IteratorErrorRequest) String() string { return proto.CompactTextString(m) } +func (*IteratorErrorRequest) ProtoMessage() {} +func (*IteratorErrorRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_8817812184a13374, []int{21} +} + +func (m *IteratorErrorRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_IteratorErrorRequest.Unmarshal(m, b) +} +func (m *IteratorErrorRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_IteratorErrorRequest.Marshal(b, m, deterministic) +} +func (m *IteratorErrorRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_IteratorErrorRequest.Merge(m, src) +} +func (m *IteratorErrorRequest) XXX_Size() int { + return xxx_messageInfo_IteratorErrorRequest.Size(m) +} +func (m *IteratorErrorRequest) XXX_DiscardUnknown() { + xxx_messageInfo_IteratorErrorRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_IteratorErrorRequest proto.InternalMessageInfo + +func (m *IteratorErrorRequest) GetId() uint64 { + if m != nil { + return m.Id + } + return 0 +} + +type IteratorErrorResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *IteratorErrorResponse) Reset() { *m = IteratorErrorResponse{} } +func (m *IteratorErrorResponse) String() string { return proto.CompactTextString(m) } +func (*IteratorErrorResponse) ProtoMessage() {} +func (*IteratorErrorResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_8817812184a13374, []int{22} +} + +func (m *IteratorErrorResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_IteratorErrorResponse.Unmarshal(m, b) +} +func (m *IteratorErrorResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_IteratorErrorResponse.Marshal(b, m, deterministic) +} +func (m *IteratorErrorResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_IteratorErrorResponse.Merge(m, src) +} +func (m *IteratorErrorResponse) XXX_Size() int { + return xxx_messageInfo_IteratorErrorResponse.Size(m) +} +func (m *IteratorErrorResponse) XXX_DiscardUnknown() { + xxx_messageInfo_IteratorErrorResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_IteratorErrorResponse proto.InternalMessageInfo + +type IteratorReleaseRequest struct { + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *IteratorReleaseRequest) Reset() { *m = IteratorReleaseRequest{} } +func (m *IteratorReleaseRequest) String() string { return proto.CompactTextString(m) } +func (*IteratorReleaseRequest) ProtoMessage() {} +func (*IteratorReleaseRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_8817812184a13374, []int{23} +} + +func (m *IteratorReleaseRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_IteratorReleaseRequest.Unmarshal(m, b) +} +func (m *IteratorReleaseRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_IteratorReleaseRequest.Marshal(b, m, deterministic) +} +func (m *IteratorReleaseRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_IteratorReleaseRequest.Merge(m, src) +} +func (m *IteratorReleaseRequest) XXX_Size() int { + return xxx_messageInfo_IteratorReleaseRequest.Size(m) +} +func (m *IteratorReleaseRequest) XXX_DiscardUnknown() { + xxx_messageInfo_IteratorReleaseRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_IteratorReleaseRequest proto.InternalMessageInfo + +func (m *IteratorReleaseRequest) GetId() uint64 { + if m != nil { + return m.Id + } + return 0 +} + +type IteratorReleaseResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *IteratorReleaseResponse) Reset() { *m = IteratorReleaseResponse{} } +func (m *IteratorReleaseResponse) String() string { return proto.CompactTextString(m) } +func (*IteratorReleaseResponse) ProtoMessage() {} +func (*IteratorReleaseResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_8817812184a13374, []int{24} +} + +func (m *IteratorReleaseResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_IteratorReleaseResponse.Unmarshal(m, b) +} +func (m *IteratorReleaseResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_IteratorReleaseResponse.Marshal(b, m, deterministic) +} +func (m *IteratorReleaseResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_IteratorReleaseResponse.Merge(m, src) +} +func (m *IteratorReleaseResponse) XXX_Size() int { + return xxx_messageInfo_IteratorReleaseResponse.Size(m) +} +func (m *IteratorReleaseResponse) XXX_DiscardUnknown() { + xxx_messageInfo_IteratorReleaseResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_IteratorReleaseResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*HasRequest)(nil), "proto.HasRequest") + proto.RegisterType((*HasResponse)(nil), "proto.HasResponse") + proto.RegisterType((*GetRequest)(nil), "proto.GetRequest") + proto.RegisterType((*GetResponse)(nil), "proto.GetResponse") + proto.RegisterType((*PutRequest)(nil), "proto.PutRequest") + proto.RegisterType((*PutResponse)(nil), "proto.PutResponse") + proto.RegisterType((*DeleteRequest)(nil), "proto.DeleteRequest") + proto.RegisterType((*DeleteResponse)(nil), "proto.DeleteResponse") + proto.RegisterType((*StatRequest)(nil), "proto.StatRequest") + proto.RegisterType((*StatResponse)(nil), "proto.StatResponse") + proto.RegisterType((*CompactRequest)(nil), "proto.CompactRequest") + proto.RegisterType((*CompactResponse)(nil), "proto.CompactResponse") + proto.RegisterType((*CloseRequest)(nil), "proto.CloseRequest") + proto.RegisterType((*CloseResponse)(nil), "proto.CloseResponse") + proto.RegisterType((*WriteBatchRequest)(nil), "proto.WriteBatchRequest") + proto.RegisterType((*WriteBatchResponse)(nil), "proto.WriteBatchResponse") + proto.RegisterType((*NewIteratorRequest)(nil), "proto.NewIteratorRequest") + proto.RegisterType((*NewIteratorWithStartAndPrefixRequest)(nil), "proto.NewIteratorWithStartAndPrefixRequest") + proto.RegisterType((*NewIteratorWithStartAndPrefixResponse)(nil), "proto.NewIteratorWithStartAndPrefixResponse") + proto.RegisterType((*IteratorNextRequest)(nil), "proto.IteratorNextRequest") + proto.RegisterType((*IteratorNextResponse)(nil), "proto.IteratorNextResponse") + proto.RegisterType((*IteratorErrorRequest)(nil), "proto.IteratorErrorRequest") + proto.RegisterType((*IteratorErrorResponse)(nil), "proto.IteratorErrorResponse") + proto.RegisterType((*IteratorReleaseRequest)(nil), "proto.IteratorReleaseRequest") + proto.RegisterType((*IteratorReleaseResponse)(nil), "proto.IteratorReleaseResponse") +} + +func init() { proto.RegisterFile("db.proto", fileDescriptor_8817812184a13374) } + +var fileDescriptor_8817812184a13374 = []byte{ + // 639 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0x5b, 0x4f, 0x13, 0x41, + 0x18, 0x0d, 0xbd, 0x51, 0x4e, 0x2f, 0xc0, 0xb0, 0xdc, 0x46, 0x40, 0x1d, 0xc5, 0x60, 0x6c, 0x30, + 0x41, 0x8d, 0x3e, 0xf8, 0x82, 0x60, 0x40, 0x1f, 0x48, 0xb3, 0x98, 0xf0, 0xe2, 0xcb, 0x40, 0x87, + 0xb0, 0x5a, 0xd8, 0x75, 0x77, 0xaa, 0xe8, 0xaf, 0xf0, 0x27, 0x9b, 0x9d, 0xfd, 0x66, 0x6f, 0x6d, + 0x91, 0xa7, 0xee, 0x7c, 0xdf, 0x39, 0x67, 0x66, 0xbe, 0x39, 0xa7, 0x68, 0x0e, 0xce, 0x77, 0x83, + 0xd0, 0xd7, 0x3e, 0xab, 0x9b, 0x1f, 0xb1, 0x05, 0x1c, 0xcb, 0xc8, 0x55, 0x3f, 0x46, 0x2a, 0xd2, + 0x6c, 0x01, 0xd5, 0xef, 0xea, 0xf7, 0xda, 0xcc, 0xa3, 0x99, 0x9d, 0xb6, 0x1b, 0x7f, 0x8a, 0x87, + 0x68, 0x99, 0x7e, 0x14, 0xf8, 0x37, 0x91, 0x8a, 0x01, 0x57, 0x32, 0x32, 0x80, 0xa6, 0x1b, 0x7f, + 0xc6, 0x02, 0x47, 0x4a, 0x4f, 0x17, 0x78, 0x82, 0x96, 0xe9, 0x93, 0x80, 0x83, 0xfa, 0x4f, 0x39, + 0x1c, 0x29, 0x82, 0x24, 0x0b, 0xf1, 0x1a, 0xe8, 0x8f, 0xa6, 0x8b, 0x64, 0xac, 0x4a, 0x9e, 0xd5, + 0x41, 0xcb, 0xb0, 0x12, 0x69, 0xf1, 0x18, 0x9d, 0x43, 0x35, 0x54, 0x5a, 0x4d, 0x3f, 0xcc, 0x02, + 0xba, 0x16, 0x42, 0xa4, 0xe7, 0x68, 0x9d, 0x6a, 0x99, 0x6e, 0xcd, 0xd1, 0x0c, 0x42, 0x3f, 0x50, + 0xa1, 0x4e, 0x78, 0x73, 0x6e, 0xba, 0x16, 0x02, 0xed, 0x04, 0x4a, 0x57, 0x61, 0xa8, 0x45, 0x5a, + 0x6a, 0xc2, 0x99, 0x6f, 0xf1, 0x1e, 0xdd, 0x03, 0xff, 0x3a, 0x90, 0x17, 0xa9, 0xa2, 0x83, 0x7a, + 0xa4, 0x65, 0xa8, 0xed, 0x85, 0xcd, 0x22, 0xae, 0x0e, 0xbd, 0x6b, 0x4f, 0xdb, 0x0b, 0x99, 0x85, + 0x58, 0xc4, 0x7c, 0xca, 0xa6, 0xf3, 0x75, 0xd1, 0x3e, 0x18, 0xfa, 0x91, 0xbd, 0x93, 0x98, 0x47, + 0x87, 0xd6, 0x04, 0xf8, 0x86, 0xc5, 0xb3, 0xd0, 0xd3, 0xea, 0x83, 0xd4, 0x17, 0x57, 0x76, 0xd3, + 0x6d, 0xd4, 0x82, 0x91, 0x8e, 0xdf, 0xa9, 0xba, 0xd3, 0xda, 0x5b, 0x4c, 0x9e, 0x7c, 0x37, 0x1b, + 0xb1, 0x6b, 0xda, 0x6c, 0x17, 0xb3, 0x03, 0x33, 0x8e, 0x68, 0xad, 0x62, 0x90, 0x0e, 0x21, 0x0b, + 0x73, 0x74, 0x2d, 0x48, 0x38, 0x60, 0xf9, 0xbd, 0xe8, 0x04, 0x0e, 0xd8, 0x89, 0xfa, 0xf5, 0x49, + 0xab, 0x50, 0x6a, 0x3f, 0xb4, 0x07, 0xfd, 0x82, 0xa7, 0xb9, 0xea, 0x99, 0xa7, 0xaf, 0x4e, 0xe3, + 0x9b, 0xef, 0xdf, 0x0c, 0xfa, 0xa1, 0xba, 0xf4, 0x6e, 0xef, 0x9e, 0xcf, 0x0a, 0x1a, 0x81, 0x81, + 0xd1, 0x80, 0x68, 0x25, 0xde, 0x62, 0xfb, 0x3f, 0xaa, 0xf4, 0x38, 0x5d, 0x54, 0xbc, 0x81, 0xd1, + 0xac, 0xb9, 0x15, 0x6f, 0x20, 0xb6, 0xb1, 0x64, 0x59, 0x27, 0xea, 0x36, 0x7d, 0x9d, 0x32, 0xec, + 0x2b, 0x9c, 0x22, 0x8c, 0xe4, 0x36, 0x30, 0x77, 0xe9, 0x8f, 0x6e, 0x06, 0x71, 0x91, 0xdc, 0x9f, + 0x15, 0xac, 0xd1, 0x2a, 0x13, 0x0c, 0x5b, 0xcd, 0x1b, 0xf6, 0x59, 0xa6, 0xfe, 0x31, 0x0c, 0xd3, + 0x59, 0x8d, 0x9d, 0x62, 0x15, 0xcb, 0x25, 0x1c, 0x8d, 0x7a, 0x07, 0x2b, 0xd9, 0x9c, 0x87, 0x4a, + 0xa6, 0xbe, 0x18, 0x93, 0x58, 0xc7, 0xea, 0x18, 0x32, 0x11, 0xd9, 0xfb, 0xdb, 0x40, 0xf3, 0x50, + 0x6a, 0x79, 0x2e, 0x23, 0xc5, 0x7a, 0xa8, 0x1e, 0xcb, 0x88, 0x59, 0x8b, 0x64, 0xff, 0x05, 0x9c, + 0xe5, 0x4b, 0x34, 0x86, 0x1e, 0xaa, 0x47, 0x4a, 0xa7, 0xe8, 0x2c, 0xf8, 0x29, 0x3a, 0x9f, 0xf5, + 0x1e, 0xaa, 0xfd, 0x51, 0x86, 0xce, 0xec, 0x97, 0xa2, 0x73, 0xf1, 0x65, 0x6f, 0xd0, 0x48, 0x6c, + 0xc7, 0x26, 0xba, 0x90, 0x2f, 0x97, 0xaa, 0x44, 0x7b, 0x89, 0x5a, 0x9c, 0x4a, 0x66, 0x25, 0x73, + 0x69, 0xe6, 0x4b, 0x85, 0x1a, 0x11, 0xde, 0x61, 0x96, 0x42, 0xc6, 0xac, 0x64, 0x31, 0xb2, 0x7c, + 0xa5, 0x5c, 0x26, 0xe6, 0x1e, 0xea, 0x26, 0x7b, 0xcc, 0xea, 0xe6, 0x93, 0xc9, 0x9d, 0x62, 0x91, + 0x38, 0xfb, 0x40, 0x16, 0x19, 0xb6, 0x46, 0x98, 0xb1, 0xc4, 0xf2, 0xf5, 0x09, 0x1d, 0x92, 0xf8, + 0x83, 0xcd, 0x3b, 0x3d, 0xcf, 0x5e, 0x10, 0xf7, 0x3e, 0x79, 0xe3, 0xbd, 0xfb, 0x81, 0x69, 0xef, + 0x23, 0xb4, 0xf3, 0x79, 0x60, 0x9c, 0xd8, 0x13, 0xb2, 0xc4, 0x1f, 0x4c, 0xec, 0x91, 0xd0, 0x67, + 0x74, 0x0a, 0x96, 0x66, 0x65, 0x74, 0x3e, 0x10, 0x7c, 0x63, 0x72, 0x93, 0xb4, 0xfa, 0x98, 0x2f, + 0x79, 0x9b, 0x6d, 0x96, 0x08, 0xc5, 0x74, 0xf0, 0xad, 0x69, 0xed, 0x44, 0xf1, 0xbc, 0x61, 0xda, + 0xaf, 0xfe, 0x05, 0x00, 0x00, 0xff, 0xff, 0x84, 0x99, 0x7f, 0xf3, 0x1f, 0x07, 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 + +// DatabaseClient is the client API for Database service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type DatabaseClient interface { + Has(ctx context.Context, in *HasRequest, opts ...grpc.CallOption) (*HasResponse, error) + Get(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*GetResponse, error) + Put(ctx context.Context, in *PutRequest, opts ...grpc.CallOption) (*PutResponse, error) + Delete(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*DeleteResponse, error) + Stat(ctx context.Context, in *StatRequest, opts ...grpc.CallOption) (*StatResponse, error) + Compact(ctx context.Context, in *CompactRequest, opts ...grpc.CallOption) (*CompactResponse, error) + Close(ctx context.Context, in *CloseRequest, opts ...grpc.CallOption) (*CloseResponse, error) + WriteBatch(ctx context.Context, in *WriteBatchRequest, opts ...grpc.CallOption) (*WriteBatchResponse, error) + NewIteratorWithStartAndPrefix(ctx context.Context, in *NewIteratorWithStartAndPrefixRequest, opts ...grpc.CallOption) (*NewIteratorWithStartAndPrefixResponse, error) + IteratorNext(ctx context.Context, in *IteratorNextRequest, opts ...grpc.CallOption) (*IteratorNextResponse, error) + IteratorError(ctx context.Context, in *IteratorErrorRequest, opts ...grpc.CallOption) (*IteratorErrorResponse, error) + IteratorRelease(ctx context.Context, in *IteratorReleaseRequest, opts ...grpc.CallOption) (*IteratorReleaseResponse, error) +} + +type databaseClient struct { + cc grpc.ClientConnInterface +} + +func NewDatabaseClient(cc grpc.ClientConnInterface) DatabaseClient { + return &databaseClient{cc} +} + +func (c *databaseClient) Has(ctx context.Context, in *HasRequest, opts ...grpc.CallOption) (*HasResponse, error) { + out := new(HasResponse) + err := c.cc.Invoke(ctx, "/proto.Database/Has", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *databaseClient) Get(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*GetResponse, error) { + out := new(GetResponse) + err := c.cc.Invoke(ctx, "/proto.Database/Get", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *databaseClient) Put(ctx context.Context, in *PutRequest, opts ...grpc.CallOption) (*PutResponse, error) { + out := new(PutResponse) + err := c.cc.Invoke(ctx, "/proto.Database/Put", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *databaseClient) Delete(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*DeleteResponse, error) { + out := new(DeleteResponse) + err := c.cc.Invoke(ctx, "/proto.Database/Delete", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *databaseClient) Stat(ctx context.Context, in *StatRequest, opts ...grpc.CallOption) (*StatResponse, error) { + out := new(StatResponse) + err := c.cc.Invoke(ctx, "/proto.Database/Stat", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *databaseClient) Compact(ctx context.Context, in *CompactRequest, opts ...grpc.CallOption) (*CompactResponse, error) { + out := new(CompactResponse) + err := c.cc.Invoke(ctx, "/proto.Database/Compact", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *databaseClient) Close(ctx context.Context, in *CloseRequest, opts ...grpc.CallOption) (*CloseResponse, error) { + out := new(CloseResponse) + err := c.cc.Invoke(ctx, "/proto.Database/Close", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *databaseClient) WriteBatch(ctx context.Context, in *WriteBatchRequest, opts ...grpc.CallOption) (*WriteBatchResponse, error) { + out := new(WriteBatchResponse) + err := c.cc.Invoke(ctx, "/proto.Database/WriteBatch", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *databaseClient) NewIteratorWithStartAndPrefix(ctx context.Context, in *NewIteratorWithStartAndPrefixRequest, opts ...grpc.CallOption) (*NewIteratorWithStartAndPrefixResponse, error) { + out := new(NewIteratorWithStartAndPrefixResponse) + err := c.cc.Invoke(ctx, "/proto.Database/NewIteratorWithStartAndPrefix", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *databaseClient) IteratorNext(ctx context.Context, in *IteratorNextRequest, opts ...grpc.CallOption) (*IteratorNextResponse, error) { + out := new(IteratorNextResponse) + err := c.cc.Invoke(ctx, "/proto.Database/IteratorNext", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *databaseClient) IteratorError(ctx context.Context, in *IteratorErrorRequest, opts ...grpc.CallOption) (*IteratorErrorResponse, error) { + out := new(IteratorErrorResponse) + err := c.cc.Invoke(ctx, "/proto.Database/IteratorError", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *databaseClient) IteratorRelease(ctx context.Context, in *IteratorReleaseRequest, opts ...grpc.CallOption) (*IteratorReleaseResponse, error) { + out := new(IteratorReleaseResponse) + err := c.cc.Invoke(ctx, "/proto.Database/IteratorRelease", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// DatabaseServer is the server API for Database service. +type DatabaseServer interface { + Has(context.Context, *HasRequest) (*HasResponse, error) + Get(context.Context, *GetRequest) (*GetResponse, error) + Put(context.Context, *PutRequest) (*PutResponse, error) + Delete(context.Context, *DeleteRequest) (*DeleteResponse, error) + Stat(context.Context, *StatRequest) (*StatResponse, error) + Compact(context.Context, *CompactRequest) (*CompactResponse, error) + Close(context.Context, *CloseRequest) (*CloseResponse, error) + WriteBatch(context.Context, *WriteBatchRequest) (*WriteBatchResponse, error) + NewIteratorWithStartAndPrefix(context.Context, *NewIteratorWithStartAndPrefixRequest) (*NewIteratorWithStartAndPrefixResponse, error) + IteratorNext(context.Context, *IteratorNextRequest) (*IteratorNextResponse, error) + IteratorError(context.Context, *IteratorErrorRequest) (*IteratorErrorResponse, error) + IteratorRelease(context.Context, *IteratorReleaseRequest) (*IteratorReleaseResponse, error) +} + +// UnimplementedDatabaseServer can be embedded to have forward compatible implementations. +type UnimplementedDatabaseServer struct { +} + +func (*UnimplementedDatabaseServer) Has(ctx context.Context, req *HasRequest) (*HasResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Has not implemented") +} +func (*UnimplementedDatabaseServer) Get(ctx context.Context, req *GetRequest) (*GetResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Get not implemented") +} +func (*UnimplementedDatabaseServer) Put(ctx context.Context, req *PutRequest) (*PutResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Put not implemented") +} +func (*UnimplementedDatabaseServer) Delete(ctx context.Context, req *DeleteRequest) (*DeleteResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented") +} +func (*UnimplementedDatabaseServer) Stat(ctx context.Context, req *StatRequest) (*StatResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Stat not implemented") +} +func (*UnimplementedDatabaseServer) Compact(ctx context.Context, req *CompactRequest) (*CompactResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Compact not implemented") +} +func (*UnimplementedDatabaseServer) Close(ctx context.Context, req *CloseRequest) (*CloseResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Close not implemented") +} +func (*UnimplementedDatabaseServer) WriteBatch(ctx context.Context, req *WriteBatchRequest) (*WriteBatchResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method WriteBatch not implemented") +} +func (*UnimplementedDatabaseServer) NewIteratorWithStartAndPrefix(ctx context.Context, req *NewIteratorWithStartAndPrefixRequest) (*NewIteratorWithStartAndPrefixResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method NewIteratorWithStartAndPrefix not implemented") +} +func (*UnimplementedDatabaseServer) IteratorNext(ctx context.Context, req *IteratorNextRequest) (*IteratorNextResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method IteratorNext not implemented") +} +func (*UnimplementedDatabaseServer) IteratorError(ctx context.Context, req *IteratorErrorRequest) (*IteratorErrorResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method IteratorError not implemented") +} +func (*UnimplementedDatabaseServer) IteratorRelease(ctx context.Context, req *IteratorReleaseRequest) (*IteratorReleaseResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method IteratorRelease not implemented") +} + +func RegisterDatabaseServer(s *grpc.Server, srv DatabaseServer) { + s.RegisterService(&_Database_serviceDesc, srv) +} + +func _Database_Has_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(HasRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DatabaseServer).Has(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Database/Has", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DatabaseServer).Has(ctx, req.(*HasRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Database_Get_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DatabaseServer).Get(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Database/Get", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DatabaseServer).Get(ctx, req.(*GetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Database_Put_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PutRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DatabaseServer).Put(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Database/Put", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DatabaseServer).Put(ctx, req.(*PutRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Database_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DatabaseServer).Delete(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Database/Delete", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DatabaseServer).Delete(ctx, req.(*DeleteRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Database_Stat_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StatRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DatabaseServer).Stat(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Database/Stat", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DatabaseServer).Stat(ctx, req.(*StatRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Database_Compact_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CompactRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DatabaseServer).Compact(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Database/Compact", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DatabaseServer).Compact(ctx, req.(*CompactRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Database_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.(DatabaseServer).Close(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Database/Close", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DatabaseServer).Close(ctx, req.(*CloseRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Database_WriteBatch_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(WriteBatchRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DatabaseServer).WriteBatch(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Database/WriteBatch", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DatabaseServer).WriteBatch(ctx, req.(*WriteBatchRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Database_NewIteratorWithStartAndPrefix_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(NewIteratorWithStartAndPrefixRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DatabaseServer).NewIteratorWithStartAndPrefix(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Database/NewIteratorWithStartAndPrefix", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DatabaseServer).NewIteratorWithStartAndPrefix(ctx, req.(*NewIteratorWithStartAndPrefixRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Database_IteratorNext_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(IteratorNextRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DatabaseServer).IteratorNext(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Database/IteratorNext", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DatabaseServer).IteratorNext(ctx, req.(*IteratorNextRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Database_IteratorError_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(IteratorErrorRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DatabaseServer).IteratorError(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Database/IteratorError", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DatabaseServer).IteratorError(ctx, req.(*IteratorErrorRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Database_IteratorRelease_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(IteratorReleaseRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(DatabaseServer).IteratorRelease(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.Database/IteratorRelease", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(DatabaseServer).IteratorRelease(ctx, req.(*IteratorReleaseRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Database_serviceDesc = grpc.ServiceDesc{ + ServiceName: "proto.Database", + HandlerType: (*DatabaseServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Has", + Handler: _Database_Has_Handler, + }, + { + MethodName: "Get", + Handler: _Database_Get_Handler, + }, + { + MethodName: "Put", + Handler: _Database_Put_Handler, + }, + { + MethodName: "Delete", + Handler: _Database_Delete_Handler, + }, + { + MethodName: "Stat", + Handler: _Database_Stat_Handler, + }, + { + MethodName: "Compact", + Handler: _Database_Compact_Handler, + }, + { + MethodName: "Close", + Handler: _Database_Close_Handler, + }, + { + MethodName: "WriteBatch", + Handler: _Database_WriteBatch_Handler, + }, + { + MethodName: "NewIteratorWithStartAndPrefix", + Handler: _Database_NewIteratorWithStartAndPrefix_Handler, + }, + { + MethodName: "IteratorNext", + Handler: _Database_IteratorNext_Handler, + }, + { + MethodName: "IteratorError", + Handler: _Database_IteratorError_Handler, + }, + { + MethodName: "IteratorRelease", + Handler: _Database_IteratorRelease_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "db.proto", +} diff --git a/database/rpcdb/proto/db.proto b/database/rpcdb/proto/db.proto new file mode 100644 index 0000000..1f6f60c --- /dev/null +++ b/database/rpcdb/proto/db.proto @@ -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); +} \ No newline at end of file diff --git a/database/test_database.go b/database/test_database.go index d299bb1..2e33b25 100644 --- a/database/test_database.go +++ b/database/test_database.go @@ -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") diff --git a/database/versiondb/versiondb.go b/database/versiondb/db.go similarity index 100% rename from database/versiondb/versiondb.go rename to database/versiondb/db.go diff --git a/database/versiondb/versiondb_test.go b/database/versiondb/db_test.go similarity index 100% rename from database/versiondb/versiondb_test.go rename to database/versiondb/db_test.go diff --git a/genesis/aliases.go b/genesis/aliases.go index 41ff25a..80e5dcd 100644 --- a/genesis/aliases.go +++ b/genesis/aliases.go @@ -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): diff --git a/genesis/config.go b/genesis/config.go index 5db0302..ceab4d5 100644 --- a/genesis/config.go +++ b/genesis/config.go @@ -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, + }, } ) diff --git a/genesis/genesis.go b/genesis/genesis.go index f3c752e..4cad047 100644 --- a/genesis/genesis.go +++ b/genesis/genesis.go @@ -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{ diff --git a/genesis/genesis_test.go b/genesis/genesis_test.go index 31aea89..825d07b 100644 --- a/genesis/genesis_test.go +++ b/genesis/genesis_test.go @@ -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", }, } diff --git a/main/main.go b/main/main.go index db293b5..fc7ae99 100644 --- a/main/main.go +++ b/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 diff --git a/main/params.go b/main/params.go index 0fafe87..b17b5cd 100644 --- a/main/params.go +++ b/main/params.go @@ -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"+ diff --git a/nat/mapper.go b/nat/mapper.go new file mode 100644 index 0000000..3beaedd --- /dev/null +++ b/nat/mapper.go @@ -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 +} diff --git a/nat/no_router.go b/nat/no_router.go new file mode 100644 index 0000000..edb86b6 --- /dev/null +++ b/nat/no_router.go @@ -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 +} diff --git a/nat/pmp.go b/nat/pmp.go new file mode 100644 index 0000000..311375d --- /dev/null +++ b/nat/pmp.go @@ -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 +} diff --git a/nat/router.go b/nat/router.go new file mode 100644 index 0000000..11b58f9 --- /dev/null +++ b/nat/router.go @@ -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{} +} diff --git a/nat/upnp.go b/nat/upnp.go new file mode 100644 index 0000000..e60cd6e --- /dev/null +++ b/nat/upnp.go @@ -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 +} diff --git a/node/config.go b/node/config.go index 76c9e48..b35d997 100644 --- a/node/config.go +++ b/node/config.go @@ -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 diff --git a/node/node.go b/node/node.go index caded55..9257ca7 100644 --- a/node/node.go +++ b/node/node.go @@ -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" @@ -359,7 +360,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 { @@ -376,7 +377,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{}), diff --git a/scripts/build.sh b/scripts/build.sh index 6bb31a3..b2d1984 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -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 diff --git a/scripts/build_image.sh b/scripts/build_image.sh index 1b91410..5da7f59 100755 --- a/scripts/build_image.sh +++ b/scripts/build_image.sh @@ -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)" diff --git a/snow/engine/common/http_handler.go b/snow/engine/common/http_handler.go index c6b898d..ca00136 100644 --- a/snow/engine/common/http_handler.go +++ b/snow/engine/common/http_handler.go @@ -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 ( diff --git a/snow/engine/common/message.go b/snow/engine/common/message.go index f987902..19f4205 100644 --- a/snow/engine/common/message.go +++ b/snow/engine/common/message.go @@ -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 diff --git a/utils/crypto/crypto_benchmark_test.go b/utils/crypto/crypto_benchmark_test.go index 2d4d2f9..6262a34 100644 --- a/utils/crypto/crypto_benchmark_test.go +++ b/utils/crypto/crypto_benchmark_test.go @@ -41,7 +41,7 @@ func init() { RSA: &FactoryRSA{}, RSAPSS: &FactoryRSAPSS{}, ED25519: &FactoryED25519{}, - SECP256K1: &FactorySECP256K1{}, + SECP256K1: &FactorySECP256K1R{}, } for _, f := range factories { fKeys := []PublicKey{} diff --git a/utils/crypto/secp256k1.go b/utils/crypto/secp256k1.go deleted file mode 100644 index b9fa41a..0000000 --- a/utils/crypto/secp256k1.go +++ /dev/null @@ -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 -} diff --git a/utils/crypto/secp256k1_recover_benchmark_test.go b/utils/crypto/secp256k1_recover_benchmark_test.go deleted file mode 100644 index d1a3530..0000000 --- a/utils/crypto/secp256k1_recover_benchmark_test.go +++ /dev/null @@ -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() - } -} diff --git a/utils/crypto/secp256k1r.go b/utils/crypto/secp256k1r.go index ef50618..1fde767 100644 --- a/utils/crypto/secp256k1r.go +++ b/utils/crypto/secp256k1r.go @@ -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 diff --git a/utils/crypto/secp256k1r_test.go b/utils/crypto/secp256k1r_test.go index 244b30b..4ed7f75 100644 --- a/utils/crypto/secp256k1r_test.go +++ b/utils/crypto/secp256k1r_test.go @@ -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) +} diff --git a/vms/avm/factory.go b/vms/avm/factory.go index b8896ad..96865c6 100644 --- a/vms/avm/factory.go +++ b/vms/avm/factory.go @@ -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 } diff --git a/vms/avm/vm.go b/vms/avm/vm.go index e6af76d..c8b33f1 100644 --- a/vms/avm/vm.go +++ b/vms/avm/vm.go @@ -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) diff --git a/vms/components/core/snowman_vm.go b/vms/components/core/snowman_vm.go index a659b1b..f710edd 100644 --- a/vms/components/core/snowman_vm.go +++ b/vms/components/core/snowman_vm.go @@ -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 diff --git a/vms/evm/block.go b/vms/evm/block.go deleted file mode 100644 index ec47490..0000000 --- a/vms/evm/block.go +++ /dev/null @@ -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()) } diff --git a/vms/evm/database.go b/vms/evm/database.go deleted file mode 100644 index de592e1..0000000 --- a/vms/evm/database.go +++ /dev/null @@ -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) } diff --git a/vms/evm/factory.go b/vms/evm/factory.go deleted file mode 100644 index a4c0eca..0000000 --- a/vms/evm/factory.go +++ /dev/null @@ -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{} } diff --git a/vms/evm/service.go b/vms/evm/service.go deleted file mode 100644 index 70135cc..0000000 --- a/vms/evm/service.go +++ /dev/null @@ -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() -} diff --git a/vms/evm/static_service.go b/vms/evm/static_service.go deleted file mode 100644 index d3870ca..0000000 --- a/vms/evm/static_service.go +++ /dev/null @@ -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 -} diff --git a/vms/evm/static_service_test.go b/vms/evm/static_service_test.go deleted file mode 100644 index c492798..0000000 --- a/vms/evm/static_service_test.go +++ /dev/null @@ -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) - } -} diff --git a/vms/evm/vm.go b/vms/evm/vm.go deleted file mode 100644 index e1e9846..0000000 --- a/vms/evm/vm.go +++ /dev/null @@ -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 -} diff --git a/vms/evm/vm_genesis_parse_test.go b/vms/evm/vm_genesis_parse_test.go deleted file mode 100644 index 9a113fb..0000000 --- a/vms/evm/vm_genesis_parse_test.go +++ /dev/null @@ -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) - } -} diff --git a/vms/manager.go b/vms/manager.go index 1509d49..9f8cf3b 100644 --- a/vms/manager.go +++ b/vms/manager.go @@ -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 } diff --git a/vms/nftfx/factory.go b/vms/nftfx/factory.go index 5a3b0c2..fc28262 100644 --- a/vms/nftfx/factory.go +++ b/vms/nftfx/factory.go @@ -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 } diff --git a/vms/nftfx/factory_test.go b/vms/nftfx/factory_test.go index 0f533c9..7144129 100644 --- a/vms/nftfx/factory_test.go +++ b/vms/nftfx/factory_test.go @@ -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") } } diff --git a/vms/platformvm/factory.go b/vms/platformvm/factory.go index 7cdd916..c55c070 100644 --- a/vms/platformvm/factory.go +++ b/vms/platformvm/factory.go @@ -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 } diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 10fc512..3e4bf78 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -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) diff --git a/vms/propertyfx/factory.go b/vms/propertyfx/factory.go index 6cb6fba..67ebb5a 100644 --- a/vms/propertyfx/factory.go +++ b/vms/propertyfx/factory.go @@ -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 } diff --git a/vms/propertyfx/factory_test.go b/vms/propertyfx/factory_test.go index a22fdd2..d49d27c 100644 --- a/vms/propertyfx/factory_test.go +++ b/vms/propertyfx/factory_test.go @@ -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") } } diff --git a/vms/rpcchainvm/factory.go b/vms/rpcchainvm/factory.go new file mode 100644 index 0000000..78e1ead --- /dev/null +++ b/vms/rpcchainvm/factory.go @@ -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 +} diff --git a/vms/rpcchainvm/ghttp/http_client.go b/vms/rpcchainvm/ghttp/http_client.go new file mode 100644 index 0000000..e06ef2c --- /dev/null +++ b/vms/rpcchainvm/ghttp/http_client.go @@ -0,0 +1,64 @@ +// (c) 2019-2020, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package ghttp + +import ( + "io/ioutil" + "net/http" + + "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 proto.HTTPClient } + +// NewClient returns a database instance connected to a remote database instance +func NewClient(client proto.HTTPClient) *Client { + return &Client{client: client} +} + +// Handle ... +func (c *Client) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // get the headers + inboundHeaders := make([]*proto.Header, len(r.Header))[:0] + for key, values := range r.Header { + inboundHeaders = append(inboundHeaders, &proto.Header{ + Key: key, + Values: values, + }) + } + + // get the body + body, err := ioutil.ReadAll(r.Body) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // execute the call + resp, err := c.client.Handle(r.Context(), &proto.HTTPRequest{ + Url: r.RequestURI, + Method: r.Method, + Headers: inboundHeaders, + Body: body, + }) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // return the code + w.WriteHeader(int(resp.Code)) + + // return the headers + outboundHeaders := w.Header() + for _, header := range resp.Headers { + outboundHeaders[header.Key] = header.Values + } + + // return the body + if _, err := w.Write(resp.Body); err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } +} diff --git a/vms/rpcchainvm/ghttp/http_server.go b/vms/rpcchainvm/ghttp/http_server.go new file mode 100644 index 0000000..0ee8eb0 --- /dev/null +++ b/vms/rpcchainvm/ghttp/http_server.go @@ -0,0 +1,62 @@ +// (c) 2019-2020, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package ghttp + +import ( + "bytes" + "context" + "io/ioutil" + "net/http" + "net/http/httptest" + + "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 } + +// NewServer returns a http.Handler instance manage remotely +func NewServer(handler http.Handler) *Server { + return &Server{handler: handler} +} + +// Handle ... +func (s Server) Handle(ctx context.Context, req *proto.HTTPRequest) (*proto.HTTPResponse, error) { + // create the request with the current context + r, err := http.NewRequestWithContext( + ctx, + req.Method, + req.Url, + ioutil.NopCloser(bytes.NewReader(req.Body)), + ) + if err != nil { + return nil, err + } + + // populate the headers + for _, header := range req.Headers { + r.Header[header.Key] = header.Values + } + + // send the request to the recorder + recorder := httptest.NewRecorder() + s.handler.ServeHTTP(recorder, r) + + // get the returned headers + returnedHeaders := recorder.Header() + headers := make([]*proto.Header, len(returnedHeaders))[:0] + for key, values := range returnedHeaders { + headers = append(headers, &proto.Header{ + Key: key, + Values: values, + }) + } + + // return the response + return &proto.HTTPResponse{ + Code: int32(recorder.Code), + Headers: headers, + Body: recorder.Body.Bytes(), + }, nil +} diff --git a/vms/rpcchainvm/ghttp/http_test.go b/vms/rpcchainvm/ghttp/http_test.go new file mode 100644 index 0000000..0c60f27 --- /dev/null +++ b/vms/rpcchainvm/ghttp/http_test.go @@ -0,0 +1,96 @@ +// (c) 2019-2020, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package ghttp + +import ( + "bytes" + "log" + "net" + "net/http" + "net/http/httptest" + "testing" + + "golang.org/x/net/context" + + "google.golang.org/grpc" + "google.golang.org/grpc/test/bufconn" + + "github.com/gorilla/rpc/v2" + "github.com/gorilla/rpc/v2/json2" + + "github.com/ava-labs/gecko/utils/json" + "github.com/ava-labs/gecko/vms/rpcchainvm/ghttp/proto" +) + +const ( + bufSize = 1 << 20 +) + +type service struct{} + +type Args struct{} + +type Reply struct { + Called bool +} + +func (s *service) Call(r *http.Request, args *Args, reply *Reply) error { + reply.Called = true + return nil +} + +func TestRPC(t *testing.T) { + rpcServer := rpc.NewServer() + codec := json.NewCodec() + rpcServer.RegisterCodec(codec, "application/json") + rpcServer.RegisterCodec(codec, "application/json;charset=UTF-8") + rpcServer.RegisterService(&service{}, "service") + + listener := bufconn.Listen(bufSize) + server := grpc.NewServer() + proto.RegisterHTTPServer(server, NewServer(rpcServer)) + go func() { + if err := server.Serve(listener); err != nil { + log.Fatal(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.Fatal(err) + } + defer conn.Close() + + rpcClient := NewClient(proto.NewHTTPClient(conn)) + + req := &Args{} + buf, err := json2.EncodeClientRequest("service.call", req) + if err != nil { + t.Fatal(err) + } + body := bytes.NewBuffer(buf) + r, err := http.NewRequest("POST", "http://localhost:8080/", body) + if err != nil { + t.Fatal(err) + } + r.Header.Set("Content-Type", "application/json") + + w := httptest.NewRecorder() + rpcClient.ServeHTTP(w, r) + + res := &Reply{} + if err := json2.DecodeClientResponse(w.Body, res); err != nil { + t.Fatal(err) + } + + if !res.Called { + t.Fatalf("Should have called the function") + } +} diff --git a/vms/rpcchainvm/ghttp/proto/http.pb.go b/vms/rpcchainvm/ghttp/proto/http.pb.go new file mode 100644 index 0000000..e654dde --- /dev/null +++ b/vms/rpcchainvm/ghttp/proto/http.pb.go @@ -0,0 +1,297 @@ +// 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 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_11b04836674e6f94, []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 HTTPRequest struct { + Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"` + Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"` + Headers []*Header `protobuf:"bytes,3,rep,name=headers,proto3" json:"headers,omitempty"` + Body []byte `protobuf:"bytes,4,opt,name=body,proto3" json:"body,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{1} +} + +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) GetUrl() string { + if m != nil { + return m.Url + } + return "" +} + +func (m *HTTPRequest) GetMethod() string { + if m != nil { + return m.Method + } + return "" +} + +func (m *HTTPRequest) GetHeaders() []*Header { + if m != nil { + return m.Headers + } + return nil +} + +func (m *HTTPRequest) GetBody() []byte { + if m != nil { + return m.Body + } + return nil +} + +type HTTPResponse struct { + Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Headers []*Header `protobuf:"bytes,2,rep,name=headers,proto3" json:"headers,omitempty"` + Body []byte `protobuf:"bytes,3,opt,name=body,proto3" json:"body,omitempty"` + 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{2} +} + +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 (m *HTTPResponse) GetCode() int32 { + if m != nil { + return m.Code + } + return 0 +} + +func (m *HTTPResponse) GetHeaders() []*Header { + if m != nil { + return m.Headers + } + return nil +} + +func (m *HTTPResponse) GetBody() []byte { + if m != nil { + return m.Body + } + return nil +} + +func init() { + proto.RegisterType((*Header)(nil), "proto.Header") + proto.RegisterType((*HTTPRequest)(nil), "proto.HTTPRequest") + proto.RegisterType((*HTTPResponse)(nil), "proto.HTTPResponse") +} + +func init() { proto.RegisterFile("http.proto", fileDescriptor_11b04836674e6f94) } + +var fileDescriptor_11b04836674e6f94 = []byte{ + // 225 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x8f, 0x4f, 0x4b, 0x03, 0x31, + 0x14, 0xc4, 0xd9, 0xcd, 0x76, 0xa5, 0xaf, 0x15, 0xe4, 0x09, 0x12, 0x3c, 0x85, 0xbd, 0x98, 0x53, + 0xc1, 0xf5, 0xe4, 0x37, 0xd8, 0xa3, 0x84, 0xde, 0x65, 0x6b, 0x1e, 0x2c, 0x18, 0x9b, 0x35, 0x7f, + 0x84, 0x7e, 0x7b, 0x49, 0xd2, 0xa5, 0x7a, 0xeb, 0x29, 0x33, 0x93, 0x0c, 0xbf, 0x09, 0xc0, 0x14, + 0xc2, 0xbc, 0x9b, 0x9d, 0x0d, 0x16, 0x57, 0xf9, 0xe8, 0x7a, 0x68, 0x07, 0x1a, 0x35, 0x39, 0xbc, + 0x03, 0xf6, 0x49, 0x27, 0x5e, 0x89, 0x4a, 0xae, 0x55, 0x92, 0xf8, 0x00, 0xed, 0xcf, 0x68, 0x22, + 0x79, 0x5e, 0x0b, 0x26, 0xd7, 0xea, 0xec, 0xba, 0x00, 0x9b, 0x61, 0xbf, 0x7f, 0x53, 0xf4, 0x1d, + 0xc9, 0x87, 0x54, 0x8c, 0xce, 0x2c, 0xc5, 0xe8, 0x4c, 0x2a, 0x7e, 0x51, 0x98, 0xac, 0xe6, 0x75, + 0x0e, 0xcf, 0x0e, 0x9f, 0xe0, 0x66, 0xca, 0x30, 0xcf, 0x99, 0x60, 0x72, 0xd3, 0xdf, 0x96, 0x31, + 0xbb, 0x32, 0x41, 0x2d, 0xb7, 0x88, 0xd0, 0x1c, 0xac, 0x3e, 0xf1, 0x46, 0x54, 0x72, 0xab, 0xb2, + 0xee, 0xde, 0x61, 0x5b, 0xa8, 0x7e, 0xb6, 0x47, 0x4f, 0xe9, 0xcd, 0x87, 0xd5, 0x94, 0xb9, 0x2b, + 0x95, 0xf5, 0x5f, 0x40, 0x7d, 0x15, 0x80, 0x5d, 0x00, 0xfd, 0x2b, 0x34, 0x09, 0x80, 0xcf, 0xd0, + 0x0e, 0xe3, 0x51, 0x1b, 0x42, 0x5c, 0xda, 0x97, 0xdf, 0x3e, 0xde, 0xff, 0xcb, 0xca, 0x96, 0x43, + 0x9b, 0xb3, 0x97, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xbf, 0x5a, 0x2a, 0xb5, 0x61, 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 + +// 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", +} diff --git a/vms/rpcchainvm/ghttp/proto/http.proto b/vms/rpcchainvm/ghttp/proto/http.proto new file mode 100644 index 0000000..ec23597 --- /dev/null +++ b/vms/rpcchainvm/ghttp/proto/http.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; +package proto; + +message Header { + string key = 1; + repeated string values = 2; +} + +message HTTPRequest { + string url = 1; + string method = 2; + repeated Header headers = 3; + bytes body = 4; +} + +message HTTPResponse { + int32 code = 1; + repeated Header headers = 2; + bytes body = 3; +} + +service HTTP { + rpc Handle(HTTPRequest) returns (HTTPResponse); +} \ No newline at end of file diff --git a/vms/rpcchainvm/messenger/messenger_client.go b/vms/rpcchainvm/messenger/messenger_client.go new file mode 100644 index 0000000..f8f8033 --- /dev/null +++ b/vms/rpcchainvm/messenger/messenger_client.go @@ -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 +} diff --git a/vms/rpcchainvm/messenger/messenger_server.go b/vms/rpcchainvm/messenger/messenger_server.go new file mode 100644 index 0000000..a051d7b --- /dev/null +++ b/vms/rpcchainvm/messenger/messenger_server.go @@ -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 + } +} diff --git a/vms/rpcchainvm/messenger/proto/messenger.pb.go b/vms/rpcchainvm/messenger/proto/messenger.pb.go new file mode 100644 index 0000000..35dd59c --- /dev/null +++ b/vms/rpcchainvm/messenger/proto/messenger.pb.go @@ -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", +} diff --git a/vms/rpcchainvm/messenger/proto/messenger.proto b/vms/rpcchainvm/messenger/proto/messenger.proto new file mode 100644 index 0000000..b1cb02b --- /dev/null +++ b/vms/rpcchainvm/messenger/proto/messenger.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; +package proto; + +message NotifyRequest { + uint32 message = 1; +} + +message NotifyResponse {} + +service Messenger { + rpc Notify(NotifyRequest) returns (NotifyResponse); +} \ No newline at end of file diff --git a/vms/rpcchainvm/proto/vm.pb.go b/vms/rpcchainvm/proto/vm.pb.go new file mode 100644 index 0000000..f39e89d --- /dev/null +++ b/vms/rpcchainvm/proto/vm.pb.go @@ -0,0 +1,1433 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: vm.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 InitializeRequest struct { + DbServer uint32 `protobuf:"varint,1,opt,name=dbServer,proto3" json:"dbServer,omitempty"` + GenesisBytes []byte `protobuf:"bytes,2,opt,name=genesisBytes,proto3" json:"genesisBytes,omitempty"` + EngineServer uint32 `protobuf:"varint,3,opt,name=engineServer,proto3" json:"engineServer,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *InitializeRequest) Reset() { *m = InitializeRequest{} } +func (m *InitializeRequest) String() string { return proto.CompactTextString(m) } +func (*InitializeRequest) ProtoMessage() {} +func (*InitializeRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_cab246c8c7c5372d, []int{0} +} + +func (m *InitializeRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_InitializeRequest.Unmarshal(m, b) +} +func (m *InitializeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_InitializeRequest.Marshal(b, m, deterministic) +} +func (m *InitializeRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_InitializeRequest.Merge(m, src) +} +func (m *InitializeRequest) XXX_Size() int { + return xxx_messageInfo_InitializeRequest.Size(m) +} +func (m *InitializeRequest) XXX_DiscardUnknown() { + xxx_messageInfo_InitializeRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_InitializeRequest proto.InternalMessageInfo + +func (m *InitializeRequest) GetDbServer() uint32 { + if m != nil { + return m.DbServer + } + return 0 +} + +func (m *InitializeRequest) GetGenesisBytes() []byte { + if m != nil { + return m.GenesisBytes + } + return nil +} + +func (m *InitializeRequest) GetEngineServer() uint32 { + if m != nil { + return m.EngineServer + } + return 0 +} + +type InitializeResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *InitializeResponse) Reset() { *m = InitializeResponse{} } +func (m *InitializeResponse) String() string { return proto.CompactTextString(m) } +func (*InitializeResponse) ProtoMessage() {} +func (*InitializeResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_cab246c8c7c5372d, []int{1} +} + +func (m *InitializeResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_InitializeResponse.Unmarshal(m, b) +} +func (m *InitializeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_InitializeResponse.Marshal(b, m, deterministic) +} +func (m *InitializeResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_InitializeResponse.Merge(m, src) +} +func (m *InitializeResponse) XXX_Size() int { + return xxx_messageInfo_InitializeResponse.Size(m) +} +func (m *InitializeResponse) XXX_DiscardUnknown() { + xxx_messageInfo_InitializeResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_InitializeResponse proto.InternalMessageInfo + +type ShutdownRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ShutdownRequest) Reset() { *m = ShutdownRequest{} } +func (m *ShutdownRequest) String() string { return proto.CompactTextString(m) } +func (*ShutdownRequest) ProtoMessage() {} +func (*ShutdownRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_cab246c8c7c5372d, []int{2} +} + +func (m *ShutdownRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ShutdownRequest.Unmarshal(m, b) +} +func (m *ShutdownRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ShutdownRequest.Marshal(b, m, deterministic) +} +func (m *ShutdownRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ShutdownRequest.Merge(m, src) +} +func (m *ShutdownRequest) XXX_Size() int { + return xxx_messageInfo_ShutdownRequest.Size(m) +} +func (m *ShutdownRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ShutdownRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ShutdownRequest proto.InternalMessageInfo + +type ShutdownResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ShutdownResponse) Reset() { *m = ShutdownResponse{} } +func (m *ShutdownResponse) String() string { return proto.CompactTextString(m) } +func (*ShutdownResponse) ProtoMessage() {} +func (*ShutdownResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_cab246c8c7c5372d, []int{3} +} + +func (m *ShutdownResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ShutdownResponse.Unmarshal(m, b) +} +func (m *ShutdownResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ShutdownResponse.Marshal(b, m, deterministic) +} +func (m *ShutdownResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ShutdownResponse.Merge(m, src) +} +func (m *ShutdownResponse) XXX_Size() int { + return xxx_messageInfo_ShutdownResponse.Size(m) +} +func (m *ShutdownResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ShutdownResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ShutdownResponse proto.InternalMessageInfo + +type CreateHandlersRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CreateHandlersRequest) Reset() { *m = CreateHandlersRequest{} } +func (m *CreateHandlersRequest) String() string { return proto.CompactTextString(m) } +func (*CreateHandlersRequest) ProtoMessage() {} +func (*CreateHandlersRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_cab246c8c7c5372d, []int{4} +} + +func (m *CreateHandlersRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CreateHandlersRequest.Unmarshal(m, b) +} +func (m *CreateHandlersRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CreateHandlersRequest.Marshal(b, m, deterministic) +} +func (m *CreateHandlersRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_CreateHandlersRequest.Merge(m, src) +} +func (m *CreateHandlersRequest) XXX_Size() int { + return xxx_messageInfo_CreateHandlersRequest.Size(m) +} +func (m *CreateHandlersRequest) XXX_DiscardUnknown() { + xxx_messageInfo_CreateHandlersRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_CreateHandlersRequest proto.InternalMessageInfo + +type CreateHandlersResponse struct { + Handlers []*Handler `protobuf:"bytes,1,rep,name=handlers,proto3" json:"handlers,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CreateHandlersResponse) Reset() { *m = CreateHandlersResponse{} } +func (m *CreateHandlersResponse) String() string { return proto.CompactTextString(m) } +func (*CreateHandlersResponse) ProtoMessage() {} +func (*CreateHandlersResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_cab246c8c7c5372d, []int{5} +} + +func (m *CreateHandlersResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_CreateHandlersResponse.Unmarshal(m, b) +} +func (m *CreateHandlersResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_CreateHandlersResponse.Marshal(b, m, deterministic) +} +func (m *CreateHandlersResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_CreateHandlersResponse.Merge(m, src) +} +func (m *CreateHandlersResponse) XXX_Size() int { + return xxx_messageInfo_CreateHandlersResponse.Size(m) +} +func (m *CreateHandlersResponse) XXX_DiscardUnknown() { + xxx_messageInfo_CreateHandlersResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_CreateHandlersResponse proto.InternalMessageInfo + +func (m *CreateHandlersResponse) GetHandlers() []*Handler { + if m != nil { + return m.Handlers + } + return nil +} + +type Handler struct { + Prefix string `protobuf:"bytes,1,opt,name=prefix,proto3" json:"prefix,omitempty"` + LockOptions uint32 `protobuf:"varint,2,opt,name=lockOptions,proto3" json:"lockOptions,omitempty"` + Server uint32 `protobuf:"varint,3,opt,name=server,proto3" json:"server,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Handler) Reset() { *m = Handler{} } +func (m *Handler) String() string { return proto.CompactTextString(m) } +func (*Handler) ProtoMessage() {} +func (*Handler) Descriptor() ([]byte, []int) { + return fileDescriptor_cab246c8c7c5372d, []int{6} +} + +func (m *Handler) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Handler.Unmarshal(m, b) +} +func (m *Handler) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Handler.Marshal(b, m, deterministic) +} +func (m *Handler) XXX_Merge(src proto.Message) { + xxx_messageInfo_Handler.Merge(m, src) +} +func (m *Handler) XXX_Size() int { + return xxx_messageInfo_Handler.Size(m) +} +func (m *Handler) XXX_DiscardUnknown() { + xxx_messageInfo_Handler.DiscardUnknown(m) +} + +var xxx_messageInfo_Handler proto.InternalMessageInfo + +func (m *Handler) GetPrefix() string { + if m != nil { + return m.Prefix + } + return "" +} + +func (m *Handler) GetLockOptions() uint32 { + if m != nil { + return m.LockOptions + } + return 0 +} + +func (m *Handler) GetServer() uint32 { + if m != nil { + return m.Server + } + return 0 +} + +type BuildBlockRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BuildBlockRequest) Reset() { *m = BuildBlockRequest{} } +func (m *BuildBlockRequest) String() string { return proto.CompactTextString(m) } +func (*BuildBlockRequest) ProtoMessage() {} +func (*BuildBlockRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_cab246c8c7c5372d, []int{7} +} + +func (m *BuildBlockRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BuildBlockRequest.Unmarshal(m, b) +} +func (m *BuildBlockRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BuildBlockRequest.Marshal(b, m, deterministic) +} +func (m *BuildBlockRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_BuildBlockRequest.Merge(m, src) +} +func (m *BuildBlockRequest) XXX_Size() int { + return xxx_messageInfo_BuildBlockRequest.Size(m) +} +func (m *BuildBlockRequest) XXX_DiscardUnknown() { + xxx_messageInfo_BuildBlockRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_BuildBlockRequest proto.InternalMessageInfo + +type BuildBlockResponse struct { + Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + ParentID []byte `protobuf:"bytes,2,opt,name=parentID,proto3" json:"parentID,omitempty"` + Bytes []byte `protobuf:"bytes,3,opt,name=bytes,proto3" json:"bytes,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BuildBlockResponse) Reset() { *m = BuildBlockResponse{} } +func (m *BuildBlockResponse) String() string { return proto.CompactTextString(m) } +func (*BuildBlockResponse) ProtoMessage() {} +func (*BuildBlockResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_cab246c8c7c5372d, []int{8} +} + +func (m *BuildBlockResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BuildBlockResponse.Unmarshal(m, b) +} +func (m *BuildBlockResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BuildBlockResponse.Marshal(b, m, deterministic) +} +func (m *BuildBlockResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_BuildBlockResponse.Merge(m, src) +} +func (m *BuildBlockResponse) XXX_Size() int { + return xxx_messageInfo_BuildBlockResponse.Size(m) +} +func (m *BuildBlockResponse) XXX_DiscardUnknown() { + xxx_messageInfo_BuildBlockResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_BuildBlockResponse proto.InternalMessageInfo + +func (m *BuildBlockResponse) GetId() []byte { + if m != nil { + return m.Id + } + return nil +} + +func (m *BuildBlockResponse) GetParentID() []byte { + if m != nil { + return m.ParentID + } + return nil +} + +func (m *BuildBlockResponse) GetBytes() []byte { + if m != nil { + return m.Bytes + } + return nil +} + +type ParseBlockRequest struct { + Bytes []byte `protobuf:"bytes,1,opt,name=bytes,proto3" json:"bytes,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ParseBlockRequest) Reset() { *m = ParseBlockRequest{} } +func (m *ParseBlockRequest) String() string { return proto.CompactTextString(m) } +func (*ParseBlockRequest) ProtoMessage() {} +func (*ParseBlockRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_cab246c8c7c5372d, []int{9} +} + +func (m *ParseBlockRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ParseBlockRequest.Unmarshal(m, b) +} +func (m *ParseBlockRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ParseBlockRequest.Marshal(b, m, deterministic) +} +func (m *ParseBlockRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ParseBlockRequest.Merge(m, src) +} +func (m *ParseBlockRequest) XXX_Size() int { + return xxx_messageInfo_ParseBlockRequest.Size(m) +} +func (m *ParseBlockRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ParseBlockRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ParseBlockRequest proto.InternalMessageInfo + +func (m *ParseBlockRequest) GetBytes() []byte { + if m != nil { + return m.Bytes + } + return nil +} + +type ParseBlockResponse struct { + Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + ParentID []byte `protobuf:"bytes,2,opt,name=parentID,proto3" json:"parentID,omitempty"` + Status uint32 `protobuf:"varint,3,opt,name=status,proto3" json:"status,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ParseBlockResponse) Reset() { *m = ParseBlockResponse{} } +func (m *ParseBlockResponse) String() string { return proto.CompactTextString(m) } +func (*ParseBlockResponse) ProtoMessage() {} +func (*ParseBlockResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_cab246c8c7c5372d, []int{10} +} + +func (m *ParseBlockResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ParseBlockResponse.Unmarshal(m, b) +} +func (m *ParseBlockResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ParseBlockResponse.Marshal(b, m, deterministic) +} +func (m *ParseBlockResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ParseBlockResponse.Merge(m, src) +} +func (m *ParseBlockResponse) XXX_Size() int { + return xxx_messageInfo_ParseBlockResponse.Size(m) +} +func (m *ParseBlockResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ParseBlockResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ParseBlockResponse proto.InternalMessageInfo + +func (m *ParseBlockResponse) GetId() []byte { + if m != nil { + return m.Id + } + return nil +} + +func (m *ParseBlockResponse) GetParentID() []byte { + if m != nil { + return m.ParentID + } + return nil +} + +func (m *ParseBlockResponse) GetStatus() uint32 { + if m != nil { + return m.Status + } + return 0 +} + +type GetBlockRequest struct { + Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetBlockRequest) Reset() { *m = GetBlockRequest{} } +func (m *GetBlockRequest) String() string { return proto.CompactTextString(m) } +func (*GetBlockRequest) ProtoMessage() {} +func (*GetBlockRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_cab246c8c7c5372d, []int{11} +} + +func (m *GetBlockRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetBlockRequest.Unmarshal(m, b) +} +func (m *GetBlockRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetBlockRequest.Marshal(b, m, deterministic) +} +func (m *GetBlockRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetBlockRequest.Merge(m, src) +} +func (m *GetBlockRequest) XXX_Size() int { + return xxx_messageInfo_GetBlockRequest.Size(m) +} +func (m *GetBlockRequest) XXX_DiscardUnknown() { + xxx_messageInfo_GetBlockRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_GetBlockRequest proto.InternalMessageInfo + +func (m *GetBlockRequest) GetId() []byte { + if m != nil { + return m.Id + } + return nil +} + +type GetBlockResponse struct { + ParentID []byte `protobuf:"bytes,1,opt,name=parentID,proto3" json:"parentID,omitempty"` + Bytes []byte `protobuf:"bytes,2,opt,name=bytes,proto3" json:"bytes,omitempty"` + Status uint32 `protobuf:"varint,3,opt,name=status,proto3" json:"status,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GetBlockResponse) Reset() { *m = GetBlockResponse{} } +func (m *GetBlockResponse) String() string { return proto.CompactTextString(m) } +func (*GetBlockResponse) ProtoMessage() {} +func (*GetBlockResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_cab246c8c7c5372d, []int{12} +} + +func (m *GetBlockResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GetBlockResponse.Unmarshal(m, b) +} +func (m *GetBlockResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GetBlockResponse.Marshal(b, m, deterministic) +} +func (m *GetBlockResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetBlockResponse.Merge(m, src) +} +func (m *GetBlockResponse) XXX_Size() int { + return xxx_messageInfo_GetBlockResponse.Size(m) +} +func (m *GetBlockResponse) XXX_DiscardUnknown() { + xxx_messageInfo_GetBlockResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_GetBlockResponse proto.InternalMessageInfo + +func (m *GetBlockResponse) GetParentID() []byte { + if m != nil { + return m.ParentID + } + return nil +} + +func (m *GetBlockResponse) GetBytes() []byte { + if m != nil { + return m.Bytes + } + return nil +} + +func (m *GetBlockResponse) GetStatus() uint32 { + if m != nil { + return m.Status + } + return 0 +} + +type SetPreferenceRequest struct { + Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SetPreferenceRequest) Reset() { *m = SetPreferenceRequest{} } +func (m *SetPreferenceRequest) String() string { return proto.CompactTextString(m) } +func (*SetPreferenceRequest) ProtoMessage() {} +func (*SetPreferenceRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_cab246c8c7c5372d, []int{13} +} + +func (m *SetPreferenceRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SetPreferenceRequest.Unmarshal(m, b) +} +func (m *SetPreferenceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SetPreferenceRequest.Marshal(b, m, deterministic) +} +func (m *SetPreferenceRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SetPreferenceRequest.Merge(m, src) +} +func (m *SetPreferenceRequest) XXX_Size() int { + return xxx_messageInfo_SetPreferenceRequest.Size(m) +} +func (m *SetPreferenceRequest) XXX_DiscardUnknown() { + xxx_messageInfo_SetPreferenceRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_SetPreferenceRequest proto.InternalMessageInfo + +func (m *SetPreferenceRequest) GetId() []byte { + if m != nil { + return m.Id + } + return nil +} + +type SetPreferenceResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SetPreferenceResponse) Reset() { *m = SetPreferenceResponse{} } +func (m *SetPreferenceResponse) String() string { return proto.CompactTextString(m) } +func (*SetPreferenceResponse) ProtoMessage() {} +func (*SetPreferenceResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_cab246c8c7c5372d, []int{14} +} + +func (m *SetPreferenceResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SetPreferenceResponse.Unmarshal(m, b) +} +func (m *SetPreferenceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SetPreferenceResponse.Marshal(b, m, deterministic) +} +func (m *SetPreferenceResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_SetPreferenceResponse.Merge(m, src) +} +func (m *SetPreferenceResponse) XXX_Size() int { + return xxx_messageInfo_SetPreferenceResponse.Size(m) +} +func (m *SetPreferenceResponse) XXX_DiscardUnknown() { + xxx_messageInfo_SetPreferenceResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_SetPreferenceResponse proto.InternalMessageInfo + +type LastAcceptedRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LastAcceptedRequest) Reset() { *m = LastAcceptedRequest{} } +func (m *LastAcceptedRequest) String() string { return proto.CompactTextString(m) } +func (*LastAcceptedRequest) ProtoMessage() {} +func (*LastAcceptedRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_cab246c8c7c5372d, []int{15} +} + +func (m *LastAcceptedRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LastAcceptedRequest.Unmarshal(m, b) +} +func (m *LastAcceptedRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LastAcceptedRequest.Marshal(b, m, deterministic) +} +func (m *LastAcceptedRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_LastAcceptedRequest.Merge(m, src) +} +func (m *LastAcceptedRequest) XXX_Size() int { + return xxx_messageInfo_LastAcceptedRequest.Size(m) +} +func (m *LastAcceptedRequest) XXX_DiscardUnknown() { + xxx_messageInfo_LastAcceptedRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_LastAcceptedRequest proto.InternalMessageInfo + +type LastAcceptedResponse struct { + Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LastAcceptedResponse) Reset() { *m = LastAcceptedResponse{} } +func (m *LastAcceptedResponse) String() string { return proto.CompactTextString(m) } +func (*LastAcceptedResponse) ProtoMessage() {} +func (*LastAcceptedResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_cab246c8c7c5372d, []int{16} +} + +func (m *LastAcceptedResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LastAcceptedResponse.Unmarshal(m, b) +} +func (m *LastAcceptedResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LastAcceptedResponse.Marshal(b, m, deterministic) +} +func (m *LastAcceptedResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_LastAcceptedResponse.Merge(m, src) +} +func (m *LastAcceptedResponse) XXX_Size() int { + return xxx_messageInfo_LastAcceptedResponse.Size(m) +} +func (m *LastAcceptedResponse) XXX_DiscardUnknown() { + xxx_messageInfo_LastAcceptedResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_LastAcceptedResponse proto.InternalMessageInfo + +func (m *LastAcceptedResponse) GetId() []byte { + if m != nil { + return m.Id + } + return nil +} + +type BlockVerifyRequest struct { + Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BlockVerifyRequest) Reset() { *m = BlockVerifyRequest{} } +func (m *BlockVerifyRequest) String() string { return proto.CompactTextString(m) } +func (*BlockVerifyRequest) ProtoMessage() {} +func (*BlockVerifyRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_cab246c8c7c5372d, []int{17} +} + +func (m *BlockVerifyRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BlockVerifyRequest.Unmarshal(m, b) +} +func (m *BlockVerifyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BlockVerifyRequest.Marshal(b, m, deterministic) +} +func (m *BlockVerifyRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_BlockVerifyRequest.Merge(m, src) +} +func (m *BlockVerifyRequest) XXX_Size() int { + return xxx_messageInfo_BlockVerifyRequest.Size(m) +} +func (m *BlockVerifyRequest) XXX_DiscardUnknown() { + xxx_messageInfo_BlockVerifyRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_BlockVerifyRequest proto.InternalMessageInfo + +func (m *BlockVerifyRequest) GetId() []byte { + if m != nil { + return m.Id + } + return nil +} + +type BlockVerifyResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BlockVerifyResponse) Reset() { *m = BlockVerifyResponse{} } +func (m *BlockVerifyResponse) String() string { return proto.CompactTextString(m) } +func (*BlockVerifyResponse) ProtoMessage() {} +func (*BlockVerifyResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_cab246c8c7c5372d, []int{18} +} + +func (m *BlockVerifyResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BlockVerifyResponse.Unmarshal(m, b) +} +func (m *BlockVerifyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BlockVerifyResponse.Marshal(b, m, deterministic) +} +func (m *BlockVerifyResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_BlockVerifyResponse.Merge(m, src) +} +func (m *BlockVerifyResponse) XXX_Size() int { + return xxx_messageInfo_BlockVerifyResponse.Size(m) +} +func (m *BlockVerifyResponse) XXX_DiscardUnknown() { + xxx_messageInfo_BlockVerifyResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_BlockVerifyResponse proto.InternalMessageInfo + +type BlockAcceptRequest struct { + Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BlockAcceptRequest) Reset() { *m = BlockAcceptRequest{} } +func (m *BlockAcceptRequest) String() string { return proto.CompactTextString(m) } +func (*BlockAcceptRequest) ProtoMessage() {} +func (*BlockAcceptRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_cab246c8c7c5372d, []int{19} +} + +func (m *BlockAcceptRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BlockAcceptRequest.Unmarshal(m, b) +} +func (m *BlockAcceptRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BlockAcceptRequest.Marshal(b, m, deterministic) +} +func (m *BlockAcceptRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_BlockAcceptRequest.Merge(m, src) +} +func (m *BlockAcceptRequest) XXX_Size() int { + return xxx_messageInfo_BlockAcceptRequest.Size(m) +} +func (m *BlockAcceptRequest) XXX_DiscardUnknown() { + xxx_messageInfo_BlockAcceptRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_BlockAcceptRequest proto.InternalMessageInfo + +func (m *BlockAcceptRequest) GetId() []byte { + if m != nil { + return m.Id + } + return nil +} + +type BlockAcceptResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BlockAcceptResponse) Reset() { *m = BlockAcceptResponse{} } +func (m *BlockAcceptResponse) String() string { return proto.CompactTextString(m) } +func (*BlockAcceptResponse) ProtoMessage() {} +func (*BlockAcceptResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_cab246c8c7c5372d, []int{20} +} + +func (m *BlockAcceptResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BlockAcceptResponse.Unmarshal(m, b) +} +func (m *BlockAcceptResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BlockAcceptResponse.Marshal(b, m, deterministic) +} +func (m *BlockAcceptResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_BlockAcceptResponse.Merge(m, src) +} +func (m *BlockAcceptResponse) XXX_Size() int { + return xxx_messageInfo_BlockAcceptResponse.Size(m) +} +func (m *BlockAcceptResponse) XXX_DiscardUnknown() { + xxx_messageInfo_BlockAcceptResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_BlockAcceptResponse proto.InternalMessageInfo + +type BlockRejectRequest struct { + Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BlockRejectRequest) Reset() { *m = BlockRejectRequest{} } +func (m *BlockRejectRequest) String() string { return proto.CompactTextString(m) } +func (*BlockRejectRequest) ProtoMessage() {} +func (*BlockRejectRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_cab246c8c7c5372d, []int{21} +} + +func (m *BlockRejectRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BlockRejectRequest.Unmarshal(m, b) +} +func (m *BlockRejectRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BlockRejectRequest.Marshal(b, m, deterministic) +} +func (m *BlockRejectRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_BlockRejectRequest.Merge(m, src) +} +func (m *BlockRejectRequest) XXX_Size() int { + return xxx_messageInfo_BlockRejectRequest.Size(m) +} +func (m *BlockRejectRequest) XXX_DiscardUnknown() { + xxx_messageInfo_BlockRejectRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_BlockRejectRequest proto.InternalMessageInfo + +func (m *BlockRejectRequest) GetId() []byte { + if m != nil { + return m.Id + } + return nil +} + +type BlockRejectResponse struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BlockRejectResponse) Reset() { *m = BlockRejectResponse{} } +func (m *BlockRejectResponse) String() string { return proto.CompactTextString(m) } +func (*BlockRejectResponse) ProtoMessage() {} +func (*BlockRejectResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_cab246c8c7c5372d, []int{22} +} + +func (m *BlockRejectResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_BlockRejectResponse.Unmarshal(m, b) +} +func (m *BlockRejectResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_BlockRejectResponse.Marshal(b, m, deterministic) +} +func (m *BlockRejectResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_BlockRejectResponse.Merge(m, src) +} +func (m *BlockRejectResponse) XXX_Size() int { + return xxx_messageInfo_BlockRejectResponse.Size(m) +} +func (m *BlockRejectResponse) XXX_DiscardUnknown() { + xxx_messageInfo_BlockRejectResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_BlockRejectResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*InitializeRequest)(nil), "proto.InitializeRequest") + proto.RegisterType((*InitializeResponse)(nil), "proto.InitializeResponse") + proto.RegisterType((*ShutdownRequest)(nil), "proto.ShutdownRequest") + proto.RegisterType((*ShutdownResponse)(nil), "proto.ShutdownResponse") + proto.RegisterType((*CreateHandlersRequest)(nil), "proto.CreateHandlersRequest") + proto.RegisterType((*CreateHandlersResponse)(nil), "proto.CreateHandlersResponse") + proto.RegisterType((*Handler)(nil), "proto.Handler") + proto.RegisterType((*BuildBlockRequest)(nil), "proto.BuildBlockRequest") + proto.RegisterType((*BuildBlockResponse)(nil), "proto.BuildBlockResponse") + proto.RegisterType((*ParseBlockRequest)(nil), "proto.ParseBlockRequest") + proto.RegisterType((*ParseBlockResponse)(nil), "proto.ParseBlockResponse") + proto.RegisterType((*GetBlockRequest)(nil), "proto.GetBlockRequest") + proto.RegisterType((*GetBlockResponse)(nil), "proto.GetBlockResponse") + proto.RegisterType((*SetPreferenceRequest)(nil), "proto.SetPreferenceRequest") + proto.RegisterType((*SetPreferenceResponse)(nil), "proto.SetPreferenceResponse") + proto.RegisterType((*LastAcceptedRequest)(nil), "proto.LastAcceptedRequest") + proto.RegisterType((*LastAcceptedResponse)(nil), "proto.LastAcceptedResponse") + proto.RegisterType((*BlockVerifyRequest)(nil), "proto.BlockVerifyRequest") + proto.RegisterType((*BlockVerifyResponse)(nil), "proto.BlockVerifyResponse") + proto.RegisterType((*BlockAcceptRequest)(nil), "proto.BlockAcceptRequest") + proto.RegisterType((*BlockAcceptResponse)(nil), "proto.BlockAcceptResponse") + proto.RegisterType((*BlockRejectRequest)(nil), "proto.BlockRejectRequest") + proto.RegisterType((*BlockRejectResponse)(nil), "proto.BlockRejectResponse") +} + +func init() { proto.RegisterFile("vm.proto", fileDescriptor_cab246c8c7c5372d) } + +var fileDescriptor_cab246c8c7c5372d = []byte{ + // 610 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x54, 0x4b, 0x6f, 0xd3, 0x40, + 0x10, 0x96, 0x53, 0xb5, 0x84, 0xc9, 0xa3, 0xcd, 0xe6, 0x89, 0x5b, 0xa4, 0x60, 0xa1, 0x2a, 0x70, + 0xe8, 0xa1, 0x1c, 0x7b, 0x4a, 0x88, 0x54, 0x8a, 0xa8, 0xa8, 0x1c, 0x29, 0x42, 0x82, 0x8b, 0x13, + 0x4f, 0x5a, 0x43, 0xb0, 0x8d, 0x77, 0xd3, 0x52, 0xfe, 0x3b, 0x12, 0x8a, 0x3d, 0x5e, 0xef, 0xda, + 0x8e, 0x2a, 0x71, 0xb2, 0x66, 0xe6, 0x9b, 0x6f, 0x1e, 0x3b, 0x9f, 0xa1, 0x7a, 0xff, 0xf3, 0x2c, + 0x8c, 0x02, 0x11, 0xb0, 0xfd, 0xf8, 0x63, 0x3d, 0x40, 0xeb, 0xca, 0xf7, 0x84, 0xe7, 0xac, 0xbd, + 0x3f, 0x68, 0xe3, 0xaf, 0x0d, 0x72, 0xc1, 0x4c, 0xa8, 0xba, 0x8b, 0x19, 0x46, 0xf7, 0x18, 0x0d, + 0x8c, 0xa1, 0x31, 0x6a, 0xd8, 0xd2, 0x66, 0x16, 0xd4, 0x6f, 0xd1, 0x47, 0xee, 0xf1, 0xc9, 0xa3, + 0x40, 0x3e, 0xa8, 0x0c, 0x8d, 0x51, 0xdd, 0xd6, 0x7c, 0x5b, 0x0c, 0xfa, 0xb7, 0x9e, 0x8f, 0xc4, + 0xb1, 0x17, 0x73, 0x68, 0x3e, 0xab, 0x03, 0x4c, 0x2d, 0xcc, 0xc3, 0xc0, 0xe7, 0x68, 0xb5, 0xe0, + 0x70, 0x76, 0xb7, 0x11, 0x6e, 0xf0, 0xe0, 0x53, 0x33, 0x16, 0x83, 0xa3, 0xcc, 0x45, 0xb0, 0x3e, + 0x74, 0xdf, 0x47, 0xe8, 0x08, 0xfc, 0xe0, 0xf8, 0xee, 0x1a, 0x23, 0x9e, 0x82, 0xa7, 0xd0, 0xcb, + 0x07, 0x92, 0x14, 0xf6, 0x16, 0xaa, 0x77, 0xe4, 0x1b, 0x18, 0xc3, 0xbd, 0x51, 0xed, 0xbc, 0x99, + 0x6c, 0xe2, 0x8c, 0xa0, 0xb6, 0x8c, 0x5b, 0x5f, 0xe1, 0x19, 0x39, 0x59, 0x0f, 0x0e, 0xc2, 0x08, + 0x57, 0xde, 0xef, 0x78, 0x11, 0xcf, 0x6d, 0xb2, 0xd8, 0x10, 0x6a, 0xeb, 0x60, 0xf9, 0xe3, 0x73, + 0x28, 0xbc, 0xc0, 0x4f, 0xb6, 0xd0, 0xb0, 0x55, 0xd7, 0x36, 0x93, 0xab, 0xe3, 0x93, 0x65, 0xb5, + 0xa1, 0x35, 0xd9, 0x78, 0x6b, 0x77, 0xb2, 0x05, 0xa7, 0x7d, 0xcf, 0x81, 0xa9, 0x4e, 0xea, 0xb9, + 0x09, 0x15, 0xcf, 0x8d, 0x0b, 0xd7, 0xed, 0x8a, 0xe7, 0x6e, 0xdf, 0x25, 0x74, 0x22, 0xf4, 0xc5, + 0xd5, 0x94, 0xf6, 0x2e, 0x6d, 0xd6, 0x81, 0xfd, 0x45, 0xfc, 0x20, 0x7b, 0x71, 0x20, 0x31, 0xac, + 0x37, 0xd0, 0xba, 0x71, 0x22, 0x8e, 0x6a, 0xb1, 0x0c, 0x6a, 0xa8, 0xd0, 0x2f, 0xc0, 0x54, 0xe8, + 0x7f, 0xb4, 0xb0, 0x9d, 0x58, 0x38, 0x62, 0xc3, 0xe5, 0xc4, 0xb1, 0x65, 0xbd, 0x82, 0xc3, 0x4b, + 0x14, 0x5a, 0x0b, 0x39, 0x5a, 0xeb, 0x1b, 0x1c, 0x65, 0x10, 0x2a, 0xad, 0x96, 0x32, 0x76, 0x4d, + 0x5b, 0x51, 0x46, 0xd8, 0xd9, 0xc0, 0x29, 0x74, 0x66, 0x28, 0x6e, 0x22, 0x5c, 0x61, 0x84, 0xfe, + 0x12, 0x77, 0x75, 0xd1, 0x87, 0x6e, 0x0e, 0x47, 0xf7, 0xd6, 0x85, 0xf6, 0x27, 0x87, 0x8b, 0xf1, + 0x72, 0x89, 0xa1, 0x40, 0x37, 0x7d, 0xb5, 0x53, 0xe8, 0xe8, 0xee, 0xf2, 0xa5, 0x59, 0xaf, 0x81, + 0xc5, 0xa3, 0xcd, 0x31, 0xf2, 0x56, 0x8f, 0xbb, 0xaa, 0x77, 0xa1, 0xad, 0xa1, 0xa8, 0x76, 0x9a, + 0x9c, 0x54, 0x79, 0x2a, 0x39, 0x45, 0xe5, 0x92, 0x6d, 0xfc, 0x8e, 0xcb, 0x27, 0x93, 0x53, 0x54, + 0x92, 0x7c, 0xfe, 0x77, 0x1f, 0x2a, 0xf3, 0x6b, 0x36, 0x06, 0xc8, 0x94, 0xca, 0x06, 0xa4, 0x9a, + 0xc2, 0x5f, 0xc3, 0x7c, 0x51, 0x12, 0xa1, 0x85, 0x5c, 0x40, 0x35, 0xd5, 0x30, 0xeb, 0x11, 0x2c, + 0xa7, 0x73, 0xb3, 0x5f, 0xf0, 0x53, 0xf2, 0x35, 0x34, 0x75, 0x4d, 0xb3, 0x13, 0x82, 0x96, 0xfe, + 0x03, 0xcc, 0x97, 0x3b, 0xa2, 0x44, 0x37, 0x06, 0xc8, 0xa4, 0x26, 0xc7, 0x29, 0x48, 0x52, 0x8e, + 0x53, 0xa2, 0xcb, 0x31, 0x40, 0x26, 0x15, 0x49, 0x51, 0x10, 0x9a, 0xa4, 0x28, 0xd1, 0xd5, 0x05, + 0x54, 0xd3, 0x83, 0x97, 0x1b, 0xc9, 0x89, 0x44, 0x6e, 0xa4, 0xa0, 0x8c, 0x8f, 0xd0, 0xd0, 0xee, + 0x94, 0x1d, 0xa7, 0xbb, 0x2b, 0xb9, 0x72, 0xf3, 0xa4, 0x3c, 0x48, 0x5c, 0x97, 0x50, 0x57, 0x6f, + 0x98, 0x99, 0x84, 0x2e, 0xb9, 0x77, 0xf3, 0xb8, 0x34, 0x46, 0x44, 0x53, 0xa8, 0x29, 0xe7, 0xcb, + 0xe4, 0xfa, 0x0a, 0x87, 0x6f, 0x9a, 0x65, 0xa1, 0x1c, 0x4b, 0x42, 0xaf, 0xb3, 0x68, 0x0a, 0xd0, + 0x59, 0xf4, 0xb3, 0x97, 0x2c, 0xc9, 0x41, 0xeb, 0x2c, 0x9a, 0x14, 0x74, 0x16, 0xfd, 0xfe, 0x17, + 0x07, 0x71, 0xe8, 0xdd, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x10, 0x57, 0x73, 0x31, 0x35, 0x07, + 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 + +// VMClient is the client API for VM service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type VMClient interface { + Initialize(ctx context.Context, in *InitializeRequest, opts ...grpc.CallOption) (*InitializeResponse, error) + Shutdown(ctx context.Context, in *ShutdownRequest, opts ...grpc.CallOption) (*ShutdownResponse, error) + CreateHandlers(ctx context.Context, in *CreateHandlersRequest, opts ...grpc.CallOption) (*CreateHandlersResponse, error) + BuildBlock(ctx context.Context, in *BuildBlockRequest, opts ...grpc.CallOption) (*BuildBlockResponse, error) + ParseBlock(ctx context.Context, in *ParseBlockRequest, opts ...grpc.CallOption) (*ParseBlockResponse, error) + GetBlock(ctx context.Context, in *GetBlockRequest, opts ...grpc.CallOption) (*GetBlockResponse, error) + SetPreference(ctx context.Context, in *SetPreferenceRequest, opts ...grpc.CallOption) (*SetPreferenceResponse, error) + LastAccepted(ctx context.Context, in *LastAcceptedRequest, opts ...grpc.CallOption) (*LastAcceptedResponse, error) + BlockVerify(ctx context.Context, in *BlockVerifyRequest, opts ...grpc.CallOption) (*BlockVerifyResponse, error) + BlockAccept(ctx context.Context, in *BlockAcceptRequest, opts ...grpc.CallOption) (*BlockAcceptResponse, error) + BlockReject(ctx context.Context, in *BlockRejectRequest, opts ...grpc.CallOption) (*BlockRejectResponse, error) +} + +type vMClient struct { + cc grpc.ClientConnInterface +} + +func NewVMClient(cc grpc.ClientConnInterface) VMClient { + return &vMClient{cc} +} + +func (c *vMClient) Initialize(ctx context.Context, in *InitializeRequest, opts ...grpc.CallOption) (*InitializeResponse, error) { + out := new(InitializeResponse) + err := c.cc.Invoke(ctx, "/proto.VM/Initialize", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMClient) Shutdown(ctx context.Context, in *ShutdownRequest, opts ...grpc.CallOption) (*ShutdownResponse, error) { + out := new(ShutdownResponse) + err := c.cc.Invoke(ctx, "/proto.VM/Shutdown", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMClient) CreateHandlers(ctx context.Context, in *CreateHandlersRequest, opts ...grpc.CallOption) (*CreateHandlersResponse, error) { + out := new(CreateHandlersResponse) + err := c.cc.Invoke(ctx, "/proto.VM/CreateHandlers", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMClient) BuildBlock(ctx context.Context, in *BuildBlockRequest, opts ...grpc.CallOption) (*BuildBlockResponse, error) { + out := new(BuildBlockResponse) + err := c.cc.Invoke(ctx, "/proto.VM/BuildBlock", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMClient) ParseBlock(ctx context.Context, in *ParseBlockRequest, opts ...grpc.CallOption) (*ParseBlockResponse, error) { + out := new(ParseBlockResponse) + err := c.cc.Invoke(ctx, "/proto.VM/ParseBlock", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMClient) GetBlock(ctx context.Context, in *GetBlockRequest, opts ...grpc.CallOption) (*GetBlockResponse, error) { + out := new(GetBlockResponse) + err := c.cc.Invoke(ctx, "/proto.VM/GetBlock", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMClient) SetPreference(ctx context.Context, in *SetPreferenceRequest, opts ...grpc.CallOption) (*SetPreferenceResponse, error) { + out := new(SetPreferenceResponse) + err := c.cc.Invoke(ctx, "/proto.VM/SetPreference", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMClient) LastAccepted(ctx context.Context, in *LastAcceptedRequest, opts ...grpc.CallOption) (*LastAcceptedResponse, error) { + out := new(LastAcceptedResponse) + err := c.cc.Invoke(ctx, "/proto.VM/LastAccepted", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMClient) BlockVerify(ctx context.Context, in *BlockVerifyRequest, opts ...grpc.CallOption) (*BlockVerifyResponse, error) { + out := new(BlockVerifyResponse) + err := c.cc.Invoke(ctx, "/proto.VM/BlockVerify", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMClient) BlockAccept(ctx context.Context, in *BlockAcceptRequest, opts ...grpc.CallOption) (*BlockAcceptResponse, error) { + out := new(BlockAcceptResponse) + err := c.cc.Invoke(ctx, "/proto.VM/BlockAccept", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMClient) BlockReject(ctx context.Context, in *BlockRejectRequest, opts ...grpc.CallOption) (*BlockRejectResponse, error) { + out := new(BlockRejectResponse) + err := c.cc.Invoke(ctx, "/proto.VM/BlockReject", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// VMServer is the server API for VM service. +type VMServer interface { + Initialize(context.Context, *InitializeRequest) (*InitializeResponse, error) + Shutdown(context.Context, *ShutdownRequest) (*ShutdownResponse, error) + CreateHandlers(context.Context, *CreateHandlersRequest) (*CreateHandlersResponse, error) + BuildBlock(context.Context, *BuildBlockRequest) (*BuildBlockResponse, error) + ParseBlock(context.Context, *ParseBlockRequest) (*ParseBlockResponse, error) + GetBlock(context.Context, *GetBlockRequest) (*GetBlockResponse, error) + SetPreference(context.Context, *SetPreferenceRequest) (*SetPreferenceResponse, error) + LastAccepted(context.Context, *LastAcceptedRequest) (*LastAcceptedResponse, error) + BlockVerify(context.Context, *BlockVerifyRequest) (*BlockVerifyResponse, error) + BlockAccept(context.Context, *BlockAcceptRequest) (*BlockAcceptResponse, error) + BlockReject(context.Context, *BlockRejectRequest) (*BlockRejectResponse, error) +} + +// UnimplementedVMServer can be embedded to have forward compatible implementations. +type UnimplementedVMServer struct { +} + +func (*UnimplementedVMServer) Initialize(ctx context.Context, req *InitializeRequest) (*InitializeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Initialize not implemented") +} +func (*UnimplementedVMServer) Shutdown(ctx context.Context, req *ShutdownRequest) (*ShutdownResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Shutdown not implemented") +} +func (*UnimplementedVMServer) CreateHandlers(ctx context.Context, req *CreateHandlersRequest) (*CreateHandlersResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateHandlers not implemented") +} +func (*UnimplementedVMServer) BuildBlock(ctx context.Context, req *BuildBlockRequest) (*BuildBlockResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method BuildBlock not implemented") +} +func (*UnimplementedVMServer) ParseBlock(ctx context.Context, req *ParseBlockRequest) (*ParseBlockResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ParseBlock not implemented") +} +func (*UnimplementedVMServer) GetBlock(ctx context.Context, req *GetBlockRequest) (*GetBlockResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetBlock not implemented") +} +func (*UnimplementedVMServer) SetPreference(ctx context.Context, req *SetPreferenceRequest) (*SetPreferenceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetPreference not implemented") +} +func (*UnimplementedVMServer) LastAccepted(ctx context.Context, req *LastAcceptedRequest) (*LastAcceptedResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method LastAccepted not implemented") +} +func (*UnimplementedVMServer) BlockVerify(ctx context.Context, req *BlockVerifyRequest) (*BlockVerifyResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method BlockVerify not implemented") +} +func (*UnimplementedVMServer) BlockAccept(ctx context.Context, req *BlockAcceptRequest) (*BlockAcceptResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method BlockAccept not implemented") +} +func (*UnimplementedVMServer) BlockReject(ctx context.Context, req *BlockRejectRequest) (*BlockRejectResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method BlockReject not implemented") +} + +func RegisterVMServer(s *grpc.Server, srv VMServer) { + s.RegisterService(&_VM_serviceDesc, srv) +} + +func _VM_Initialize_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InitializeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMServer).Initialize(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.VM/Initialize", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMServer).Initialize(ctx, req.(*InitializeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VM_Shutdown_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ShutdownRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMServer).Shutdown(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.VM/Shutdown", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMServer).Shutdown(ctx, req.(*ShutdownRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VM_CreateHandlers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateHandlersRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMServer).CreateHandlers(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.VM/CreateHandlers", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMServer).CreateHandlers(ctx, req.(*CreateHandlersRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VM_BuildBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BuildBlockRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMServer).BuildBlock(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.VM/BuildBlock", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMServer).BuildBlock(ctx, req.(*BuildBlockRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VM_ParseBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ParseBlockRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMServer).ParseBlock(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.VM/ParseBlock", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMServer).ParseBlock(ctx, req.(*ParseBlockRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VM_GetBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetBlockRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMServer).GetBlock(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.VM/GetBlock", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMServer).GetBlock(ctx, req.(*GetBlockRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VM_SetPreference_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SetPreferenceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMServer).SetPreference(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.VM/SetPreference", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMServer).SetPreference(ctx, req.(*SetPreferenceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VM_LastAccepted_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(LastAcceptedRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMServer).LastAccepted(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.VM/LastAccepted", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMServer).LastAccepted(ctx, req.(*LastAcceptedRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VM_BlockVerify_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BlockVerifyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMServer).BlockVerify(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.VM/BlockVerify", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMServer).BlockVerify(ctx, req.(*BlockVerifyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VM_BlockAccept_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BlockAcceptRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMServer).BlockAccept(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.VM/BlockAccept", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMServer).BlockAccept(ctx, req.(*BlockAcceptRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _VM_BlockReject_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BlockRejectRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMServer).BlockReject(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/proto.VM/BlockReject", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMServer).BlockReject(ctx, req.(*BlockRejectRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _VM_serviceDesc = grpc.ServiceDesc{ + ServiceName: "proto.VM", + HandlerType: (*VMServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Initialize", + Handler: _VM_Initialize_Handler, + }, + { + MethodName: "Shutdown", + Handler: _VM_Shutdown_Handler, + }, + { + MethodName: "CreateHandlers", + Handler: _VM_CreateHandlers_Handler, + }, + { + MethodName: "BuildBlock", + Handler: _VM_BuildBlock_Handler, + }, + { + MethodName: "ParseBlock", + Handler: _VM_ParseBlock_Handler, + }, + { + MethodName: "GetBlock", + Handler: _VM_GetBlock_Handler, + }, + { + MethodName: "SetPreference", + Handler: _VM_SetPreference_Handler, + }, + { + MethodName: "LastAccepted", + Handler: _VM_LastAccepted_Handler, + }, + { + MethodName: "BlockVerify", + Handler: _VM_BlockVerify_Handler, + }, + { + MethodName: "BlockAccept", + Handler: _VM_BlockAccept_Handler, + }, + { + MethodName: "BlockReject", + Handler: _VM_BlockReject_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "vm.proto", +} diff --git a/vms/rpcchainvm/proto/vm.proto b/vms/rpcchainvm/proto/vm.proto new file mode 100644 index 0000000..649c66b --- /dev/null +++ b/vms/rpcchainvm/proto/vm.proto @@ -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); +} \ No newline at end of file diff --git a/vms/rpcchainvm/vm.go b/vms/rpcchainvm/vm.go new file mode 100644 index 0000000..083fbd3 --- /dev/null +++ b/vms/rpcchainvm/vm.go @@ -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 +} diff --git a/vms/rpcchainvm/vm_client.go b/vms/rpcchainvm/vm_client.go new file mode 100644 index 0000000..45b727d --- /dev/null +++ b/vms/rpcchainvm/vm_client.go @@ -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)), + } + } + 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 } diff --git a/vms/rpcchainvm/vm_server.go b/vms/rpcchainvm/vm_server.go new file mode 100644 index 0000000..217a1f2 --- /dev/null +++ b/vms/rpcchainvm/vm_server.go @@ -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)) + 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 +} diff --git a/vms/secp256k1fx/factory.go b/vms/secp256k1fx/factory.go index da2e022..cdcb200 100644 --- a/vms/secp256k1fx/factory.go +++ b/vms/secp256k1fx/factory.go @@ -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 } diff --git a/vms/secp256k1fx/factory_test.go b/vms/secp256k1fx/factory_test.go index 54bc901..1c92b6a 100644 --- a/vms/secp256k1fx/factory_test.go +++ b/vms/secp256k1fx/factory_test.go @@ -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") } } diff --git a/vms/spchainvm/factory.go b/vms/spchainvm/factory.go index 6cb6fe2..0b8fa98 100644 --- a/vms/spchainvm/factory.go +++ b/vms/spchainvm/factory.go @@ -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 } diff --git a/vms/spchainvm/vm.go b/vms/spchainvm/vm.go index 6b71ce6..8956097 100644 --- a/vms/spchainvm/vm.go +++ b/vms/spchainvm/vm.go @@ -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) diff --git a/vms/spdagvm/factory.go b/vms/spdagvm/factory.go index 7e6e263..04e20ab 100644 --- a/vms/spdagvm/factory.go +++ b/vms/spdagvm/factory.go @@ -16,6 +16,6 @@ var ( type Factory struct{ TxFee uint64 } // New ... -func (f *Factory) New() interface{} { - return &VM{TxFee: f.TxFee} // Use the tx fee from the config +func (f *Factory) New() (interface{}, error) { + return &VM{TxFee: f.TxFee}, nil } diff --git a/vms/spdagvm/vm.go b/vms/spdagvm/vm.go index b873185..f23b2ca 100644 --- a/vms/spdagvm/vm.go +++ b/vms/spdagvm/vm.go @@ -130,6 +130,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) diff --git a/vms/timestampvm/factory.go b/vms/timestampvm/factory.go index 0800395..fb9a9ae 100644 --- a/vms/timestampvm/factory.go +++ b/vms/timestampvm/factory.go @@ -14,4 +14,4 @@ var ( type Factory struct{} // New ... -func (f *Factory) New() interface{} { return &VM{} } +func (f *Factory) New() (interface{}, error) { return &VM{}, nil }