From 6108e6af20ff9688fa1e2792bb39837ef5ca4301 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 20 Nov 2023 10:21:06 +0100 Subject: [PATCH 01/13] block backfilling basics: interface, metervm tracevm, rpcchainvm --- proto/pb/vm/vm.pb.go | 832 ++++++++++++------ proto/pb/vm/vm_grpc.pb.go | 78 ++ proto/vm/vm.proto | 23 + .../snowman/block/mocks/state_syncable_vm.go | 33 + .../engine/snowman/block/state_syncable_vm.go | 27 +- .../snowman/block/test_state_syncable_vm.go | 27 + vms/metervm/block_metrics.go | 6 +- vms/metervm/state_syncable_vm.go | 35 + vms/proposervm/state_syncable_vm.go | 9 + vms/rpcchainvm/errors.go | 12 +- vms/rpcchainvm/vm_client.go | 27 + vms/rpcchainvm/vm_server.go | 34 + vms/tracedvm/block_vm.go | 2 + vms/tracedvm/state_syncable_vm.go | 25 + 14 files changed, 876 insertions(+), 294 deletions(-) diff --git a/proto/pb/vm/vm.pb.go b/proto/pb/vm/vm.pb.go index ebc64f5c3a48..ae7d8b1ebf34 100644 --- a/proto/pb/vm/vm.pb.go +++ b/proto/pb/vm/vm.pb.go @@ -131,11 +131,13 @@ type Error int32 const ( // ERROR_UNSPECIFIED is used to indicate that no error occurred. - Error_ERROR_UNSPECIFIED Error = 0 - Error_ERROR_CLOSED Error = 1 - Error_ERROR_NOT_FOUND Error = 2 - Error_ERROR_HEIGHT_INDEX_INCOMPLETE Error = 3 - Error_ERROR_STATE_SYNC_NOT_IMPLEMENTED Error = 4 + Error_ERROR_UNSPECIFIED Error = 0 + Error_ERROR_CLOSED Error = 1 + Error_ERROR_NOT_FOUND Error = 2 + Error_ERROR_HEIGHT_INDEX_INCOMPLETE Error = 3 + Error_ERROR_STATE_SYNC_NOT_IMPLEMENTED Error = 4 + Error_ERROR_STATE_SYNC_BLOCK_BACKFILLING_NOT_ENABLED Error = 5 + Error_ERROR_STATE_SYNC_STOP_BLOCK_BACKFILLING Error = 6 ) // Enum value maps for Error. @@ -146,13 +148,17 @@ var ( 2: "ERROR_NOT_FOUND", 3: "ERROR_HEIGHT_INDEX_INCOMPLETE", 4: "ERROR_STATE_SYNC_NOT_IMPLEMENTED", + 5: "ERROR_STATE_SYNC_BLOCK_BACKFILLING_NOT_ENABLED", + 6: "ERROR_STATE_SYNC_STOP_BLOCK_BACKFILLING", } Error_value = map[string]int32{ - "ERROR_UNSPECIFIED": 0, - "ERROR_CLOSED": 1, - "ERROR_NOT_FOUND": 2, - "ERROR_HEIGHT_INDEX_INCOMPLETE": 3, - "ERROR_STATE_SYNC_NOT_IMPLEMENTED": 4, + "ERROR_UNSPECIFIED": 0, + "ERROR_CLOSED": 1, + "ERROR_NOT_FOUND": 2, + "ERROR_HEIGHT_INDEX_INCOMPLETE": 3, + "ERROR_STATE_SYNC_NOT_IMPLEMENTED": 4, + "ERROR_STATE_SYNC_BLOCK_BACKFILLING_NOT_ENABLED": 5, + "ERROR_STATE_SYNC_STOP_BLOCK_BACKFILLING": 6, } ) @@ -232,7 +238,7 @@ func (x StateSummaryAcceptResponse_Mode) Number() protoreflect.EnumNumber { // Deprecated: Use StateSummaryAcceptResponse_Mode.Descriptor instead. func (StateSummaryAcceptResponse_Mode) EnumDescriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{45, 0} + return file_vm_vm_proto_rawDescGZIP(), []int{48, 0} } type InitializeRequest struct { @@ -2878,6 +2884,179 @@ func (x *GetStateSummaryResponse) GetErr() Error { return Error_ERROR_UNSPECIFIED } +type BackfillBlocksEnabledResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Height uint64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"` + Err Error `protobuf:"varint,3,opt,name=err,proto3,enum=vm.Error" json:"err,omitempty"` +} + +func (x *BackfillBlocksEnabledResponse) Reset() { + *x = BackfillBlocksEnabledResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_vm_vm_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BackfillBlocksEnabledResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BackfillBlocksEnabledResponse) ProtoMessage() {} + +func (x *BackfillBlocksEnabledResponse) ProtoReflect() protoreflect.Message { + mi := &file_vm_vm_proto_msgTypes[44] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BackfillBlocksEnabledResponse.ProtoReflect.Descriptor instead. +func (*BackfillBlocksEnabledResponse) Descriptor() ([]byte, []int) { + return file_vm_vm_proto_rawDescGZIP(), []int{44} +} + +func (x *BackfillBlocksEnabledResponse) GetId() []byte { + if x != nil { + return x.Id + } + return nil +} + +func (x *BackfillBlocksEnabledResponse) GetHeight() uint64 { + if x != nil { + return x.Height + } + return 0 +} + +func (x *BackfillBlocksEnabledResponse) GetErr() Error { + if x != nil { + return x.Err + } + return Error_ERROR_UNSPECIFIED +} + +type BackfillBlocksRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + BlksBytes [][]byte `protobuf:"bytes,1,rep,name=blks_bytes,json=blksBytes,proto3" json:"blks_bytes,omitempty"` +} + +func (x *BackfillBlocksRequest) Reset() { + *x = BackfillBlocksRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_vm_vm_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BackfillBlocksRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BackfillBlocksRequest) ProtoMessage() {} + +func (x *BackfillBlocksRequest) ProtoReflect() protoreflect.Message { + mi := &file_vm_vm_proto_msgTypes[45] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BackfillBlocksRequest.ProtoReflect.Descriptor instead. +func (*BackfillBlocksRequest) Descriptor() ([]byte, []int) { + return file_vm_vm_proto_rawDescGZIP(), []int{45} +} + +func (x *BackfillBlocksRequest) GetBlksBytes() [][]byte { + if x != nil { + return x.BlksBytes + } + return nil +} + +type BackfillBlocksResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Height uint64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"` + Err Error `protobuf:"varint,3,opt,name=err,proto3,enum=vm.Error" json:"err,omitempty"` +} + +func (x *BackfillBlocksResponse) Reset() { + *x = BackfillBlocksResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_vm_vm_proto_msgTypes[46] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BackfillBlocksResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BackfillBlocksResponse) ProtoMessage() {} + +func (x *BackfillBlocksResponse) ProtoReflect() protoreflect.Message { + mi := &file_vm_vm_proto_msgTypes[46] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BackfillBlocksResponse.ProtoReflect.Descriptor instead. +func (*BackfillBlocksResponse) Descriptor() ([]byte, []int) { + return file_vm_vm_proto_rawDescGZIP(), []int{46} +} + +func (x *BackfillBlocksResponse) GetId() []byte { + if x != nil { + return x.Id + } + return nil +} + +func (x *BackfillBlocksResponse) GetHeight() uint64 { + if x != nil { + return x.Height + } + return 0 +} + +func (x *BackfillBlocksResponse) GetErr() Error { + if x != nil { + return x.Err + } + return Error_ERROR_UNSPECIFIED +} + type StateSummaryAcceptRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2889,7 +3068,7 @@ type StateSummaryAcceptRequest struct { func (x *StateSummaryAcceptRequest) Reset() { *x = StateSummaryAcceptRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[44] + mi := &file_vm_vm_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2902,7 +3081,7 @@ func (x *StateSummaryAcceptRequest) String() string { func (*StateSummaryAcceptRequest) ProtoMessage() {} func (x *StateSummaryAcceptRequest) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[44] + mi := &file_vm_vm_proto_msgTypes[47] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2915,7 +3094,7 @@ func (x *StateSummaryAcceptRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StateSummaryAcceptRequest.ProtoReflect.Descriptor instead. func (*StateSummaryAcceptRequest) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{44} + return file_vm_vm_proto_rawDescGZIP(), []int{47} } func (x *StateSummaryAcceptRequest) GetBytes() []byte { @@ -2937,7 +3116,7 @@ type StateSummaryAcceptResponse struct { func (x *StateSummaryAcceptResponse) Reset() { *x = StateSummaryAcceptResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vm_vm_proto_msgTypes[45] + mi := &file_vm_vm_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2950,7 +3129,7 @@ func (x *StateSummaryAcceptResponse) String() string { func (*StateSummaryAcceptResponse) ProtoMessage() {} func (x *StateSummaryAcceptResponse) ProtoReflect() protoreflect.Message { - mi := &file_vm_vm_proto_msgTypes[45] + mi := &file_vm_vm_proto_msgTypes[48] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2963,7 +3142,7 @@ func (x *StateSummaryAcceptResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use StateSummaryAcceptResponse.ProtoReflect.Descriptor instead. func (*StateSummaryAcceptResponse) Descriptor() ([]byte, []int) { - return file_vm_vm_proto_rawDescGZIP(), []int{45} + return file_vm_vm_proto_rawDescGZIP(), []int{48} } func (x *StateSummaryAcceptResponse) GetMode() StateSummaryAcceptResponse_Mode { @@ -3279,194 +3458,226 @@ var file_vm_vm_proto_rawDesc = []byte{ 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, - 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x31, 0x0a, 0x19, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, - 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, - 0xc5, 0x01, 0x0a, 0x1a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, - 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x76, - 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, - 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x6f, 0x64, - 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, - 0x03, 0x65, 0x72, 0x72, 0x22, 0x51, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x10, - 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x4b, 0x49, 0x50, 0x50, - 0x45, 0x44, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x49, 0x43, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x59, - 0x4e, 0x41, 0x4d, 0x49, 0x43, 0x10, 0x03, 0x2a, 0x65, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x12, 0x15, 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, - 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x54, 0x41, 0x54, 0x45, - 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x49, 0x4e, 0x47, 0x10, 0x01, - 0x12, 0x17, 0x0a, 0x13, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, - 0x52, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, - 0x54, 0x45, 0x5f, 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x5f, 0x4f, 0x50, 0x10, 0x03, 0x2a, 0x61, - 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54, - 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x15, 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45, - 0x53, 0x53, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x55, - 0x53, 0x5f, 0x52, 0x45, 0x4a, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, - 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, 0x44, 0x10, - 0x03, 0x2a, 0x8e, 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x15, 0x0a, 0x11, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, - 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4c, 0x4f, 0x53, - 0x45, 0x44, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, - 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x48, 0x45, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x5f, - 0x49, 0x4e, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x03, 0x12, 0x24, 0x0a, 0x20, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, - 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4d, 0x50, 0x4c, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x45, 0x44, - 0x10, 0x04, 0x32, 0xa4, 0x12, 0x0a, 0x02, 0x56, 0x4d, 0x12, 0x3b, 0x0a, 0x0a, 0x49, 0x6e, 0x69, - 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x15, 0x2e, 0x76, 0x6d, 0x2e, 0x49, 0x6e, 0x69, - 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, - 0x2e, 0x76, 0x6d, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x65, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, - 0x08, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x44, 0x0a, 0x0e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, - 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x50, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x48, - 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x64, 0x0a, 0x1d, + 0x42, 0x61, 0x63, 0x6b, 0x66, 0x69, 0x6c, 0x6c, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x45, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, + 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, + 0x72, 0x72, 0x22, 0x36, 0x0a, 0x15, 0x42, 0x61, 0x63, 0x6b, 0x66, 0x69, 0x6c, 0x6c, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x62, + 0x6c, 0x6b, 0x73, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, + 0x09, 0x62, 0x6c, 0x6b, 0x73, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x5d, 0x0a, 0x16, 0x42, 0x61, + 0x63, 0x6b, 0x66, 0x69, 0x6c, 0x6c, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1b, 0x0a, 0x03, + 0x65, 0x72, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, 0x72, 0x22, 0x31, 0x0a, 0x19, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x22, 0xc5, 0x01, 0x0a, + 0x1a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, + 0x65, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x04, 0x6d, + 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x76, 0x6d, 0x2e, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, + 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x03, 0x65, 0x72, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x09, 0x2e, 0x76, 0x6d, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x03, 0x65, 0x72, + 0x72, 0x22, 0x51, 0x0a, 0x04, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x4f, 0x44, + 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x10, 0x0a, 0x0c, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x4b, 0x49, 0x50, 0x50, 0x45, 0x44, 0x10, + 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, + 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x59, 0x4e, 0x41, 0x4d, + 0x49, 0x43, 0x10, 0x03, 0x2a, 0x65, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x15, 0x0a, + 0x11, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, + 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x17, 0x0a, + 0x13, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x54, 0x53, 0x54, 0x52, 0x41, 0x50, + 0x50, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, + 0x4e, 0x4f, 0x52, 0x4d, 0x41, 0x4c, 0x5f, 0x4f, 0x50, 0x10, 0x03, 0x2a, 0x61, 0x0a, 0x06, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, + 0x11, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x49, + 0x4e, 0x47, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, + 0x45, 0x4a, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, + 0x54, 0x55, 0x53, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x45, 0x44, 0x10, 0x03, 0x2a, 0xef, + 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x15, 0x0a, 0x11, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x10, 0x0a, 0x0c, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x44, 0x10, + 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, + 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x02, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x48, 0x45, 0x49, 0x47, 0x48, 0x54, 0x5f, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x5f, 0x49, 0x4e, 0x43, + 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x03, 0x12, 0x24, 0x0a, 0x20, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x4e, 0x4f, + 0x54, 0x5f, 0x49, 0x4d, 0x50, 0x4c, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x45, 0x44, 0x10, 0x04, 0x12, + 0x32, 0x0a, 0x2e, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, + 0x59, 0x4e, 0x43, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x42, 0x41, 0x43, 0x4b, 0x46, 0x49, + 0x4c, 0x4c, 0x49, 0x4e, 0x47, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45, + 0x44, 0x10, 0x05, 0x12, 0x2b, 0x0a, 0x27, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x5f, 0x42, 0x4c, 0x4f, + 0x43, 0x4b, 0x5f, 0x42, 0x41, 0x43, 0x4b, 0x46, 0x49, 0x4c, 0x4c, 0x49, 0x4e, 0x47, 0x10, 0x06, + 0x32, 0xc1, 0x13, 0x0a, 0x02, 0x56, 0x4d, 0x12, 0x3b, 0x0a, 0x0a, 0x49, 0x6e, 0x69, 0x74, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x12, 0x15, 0x2e, 0x76, 0x6d, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x76, + 0x6d, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x12, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x65, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x08, 0x53, + 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, - 0x20, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, - 0x63, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x39, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x14, - 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x0c, - 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x17, 0x2e, 0x76, - 0x6d, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3b, 0x0a, - 0x0a, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x15, 0x2e, 0x76, 0x6d, - 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x50, 0x61, - 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x15, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, - 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x42, 0x6c, - 0x6f, 0x63, 0x6b, 0x12, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, - 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, - 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, - 0x0a, 0x0d, 0x53, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, - 0x18, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x44, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x12, 0x34, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x1a, 0x12, 0x2e, 0x76, 0x6d, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x13, 0x2e, 0x76, 0x6d, 0x2e, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x37, 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x11, 0x2e, - 0x76, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, - 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x10, 0x41, 0x70, 0x70, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x17, 0x2e, 0x76, - 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, - 0x65, 0x64, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x39, 0x0a, - 0x0b, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x2e, 0x76, - 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, - 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x35, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x47, - 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x10, 0x2e, 0x76, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x47, 0x6f, - 0x73, 0x73, 0x69, 0x70, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x79, 0x1a, 0x1a, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x48, 0x61, 0x6e, + 0x64, 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, + 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x48, 0x61, 0x6e, + 0x64, 0x6c, 0x65, 0x72, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x20, 0x2e, + 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x48, + 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x39, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x14, 0x2e, 0x76, + 0x6d, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x0c, 0x44, 0x69, + 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x17, 0x2e, 0x76, 0x6d, 0x2e, + 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3b, 0x0a, 0x0a, 0x42, + 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x15, 0x2e, 0x76, 0x6d, 0x2e, 0x42, + 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x50, 0x61, 0x72, 0x73, + 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x15, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, + 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, + 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, + 0x6b, 0x12, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0d, + 0x53, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x18, 0x2e, + 0x76, 0x6d, 0x2e, 0x53, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, - 0x34, 0x0a, 0x06, 0x47, 0x61, 0x74, 0x68, 0x65, 0x72, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x34, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x1a, 0x12, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x61, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x14, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, - 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x2e, - 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x12, 0x57, 0x0a, 0x1a, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, - 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, - 0x12, 0x21, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, + 0x79, 0x1a, 0x12, 0x2e, 0x76, 0x6d, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x13, 0x2e, 0x76, 0x6d, 0x2e, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, + 0x0a, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x11, 0x2e, 0x76, 0x6d, + 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, 0x1a, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x10, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x17, 0x2e, 0x76, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4d, 0x0a, 0x15, 0x43, - 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, - 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, - 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x41, 0x0a, 0x0c, 0x47, 0x65, - 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x17, 0x2e, 0x76, 0x6d, 0x2e, - 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, - 0x73, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, - 0x11, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x12, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, - 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, - 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x4a, 0x0a, 0x11, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x49, - 0x6e, 0x64, 0x65, 0x78, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1d, 0x2e, 0x76, - 0x6d, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x49, 0x6e, - 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x12, 0x47, - 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x12, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, - 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1e, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, - 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x48, 0x0a, 0x10, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, 0x61, - 0x62, 0x6c, 0x65, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x76, - 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x1a, 0x47, 0x65, - 0x74, 0x4f, 0x6e, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0b, 0x41, + 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x2e, 0x76, 0x6d, 0x2e, + 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, 0x1a, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x35, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, + 0x73, 0x69, 0x70, 0x12, 0x10, 0x2e, 0x76, 0x6d, 0x2e, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, + 0x69, 0x70, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x34, 0x0a, + 0x06, 0x47, 0x61, 0x74, 0x68, 0x65, 0x72, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, + 0x12, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x61, 0x74, 0x68, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x4b, 0x0a, 0x14, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, + 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x2e, 0x76, 0x6d, + 0x2e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x73, 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x1a, 0x26, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x67, 0x6f, 0x69, 0x6e, 0x67, - 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4c, - 0x61, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, - 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1f, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, - 0x4c, 0x61, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x50, 0x61, 0x72, 0x73, - 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1c, 0x2e, - 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, - 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x6d, + 0x12, 0x57, 0x0a, 0x1a, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, + 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x21, + 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, + 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4d, 0x73, + 0x67, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4d, 0x0a, 0x15, 0x43, 0x72, 0x6f, + 0x73, 0x73, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x43, 0x68, 0x61, + 0x69, 0x6e, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x73, 0x67, + 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x41, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, + 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x17, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, + 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x18, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, + 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x12, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, + 0x73, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, + 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x50, 0x61, 0x72, 0x73, 0x65, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, + 0x11, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x49, 0x6e, 0x64, + 0x65, 0x78, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, + 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x12, 0x47, 0x65, 0x74, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, + 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, + 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, + 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x44, 0x41, 0x74, + 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, + 0x0a, 0x10, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x4f, + 0x6e, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x26, + 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x6e, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x53, 0x79, + 0x6e, 0x63, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, + 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1f, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, + 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x11, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1c, 0x2e, 0x76, 0x6d, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x0f, 0x47, 0x65, - 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1a, 0x2e, - 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, - 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x76, 0x6d, 0x2e, 0x47, - 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, - 0x65, 0x72, 0x69, 0x66, 0x79, 0x12, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, - 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, - 0x63, 0x63, 0x65, 0x70, 0x74, 0x12, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, - 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, + 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x50, + 0x61, 0x72, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1a, 0x2e, 0x76, 0x6d, + 0x2e, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x76, 0x6d, 0x2e, 0x47, 0x65, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x52, 0x0a, 0x15, 0x42, 0x61, 0x63, 0x6b, 0x66, 0x69, 0x6c, 0x6c, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, - 0x6a, 0x65, 0x63, 0x74, 0x12, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, - 0x65, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x12, 0x53, 0x0a, 0x12, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, - 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x12, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, - 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x6d, 0x2e, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, - 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x76, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x21, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x66, + 0x69, 0x6c, 0x6c, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x0e, 0x42, 0x61, 0x63, 0x6b, + 0x66, 0x69, 0x6c, 0x6c, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x19, 0x2e, 0x76, 0x6d, 0x2e, + 0x42, 0x61, 0x63, 0x6b, 0x66, 0x69, 0x6c, 0x6c, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x66, + 0x69, 0x6c, 0x6c, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, + 0x12, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x69, 0x66, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x3d, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, + 0x12, 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x41, 0x63, 0x63, 0x65, 0x70, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x12, 0x3d, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x12, + 0x16, 0x2e, 0x76, 0x6d, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x6a, 0x65, 0x63, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, + 0x53, 0x0a, 0x12, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, + 0x63, 0x63, 0x65, 0x70, 0x74, 0x12, 0x1d, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x6d, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, + 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, + 0x2f, 0x76, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3482,7 +3693,7 @@ func file_vm_vm_proto_rawDescGZIP() []byte { } var file_vm_vm_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_vm_vm_proto_msgTypes = make([]protoimpl.MessageInfo, 46) +var file_vm_vm_proto_msgTypes = make([]protoimpl.MessageInfo, 49) var file_vm_vm_proto_goTypes = []interface{}{ (State)(0), // 0: vm.State (Status)(0), // 1: vm.Status @@ -3532,111 +3743,120 @@ var file_vm_vm_proto_goTypes = []interface{}{ (*ParseStateSummaryResponse)(nil), // 45: vm.ParseStateSummaryResponse (*GetStateSummaryRequest)(nil), // 46: vm.GetStateSummaryRequest (*GetStateSummaryResponse)(nil), // 47: vm.GetStateSummaryResponse - (*StateSummaryAcceptRequest)(nil), // 48: vm.StateSummaryAcceptRequest - (*StateSummaryAcceptResponse)(nil), // 49: vm.StateSummaryAcceptResponse - (*timestamppb.Timestamp)(nil), // 50: google.protobuf.Timestamp - (*_go.MetricFamily)(nil), // 51: io.prometheus.client.MetricFamily - (*emptypb.Empty)(nil), // 52: google.protobuf.Empty + (*BackfillBlocksEnabledResponse)(nil), // 48: vm.BackfillBlocksEnabledResponse + (*BackfillBlocksRequest)(nil), // 49: vm.BackfillBlocksRequest + (*BackfillBlocksResponse)(nil), // 50: vm.BackfillBlocksResponse + (*StateSummaryAcceptRequest)(nil), // 51: vm.StateSummaryAcceptRequest + (*StateSummaryAcceptResponse)(nil), // 52: vm.StateSummaryAcceptResponse + (*timestamppb.Timestamp)(nil), // 53: google.protobuf.Timestamp + (*_go.MetricFamily)(nil), // 54: io.prometheus.client.MetricFamily + (*emptypb.Empty)(nil), // 55: google.protobuf.Empty } var file_vm_vm_proto_depIdxs = []int32{ - 50, // 0: vm.InitializeResponse.timestamp:type_name -> google.protobuf.Timestamp + 53, // 0: vm.InitializeResponse.timestamp:type_name -> google.protobuf.Timestamp 0, // 1: vm.SetStateRequest.state:type_name -> vm.State - 50, // 2: vm.SetStateResponse.timestamp:type_name -> google.protobuf.Timestamp + 53, // 2: vm.SetStateResponse.timestamp:type_name -> google.protobuf.Timestamp 10, // 3: vm.CreateHandlersResponse.handlers:type_name -> vm.Handler 10, // 4: vm.CreateStaticHandlersResponse.handlers:type_name -> vm.Handler - 50, // 5: vm.BuildBlockResponse.timestamp:type_name -> google.protobuf.Timestamp + 53, // 5: vm.BuildBlockResponse.timestamp:type_name -> google.protobuf.Timestamp 1, // 6: vm.ParseBlockResponse.status:type_name -> vm.Status - 50, // 7: vm.ParseBlockResponse.timestamp:type_name -> google.protobuf.Timestamp + 53, // 7: vm.ParseBlockResponse.timestamp:type_name -> google.protobuf.Timestamp 1, // 8: vm.GetBlockResponse.status:type_name -> vm.Status - 50, // 9: vm.GetBlockResponse.timestamp:type_name -> google.protobuf.Timestamp + 53, // 9: vm.GetBlockResponse.timestamp:type_name -> google.protobuf.Timestamp 2, // 10: vm.GetBlockResponse.err:type_name -> vm.Error - 50, // 11: vm.BlockVerifyResponse.timestamp:type_name -> google.protobuf.Timestamp - 50, // 12: vm.AppRequestMsg.deadline:type_name -> google.protobuf.Timestamp - 50, // 13: vm.CrossChainAppRequestMsg.deadline:type_name -> google.protobuf.Timestamp + 53, // 11: vm.BlockVerifyResponse.timestamp:type_name -> google.protobuf.Timestamp + 53, // 12: vm.AppRequestMsg.deadline:type_name -> google.protobuf.Timestamp + 53, // 13: vm.CrossChainAppRequestMsg.deadline:type_name -> google.protobuf.Timestamp 14, // 14: vm.BatchedParseBlockResponse.response:type_name -> vm.ParseBlockResponse 2, // 15: vm.VerifyHeightIndexResponse.err:type_name -> vm.Error 2, // 16: vm.GetBlockIDAtHeightResponse.err:type_name -> vm.Error - 51, // 17: vm.GatherResponse.metric_families:type_name -> io.prometheus.client.MetricFamily + 54, // 17: vm.GatherResponse.metric_families:type_name -> io.prometheus.client.MetricFamily 2, // 18: vm.StateSyncEnabledResponse.err:type_name -> vm.Error 2, // 19: vm.GetOngoingSyncStateSummaryResponse.err:type_name -> vm.Error 2, // 20: vm.GetLastStateSummaryResponse.err:type_name -> vm.Error 2, // 21: vm.ParseStateSummaryResponse.err:type_name -> vm.Error 2, // 22: vm.GetStateSummaryResponse.err:type_name -> vm.Error - 3, // 23: vm.StateSummaryAcceptResponse.mode:type_name -> vm.StateSummaryAcceptResponse.Mode - 2, // 24: vm.StateSummaryAcceptResponse.err:type_name -> vm.Error - 4, // 25: vm.VM.Initialize:input_type -> vm.InitializeRequest - 6, // 26: vm.VM.SetState:input_type -> vm.SetStateRequest - 52, // 27: vm.VM.Shutdown:input_type -> google.protobuf.Empty - 52, // 28: vm.VM.CreateHandlers:input_type -> google.protobuf.Empty - 52, // 29: vm.VM.CreateStaticHandlers:input_type -> google.protobuf.Empty - 31, // 30: vm.VM.Connected:input_type -> vm.ConnectedRequest - 32, // 31: vm.VM.Disconnected:input_type -> vm.DisconnectedRequest - 11, // 32: vm.VM.BuildBlock:input_type -> vm.BuildBlockRequest - 13, // 33: vm.VM.ParseBlock:input_type -> vm.ParseBlockRequest - 15, // 34: vm.VM.GetBlock:input_type -> vm.GetBlockRequest - 17, // 35: vm.VM.SetPreference:input_type -> vm.SetPreferenceRequest - 52, // 36: vm.VM.Health:input_type -> google.protobuf.Empty - 52, // 37: vm.VM.Version:input_type -> google.protobuf.Empty - 24, // 38: vm.VM.AppRequest:input_type -> vm.AppRequestMsg - 25, // 39: vm.VM.AppRequestFailed:input_type -> vm.AppRequestFailedMsg - 26, // 40: vm.VM.AppResponse:input_type -> vm.AppResponseMsg - 27, // 41: vm.VM.AppGossip:input_type -> vm.AppGossipMsg - 52, // 42: vm.VM.Gather:input_type -> google.protobuf.Empty - 28, // 43: vm.VM.CrossChainAppRequest:input_type -> vm.CrossChainAppRequestMsg - 29, // 44: vm.VM.CrossChainAppRequestFailed:input_type -> vm.CrossChainAppRequestFailedMsg - 30, // 45: vm.VM.CrossChainAppResponse:input_type -> vm.CrossChainAppResponseMsg - 33, // 46: vm.VM.GetAncestors:input_type -> vm.GetAncestorsRequest - 35, // 47: vm.VM.BatchedParseBlock:input_type -> vm.BatchedParseBlockRequest - 52, // 48: vm.VM.VerifyHeightIndex:input_type -> google.protobuf.Empty - 38, // 49: vm.VM.GetBlockIDAtHeight:input_type -> vm.GetBlockIDAtHeightRequest - 52, // 50: vm.VM.StateSyncEnabled:input_type -> google.protobuf.Empty - 52, // 51: vm.VM.GetOngoingSyncStateSummary:input_type -> google.protobuf.Empty - 52, // 52: vm.VM.GetLastStateSummary:input_type -> google.protobuf.Empty - 44, // 53: vm.VM.ParseStateSummary:input_type -> vm.ParseStateSummaryRequest - 46, // 54: vm.VM.GetStateSummary:input_type -> vm.GetStateSummaryRequest - 18, // 55: vm.VM.BlockVerify:input_type -> vm.BlockVerifyRequest - 20, // 56: vm.VM.BlockAccept:input_type -> vm.BlockAcceptRequest - 21, // 57: vm.VM.BlockReject:input_type -> vm.BlockRejectRequest - 48, // 58: vm.VM.StateSummaryAccept:input_type -> vm.StateSummaryAcceptRequest - 5, // 59: vm.VM.Initialize:output_type -> vm.InitializeResponse - 7, // 60: vm.VM.SetState:output_type -> vm.SetStateResponse - 52, // 61: vm.VM.Shutdown:output_type -> google.protobuf.Empty - 8, // 62: vm.VM.CreateHandlers:output_type -> vm.CreateHandlersResponse - 9, // 63: vm.VM.CreateStaticHandlers:output_type -> vm.CreateStaticHandlersResponse - 52, // 64: vm.VM.Connected:output_type -> google.protobuf.Empty - 52, // 65: vm.VM.Disconnected:output_type -> google.protobuf.Empty - 12, // 66: vm.VM.BuildBlock:output_type -> vm.BuildBlockResponse - 14, // 67: vm.VM.ParseBlock:output_type -> vm.ParseBlockResponse - 16, // 68: vm.VM.GetBlock:output_type -> vm.GetBlockResponse - 52, // 69: vm.VM.SetPreference:output_type -> google.protobuf.Empty - 22, // 70: vm.VM.Health:output_type -> vm.HealthResponse - 23, // 71: vm.VM.Version:output_type -> vm.VersionResponse - 52, // 72: vm.VM.AppRequest:output_type -> google.protobuf.Empty - 52, // 73: vm.VM.AppRequestFailed:output_type -> google.protobuf.Empty - 52, // 74: vm.VM.AppResponse:output_type -> google.protobuf.Empty - 52, // 75: vm.VM.AppGossip:output_type -> google.protobuf.Empty - 40, // 76: vm.VM.Gather:output_type -> vm.GatherResponse - 52, // 77: vm.VM.CrossChainAppRequest:output_type -> google.protobuf.Empty - 52, // 78: vm.VM.CrossChainAppRequestFailed:output_type -> google.protobuf.Empty - 52, // 79: vm.VM.CrossChainAppResponse:output_type -> google.protobuf.Empty - 34, // 80: vm.VM.GetAncestors:output_type -> vm.GetAncestorsResponse - 36, // 81: vm.VM.BatchedParseBlock:output_type -> vm.BatchedParseBlockResponse - 37, // 82: vm.VM.VerifyHeightIndex:output_type -> vm.VerifyHeightIndexResponse - 39, // 83: vm.VM.GetBlockIDAtHeight:output_type -> vm.GetBlockIDAtHeightResponse - 41, // 84: vm.VM.StateSyncEnabled:output_type -> vm.StateSyncEnabledResponse - 42, // 85: vm.VM.GetOngoingSyncStateSummary:output_type -> vm.GetOngoingSyncStateSummaryResponse - 43, // 86: vm.VM.GetLastStateSummary:output_type -> vm.GetLastStateSummaryResponse - 45, // 87: vm.VM.ParseStateSummary:output_type -> vm.ParseStateSummaryResponse - 47, // 88: vm.VM.GetStateSummary:output_type -> vm.GetStateSummaryResponse - 19, // 89: vm.VM.BlockVerify:output_type -> vm.BlockVerifyResponse - 52, // 90: vm.VM.BlockAccept:output_type -> google.protobuf.Empty - 52, // 91: vm.VM.BlockReject:output_type -> google.protobuf.Empty - 49, // 92: vm.VM.StateSummaryAccept:output_type -> vm.StateSummaryAcceptResponse - 59, // [59:93] is the sub-list for method output_type - 25, // [25:59] is the sub-list for method input_type - 25, // [25:25] is the sub-list for extension type_name - 25, // [25:25] is the sub-list for extension extendee - 0, // [0:25] is the sub-list for field type_name + 2, // 23: vm.BackfillBlocksEnabledResponse.err:type_name -> vm.Error + 2, // 24: vm.BackfillBlocksResponse.err:type_name -> vm.Error + 3, // 25: vm.StateSummaryAcceptResponse.mode:type_name -> vm.StateSummaryAcceptResponse.Mode + 2, // 26: vm.StateSummaryAcceptResponse.err:type_name -> vm.Error + 4, // 27: vm.VM.Initialize:input_type -> vm.InitializeRequest + 6, // 28: vm.VM.SetState:input_type -> vm.SetStateRequest + 55, // 29: vm.VM.Shutdown:input_type -> google.protobuf.Empty + 55, // 30: vm.VM.CreateHandlers:input_type -> google.protobuf.Empty + 55, // 31: vm.VM.CreateStaticHandlers:input_type -> google.protobuf.Empty + 31, // 32: vm.VM.Connected:input_type -> vm.ConnectedRequest + 32, // 33: vm.VM.Disconnected:input_type -> vm.DisconnectedRequest + 11, // 34: vm.VM.BuildBlock:input_type -> vm.BuildBlockRequest + 13, // 35: vm.VM.ParseBlock:input_type -> vm.ParseBlockRequest + 15, // 36: vm.VM.GetBlock:input_type -> vm.GetBlockRequest + 17, // 37: vm.VM.SetPreference:input_type -> vm.SetPreferenceRequest + 55, // 38: vm.VM.Health:input_type -> google.protobuf.Empty + 55, // 39: vm.VM.Version:input_type -> google.protobuf.Empty + 24, // 40: vm.VM.AppRequest:input_type -> vm.AppRequestMsg + 25, // 41: vm.VM.AppRequestFailed:input_type -> vm.AppRequestFailedMsg + 26, // 42: vm.VM.AppResponse:input_type -> vm.AppResponseMsg + 27, // 43: vm.VM.AppGossip:input_type -> vm.AppGossipMsg + 55, // 44: vm.VM.Gather:input_type -> google.protobuf.Empty + 28, // 45: vm.VM.CrossChainAppRequest:input_type -> vm.CrossChainAppRequestMsg + 29, // 46: vm.VM.CrossChainAppRequestFailed:input_type -> vm.CrossChainAppRequestFailedMsg + 30, // 47: vm.VM.CrossChainAppResponse:input_type -> vm.CrossChainAppResponseMsg + 33, // 48: vm.VM.GetAncestors:input_type -> vm.GetAncestorsRequest + 35, // 49: vm.VM.BatchedParseBlock:input_type -> vm.BatchedParseBlockRequest + 55, // 50: vm.VM.VerifyHeightIndex:input_type -> google.protobuf.Empty + 38, // 51: vm.VM.GetBlockIDAtHeight:input_type -> vm.GetBlockIDAtHeightRequest + 55, // 52: vm.VM.StateSyncEnabled:input_type -> google.protobuf.Empty + 55, // 53: vm.VM.GetOngoingSyncStateSummary:input_type -> google.protobuf.Empty + 55, // 54: vm.VM.GetLastStateSummary:input_type -> google.protobuf.Empty + 44, // 55: vm.VM.ParseStateSummary:input_type -> vm.ParseStateSummaryRequest + 46, // 56: vm.VM.GetStateSummary:input_type -> vm.GetStateSummaryRequest + 55, // 57: vm.VM.BackfillBlocksEnabled:input_type -> google.protobuf.Empty + 49, // 58: vm.VM.BackfillBlocks:input_type -> vm.BackfillBlocksRequest + 18, // 59: vm.VM.BlockVerify:input_type -> vm.BlockVerifyRequest + 20, // 60: vm.VM.BlockAccept:input_type -> vm.BlockAcceptRequest + 21, // 61: vm.VM.BlockReject:input_type -> vm.BlockRejectRequest + 51, // 62: vm.VM.StateSummaryAccept:input_type -> vm.StateSummaryAcceptRequest + 5, // 63: vm.VM.Initialize:output_type -> vm.InitializeResponse + 7, // 64: vm.VM.SetState:output_type -> vm.SetStateResponse + 55, // 65: vm.VM.Shutdown:output_type -> google.protobuf.Empty + 8, // 66: vm.VM.CreateHandlers:output_type -> vm.CreateHandlersResponse + 9, // 67: vm.VM.CreateStaticHandlers:output_type -> vm.CreateStaticHandlersResponse + 55, // 68: vm.VM.Connected:output_type -> google.protobuf.Empty + 55, // 69: vm.VM.Disconnected:output_type -> google.protobuf.Empty + 12, // 70: vm.VM.BuildBlock:output_type -> vm.BuildBlockResponse + 14, // 71: vm.VM.ParseBlock:output_type -> vm.ParseBlockResponse + 16, // 72: vm.VM.GetBlock:output_type -> vm.GetBlockResponse + 55, // 73: vm.VM.SetPreference:output_type -> google.protobuf.Empty + 22, // 74: vm.VM.Health:output_type -> vm.HealthResponse + 23, // 75: vm.VM.Version:output_type -> vm.VersionResponse + 55, // 76: vm.VM.AppRequest:output_type -> google.protobuf.Empty + 55, // 77: vm.VM.AppRequestFailed:output_type -> google.protobuf.Empty + 55, // 78: vm.VM.AppResponse:output_type -> google.protobuf.Empty + 55, // 79: vm.VM.AppGossip:output_type -> google.protobuf.Empty + 40, // 80: vm.VM.Gather:output_type -> vm.GatherResponse + 55, // 81: vm.VM.CrossChainAppRequest:output_type -> google.protobuf.Empty + 55, // 82: vm.VM.CrossChainAppRequestFailed:output_type -> google.protobuf.Empty + 55, // 83: vm.VM.CrossChainAppResponse:output_type -> google.protobuf.Empty + 34, // 84: vm.VM.GetAncestors:output_type -> vm.GetAncestorsResponse + 36, // 85: vm.VM.BatchedParseBlock:output_type -> vm.BatchedParseBlockResponse + 37, // 86: vm.VM.VerifyHeightIndex:output_type -> vm.VerifyHeightIndexResponse + 39, // 87: vm.VM.GetBlockIDAtHeight:output_type -> vm.GetBlockIDAtHeightResponse + 41, // 88: vm.VM.StateSyncEnabled:output_type -> vm.StateSyncEnabledResponse + 42, // 89: vm.VM.GetOngoingSyncStateSummary:output_type -> vm.GetOngoingSyncStateSummaryResponse + 43, // 90: vm.VM.GetLastStateSummary:output_type -> vm.GetLastStateSummaryResponse + 45, // 91: vm.VM.ParseStateSummary:output_type -> vm.ParseStateSummaryResponse + 47, // 92: vm.VM.GetStateSummary:output_type -> vm.GetStateSummaryResponse + 48, // 93: vm.VM.BackfillBlocksEnabled:output_type -> vm.BackfillBlocksEnabledResponse + 50, // 94: vm.VM.BackfillBlocks:output_type -> vm.BackfillBlocksResponse + 19, // 95: vm.VM.BlockVerify:output_type -> vm.BlockVerifyResponse + 55, // 96: vm.VM.BlockAccept:output_type -> google.protobuf.Empty + 55, // 97: vm.VM.BlockReject:output_type -> google.protobuf.Empty + 52, // 98: vm.VM.StateSummaryAccept:output_type -> vm.StateSummaryAcceptResponse + 63, // [63:99] is the sub-list for method output_type + 27, // [27:63] is the sub-list for method input_type + 27, // [27:27] is the sub-list for extension type_name + 27, // [27:27] is the sub-list for extension extendee + 0, // [0:27] is the sub-list for field type_name } func init() { file_vm_vm_proto_init() } @@ -4174,7 +4394,7 @@ func file_vm_vm_proto_init() { } } file_vm_vm_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StateSummaryAcceptRequest); i { + switch v := v.(*BackfillBlocksEnabledResponse); i { case 0: return &v.state case 1: @@ -4186,6 +4406,42 @@ func file_vm_vm_proto_init() { } } file_vm_vm_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BackfillBlocksRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vm_vm_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BackfillBlocksResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vm_vm_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StateSummaryAcceptRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vm_vm_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*StateSummaryAcceptResponse); i { case 0: return &v.state @@ -4206,7 +4462,7 @@ func file_vm_vm_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_vm_vm_proto_rawDesc, NumEnums: 4, - NumMessages: 46, + NumMessages: 49, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/pb/vm/vm_grpc.pb.go b/proto/pb/vm/vm_grpc.pb.go index 5250af11f86f..6b5b048c7641 100644 --- a/proto/pb/vm/vm_grpc.pb.go +++ b/proto/pb/vm/vm_grpc.pb.go @@ -50,6 +50,8 @@ const ( VM_GetLastStateSummary_FullMethodName = "/vm.VM/GetLastStateSummary" VM_ParseStateSummary_FullMethodName = "/vm.VM/ParseStateSummary" VM_GetStateSummary_FullMethodName = "/vm.VM/GetStateSummary" + VM_BackfillBlocksEnabled_FullMethodName = "/vm.VM/BackfillBlocksEnabled" + VM_BackfillBlocks_FullMethodName = "/vm.VM/BackfillBlocks" VM_BlockVerify_FullMethodName = "/vm.VM/BlockVerify" VM_BlockAccept_FullMethodName = "/vm.VM/BlockAccept" VM_BlockReject_FullMethodName = "/vm.VM/BlockReject" @@ -125,6 +127,10 @@ type VMClient interface { // GetStateSummary retrieves the state summary that was generated at height // [summaryHeight]. GetStateSummary(ctx context.Context, in *GetStateSummaryRequest, opts ...grpc.CallOption) (*GetStateSummaryResponse, error) + // BackfillBlocksEnabled indicates whether the block backfilling is enabled for this VM. + BackfillBlocksEnabled(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*BackfillBlocksEnabledResponse, error) + // BackfillBlocks pushes to the VM downloaded blocks to be backfilled. + BackfillBlocks(ctx context.Context, in *BackfillBlocksRequest, opts ...grpc.CallOption) (*BackfillBlocksResponse, error) // Block BlockVerify(ctx context.Context, in *BlockVerifyRequest, opts ...grpc.CallOption) (*BlockVerifyResponse, error) BlockAccept(ctx context.Context, in *BlockAcceptRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) @@ -411,6 +417,24 @@ func (c *vMClient) GetStateSummary(ctx context.Context, in *GetStateSummaryReque return out, nil } +func (c *vMClient) BackfillBlocksEnabled(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*BackfillBlocksEnabledResponse, error) { + out := new(BackfillBlocksEnabledResponse) + err := c.cc.Invoke(ctx, VM_BackfillBlocksEnabled_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vMClient) BackfillBlocks(ctx context.Context, in *BackfillBlocksRequest, opts ...grpc.CallOption) (*BackfillBlocksResponse, error) { + out := new(BackfillBlocksResponse) + err := c.cc.Invoke(ctx, VM_BackfillBlocks_FullMethodName, 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, VM_BlockVerify_FullMethodName, in, out, opts...) @@ -516,6 +540,10 @@ type VMServer interface { // GetStateSummary retrieves the state summary that was generated at height // [summaryHeight]. GetStateSummary(context.Context, *GetStateSummaryRequest) (*GetStateSummaryResponse, error) + // BackfillBlocksEnabled indicates whether the block backfilling is enabled for this VM. + BackfillBlocksEnabled(context.Context, *emptypb.Empty) (*BackfillBlocksEnabledResponse, error) + // BackfillBlocks pushes to the VM downloaded blocks to be backfilled. + BackfillBlocks(context.Context, *BackfillBlocksRequest) (*BackfillBlocksResponse, error) // Block BlockVerify(context.Context, *BlockVerifyRequest) (*BlockVerifyResponse, error) BlockAccept(context.Context, *BlockAcceptRequest) (*emptypb.Empty, error) @@ -619,6 +647,12 @@ func (UnimplementedVMServer) ParseStateSummary(context.Context, *ParseStateSumma func (UnimplementedVMServer) GetStateSummary(context.Context, *GetStateSummaryRequest) (*GetStateSummaryResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetStateSummary not implemented") } +func (UnimplementedVMServer) BackfillBlocksEnabled(context.Context, *emptypb.Empty) (*BackfillBlocksEnabledResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method BackfillBlocksEnabled not implemented") +} +func (UnimplementedVMServer) BackfillBlocks(context.Context, *BackfillBlocksRequest) (*BackfillBlocksResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method BackfillBlocks not implemented") +} func (UnimplementedVMServer) BlockVerify(context.Context, *BlockVerifyRequest) (*BlockVerifyResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method BlockVerify not implemented") } @@ -1184,6 +1218,42 @@ func _VM_GetStateSummary_Handler(srv interface{}, ctx context.Context, dec func( return interceptor(ctx, in, info, handler) } +func _VM_BackfillBlocksEnabled_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMServer).BackfillBlocksEnabled(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VM_BackfillBlocksEnabled_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMServer).BackfillBlocksEnabled(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _VM_BackfillBlocks_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BackfillBlocksRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VMServer).BackfillBlocks(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: VM_BackfillBlocks_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VMServer).BackfillBlocks(ctx, req.(*BackfillBlocksRequest)) + } + 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 { @@ -1383,6 +1453,14 @@ var VM_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetStateSummary", Handler: _VM_GetStateSummary_Handler, }, + { + MethodName: "BackfillBlocksEnabled", + Handler: _VM_BackfillBlocksEnabled_Handler, + }, + { + MethodName: "BackfillBlocks", + Handler: _VM_BackfillBlocks_Handler, + }, { MethodName: "BlockVerify", Handler: _VM_BlockVerify_Handler, diff --git a/proto/vm/vm.proto b/proto/vm/vm.proto index 0eca74b46041..c37fc5916dbd 100644 --- a/proto/vm/vm.proto +++ b/proto/vm/vm.proto @@ -80,6 +80,11 @@ service VM { // [summaryHeight]. rpc GetStateSummary(GetStateSummaryRequest) returns (GetStateSummaryResponse); + // BackfillBlocksEnabled indicates whether the block backfilling is enabled for this VM. + rpc BackfillBlocksEnabled(google.protobuf.Empty) returns (BackfillBlocksEnabledResponse); + // BackfillBlocks pushes to the VM downloaded blocks to be backfilled. + rpc BackfillBlocks(BackfillBlocksRequest) returns (BackfillBlocksResponse); + // Block rpc BlockVerify(BlockVerifyRequest) returns (BlockVerifyResponse); rpc BlockAccept(BlockAcceptRequest) returns (google.protobuf.Empty); @@ -110,6 +115,8 @@ enum Error { ERROR_NOT_FOUND = 2; ERROR_HEIGHT_INDEX_INCOMPLETE = 3; ERROR_STATE_SYNC_NOT_IMPLEMENTED = 4; + ERROR_STATE_SYNC_BLOCK_BACKFILLING_NOT_ENABLED = 5; + ERROR_STATE_SYNC_STOP_BLOCK_BACKFILLING = 6; } message InitializeRequest { @@ -388,6 +395,22 @@ message GetStateSummaryResponse { Error err = 3; } +message BackfillBlocksEnabledResponse { + bytes id = 1; + uint64 height = 2; + Error err = 3; +} + +message BackfillBlocksRequest { + repeated bytes blks_bytes = 1; +} + +message BackfillBlocksResponse { + bytes id = 1; + uint64 height = 2; + Error err = 3; +} + message StateSummaryAcceptRequest { bytes bytes = 1; } diff --git a/snow/engine/snowman/block/mocks/state_syncable_vm.go b/snow/engine/snowman/block/mocks/state_syncable_vm.go index 50a1fe92e117..90f929f4f762 100644 --- a/snow/engine/snowman/block/mocks/state_syncable_vm.go +++ b/snow/engine/snowman/block/mocks/state_syncable_vm.go @@ -11,6 +11,7 @@ import ( context "context" reflect "reflect" + ids "github.com/ava-labs/avalanchego/ids" block "github.com/ava-labs/avalanchego/snow/engine/snowman/block" gomock "go.uber.org/mock/gomock" ) @@ -38,6 +39,38 @@ func (m *MockStateSyncableVM) EXPECT() *MockStateSyncableVMMockRecorder { return m.recorder } +// BackfillBlocks mocks base method. +func (m *MockStateSyncableVM) BackfillBlocks(arg0 context.Context, arg1 [][]byte) (ids.ID, uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BackfillBlocks", arg0, arg1) + ret0, _ := ret[0].(ids.ID) + ret1, _ := ret[1].(uint64) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// BackfillBlocks indicates an expected call of BackfillBlocks. +func (mr *MockStateSyncableVMMockRecorder) BackfillBlocks(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BackfillBlocks", reflect.TypeOf((*MockStateSyncableVM)(nil).BackfillBlocks), arg0, arg1) +} + +// BackfillBlocksEnabled mocks base method. +func (m *MockStateSyncableVM) BackfillBlocksEnabled(arg0 context.Context) (ids.ID, uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BackfillBlocksEnabled", arg0) + ret0, _ := ret[0].(ids.ID) + ret1, _ := ret[1].(uint64) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// BackfillBlocksEnabled indicates an expected call of BackfillBlocksEnabled. +func (mr *MockStateSyncableVMMockRecorder) BackfillBlocksEnabled(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BackfillBlocksEnabled", reflect.TypeOf((*MockStateSyncableVM)(nil).BackfillBlocksEnabled), arg0) +} + // GetLastStateSummary mocks base method. func (m *MockStateSyncableVM) GetLastStateSummary(arg0 context.Context) (block.StateSummary, error) { m.ctrl.T.Helper() diff --git a/snow/engine/snowman/block/state_syncable_vm.go b/snow/engine/snowman/block/state_syncable_vm.go index 5c25f37a7ad7..c4bfaf7aa69e 100644 --- a/snow/engine/snowman/block/state_syncable_vm.go +++ b/snow/engine/snowman/block/state_syncable_vm.go @@ -6,9 +6,16 @@ package block import ( "context" "errors" + + "github.com/ava-labs/avalanchego/ids" ) -var ErrStateSyncableVMNotImplemented = errors.New("vm does not implement StateSyncableVM interface") +var ( + ErrStateSyncableVMNotImplemented = errors.New("vm does not implement StateSyncableVM interface") + ErrBlockBackfillingNotEnabled = errors.New("vm does not require block backfilling") + ErrStopBlockBackfilling = errors.New("vm required stopping block backfilling") + ErrInternalBlockBackfilling = errors.New("block backfilling internal error") +) // StateSyncableVM contains the functionality to allow VMs to sync to a given // state, rather then boostrapping from genesis. @@ -42,4 +49,22 @@ type StateSyncableVM interface { // Returns database.ErrNotFound if no summary is available at // [summaryHeight]. GetStateSummary(ctx context.Context, summaryHeight uint64) (StateSummary, error) + + // BackfillBlocksEnabled checks if VM wants to download all blocks from state summary one + // down to genesis. + // + // Returns the ID and height of the block it wants to start backfilling from. + // Returns ErrBlockBackfillingNotEnabled if block backfilling is not enabled. + // BackfillBlocksEnabled can be called multiple times by the engine + BackfillBlocksEnabled(ctx context.Context) (ids.ID, uint64, error) + + // BackfillBlocks passes blocks bytes retrieved via GetAncestors calls to the VM + // It's left to the VM the to parse, validate and index the blocks. + // BackfillBlocks returns the next block ID to be requested and an error + // Returns the ID and height of the block it wants to start backfilling from. + // Returns [ErrStopBlockBackfilling] if VM has done backfilling; engine will stop requesting blocks. + // Returns [ErrInternalBlockBackfilling] if VM has erred in a way that should make block backfilling fail. + // If BackfillBlocks returns any other error, engine will issue a GetAncestor call to a different peer + // with the previously requested block ID + BackfillBlocks(ctx context.Context, blocks [][]byte) (ids.ID, uint64, error) } diff --git a/snow/engine/snowman/block/test_state_syncable_vm.go b/snow/engine/snowman/block/test_state_syncable_vm.go index b05dd8118683..5199685bafe1 100644 --- a/snow/engine/snowman/block/test_state_syncable_vm.go +++ b/snow/engine/snowman/block/test_state_syncable_vm.go @@ -9,6 +9,8 @@ import ( "testing" "github.com/stretchr/testify/require" + + "github.com/ava-labs/avalanchego/ids" ) var ( @@ -19,6 +21,8 @@ var ( errGetLastStateSummary = errors.New("unexpectedly called GetLastStateSummary") errParseStateSummary = errors.New("unexpectedly called ParseStateSummary") errGetStateSummary = errors.New("unexpectedly called GetStateSummary") + errBackfillBlocksEnabled = errors.New("unexpectedly called BackfillBlocksEnabled") + errBackfillBlock = errors.New("unexpectedly called BackfillBlock") ) type TestStateSyncableVM struct { @@ -35,6 +39,9 @@ type TestStateSyncableVM struct { GetLastStateSummaryF func(context.Context) (StateSummary, error) ParseStateSummaryF func(ctx context.Context, summaryBytes []byte) (StateSummary, error) GetStateSummaryF func(ctx context.Context, summaryHeight uint64) (StateSummary, error) + + BackfillBlocksEnabledF func(context.Context) (ids.ID, uint64, error) + BackfillBlocksF func(context.Context, [][]byte) (ids.ID, uint64, error) } func (vm *TestStateSyncableVM) StateSyncEnabled(ctx context.Context) (bool, error) { @@ -86,3 +93,23 @@ func (vm *TestStateSyncableVM) GetStateSummary(ctx context.Context, summaryHeigh } return nil, errGetStateSummary } + +func (vm *TestStateSyncableVM) BackfillBlocksEnabled(ctx context.Context) (ids.ID, uint64, error) { + if vm.BackfillBlocksEnabledF != nil { + return vm.BackfillBlocksEnabledF(ctx) + } + if vm.CantGetStateSummary && vm.T != nil { + require.FailNow(vm.T, errGetStateSummary.Error()) + } + return ids.Empty, 0, errBackfillBlocksEnabled +} + +func (vm *TestStateSyncableVM) BackfillBlocks(ctx context.Context, blocks [][]byte) (ids.ID, uint64, error) { + if vm.BackfillBlocksF != nil { + return vm.BackfillBlocksF(ctx, blocks) + } + if vm.CantGetStateSummary && vm.T != nil { + require.FailNow(vm.T, errGetStateSummary.Error()) + } + return ids.Empty, 0, errBackfillBlock +} diff --git a/vms/metervm/block_metrics.go b/vms/metervm/block_metrics.go index 094e41875aac..967e983b0f1d 100644 --- a/vms/metervm/block_metrics.go +++ b/vms/metervm/block_metrics.go @@ -43,7 +43,9 @@ type blockMetrics struct { parseStateSummary, parseStateSummaryErr, getStateSummary, - getStateSummaryErr metric.Averager + getStateSummaryErr, + backfillBlocksEnabled, + backfillBlocks metric.Averager } func (m *blockMetrics) Initialize( @@ -88,6 +90,8 @@ func (m *blockMetrics) Initialize( m.parseStateSummaryErr = newAverager(namespace, "parse_state_summary_err", reg, &errs) m.getStateSummary = newAverager(namespace, "get_state_summary", reg, &errs) m.getStateSummaryErr = newAverager(namespace, "get_state_summary_err", reg, &errs) + m.backfillBlocksEnabled = newAverager(namespace, "backfill_blocks_enabled", reg, &errs) + m.backfillBlocks = newAverager(namespace, "backfill_blocks", reg, &errs) } return errs.Err } diff --git a/vms/metervm/state_syncable_vm.go b/vms/metervm/state_syncable_vm.go index bcb27d682b08..f6eb4bdec4b7 100644 --- a/vms/metervm/state_syncable_vm.go +++ b/vms/metervm/state_syncable_vm.go @@ -6,6 +6,7 @@ package metervm import ( "context" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" ) @@ -78,3 +79,37 @@ func (vm *blockVM) GetStateSummary(ctx context.Context, height uint64) (block.St vm.blockMetrics.getStateSummary.Observe(duration) return summary, nil } + +func (vm *blockVM) BackfillBlocksEnabled(ctx context.Context) (ids.ID, uint64, error) { + if vm.ssVM == nil { + return ids.Empty, 0, block.ErrStateSyncableVMNotImplemented + } + + start := vm.clock.Time() + blkID, blkHeight, err := vm.ssVM.BackfillBlocksEnabled(ctx) + end := vm.clock.Time() + duration := float64(end.Sub(start)) + if err != nil { + vm.blockMetrics.backfillBlocksEnabled.Observe(duration) + return ids.Empty, blkHeight, err + } + vm.blockMetrics.backfillBlocksEnabled.Observe(duration) + return blkID, blkHeight, nil +} + +func (vm *blockVM) BackfillBlocks(ctx context.Context, blocks [][]byte) (ids.ID, uint64, error) { + if vm.ssVM == nil { + return ids.Empty, 0, block.ErrStateSyncableVMNotImplemented + } + + start := vm.clock.Time() + nextWantedBlkID, nextWantedBlkHeight, err := vm.ssVM.BackfillBlocks(ctx, blocks) + end := vm.clock.Time() + duration := float64(end.Sub(start)) + if err != nil { + vm.blockMetrics.backfillBlocks.Observe(duration) + return nextWantedBlkID, nextWantedBlkHeight, err + } + vm.blockMetrics.backfillBlocks.Observe(duration) + return nextWantedBlkID, nextWantedBlkHeight, nil +} diff --git a/vms/proposervm/state_syncable_vm.go b/vms/proposervm/state_syncable_vm.go index da86d8c36e5c..440e5f17223d 100644 --- a/vms/proposervm/state_syncable_vm.go +++ b/vms/proposervm/state_syncable_vm.go @@ -10,6 +10,7 @@ import ( "go.uber.org/zap" "github.com/ava-labs/avalanchego/database" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/vms/proposervm/summary" ) @@ -159,3 +160,11 @@ func (vm *VM) buildStateSummary(ctx context.Context, innerSummary block.StateSum vm: vm, }, nil } + +func (*VM) BackfillBlocksEnabled(context.Context) (ids.ID, uint64, error) { + return ids.Empty, 0, block.ErrBlockBackfillingNotEnabled +} + +func (*VM) BackfillBlocks(context.Context, [][]byte) (ids.ID, uint64, error) { + return ids.Empty, 0, block.ErrStopBlockBackfilling +} diff --git a/vms/rpcchainvm/errors.go b/vms/rpcchainvm/errors.go index 3795024378c4..152e051a67be 100644 --- a/vms/rpcchainvm/errors.go +++ b/vms/rpcchainvm/errors.go @@ -12,16 +12,20 @@ import ( var ( errEnumToError = map[vmpb.Error]error{ - vmpb.Error_ERROR_CLOSED: database.ErrClosed, - vmpb.Error_ERROR_NOT_FOUND: database.ErrNotFound, - vmpb.Error_ERROR_HEIGHT_INDEX_INCOMPLETE: block.ErrIndexIncomplete, - vmpb.Error_ERROR_STATE_SYNC_NOT_IMPLEMENTED: block.ErrStateSyncableVMNotImplemented, + vmpb.Error_ERROR_CLOSED: database.ErrClosed, + vmpb.Error_ERROR_NOT_FOUND: database.ErrNotFound, + vmpb.Error_ERROR_HEIGHT_INDEX_INCOMPLETE: block.ErrIndexIncomplete, + vmpb.Error_ERROR_STATE_SYNC_NOT_IMPLEMENTED: block.ErrStateSyncableVMNotImplemented, + vmpb.Error_ERROR_STATE_SYNC_BLOCK_BACKFILLING_NOT_ENABLED: block.ErrBlockBackfillingNotEnabled, + vmpb.Error_ERROR_STATE_SYNC_STOP_BLOCK_BACKFILLING: block.ErrStopBlockBackfilling, } errorToErrEnum = map[error]vmpb.Error{ database.ErrClosed: vmpb.Error_ERROR_CLOSED, database.ErrNotFound: vmpb.Error_ERROR_NOT_FOUND, block.ErrIndexIncomplete: vmpb.Error_ERROR_HEIGHT_INDEX_INCOMPLETE, block.ErrStateSyncableVMNotImplemented: vmpb.Error_ERROR_STATE_SYNC_NOT_IMPLEMENTED, + block.ErrBlockBackfillingNotEnabled: vmpb.Error_ERROR_STATE_SYNC_BLOCK_BACKFILLING_NOT_ENABLED, + block.ErrStopBlockBackfilling: vmpb.Error_ERROR_STATE_SYNC_STOP_BLOCK_BACKFILLING, } ) diff --git a/vms/rpcchainvm/vm_client.go b/vms/rpcchainvm/vm_client.go index d9915bfbfcd6..9221b9fa0cc8 100644 --- a/vms/rpcchainvm/vm_client.go +++ b/vms/rpcchainvm/vm_client.go @@ -802,6 +802,33 @@ func (vm *VMClient) GetStateSummary(ctx context.Context, summaryHeight uint64) ( }, err } +func (vm *VMClient) BackfillBlocksEnabled(ctx context.Context) (ids.ID, uint64, error) { + resp, err := vm.client.BackfillBlocksEnabled(ctx, &emptypb.Empty{}) + if err != nil { + return ids.Empty, 0, err + } + if errEnum := resp.Err; errEnum != vmpb.Error_ERROR_UNSPECIFIED { + return ids.ID(resp.Id), resp.Height, errEnumToError[errEnum] + } + return ids.ID(resp.Id), resp.Height, nil +} + +func (vm *VMClient) BackfillBlocks(ctx context.Context, blocks [][]byte) (ids.ID, uint64, error) { + resp, err := vm.client.BackfillBlocks( + ctx, + &vmpb.BackfillBlocksRequest{ + BlksBytes: blocks, + }, + ) + if err != nil { + return ids.Empty, 0, err + } + if errEnum := resp.Err; errEnum != vmpb.Error_ERROR_UNSPECIFIED { + return ids.ID(resp.Id), resp.Height, errEnumToError[errEnum] + } + return ids.ID(resp.Id), resp.Height, nil +} + func (vm *VMClient) newBlockFromBuildBlock(resp *vmpb.BuildBlockResponse) (*blockClient, error) { id, err := ids.ToID(resp.Id) if err != nil { diff --git a/vms/rpcchainvm/vm_server.go b/vms/rpcchainvm/vm_server.go index 7ee82a241506..29e309776e39 100644 --- a/vms/rpcchainvm/vm_server.go +++ b/vms/rpcchainvm/vm_server.go @@ -784,6 +784,40 @@ func (vm *VMServer) GetStateSummary( }, nil } +func (vm *VMServer) BackfillBlocksEnabled(ctx context.Context, _ *emptypb.Empty) (*vmpb.BackfillBlocksEnabledResponse, error) { + var ( + blkID = ids.Empty + height uint64 + err error + ) + if vm.ssVM != nil { + blkID, height, err = vm.ssVM.BackfillBlocksEnabled(ctx) + } + + return &vmpb.BackfillBlocksEnabledResponse{ + Id: blkID[:], + Height: height, + Err: errorToErrEnum[err], + }, errorToRPCError(err) +} + +func (vm *VMServer) BackfillBlocks(ctx context.Context, req *vmpb.BackfillBlocksRequest) (*vmpb.BackfillBlocksResponse, error) { + var ( + nextWantedBlkID ids.ID + nextWantedBlkHeight uint64 + err error + ) + if vm.ssVM != nil { + nextWantedBlkID, nextWantedBlkHeight, err = vm.ssVM.BackfillBlocks(ctx, req.BlksBytes) + } + + return &vmpb.BackfillBlocksResponse{ + Id: nextWantedBlkID[:], + Height: nextWantedBlkHeight, + Err: errorToErrEnum[err], + }, errorToRPCError(err) +} + func (vm *VMServer) BlockVerify(ctx context.Context, req *vmpb.BlockVerifyRequest) (*vmpb.BlockVerifyResponse, error) { blk, err := vm.vm.ParseBlock(ctx, req.Bytes) if err != nil { diff --git a/vms/tracedvm/block_vm.go b/vms/tracedvm/block_vm.go index 969a6bc09637..bf18bbbbd477 100644 --- a/vms/tracedvm/block_vm.go +++ b/vms/tracedvm/block_vm.go @@ -59,6 +59,8 @@ type blockVM struct { getLastStateSummaryTag string parseStateSummaryTag string getStateSummaryTag string + backfillBlocksEnabledTag string + backfillBlocksTag string tracer trace.Tracer } diff --git a/vms/tracedvm/state_syncable_vm.go b/vms/tracedvm/state_syncable_vm.go index 75738462368b..514002056cdc 100644 --- a/vms/tracedvm/state_syncable_vm.go +++ b/vms/tracedvm/state_syncable_vm.go @@ -10,6 +10,7 @@ import ( oteltrace "go.opentelemetry.io/otel/trace" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" ) @@ -71,3 +72,27 @@ func (vm *blockVM) GetStateSummary(ctx context.Context, height uint64) (block.St return vm.ssVM.GetStateSummary(ctx, height) } + +func (vm *blockVM) BackfillBlocksEnabled(ctx context.Context) (ids.ID, uint64, error) { + if vm.ssVM == nil { + return ids.Empty, 0, block.ErrStateSyncableVMNotImplemented + } + + ctx, span := vm.tracer.Start(ctx, vm.backfillBlocksEnabledTag) + defer span.End() + + return vm.ssVM.BackfillBlocksEnabled(ctx) +} + +func (vm *blockVM) BackfillBlocks(ctx context.Context, blocks [][]byte) (ids.ID, uint64, error) { + if vm.ssVM == nil { + return ids.Empty, 0, block.ErrStateSyncableVMNotImplemented + } + + ctx, span := vm.tracer.Start(ctx, vm.backfillBlocksTag, oteltrace.WithAttributes( + attribute.Int("blocksCount", len(blocks)), + )) + defer span.End() + + return vm.ssVM.BackfillBlocks(ctx, blocks) +} From 76dbcc4e907b6a5a23707a0d0f689c483524a543 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 30 Oct 2023 08:28:32 +0100 Subject: [PATCH 02/13] temporarily cut coreth dependency --- go.mod | 25 - go.sum | 76 -- node/node.go | 4 +- tests/e2e/c/dynamic_fees.go | 326 +++---- tests/e2e/c/interchain_workflow.go | 320 +++---- tests/e2e/p/interchain_workflow.go | 444 +++++----- tests/e2e/x/interchain_workflow.go | 296 +++---- tests/fixture/e2e/helpers.go | 123 +-- tests/fixture/testnet/config.go | 56 +- vms/example/xsvm/cmd/chain/create/cmd.go | 6 +- wallet/chain/c/backend.go | 300 +++---- wallet/chain/c/builder.go | 792 +++++++++--------- wallet/chain/c/builder_with_options.go | 136 +-- wallet/chain/c/context.go | 130 +-- wallet/chain/c/signer.go | 436 +++++----- wallet/chain/c/wallet.go | 402 ++++----- wallet/chain/c/wallet_with_options.go | 134 +-- wallet/subnet/primary/api.go | 122 +-- wallet/subnet/primary/example_test.go | 2 +- .../add-permissioned-subnet-validator/main.go | 6 +- .../examples/add-primary-validator/main.go | 2 +- .../primary/examples/c-chain-export/main.go | 118 +-- .../primary/examples/c-chain-import/main.go | 126 +-- .../primary/examples/create-asset/main.go | 2 +- .../primary/examples/create-chain/main.go | 6 +- .../examples/create-locked-stakeable/main.go | 2 +- .../primary/examples/create-subnet/main.go | 2 +- .../examples/remove-subnet-validator/main.go | 6 +- wallet/subnet/primary/wallet.go | 43 +- 29 files changed, 2173 insertions(+), 2270 deletions(-) diff --git a/go.mod b/go.mod index bf06bbc74e83..23b752198fdd 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,6 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 - github.com/ava-labs/coreth v0.12.9-rc.0 github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 @@ -75,7 +74,6 @@ require ( github.com/BurntSushi/toml v1.2.1 // indirect github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect - github.com/VictoriaMetrics/fastcache v1.10.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect @@ -83,44 +81,26 @@ require ( github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/redact v1.1.3 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/deckarep/golang-set/v2 v2.1.0 // indirect - github.com/dlclark/regexp2 v1.7.0 // indirect - github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 // indirect - github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect github.com/frankban/quicktest v1.14.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/getsentry/sentry-go v0.18.0 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect - github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect - github.com/go-stack/stack v1.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/go-cmp v0.5.9 // indirect - github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect - github.com/google/uuid v1.3.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 // indirect - github.com/hashicorp/go-bexpr v0.1.10 // indirect - github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e // indirect github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/klauspost/compress v1.15.15 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/magiconair/properties v1.8.6 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect - github.com/mattn/go-runewidth v0.0.9 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/mitchellh/pointerstructure v1.2.0 // indirect - github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -128,17 +108,12 @@ require ( github.com/prometheus/common v0.39.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sanity-io/litter v1.5.1 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/status-im/keycard-go v0.2.0 // indirect github.com/subosito/gotenv v1.3.0 // indirect github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tklauser/numcpus v0.2.2 // indirect - github.com/tyler-smith/go-bip39 v1.1.0 // indirect - github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa // indirect - github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect diff --git a/go.sum b/go.sum index 573d618f19cb..2ae152b17faf 100644 --- a/go.sum +++ b/go.sum @@ -56,18 +56,12 @@ github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cq github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= -github.com/VictoriaMetrics/fastcache v1.10.0 h1:5hDJnLsKLpnUEToub7ETuRu8RCkb40woBZAUiKonXzY= -github.com/VictoriaMetrics/fastcache v1.10.0/go.mod h1:tjiYeEfYXCqacuvYw/7UoDIeJaNxq6132xHICNP77w8= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/coreth v0.12.9-rc.0 h1:Xvk/iJTY2MSBkkiOs9Eo92nxd67VXzRjaC/WmQXRIb0= -github.com/ava-labs/coreth v0.12.9-rc.0/go.mod h1:rECKQfGFDeodrwGPlJSvFUJDbVr30jSMIVjQLi6pNX4= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= @@ -102,18 +96,13 @@ github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46f github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw= github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA= @@ -145,16 +134,12 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= -github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= @@ -165,14 +150,6 @@ github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6ps github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= -github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= -github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 h1:+3HCtB74++ClLy8GgjUQYeC8R4ILzVcIe8+5edAJJnE= -github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= -github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= -github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -189,8 +166,6 @@ github.com/ethereum/go-ethereum v1.12.0 h1:bdnhLPtqETd4m3mS8BGMNvBTf36bO5bx/hxE2 github.com/ethereum/go-ethereum v1.12.0/go.mod h1:/oo2X/dZLJjf2mJ6YT9wcWxa4nNJDBKDBU6sFIpx1Gs= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -199,8 +174,6 @@ github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmV github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= -github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= -github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= @@ -224,11 +197,7 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= -github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= -github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= @@ -313,14 +282,10 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= -github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= @@ -341,17 +306,11 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 h1:kr3j8iIMR4ywO/O0rvksXaJvauGGCMg2zAZIiNZ9uIQ= github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0/go.mod h1:ummNFgdgLhhX7aIiy35vVmQNS0rWXknfPE0qe6fmFXg= -github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= -github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e h1:pIYdhNkDh+YENVNi3gto8n9hAmRxKxoar0iE6BLucjw= -github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e/go.mod h1:j9cQbcqHQujT0oKJ38PylVfqohClLr3CvDC+Qcg+lhU= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c h1:DZfsyhDK1hnSS5lH8l+JggqzEleHteTYfutAiVlSUM8= @@ -363,7 +322,6 @@ github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3 github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -405,7 +363,6 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -413,7 +370,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= @@ -424,17 +380,11 @@ github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPK github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= @@ -443,11 +393,8 @@ github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= -github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -466,8 +413,6 @@ github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= -github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -535,8 +480,6 @@ github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sanity-io/litter v1.5.1 h1:dwnrSypP6q56o3lFxTU+t2fwQ9A+U5qrXVO4Qg9KwVU= github.com/sanity-io/litter v1.5.1/go.mod h1:5Z71SvaYy5kcGtyglXOC9rrUi3c1E8CamFWjQsazTh0= @@ -572,8 +515,6 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= -github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= -github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -605,14 +546,10 @@ github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZF github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE= github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE= -github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= -github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa h1:5SqCsI/2Qya2bCzK15ozrqo2sZxkh0FHynJZOTVoV6Q= -github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= @@ -624,8 +561,6 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= @@ -635,7 +570,6 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= @@ -731,7 +665,6 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -777,7 +710,6 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -801,7 +733,6 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -866,12 +797,8 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -888,7 +815,6 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -952,7 +878,6 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1077,7 +1002,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= diff --git a/node/node.go b/node/node.go index 06544e8f9e6b..98d697a66359 100644 --- a/node/node.go +++ b/node/node.go @@ -25,7 +25,7 @@ import ( "go.uber.org/zap" - coreth "github.com/ava-labs/coreth/plugin/evm" + // coreth "github.com/ava-labs/coreth/plugin/evm" "github.com/ava-labs/avalanchego/api/admin" "github.com/ava-labs/avalanchego/api/auth" @@ -1094,7 +1094,7 @@ func (n *Node) initVMs() error { CreateAssetTxFee: n.Config.CreateAssetTxFee, }, }), - vmRegisterer.Register(context.TODO(), constants.EVMID, &coreth.Factory{}), + // vmRegisterer.Register(context.TODO(), constants.EVMID, &coreth.Factory{}), n.VMManager.RegisterFactory(context.TODO(), secp256k1fx.ID, &secp256k1fx.Factory{}), n.VMManager.RegisterFactory(context.TODO(), nftfx.ID, &nftfx.Factory{}), n.VMManager.RegisterFactory(context.TODO(), propertyfx.ID, &propertyfx.Factory{}), diff --git a/tests/e2e/c/dynamic_fees.go b/tests/e2e/c/dynamic_fees.go index 8f15b6d43caf..8748dda7451d 100644 --- a/tests/e2e/c/dynamic_fees.go +++ b/tests/e2e/c/dynamic_fees.go @@ -3,166 +3,166 @@ package c -import ( - "math/big" - "strings" - - ginkgo "github.com/onsi/ginkgo/v2" - - "github.com/stretchr/testify/require" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/plugin/evm" - - "github.com/ava-labs/avalanchego/tests" - "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/tests/fixture/testnet" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -) - -// This test uses the compiled bin for `hashing.sol` as -// well as its ABI contained in `hashing_contract.go`. - -var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { - require := require.New(ginkgo.GinkgoT()) - - // Need a gas limit much larger than the standard 21_000 to enable - // the contract to induce a gas price increase - const largeGasLimit = uint64(8_000_000) - - // TODO(marun) What is the significance of this value? - gasTip := big.NewInt(1000 * params.GWei) - - ginkgo.It("should ensure that the gas price is affected by load", func() { - ginkgo.By("creating a new private network to ensure isolation from other tests") - privateNetwork := e2e.Env.NewPrivateNetwork() - - ginkgo.By("allocating a pre-funded key") - key := privateNetwork.GetConfig().FundedKeys[0] - ethAddress := evm.GetEthAddress(key) - - ginkgo.By("initializing a coreth client") - node := privateNetwork.GetNodes()[0] - nodeURI := testnet.NodeURI{ - NodeID: node.GetID(), - URI: node.GetProcessContext().URI, - } - ethClient := e2e.NewEthClient(nodeURI) - - ginkgo.By("initializing a transaction signer") - cChainID, err := ethClient.ChainID(e2e.DefaultContext()) - require.NoError(err) - signer := types.NewEIP155Signer(cChainID) - ecdsaKey := key.ToECDSA() - sign := func(tx *types.Transaction) *types.Transaction { - signedTx, err := types.SignTx(tx, signer, ecdsaKey) - require.NoError(err) - return signedTx - } - - var contractAddress common.Address - ginkgo.By("deploying an expensive contract", func() { - // Create transaction - nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) - require.NoError(err) - compiledContract := common.Hex2Bytes(hashingCompiledContract) - tx := types.NewTx(&types.LegacyTx{ - Nonce: nonce, - GasPrice: gasTip, - Gas: largeGasLimit, - Value: common.Big0, - Data: compiledContract, - }) - - // Send the transaction and wait for acceptance - signedTx := sign(tx) - receipt := e2e.SendEthTransaction(ethClient, signedTx) - - contractAddress = receipt.ContractAddress - }) - - var gasPrice *big.Int - ginkgo.By("calling the expensive contract repeatedly until a gas price increase is detected", func() { - // Evaluate the bytes representation of the contract - hashingABI, err := abi.JSON(strings.NewReader(hashingABIJson)) - require.NoError(err) - contractData, err := hashingABI.Pack("hashIt") - require.NoError(err) - - var initialGasPrice *big.Int - e2e.Eventually(func() bool { - // Check the gas price - var err error - gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) - require.NoError(err) - if initialGasPrice == nil { - initialGasPrice = gasPrice - tests.Outf("{{blue}}initial gas price is %v{{/}}\n", initialGasPrice) - } else if gasPrice.Cmp(initialGasPrice) > 0 { - // Gas price has increased - tests.Outf("{{blue}}gas price has increased to %v{{/}}\n", gasPrice) - return true - } - - // Create the transaction - nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) - require.NoError(err) - tx := types.NewTx(&types.LegacyTx{ - Nonce: nonce, - GasPrice: gasTip, - Gas: largeGasLimit, - To: &contractAddress, - Value: common.Big0, - Data: contractData, - }) - - // Send the transaction and wait for acceptance - signedTx := sign(tx) - _ = e2e.SendEthTransaction(ethClient, signedTx) - - // The gas price will be checked at the start of the next iteration - return false - }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price increase before timeout") - }) - - ginkgo.By("waiting for the gas price to decrease...", func() { - initialGasPrice := gasPrice - e2e.Eventually(func() bool { - var err error - gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) - require.NoError(err) - tests.Outf("{{blue}}.{{/}}") - return initialGasPrice.Cmp(gasPrice) > 0 - }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price decrease before timeout") - tests.Outf("\n{{blue}}gas price has decreased to %v{{/}}\n", gasPrice) - }) - - ginkgo.By("sending funds at the current gas price", func() { - // Create a recipient address - recipientKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - recipientEthAddress := evm.GetEthAddress(recipientKey) - - // Create transaction - nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) - require.NoError(err) - tx := types.NewTx(&types.LegacyTx{ - Nonce: nonce, - GasPrice: gasPrice, - Gas: e2e.DefaultGasLimit, - To: &recipientEthAddress, - Value: common.Big0, - }) - - // Send the transaction and wait for acceptance - signedTx := sign(tx) - _ = e2e.SendEthTransaction(ethClient, signedTx) - }) - - e2e.CheckBootstrapIsPossible(privateNetwork) - }) -}) +// import ( +// "math/big" +// "strings" + +// ginkgo "github.com/onsi/ginkgo/v2" + +// "github.com/stretchr/testify/require" + +// "github.com/ethereum/go-ethereum/accounts/abi" +// "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/coreth/core/types" +// "github.com/ava-labs/coreth/params" +// "github.com/ava-labs/coreth/plugin/evm" + +// "github.com/ava-labs/avalanchego/tests" +// "github.com/ava-labs/avalanchego/tests/e2e" +// "github.com/ava-labs/avalanchego/tests/fixture/testnet" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// ) + +// // This test uses the compiled bin for `hashing.sol` as +// // well as its ABI contained in `hashing_contract.go`. + +// var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { +// require := require.New(ginkgo.GinkgoT()) + +// // Need a gas limit much larger than the standard 21_000 to enable +// // the contract to induce a gas price increase +// const largeGasLimit = uint64(8_000_000) + +// // TODO(marun) What is the significance of this value? +// gasTip := big.NewInt(1000 * params.GWei) + +// ginkgo.It("should ensure that the gas price is affected by load", func() { +// ginkgo.By("creating a new private network to ensure isolation from other tests") +// privateNetwork := e2e.Env.NewPrivateNetwork() + +// ginkgo.By("allocating a pre-funded key") +// key := privateNetwork.GetConfig().FundedKeys[0] +// ethAddress := evm.GetEthAddress(key) + +// ginkgo.By("initializing a coreth client") +// node := privateNetwork.GetNodes()[0] +// nodeURI := testnet.NodeURI{ +// NodeID: node.GetID(), +// URI: node.GetProcessContext().URI, +// } +// ethClient := e2e.NewEthClient(nodeURI) + +// ginkgo.By("initializing a transaction signer") +// cChainID, err := ethClient.ChainID(e2e.DefaultContext()) +// require.NoError(err) +// signer := types.NewEIP155Signer(cChainID) +// ecdsaKey := key.ToECDSA() +// sign := func(tx *types.Transaction) *types.Transaction { +// signedTx, err := types.SignTx(tx, signer, ecdsaKey) +// require.NoError(err) +// return signedTx +// } + +// var contractAddress common.Address +// ginkgo.By("deploying an expensive contract", func() { +// // Create transaction +// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) +// require.NoError(err) +// compiledContract := common.Hex2Bytes(hashingCompiledContract) +// tx := types.NewTx(&types.LegacyTx{ +// Nonce: nonce, +// GasPrice: gasTip, +// Gas: largeGasLimit, +// Value: common.Big0, +// Data: compiledContract, +// }) + +// // Send the transaction and wait for acceptance +// signedTx := sign(tx) +// receipt := e2e.SendEthTransaction(ethClient, signedTx) + +// contractAddress = receipt.ContractAddress +// }) + +// var gasPrice *big.Int +// ginkgo.By("calling the expensive contract repeatedly until a gas price increase is detected", func() { +// // Evaluate the bytes representation of the contract +// hashingABI, err := abi.JSON(strings.NewReader(hashingABIJson)) +// require.NoError(err) +// contractData, err := hashingABI.Pack("hashIt") +// require.NoError(err) + +// var initialGasPrice *big.Int +// e2e.Eventually(func() bool { +// // Check the gas price +// var err error +// gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) +// require.NoError(err) +// if initialGasPrice == nil { +// initialGasPrice = gasPrice +// tests.Outf("{{blue}}initial gas price is %v{{/}}\n", initialGasPrice) +// } else if gasPrice.Cmp(initialGasPrice) > 0 { +// // Gas price has increased +// tests.Outf("{{blue}}gas price has increased to %v{{/}}\n", gasPrice) +// return true +// } + +// // Create the transaction +// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) +// require.NoError(err) +// tx := types.NewTx(&types.LegacyTx{ +// Nonce: nonce, +// GasPrice: gasTip, +// Gas: largeGasLimit, +// To: &contractAddress, +// Value: common.Big0, +// Data: contractData, +// }) + +// // Send the transaction and wait for acceptance +// signedTx := sign(tx) +// _ = e2e.SendEthTransaction(ethClient, signedTx) + +// // The gas price will be checked at the start of the next iteration +// return false +// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price increase before timeout") +// }) + +// ginkgo.By("waiting for the gas price to decrease...", func() { +// initialGasPrice := gasPrice +// e2e.Eventually(func() bool { +// var err error +// gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) +// require.NoError(err) +// tests.Outf("{{blue}}.{{/}}") +// return initialGasPrice.Cmp(gasPrice) > 0 +// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price decrease before timeout") +// tests.Outf("\n{{blue}}gas price has decreased to %v{{/}}\n", gasPrice) +// }) + +// ginkgo.By("sending funds at the current gas price", func() { +// // Create a recipient address +// recipientKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) +// recipientEthAddress := evm.GetEthAddress(recipientKey) + +// // Create transaction +// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) +// require.NoError(err) +// tx := types.NewTx(&types.LegacyTx{ +// Nonce: nonce, +// GasPrice: gasPrice, +// Gas: e2e.DefaultGasLimit, +// To: &recipientEthAddress, +// Value: common.Big0, +// }) + +// // Send the transaction and wait for acceptance +// signedTx := sign(tx) +// _ = e2e.SendEthTransaction(ethClient, signedTx) +// }) + +// e2e.CheckBootstrapIsPossible(privateNetwork) +// }) +// }) diff --git a/tests/e2e/c/interchain_workflow.go b/tests/e2e/c/interchain_workflow.go index 2c9bd198ec39..c5af17c750bf 100644 --- a/tests/e2e/c/interchain_workflow.go +++ b/tests/e2e/c/interchain_workflow.go @@ -3,163 +3,163 @@ package c -import ( - "math/big" - - ginkgo "github.com/onsi/ginkgo/v2" - - "github.com/stretchr/testify/require" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/plugin/evm" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var _ = e2e.DescribeCChain("[Interchain Workflow]", func() { - require := require.New(ginkgo.GinkgoT()) - - const txAmount = 10 * units.Avax // Arbitrary amount to send and transfer - - ginkgo.It("should ensure that funds can be transferred from the C-Chain to the X-Chain and the P-Chain", func() { - ginkgo.By("initializing a new eth client") - // Select a random node URI to use for both the eth client and - // the wallet to avoid having to verify that all nodes are at - // the same height before initializing the wallet. - nodeURI := e2e.Env.GetRandomNodeURI() - ethClient := e2e.NewEthClient(nodeURI) - - ginkgo.By("allocating a pre-funded key to send from and a recipient key to deliver to") - senderKey := e2e.Env.AllocateFundedKey() - senderEthAddress := evm.GetEthAddress(senderKey) - recipientKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - recipientEthAddress := evm.GetEthAddress(recipientKey) - - ginkgo.By("sending funds from one address to another on the C-Chain", func() { - // Create transaction - acceptedNonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), senderEthAddress) - require.NoError(err) - gasPrice := e2e.SuggestGasPrice(ethClient) - tx := types.NewTransaction( - acceptedNonce, - recipientEthAddress, - big.NewInt(int64(txAmount)), - e2e.DefaultGasLimit, - gasPrice, - nil, - ) - - // Sign transaction - cChainID, err := ethClient.ChainID(e2e.DefaultContext()) - require.NoError(err) - signer := types.NewEIP155Signer(cChainID) - signedTx, err := types.SignTx(tx, signer, senderKey.ToECDSA()) - require.NoError(err) - - _ = e2e.SendEthTransaction(ethClient, signedTx) - - ginkgo.By("waiting for the C-Chain recipient address to have received the sent funds") - e2e.Eventually(func() bool { - balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) - require.NoError(err) - return balance.Cmp(big.NewInt(0)) > 0 - }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see funds delivered before timeout") - }) - - // Wallet must be initialized after sending funds on the - // C-Chain with the same node URI to ensure wallet state - // matches on-chain state. - ginkgo.By("initializing a keychain and associated wallet") - keychain := secp256k1fx.NewKeychain(senderKey, recipientKey) - baseWallet := e2e.NewWallet(keychain, nodeURI) - xWallet := baseWallet.X() - cWallet := baseWallet.C() - pWallet := baseWallet.P() - - ginkgo.By("defining common configuration") - avaxAssetID := xWallet.AVAXAssetID() - // Use the same owner for import funds to X-Chain and P-Chain - recipientOwner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - recipientKey.Address(), - }, - } - // Use the same outputs for both X-Chain and P-Chain exports - exportOutputs := []*secp256k1fx.TransferOutput{ - { - Amt: txAmount, - OutputOwners: secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - keychain.Keys[0].Address(), - }, - }, - }, - } - - ginkgo.By("exporting AVAX from the C-Chain to the X-Chain", func() { - _, err := cWallet.IssueExportTx( - xWallet.BlockchainID(), - exportOutputs, - e2e.WithDefaultContext(), - e2e.WithSuggestedGasPrice(ethClient), - ) - require.NoError(err) - }) - - ginkgo.By("importing AVAX from the C-Chain to the X-Chain", func() { - _, err := xWallet.IssueImportTx( - cWallet.BlockchainID(), - &recipientOwner, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { - balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - ginkgo.By("exporting AVAX from the C-Chain to the P-Chain", func() { - _, err := cWallet.IssueExportTx( - constants.PlatformChainID, - exportOutputs, - e2e.WithDefaultContext(), - e2e.WithSuggestedGasPrice(ethClient), - ) - require.NoError(err) - }) - - ginkgo.By("importing AVAX from the C-Chain to the P-Chain", func() { - _, err = pWallet.IssueImportTx( - cWallet.BlockchainID(), - &recipientOwner, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { - balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) - }) -}) +// import ( +// "math/big" + +// ginkgo "github.com/onsi/ginkgo/v2" + +// "github.com/stretchr/testify/require" + +// "github.com/ava-labs/coreth/core/types" +// "github.com/ava-labs/coreth/plugin/evm" + +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/tests/e2e" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var _ = e2e.DescribeCChain("[Interchain Workflow]", func() { +// require := require.New(ginkgo.GinkgoT()) + +// const txAmount = 10 * units.Avax // Arbitrary amount to send and transfer + +// ginkgo.It("should ensure that funds can be transferred from the C-Chain to the X-Chain and the P-Chain", func() { +// ginkgo.By("initializing a new eth client") +// // Select a random node URI to use for both the eth client and +// // the wallet to avoid having to verify that all nodes are at +// // the same height before initializing the wallet. +// nodeURI := e2e.Env.GetRandomNodeURI() +// ethClient := e2e.NewEthClient(nodeURI) + +// ginkgo.By("allocating a pre-funded key to send from and a recipient key to deliver to") +// senderKey := e2e.Env.AllocateFundedKey() +// senderEthAddress := evm.GetEthAddress(senderKey) +// recipientKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) +// recipientEthAddress := evm.GetEthAddress(recipientKey) + +// ginkgo.By("sending funds from one address to another on the C-Chain", func() { +// // Create transaction +// acceptedNonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), senderEthAddress) +// require.NoError(err) +// gasPrice := e2e.SuggestGasPrice(ethClient) +// tx := types.NewTransaction( +// acceptedNonce, +// recipientEthAddress, +// big.NewInt(int64(txAmount)), +// e2e.DefaultGasLimit, +// gasPrice, +// nil, +// ) + +// // Sign transaction +// cChainID, err := ethClient.ChainID(e2e.DefaultContext()) +// require.NoError(err) +// signer := types.NewEIP155Signer(cChainID) +// signedTx, err := types.SignTx(tx, signer, senderKey.ToECDSA()) +// require.NoError(err) + +// _ = e2e.SendEthTransaction(ethClient, signedTx) + +// ginkgo.By("waiting for the C-Chain recipient address to have received the sent funds") +// e2e.Eventually(func() bool { +// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) +// require.NoError(err) +// return balance.Cmp(big.NewInt(0)) > 0 +// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see funds delivered before timeout") +// }) + +// // Wallet must be initialized after sending funds on the +// // C-Chain with the same node URI to ensure wallet state +// // matches on-chain state. +// ginkgo.By("initializing a keychain and associated wallet") +// keychain := secp256k1fx.NewKeychain(senderKey, recipientKey) +// baseWallet := e2e.NewWallet(keychain, nodeURI) +// xWallet := baseWallet.X() +// cWallet := baseWallet.C() +// pWallet := baseWallet.P() + +// ginkgo.By("defining common configuration") +// avaxAssetID := xWallet.AVAXAssetID() +// // Use the same owner for import funds to X-Chain and P-Chain +// recipientOwner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// recipientKey.Address(), +// }, +// } +// // Use the same outputs for both X-Chain and P-Chain exports +// exportOutputs := []*secp256k1fx.TransferOutput{ +// { +// Amt: txAmount, +// OutputOwners: secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// keychain.Keys[0].Address(), +// }, +// }, +// }, +// } + +// ginkgo.By("exporting AVAX from the C-Chain to the X-Chain", func() { +// _, err := cWallet.IssueExportTx( +// xWallet.BlockchainID(), +// exportOutputs, +// e2e.WithDefaultContext(), +// e2e.WithSuggestedGasPrice(ethClient), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("importing AVAX from the C-Chain to the X-Chain", func() { +// _, err := xWallet.IssueImportTx( +// cWallet.BlockchainID(), +// &recipientOwner, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { +// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// ginkgo.By("exporting AVAX from the C-Chain to the P-Chain", func() { +// _, err := cWallet.IssueExportTx( +// constants.PlatformChainID, +// exportOutputs, +// e2e.WithDefaultContext(), +// e2e.WithSuggestedGasPrice(ethClient), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("importing AVAX from the C-Chain to the P-Chain", func() { +// _, err = pWallet.IssueImportTx( +// cWallet.BlockchainID(), +// &recipientOwner, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { +// balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) +// }) +// }) diff --git a/tests/e2e/p/interchain_workflow.go b/tests/e2e/p/interchain_workflow.go index 44a6912715ef..e90e0382e286 100644 --- a/tests/e2e/p/interchain_workflow.go +++ b/tests/e2e/p/interchain_workflow.go @@ -3,225 +3,225 @@ package p -import ( - "math/big" - "time" - - ginkgo "github.com/onsi/ginkgo/v2" - - "github.com/spf13/cast" - - "github.com/stretchr/testify/require" - - "github.com/ava-labs/coreth/plugin/evm" - - "github.com/ava-labs/avalanchego/api/info" - "github.com/ava-labs/avalanchego/config" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/tests/fixture/testnet" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/platformvm/reward" - "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { - require := require.New(ginkgo.GinkgoT()) - - const ( - transferAmount = 10 * units.Avax - weight = 2_000 * units.Avax // Used for both validation and delegation - ) - - ginkgo.It("should ensure that funds can be transferred from the P-Chain to the X-Chain and the C-Chain", func() { - network := e2e.Env.GetNetwork() - - ginkgo.By("checking that the network has a compatible minimum stake duration", func() { - minStakeDuration := cast.ToDuration(network.GetConfig().DefaultFlags[config.MinStakeDurationKey]) - require.Equal(testnet.DefaultMinStakeDuration, minStakeDuration) - }) - - ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") - recipientKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - keychain := e2e.Env.NewKeychain(1) - keychain.Add(recipientKey) - nodeURI := e2e.Env.GetRandomNodeURI() - baseWallet := e2e.NewWallet(keychain, nodeURI) - xWallet := baseWallet.X() - cWallet := baseWallet.C() - pWallet := baseWallet.P() - - ginkgo.By("defining common configuration") - recipientEthAddress := evm.GetEthAddress(recipientKey) - avaxAssetID := xWallet.AVAXAssetID() - // Use the same owner for sending to X-Chain and importing funds to P-Chain - recipientOwner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - recipientKey.Address(), - }, - } - // Use the same outputs for both X-Chain and C-Chain exports - exportOutputs := []*avax.TransferableOutput{ - { - Asset: avax.Asset{ - ID: avaxAssetID, - }, - Out: &secp256k1fx.TransferOutput{ - Amt: transferAmount, - OutputOwners: secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - keychain.Keys[0].Address(), - }, - }, - }, - }, - } - - ginkgo.By("adding new node and waiting for it to report healthy") - node := e2e.AddEphemeralNode(network, testnet.FlagsMap{}) - e2e.WaitForHealthy(node) - - ginkgo.By("retrieving new node's id and pop") - infoClient := info.NewClient(node.GetProcessContext().URI) - nodeID, nodePOP, err := infoClient.GetNodeID(e2e.DefaultContext()) - require.NoError(err) - - ginkgo.By("adding the new node as a validator", func() { - startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) - // Validation duration doesn't actually matter to this - // test - it is only ensuring that adding a validator - // doesn't break interchain transfer. - endTime := startTime.Add(30 * time.Second) - - rewardKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - - const ( - delegationPercent = 0.10 // 10% - delegationShare = reward.PercentDenominator * delegationPercent - ) - - _, err = pWallet.IssueAddPermissionlessValidatorTx( - &txs.SubnetValidator{ - Validator: txs.Validator{ - NodeID: nodeID, - Start: uint64(startTime.Unix()), - End: uint64(endTime.Unix()), - Wght: weight, - }, - Subnet: constants.PrimaryNetworkID, - }, - nodePOP, - pWallet.AVAXAssetID(), - &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{rewardKey.Address()}, - }, - &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{rewardKey.Address()}, - }, - delegationShare, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("adding a delegator to the new node", func() { - startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) - // Delegation duration doesn't actually matter to this - // test - it is only ensuring that adding a delegator - // doesn't break interchain transfer. - endTime := startTime.Add(15 * time.Second) - - rewardKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - - _, err = pWallet.IssueAddPermissionlessDelegatorTx( - &txs.SubnetValidator{ - Validator: txs.Validator{ - NodeID: nodeID, - Start: uint64(startTime.Unix()), - End: uint64(endTime.Unix()), - Wght: weight, - }, - Subnet: constants.PrimaryNetworkID, - }, - pWallet.AVAXAssetID(), - &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{rewardKey.Address()}, - }, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("exporting AVAX from the P-Chain to the X-Chain", func() { - _, err := pWallet.IssueExportTx( - xWallet.BlockchainID(), - exportOutputs, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("importing AVAX from the P-Chain to the X-Chain", func() { - _, err := xWallet.IssueImportTx( - constants.PlatformChainID, - &recipientOwner, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { - balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - ginkgo.By("exporting AVAX from the P-Chain to the C-Chain", func() { - _, err := pWallet.IssueExportTx( - cWallet.BlockchainID(), - exportOutputs, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("initializing a new eth client") - ethClient := e2e.NewEthClient(nodeURI) - - ginkgo.By("importing AVAX from the P-Chain to the C-Chain", func() { - _, err := cWallet.IssueImportTx( - constants.PlatformChainID, - recipientEthAddress, - e2e.WithDefaultContext(), - e2e.WithSuggestedGasPrice(ethClient), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") - balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) - require.NoError(err) - require.Positive(balance.Cmp(big.NewInt(0))) - - ginkgo.By("stopping validator node to free up resources for a bootstrap check") - require.NoError(node.Stop()) - - e2e.CheckBootstrapIsPossible(network) - }) -}) +// import ( +// "math/big" +// "time" + +// ginkgo "github.com/onsi/ginkgo/v2" + +// "github.com/spf13/cast" + +// "github.com/stretchr/testify/require" + +// "github.com/ava-labs/coreth/plugin/evm" + +// "github.com/ava-labs/avalanchego/api/info" +// "github.com/ava-labs/avalanchego/config" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/tests/e2e" +// "github.com/ava-labs/avalanchego/tests/fixture/testnet" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/platformvm/reward" +// "github.com/ava-labs/avalanchego/vms/platformvm/txs" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { +// require := require.New(ginkgo.GinkgoT()) + +// const ( +// transferAmount = 10 * units.Avax +// weight = 2_000 * units.Avax // Used for both validation and delegation +// ) + +// ginkgo.It("should ensure that funds can be transferred from the P-Chain to the X-Chain and the C-Chain", func() { +// network := e2e.Env.GetNetwork() + +// ginkgo.By("checking that the network has a compatible minimum stake duration", func() { +// minStakeDuration := cast.ToDuration(network.GetConfig().DefaultFlags[config.MinStakeDurationKey]) +// require.Equal(testnet.DefaultMinStakeDuration, minStakeDuration) +// }) + +// ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") +// recipientKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) +// keychain := e2e.Env.NewKeychain(1) +// keychain.Add(recipientKey) +// nodeURI := e2e.Env.GetRandomNodeURI() +// baseWallet := e2e.Env.NewWallet(keychain, nodeURI) +// xWallet := baseWallet.X() +// cWallet := baseWallet.C() +// pWallet := baseWallet.P() + +// ginkgo.By("defining common configuration") +// recipientEthAddress := evm.GetEthAddress(recipientKey) +// avaxAssetID := xWallet.AVAXAssetID() +// // Use the same owner for sending to X-Chain and importing funds to P-Chain +// recipientOwner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// recipientKey.Address(), +// }, +// } +// // Use the same outputs for both X-Chain and C-Chain exports +// exportOutputs := []*avax.TransferableOutput{ +// { +// Asset: avax.Asset{ +// ID: avaxAssetID, +// }, +// Out: &secp256k1fx.TransferOutput{ +// Amt: transferAmount, +// OutputOwners: secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// keychain.Keys[0].Address(), +// }, +// }, +// }, +// }, +// } + +// ginkgo.By("adding new node and waiting for it to report healthy") +// node := e2e.AddEphemeralNode(network, testnet.FlagsMap{}) +// e2e.WaitForHealthy(node) + +// ginkgo.By("retrieving new node's id and pop") +// infoClient := info.NewClient(node.GetProcessContext().URI) +// nodeID, nodePOP, err := infoClient.GetNodeID(e2e.DefaultContext()) +// require.NoError(err) + +// ginkgo.By("adding the new node as a validator", func() { +// startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) +// // Validation duration doesn't actually matter to this +// // test - it is only ensuring that adding a validator +// // doesn't break interchain transfer. +// endTime := startTime.Add(30 * time.Second) + +// rewardKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) + +// const ( +// delegationPercent = 0.10 // 10% +// delegationShare = reward.PercentDenominator * delegationPercent +// ) + +// _, err = pWallet.IssueAddPermissionlessValidatorTx( +// &txs.SubnetValidator{ +// Validator: txs.Validator{ +// NodeID: nodeID, +// Start: uint64(startTime.Unix()), +// End: uint64(endTime.Unix()), +// Wght: weight, +// }, +// Subnet: constants.PrimaryNetworkID, +// }, +// nodePOP, +// pWallet.AVAXAssetID(), +// &secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{rewardKey.Address()}, +// }, +// &secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{rewardKey.Address()}, +// }, +// delegationShare, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("adding a delegator to the new node", func() { +// startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) +// // Delegation duration doesn't actually matter to this +// // test - it is only ensuring that adding a delegator +// // doesn't break interchain transfer. +// endTime := startTime.Add(15 * time.Second) + +// rewardKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) + +// _, err = pWallet.IssueAddPermissionlessDelegatorTx( +// &txs.SubnetValidator{ +// Validator: txs.Validator{ +// NodeID: nodeID, +// Start: uint64(startTime.Unix()), +// End: uint64(endTime.Unix()), +// Wght: weight, +// }, +// Subnet: constants.PrimaryNetworkID, +// }, +// pWallet.AVAXAssetID(), +// &secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{rewardKey.Address()}, +// }, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("exporting AVAX from the P-Chain to the X-Chain", func() { +// _, err := pWallet.IssueExportTx( +// xWallet.BlockchainID(), +// exportOutputs, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("importing AVAX from the P-Chain to the X-Chain", func() { +// _, err := xWallet.IssueImportTx( +// constants.PlatformChainID, +// &recipientOwner, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { +// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// ginkgo.By("exporting AVAX from the P-Chain to the C-Chain", func() { +// _, err := pWallet.IssueExportTx( +// cWallet.BlockchainID(), +// exportOutputs, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("initializing a new eth client") +// ethClient := e2e.NewEthClient(nodeURI) + +// ginkgo.By("importing AVAX from the P-Chain to the C-Chain", func() { +// _, err := cWallet.IssueImportTx( +// constants.PlatformChainID, +// recipientEthAddress, +// e2e.WithDefaultContext(), +// e2e.WithSuggestedGasPrice(ethClient), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") +// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) +// require.NoError(err) +// require.Positive(balance.Cmp(big.NewInt(0))) + +// ginkgo.By("stopping validator node to free up resources for a bootstrap check") +// require.NoError(node.Stop()) + +// e2e.CheckBootstrapIsPossible(network) +// }) +// }) diff --git a/tests/e2e/x/interchain_workflow.go b/tests/e2e/x/interchain_workflow.go index f0c2951feb84..d738e55a7f7a 100644 --- a/tests/e2e/x/interchain_workflow.go +++ b/tests/e2e/x/interchain_workflow.go @@ -3,151 +3,151 @@ package x -import ( - "math/big" - - ginkgo "github.com/onsi/ginkgo/v2" - - "github.com/stretchr/testify/require" - - "github.com/ava-labs/coreth/plugin/evm" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var _ = e2e.DescribeXChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { - require := require.New(ginkgo.GinkgoT()) - - const transferAmount = 10 * units.Avax - - ginkgo.It("should ensure that funds can be transferred from the X-Chain to the C-Chain and the P-Chain", func() { - nodeURI := e2e.Env.GetRandomNodeURI() - - ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") - recipientKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - keychain := e2e.Env.NewKeychain(1) - keychain.Add(recipientKey) - baseWallet := e2e.NewWallet(keychain, nodeURI) - xWallet := baseWallet.X() - cWallet := baseWallet.C() - pWallet := baseWallet.P() - - ginkgo.By("defining common configuration") - recipientEthAddress := evm.GetEthAddress(recipientKey) - avaxAssetID := xWallet.AVAXAssetID() - // Use the same owner for sending to X-Chain and importing funds to P-Chain - recipientOwner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - recipientKey.Address(), - }, - } - // Use the same outputs for both C-Chain and P-Chain exports - exportOutputs := []*avax.TransferableOutput{ - { - Asset: avax.Asset{ - ID: avaxAssetID, - }, - Out: &secp256k1fx.TransferOutput{ - Amt: transferAmount, - OutputOwners: secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - keychain.Keys[0].Address(), - }, - }, - }, - }, - } - - ginkgo.By("sending funds from one address to another on the X-Chain", func() { - _, err = xWallet.IssueBaseTx( - []*avax.TransferableOutput{{ - Asset: avax.Asset{ - ID: avaxAssetID, - }, - Out: &secp256k1fx.TransferOutput{ - Amt: transferAmount, - OutputOwners: recipientOwner, - }, - }}, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the X-Chain recipient address has received the sent funds", func() { - balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - ginkgo.By("exporting AVAX from the X-Chain to the C-Chain", func() { - _, err := xWallet.IssueExportTx( - cWallet.BlockchainID(), - exportOutputs, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("initializing a new eth client") - ethClient := e2e.NewEthClient(nodeURI) - - ginkgo.By("importing AVAX from the X-Chain to the C-Chain", func() { - _, err := cWallet.IssueImportTx( - xWallet.BlockchainID(), - recipientEthAddress, - e2e.WithDefaultContext(), - e2e.WithSuggestedGasPrice(ethClient), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") - e2e.Eventually(func() bool { - balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) - require.NoError(err) - return balance.Cmp(big.NewInt(0)) > 0 - }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see recipient address funded before timeout") - - ginkgo.By("exporting AVAX from the X-Chain to the P-Chain", func() { - _, err := xWallet.IssueExportTx( - constants.PlatformChainID, - exportOutputs, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("importing AVAX from the X-Chain to the P-Chain", func() { - _, err := pWallet.IssueImportTx( - xWallet.BlockchainID(), - &recipientOwner, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { - balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) - }) -}) +// import ( +// "math/big" + +// ginkgo "github.com/onsi/ginkgo/v2" + +// "github.com/stretchr/testify/require" + +// "github.com/ava-labs/coreth/plugin/evm" + +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/tests/e2e" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var _ = e2e.DescribeXChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { +// require := require.New(ginkgo.GinkgoT()) + +// const transferAmount = 10 * units.Avax + +// ginkgo.It("should ensure that funds can be transferred from the X-Chain to the C-Chain and the P-Chain", func() { +// nodeURI := e2e.Env.GetRandomNodeURI() + +// ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") +// recipientKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) +// keychain := e2e.Env.NewKeychain(1) +// keychain.Add(recipientKey) +// baseWallet := e2e.Env.NewWallet(keychain, nodeURI) +// xWallet := baseWallet.X() +// cWallet := baseWallet.C() +// pWallet := baseWallet.P() + +// ginkgo.By("defining common configuration") +// recipientEthAddress := evm.GetEthAddress(recipientKey) +// avaxAssetID := xWallet.AVAXAssetID() +// // Use the same owner for sending to X-Chain and importing funds to P-Chain +// recipientOwner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// recipientKey.Address(), +// }, +// } +// // Use the same outputs for both C-Chain and P-Chain exports +// exportOutputs := []*avax.TransferableOutput{ +// { +// Asset: avax.Asset{ +// ID: avaxAssetID, +// }, +// Out: &secp256k1fx.TransferOutput{ +// Amt: transferAmount, +// OutputOwners: secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// keychain.Keys[0].Address(), +// }, +// }, +// }, +// }, +// } + +// ginkgo.By("sending funds from one address to another on the X-Chain", func() { +// _, err = xWallet.IssueBaseTx( +// []*avax.TransferableOutput{{ +// Asset: avax.Asset{ +// ID: avaxAssetID, +// }, +// Out: &secp256k1fx.TransferOutput{ +// Amt: transferAmount, +// OutputOwners: recipientOwner, +// }, +// }}, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the X-Chain recipient address has received the sent funds", func() { +// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// ginkgo.By("exporting AVAX from the X-Chain to the C-Chain", func() { +// _, err := xWallet.IssueExportTx( +// cWallet.BlockchainID(), +// exportOutputs, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("initializing a new eth client") +// ethClient := e2e.NewEthClient(nodeURI) + +// ginkgo.By("importing AVAX from the X-Chain to the C-Chain", func() { +// _, err := cWallet.IssueImportTx( +// xWallet.BlockchainID(), +// recipientEthAddress, +// e2e.WithDefaultContext(), +// e2e.WithSuggestedGasPrice(ethClient), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") +// e2e.Eventually(func() bool { +// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) +// require.NoError(err) +// return balance.Cmp(big.NewInt(0)) > 0 +// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see recipient address funded before timeout") + +// ginkgo.By("exporting AVAX from the X-Chain to the P-Chain", func() { +// _, err := xWallet.IssueExportTx( +// constants.PlatformChainID, +// exportOutputs, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("importing AVAX from the X-Chain to the P-Chain", func() { +// _, err := pWallet.IssueImportTx( +// xWallet.BlockchainID(), +// &recipientOwner, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { +// balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) +// }) +// }) diff --git a/tests/fixture/e2e/helpers.go b/tests/fixture/e2e/helpers.go index 15da611324e0..8e497cf398c0 100644 --- a/tests/fixture/e2e/helpers.go +++ b/tests/fixture/e2e/helpers.go @@ -5,20 +5,23 @@ package e2e import ( "context" - "errors" - "fmt" - "math/big" + + // "errors" + // "fmt" + // "math/big" + "os" - "strings" + + // "strings" "time" ginkgo "github.com/onsi/ginkgo/v2" "github.com/stretchr/testify/require" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/ethclient" - "github.com/ava-labs/coreth/interfaces" + // "github.com/ava-labs/coreth/core/types" + // "github.com/ava-labs/coreth/ethclient" + // "github.com/ava-labs/coreth/interfaces" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/tests" @@ -67,7 +70,7 @@ func NewWallet(keychain *secp256k1fx.Keychain, nodeURI testnet.NodeURI) primary. baseWallet, err := primary.MakeWallet(DefaultContext(), &primary.WalletConfig{ URI: nodeURI.URI, AVAXKeychain: keychain, - EthKeychain: keychain, + // EthKeychain: keychain, }) require.NoError(ginkgo.GinkgoT(), err) return primary.NewWalletWithOptions( @@ -80,15 +83,15 @@ func NewWallet(keychain *secp256k1fx.Keychain, nodeURI testnet.NodeURI) primary. ) } -// Create a new eth client targeting the specified node URI. -func NewEthClient(nodeURI testnet.NodeURI) ethclient.Client { - tests.Outf("{{blue}} initializing a new eth client for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) - nodeAddress := strings.Split(nodeURI.URI, "//")[1] - uri := fmt.Sprintf("ws://%s/ext/bc/C/ws", nodeAddress) - client, err := ethclient.Dial(uri) - require.NoError(ginkgo.GinkgoT(), err) - return client -} +// // Create a new eth client targeting the specified node URI. +// func NewEthClient(nodeURI testnet.NodeURI) ethclient.Client { +// tests.Outf("{{blue}} initializing a new eth client for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) +// nodeAddress := strings.Split(nodeURI.URI, "//")[1] +// uri := fmt.Sprintf("ws://%s/ext/bc/C/ws", nodeAddress) +// client, err := ethclient.Dial(uri) +// require.NoError(ginkgo.GinkgoT(), err) +// return client +// } // Helper simplifying use of a timed context by canceling the context on ginkgo teardown. func ContextWithTimeout(duration time.Duration) context.Context { @@ -152,49 +155,49 @@ func WaitForHealthy(node testnet.Node) { require.NoError(ginkgo.GinkgoT(), testnet.WaitForHealthy(ctx, node)) } -// Sends an eth transaction, waits for the transaction receipt to be issued -// and checks that the receipt indicates success. -func SendEthTransaction(ethClient ethclient.Client, signedTx *types.Transaction) *types.Receipt { - require := require.New(ginkgo.GinkgoT()) - - txID := signedTx.Hash() - tests.Outf(" sending eth transaction with ID: %s\n", txID) - - require.NoError(ethClient.SendTransaction(DefaultContext(), signedTx)) - - // Wait for the receipt - var receipt *types.Receipt - Eventually(func() bool { - var err error - receipt, err = ethClient.TransactionReceipt(DefaultContext(), txID) - if errors.Is(err, interfaces.NotFound) { - return false // Transaction is still pending - } - require.NoError(err) - return true - }, DefaultTimeout, DefaultPollingInterval, "failed to see transaction acceptance before timeout") - - require.Equal(receipt.Status, types.ReceiptStatusSuccessful) - return receipt -} - -// Determines the suggested gas price for the configured client that will -// maximize the chances of transaction acceptance. -func SuggestGasPrice(ethClient ethclient.Client) *big.Int { - gasPrice, err := ethClient.SuggestGasPrice(DefaultContext()) - require.NoError(ginkgo.GinkgoT(), err) - // Double the suggested gas price to maximize the chances of - // acceptance. Maybe this can be revisited pending resolution of - // https://github.com/ava-labs/coreth/issues/314. - gasPrice.Add(gasPrice, gasPrice) - return gasPrice -} - -// Helper simplifying use via an option of a gas price appropriate for testing. -func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { - baseFee := SuggestGasPrice(ethClient) - return common.WithBaseFee(baseFee) -} +// // Sends an eth transaction, waits for the transaction receipt to be issued +// // and checks that the receipt indicates success. +// func SendEthTransaction(ethClient ethclient.Client, signedTx *types.Transaction) *types.Receipt { +// require := require.New(ginkgo.GinkgoT()) + +// txID := signedTx.Hash() +// tests.Outf(" sending eth transaction with ID: %s\n", txID) + +// require.NoError(ethClient.SendTransaction(DefaultContext(), signedTx)) + +// // Wait for the receipt +// var receipt *types.Receipt +// Eventually(func() bool { +// var err error +// receipt, err = ethClient.TransactionReceipt(DefaultContext(), txID) +// if errors.Is(err, interfaces.NotFound) { +// return false // Transaction is still pending +// } +// require.NoError(err) +// return true +// }, DefaultTimeout, DefaultPollingInterval, "failed to see transaction acceptance before timeout") + +// require.Equal(receipt.Status, types.ReceiptStatusSuccessful) +// return receipt +// } + +// // Determines the suggested gas price for the configured client that will +// // maximize the chances of transaction acceptance. +// func SuggestGasPrice(ethClient ethclient.Client) *big.Int { +// gasPrice, err := ethClient.SuggestGasPrice(DefaultContext()) +// require.NoError(ginkgo.GinkgoT(), err) +// // Double the suggested gas price to maximize the chances of +// // acceptance. Maybe this can be revisited pending resolution of +// // https://github.com/ava-labs/coreth/issues/314. +// gasPrice.Add(gasPrice, gasPrice) +// return gasPrice +// } + +// // Helper simplifying use via an option of a gas price appropriate for testing. +// func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { +// baseFee := SuggestGasPrice(ethClient) +// return common.WithBaseFee(baseFee) +// } // Verify that a new node can bootstrap into the network. func CheckBootstrapIsPossible(network testnet.Network) { diff --git a/tests/fixture/testnet/config.go b/tests/fixture/testnet/config.go index 425aa646a690..c2e27bbff116 100644 --- a/tests/fixture/testnet/config.go +++ b/tests/fixture/testnet/config.go @@ -15,9 +15,9 @@ import ( "github.com/spf13/cast" - "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/plugin/evm" + // "github.com/ava-labs/coreth/core" + // "github.com/ava-labs/coreth/params" + // "github.com/ava-labs/coreth/plugin/evm" "github.com/ava-labs/avalanchego/config" "github.com/ava-labs/avalanchego/genesis" @@ -143,15 +143,15 @@ func (c *NetworkConfig) EnsureGenesis(networkID uint32, validatorIDs []ids.NodeI // Ensure pre-funded keys have arbitrary large balances on both chains to support testing xChainBalances := make(XChainBalanceMap, len(c.FundedKeys)) - cChainBalances := make(core.GenesisAlloc, len(c.FundedKeys)) - for _, key := range c.FundedKeys { - xChainBalances[key.Address()] = DefaultFundedKeyXChainAmount - cChainBalances[evm.GetEthAddress(key)] = core.GenesisAccount{ - Balance: DefaultFundedKeyCChainAmount, - } - } - - genesis, err := NewTestGenesis(networkID, xChainBalances, cChainBalances, validatorIDs) + // cChainBalances := make(core.GenesisAlloc, len(c.FundedKeys)) + // for _, key := range c.FundedKeys { + // xChainBalances[key.Address()] = DefaultFundedKeyXChainAmount + // cChainBalances[evm.GetEthAddress(key)] = core.GenesisAccount{ + // Balance: DefaultFundedKeyCChainAmount, + // } + // } + + genesis, err := NewTestGenesis(networkID, xChainBalances /*, cChainBalances*/, validatorIDs) if err != nil { return err } @@ -311,7 +311,7 @@ type XChainBalanceMap map[ids.ShortID]uint64 func NewTestGenesis( networkID uint32, xChainBalances XChainBalanceMap, - cChainBalances core.GenesisAlloc, + // cChainBalances core.GenesisAlloc, validatorIDs []ids.NodeID, ) (*genesis.UnparsedConfig, error) { // Validate inputs @@ -322,7 +322,7 @@ func NewTestGenesis( if len(validatorIDs) == 0 { return nil, errMissingValidatorsForGenesis } - if len(xChainBalances) == 0 || len(cChainBalances) == 0 { + if len(xChainBalances) == 0 /*|| len(cChainBalances) == 0*/ { return nil, errMissingBalancesForGenesis } @@ -394,20 +394,20 @@ func NewTestGenesis( ) } - // Define C-Chain genesis - cChainGenesis := &core.Genesis{ - Config: ¶ms.ChainConfig{ - ChainID: big.NewInt(43112), // Arbitrary chain ID is arbitrary - }, - Difficulty: big.NewInt(0), // Difficulty is a mandatory field - GasLimit: DefaultGasLimit, - Alloc: cChainBalances, - } - cChainGenesisBytes, err := json.Marshal(cChainGenesis) - if err != nil { - return nil, fmt.Errorf("failed to marshal C-Chain genesis: %w", err) - } - config.CChainGenesis = string(cChainGenesisBytes) + // // Define C-Chain genesis + // cChainGenesis := &core.Genesis{ + // Config: ¶ms.ChainConfig{ + // ChainID: big.NewInt(43112), // Arbitrary chain ID is arbitrary + // }, + // Difficulty: big.NewInt(0), // Difficulty is a mandatory field + // GasLimit: DefaultGasLimit, + // Alloc: cChainBalances, + // } + // cChainGenesisBytes, err := json.Marshal(cChainGenesis) + // if err != nil { + // return nil, fmt.Errorf("failed to marshal C-Chain genesis: %w", err) + // } + // config.CChainGenesis = string(cChainGenesisBytes) // Give staking rewards for initial validators to a random address. Any testing of staking rewards // will be easier to perform with nodes other than the initial validators since the timing of diff --git a/vms/example/xsvm/cmd/chain/create/cmd.go b/vms/example/xsvm/cmd/chain/create/cmd.go index 1f00491a4ce6..043b4298dcdf 100644 --- a/vms/example/xsvm/cmd/chain/create/cmd.go +++ b/vms/example/xsvm/cmd/chain/create/cmd.go @@ -42,9 +42,9 @@ func createFunc(c *cobra.Command, args []string) error { // that [uri] is hosting. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: config.URI, - AVAXKeychain: kc, - EthKeychain: kc, + URI: config.URI, + AVAXKeychain: kc, + // EthKeychain: kc, PChainTxsToFetch: set.Of(config.SubnetID), }) if err != nil { diff --git a/wallet/chain/c/backend.go b/wallet/chain/c/backend.go index 0a735116b646..b88c8c643bc3 100644 --- a/wallet/chain/c/backend.go +++ b/wallet/chain/c/backend.go @@ -3,153 +3,153 @@ package c -import ( - "errors" - "fmt" - "math/big" - "sync" - - stdcontext "context" - - "github.com/ava-labs/coreth/plugin/evm" - - ethcommon "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/avalanchego/database" - "github.com/ava-labs/avalanchego/utils/math" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var ( - _ Backend = (*backend)(nil) - - errUnknownTxType = errors.New("unknown tx type") -) - -// Backend defines the full interface required to support a C-chain wallet. -type Backend interface { - common.ChainUTXOs - BuilderBackend - SignerBackend - - AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error -} - -type backend struct { - Context - common.ChainUTXOs - - accountsLock sync.RWMutex - accounts map[ethcommon.Address]*Account -} - -type Account struct { - Balance *big.Int - Nonce uint64 -} - -func NewBackend( - ctx Context, - utxos common.ChainUTXOs, - accounts map[ethcommon.Address]*Account, -) Backend { - return &backend{ - Context: ctx, - ChainUTXOs: utxos, - accounts: accounts, - } -} - -func (b *backend) AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error { - switch tx := tx.UnsignedAtomicTx.(type) { - case *evm.UnsignedImportTx: - for _, input := range tx.ImportedInputs { - utxoID := input.InputID() - if err := b.RemoveUTXO(ctx, tx.SourceChain, utxoID); err != nil { - return err - } - } - - b.accountsLock.Lock() - defer b.accountsLock.Unlock() - - for _, output := range tx.Outs { - account, ok := b.accounts[output.Address] - if !ok { - continue - } - - balance := new(big.Int).SetUint64(output.Amount) - balance.Mul(balance, avaxConversionRate) - account.Balance.Add(account.Balance, balance) - } - case *evm.UnsignedExportTx: - txID := tx.ID() - for i, out := range tx.ExportedOutputs { - err := b.AddUTXO( - ctx, - tx.DestinationChain, - &avax.UTXO{ - UTXOID: avax.UTXOID{ - TxID: txID, - OutputIndex: uint32(i), - }, - Asset: avax.Asset{ID: out.AssetID()}, - Out: out.Out, - }, - ) - if err != nil { - return err - } - } - - b.accountsLock.Lock() - defer b.accountsLock.Unlock() - - for _, input := range tx.Ins { - account, ok := b.accounts[input.Address] - if !ok { - continue - } - - balance := new(big.Int).SetUint64(input.Amount) - balance.Mul(balance, avaxConversionRate) - if account.Balance.Cmp(balance) == -1 { - return errInsufficientFunds - } - account.Balance.Sub(account.Balance, balance) - - newNonce, err := math.Add64(input.Nonce, 1) - if err != nil { - return err - } - account.Nonce = newNonce - } - default: - return fmt.Errorf("%w: %T", errUnknownTxType, tx) - } - return nil -} - -func (b *backend) Balance(_ stdcontext.Context, addr ethcommon.Address) (*big.Int, error) { - b.accountsLock.RLock() - defer b.accountsLock.RUnlock() - - account, exists := b.accounts[addr] - if !exists { - return nil, database.ErrNotFound - } - return account.Balance, nil -} - -func (b *backend) Nonce(_ stdcontext.Context, addr ethcommon.Address) (uint64, error) { - b.accountsLock.RLock() - defer b.accountsLock.RUnlock() - - account, exists := b.accounts[addr] - if !exists { - return 0, database.ErrNotFound - } - return account.Nonce, nil -} +// import ( +// "errors" +// "fmt" +// "math/big" +// "sync" + +// stdcontext "context" + +// "github.com/ava-labs/coreth/plugin/evm" + +// ethcommon "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/avalanchego/database" +// "github.com/ava-labs/avalanchego/utils/math" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var ( +// _ Backend = (*backend)(nil) + +// errUnknownTxType = errors.New("unknown tx type") +// ) + +// // Backend defines the full interface required to support a C-chain wallet. +// type Backend interface { +// common.ChainUTXOs +// BuilderBackend +// SignerBackend + +// AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error +// } + +// type backend struct { +// Context +// common.ChainUTXOs + +// accountsLock sync.RWMutex +// accounts map[ethcommon.Address]*Account +// } + +// type Account struct { +// Balance *big.Int +// Nonce uint64 +// } + +// func NewBackend( +// ctx Context, +// utxos common.ChainUTXOs, +// accounts map[ethcommon.Address]*Account, +// ) Backend { +// return &backend{ +// Context: ctx, +// ChainUTXOs: utxos, +// accounts: accounts, +// } +// } + +// func (b *backend) AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error { +// switch tx := tx.UnsignedAtomicTx.(type) { +// case *evm.UnsignedImportTx: +// for _, input := range tx.ImportedInputs { +// utxoID := input.InputID() +// if err := b.RemoveUTXO(ctx, tx.SourceChain, utxoID); err != nil { +// return err +// } +// } + +// b.accountsLock.Lock() +// defer b.accountsLock.Unlock() + +// for _, output := range tx.Outs { +// account, ok := b.accounts[output.Address] +// if !ok { +// continue +// } + +// balance := new(big.Int).SetUint64(output.Amount) +// balance.Mul(balance, avaxConversionRate) +// account.Balance.Add(account.Balance, balance) +// } +// case *evm.UnsignedExportTx: +// txID := tx.ID() +// for i, out := range tx.ExportedOutputs { +// err := b.AddUTXO( +// ctx, +// tx.DestinationChain, +// &avax.UTXO{ +// UTXOID: avax.UTXOID{ +// TxID: txID, +// OutputIndex: uint32(i), +// }, +// Asset: avax.Asset{ID: out.AssetID()}, +// Out: out.Out, +// }, +// ) +// if err != nil { +// return err +// } +// } + +// b.accountsLock.Lock() +// defer b.accountsLock.Unlock() + +// for _, input := range tx.Ins { +// account, ok := b.accounts[input.Address] +// if !ok { +// continue +// } + +// balance := new(big.Int).SetUint64(input.Amount) +// balance.Mul(balance, avaxConversionRate) +// if account.Balance.Cmp(balance) == -1 { +// return errInsufficientFunds +// } +// account.Balance.Sub(account.Balance, balance) + +// newNonce, err := math.Add64(input.Nonce, 1) +// if err != nil { +// return err +// } +// account.Nonce = newNonce +// } +// default: +// return fmt.Errorf("%w: %T", errUnknownTxType, tx) +// } +// return nil +// } + +// func (b *backend) Balance(_ stdcontext.Context, addr ethcommon.Address) (*big.Int, error) { +// b.accountsLock.RLock() +// defer b.accountsLock.RUnlock() + +// account, exists := b.accounts[addr] +// if !exists { +// return nil, database.ErrNotFound +// } +// return account.Balance, nil +// } + +// func (b *backend) Nonce(_ stdcontext.Context, addr ethcommon.Address) (uint64, error) { +// b.accountsLock.RLock() +// defer b.accountsLock.RUnlock() + +// account, exists := b.accounts[addr] +// if !exists { +// return 0, database.ErrNotFound +// } +// return account.Nonce, nil +// } diff --git a/wallet/chain/c/builder.go b/wallet/chain/c/builder.go index d2d088e88a53..c51d2647777e 100644 --- a/wallet/chain/c/builder.go +++ b/wallet/chain/c/builder.go @@ -3,399 +3,399 @@ package c -import ( - "errors" - "math/big" - - stdcontext "context" - - "github.com/ava-labs/coreth/plugin/evm" - - ethcommon "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils" - "github.com/ava-labs/avalanchego/utils/math" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -const avaxConversionRateInt = 1_000_000_000 - -var ( - _ Builder = (*builder)(nil) - - errInsufficientFunds = errors.New("insufficient funds") - - // avaxConversionRate is the conversion rate between the smallest - // denomination on the X-Chain and P-chain, 1 nAVAX, and the smallest - // denomination on the C-Chain 1 wei. Where 1 nAVAX = 1 gWei. - // - // This is only required for AVAX because the denomination of 1 AVAX is 9 - // decimal places on the X and P chains, but is 18 decimal places within the - // EVM. - avaxConversionRate = big.NewInt(avaxConversionRateInt) -) - -// Builder provides a convenient interface for building unsigned C-chain -// transactions. -type Builder interface { - // GetBalance calculates the amount of AVAX that this builder has control - // over. - GetBalance( - options ...common.Option, - ) (*big.Int, error) - - // GetImportableBalance calculates the amount of AVAX that this builder - // could import from the provided chain. - // - // - [chainID] specifies the chain the funds are from. - GetImportableBalance( - chainID ids.ID, - options ...common.Option, - ) (uint64, error) - - // NewImportTx creates an import transaction that attempts to consume all - // the available UTXOs and import the funds to [to]. - // - // - [chainID] specifies the chain to be importing funds from. - // - [to] specifies where to send the imported funds to. - // - [baseFee] specifies the fee price willing to be paid by this tx. - NewImportTx( - chainID ids.ID, - to ethcommon.Address, - baseFee *big.Int, - options ...common.Option, - ) (*evm.UnsignedImportTx, error) - - // NewExportTx creates an export transaction that attempts to send all the - // provided [outputs] to the requested [chainID]. - // - // - [chainID] specifies the chain to be exporting the funds to. - // - [outputs] specifies the outputs to send to the [chainID]. - // - [baseFee] specifies the fee price willing to be paid by this tx. - NewExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - baseFee *big.Int, - options ...common.Option, - ) (*evm.UnsignedExportTx, error) -} - -// BuilderBackend specifies the required information needed to build unsigned -// C-chain transactions. -type BuilderBackend interface { - Context - - UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) - Balance(ctx stdcontext.Context, addr ethcommon.Address) (*big.Int, error) - Nonce(ctx stdcontext.Context, addr ethcommon.Address) (uint64, error) -} - -type builder struct { - avaxAddrs set.Set[ids.ShortID] - ethAddrs set.Set[ethcommon.Address] - backend BuilderBackend -} - -// NewBuilder returns a new transaction builder. -// -// - [avaxAddrs] is the set of addresses in the AVAX format that the builder -// assumes can be used when signing the transactions in the future. -// - [ethAddrs] is the set of addresses in the Eth format that the builder -// assumes can be used when signing the transactions in the future. -// - [backend] provides the required access to the chain's context and state -// to build out the transactions. -func NewBuilder( - avaxAddrs set.Set[ids.ShortID], - ethAddrs set.Set[ethcommon.Address], - backend BuilderBackend, -) Builder { - return &builder{ - avaxAddrs: avaxAddrs, - ethAddrs: ethAddrs, - backend: backend, - } -} - -func (b *builder) GetBalance( - options ...common.Option, -) (*big.Int, error) { - var ( - ops = common.NewOptions(options) - ctx = ops.Context() - addrs = ops.EthAddresses(b.ethAddrs) - totalBalance = new(big.Int) - ) - for addr := range addrs { - balance, err := b.backend.Balance(ctx, addr) - if err != nil { - return nil, err - } - totalBalance.Add(totalBalance, balance) - } - - return totalBalance, nil -} - -func (b *builder) GetImportableBalance( - chainID ids.ID, - options ...common.Option, -) (uint64, error) { - ops := common.NewOptions(options) - utxos, err := b.backend.UTXOs(ops.Context(), chainID) - if err != nil { - return 0, err - } - - var ( - addrs = ops.Addresses(b.avaxAddrs) - minIssuanceTime = ops.MinIssuanceTime() - avaxAssetID = b.backend.AVAXAssetID() - balance uint64 - ) - for _, utxo := range utxos { - amount, _, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) - if !ok { - continue - } - - newBalance, err := math.Add64(balance, amount) - if err != nil { - return 0, err - } - balance = newBalance - } - - return balance, nil -} - -func (b *builder) NewImportTx( - chainID ids.ID, - to ethcommon.Address, - baseFee *big.Int, - options ...common.Option, -) (*evm.UnsignedImportTx, error) { - ops := common.NewOptions(options) - utxos, err := b.backend.UTXOs(ops.Context(), chainID) - if err != nil { - return nil, err - } - - var ( - addrs = ops.Addresses(b.avaxAddrs) - minIssuanceTime = ops.MinIssuanceTime() - avaxAssetID = b.backend.AVAXAssetID() - - importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) - importedAmount uint64 - ) - for _, utxo := range utxos { - amount, inputSigIndices, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) - if !ok { - continue - } - - importedInputs = append(importedInputs, &avax.TransferableInput{ - UTXOID: utxo.UTXOID, - Asset: utxo.Asset, - In: &secp256k1fx.TransferInput{ - Amt: amount, - Input: secp256k1fx.Input{ - SigIndices: inputSigIndices, - }, - }, - }) - - newImportedAmount, err := math.Add64(importedAmount, amount) - if err != nil { - return nil, err - } - importedAmount = newImportedAmount - } - - utils.Sort(importedInputs) - tx := &evm.UnsignedImportTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: b.backend.BlockchainID(), - SourceChain: chainID, - ImportedInputs: importedInputs, - } - - // We must initialize the bytes of the tx to calculate the initial cost - wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} - if err := wrappedTx.Sign(evm.Codec, nil); err != nil { - return nil, err - } - - gasUsedWithoutOutput, err := tx.GasUsed(true /*=IsApricotPhase5*/) - if err != nil { - return nil, err - } - gasUsedWithOutput := gasUsedWithoutOutput + evm.EVMOutputGas - - txFee, err := evm.CalculateDynamicFee(gasUsedWithOutput, baseFee) - if err != nil { - return nil, err - } - - if importedAmount <= txFee { - return nil, errInsufficientFunds - } - - tx.Outs = []evm.EVMOutput{{ - Address: to, - Amount: importedAmount - txFee, - AssetID: avaxAssetID, - }} - return tx, nil -} - -func (b *builder) NewExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - baseFee *big.Int, - options ...common.Option, -) (*evm.UnsignedExportTx, error) { - var ( - avaxAssetID = b.backend.AVAXAssetID() - exportedOutputs = make([]*avax.TransferableOutput, len(outputs)) - exportedAmount uint64 - ) - for i, output := range outputs { - exportedOutputs[i] = &avax.TransferableOutput{ - Asset: avax.Asset{ID: avaxAssetID}, - Out: output, - } - - newExportedAmount, err := math.Add64(exportedAmount, output.Amt) - if err != nil { - return nil, err - } - exportedAmount = newExportedAmount - } - - avax.SortTransferableOutputs(exportedOutputs, evm.Codec) - tx := &evm.UnsignedExportTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: b.backend.BlockchainID(), - DestinationChain: chainID, - ExportedOutputs: exportedOutputs, - } - - // We must initialize the bytes of the tx to calculate the initial cost - wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} - if err := wrappedTx.Sign(evm.Codec, nil); err != nil { - return nil, err - } - - cost, err := tx.GasUsed(true /*=IsApricotPhase5*/) - if err != nil { - return nil, err - } - - initialFee, err := evm.CalculateDynamicFee(cost, baseFee) - if err != nil { - return nil, err - } - - amountToConsume, err := math.Add64(exportedAmount, initialFee) - if err != nil { - return nil, err - } - - var ( - ops = common.NewOptions(options) - ctx = ops.Context() - addrs = ops.EthAddresses(b.ethAddrs) - inputs = make([]evm.EVMInput, 0, addrs.Len()) - ) - for addr := range addrs { - if amountToConsume == 0 { - break - } - - prevFee, err := evm.CalculateDynamicFee(cost, baseFee) - if err != nil { - return nil, err - } - - newCost := cost + evm.EVMInputGas - newFee, err := evm.CalculateDynamicFee(newCost, baseFee) - if err != nil { - return nil, err - } - - additionalFee := newFee - prevFee - - balance, err := b.backend.Balance(ctx, addr) - if err != nil { - return nil, err - } - - // Since the asset is AVAX, we divide by the avaxConversionRate to - // convert back to the correct denomination of AVAX that can be - // exported. - avaxBalance := new(big.Int).Div(balance, avaxConversionRate).Uint64() - - // If the balance for [addr] is insufficient to cover the additional - // cost of adding an input to the transaction, skip adding the input - // altogether. - if avaxBalance <= additionalFee { - continue - } - - // Update the cost for the next iteration - cost = newCost - - amountToConsume, err = math.Add64(amountToConsume, additionalFee) - if err != nil { - return nil, err - } - - nonce, err := b.backend.Nonce(ctx, addr) - if err != nil { - return nil, err - } - - inputAmount := math.Min(amountToConsume, avaxBalance) - inputs = append(inputs, evm.EVMInput{ - Address: addr, - Amount: inputAmount, - AssetID: avaxAssetID, - Nonce: nonce, - }) - amountToConsume -= inputAmount - } - - if amountToConsume > 0 { - return nil, errInsufficientFunds - } - - utils.Sort(inputs) - tx.Ins = inputs - return tx, nil -} - -func getSpendableAmount( - utxo *avax.UTXO, - addrs set.Set[ids.ShortID], - minIssuanceTime uint64, - avaxAssetID ids.ID, -) (uint64, []uint32, bool) { - if utxo.Asset.ID != avaxAssetID { - // Only AVAX can be imported - return 0, nil, false - } - - out, ok := utxo.Out.(*secp256k1fx.TransferOutput) - if !ok { - // Can't import an unknown transfer output type - return 0, nil, false - } - - inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) - return out.Amt, inputSigIndices, ok -} +// import ( +// "errors" +// "math/big" + +// stdcontext "context" + +// "github.com/ava-labs/coreth/plugin/evm" + +// ethcommon "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/utils" +// "github.com/ava-labs/avalanchego/utils/math" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// const avaxConversionRateInt = 1_000_000_000 + +// var ( +// _ Builder = (*builder)(nil) + +// errInsufficientFunds = errors.New("insufficient funds") + +// // avaxConversionRate is the conversion rate between the smallest +// // denomination on the X-Chain and P-chain, 1 nAVAX, and the smallest +// // denomination on the C-Chain 1 wei. Where 1 nAVAX = 1 gWei. +// // +// // This is only required for AVAX because the denomination of 1 AVAX is 9 +// // decimal places on the X and P chains, but is 18 decimal places within the +// // EVM. +// avaxConversionRate = big.NewInt(avaxConversionRateInt) +// ) + +// // Builder provides a convenient interface for building unsigned C-chain +// // transactions. +// type Builder interface { +// // GetBalance calculates the amount of AVAX that this builder has control +// // over. +// GetBalance( +// options ...common.Option, +// ) (*big.Int, error) + +// // GetImportableBalance calculates the amount of AVAX that this builder +// // could import from the provided chain. +// // +// // - [chainID] specifies the chain the funds are from. +// GetImportableBalance( +// chainID ids.ID, +// options ...common.Option, +// ) (uint64, error) + +// // NewImportTx creates an import transaction that attempts to consume all +// // the available UTXOs and import the funds to [to]. +// // +// // - [chainID] specifies the chain to be importing funds from. +// // - [to] specifies where to send the imported funds to. +// // - [baseFee] specifies the fee price willing to be paid by this tx. +// NewImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedImportTx, error) + +// // NewExportTx creates an export transaction that attempts to send all the +// // provided [outputs] to the requested [chainID]. +// // +// // - [chainID] specifies the chain to be exporting the funds to. +// // - [outputs] specifies the outputs to send to the [chainID]. +// // - [baseFee] specifies the fee price willing to be paid by this tx. +// NewExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedExportTx, error) +// } + +// // BuilderBackend specifies the required information needed to build unsigned +// // C-chain transactions. +// type BuilderBackend interface { +// Context + +// UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) +// Balance(ctx stdcontext.Context, addr ethcommon.Address) (*big.Int, error) +// Nonce(ctx stdcontext.Context, addr ethcommon.Address) (uint64, error) +// } + +// type builder struct { +// avaxAddrs set.Set[ids.ShortID] +// ethAddrs set.Set[ethcommon.Address] +// backend BuilderBackend +// } + +// // NewBuilder returns a new transaction builder. +// // +// // - [avaxAddrs] is the set of addresses in the AVAX format that the builder +// // assumes can be used when signing the transactions in the future. +// // - [ethAddrs] is the set of addresses in the Eth format that the builder +// // assumes can be used when signing the transactions in the future. +// // - [backend] provides the required access to the chain's context and state +// // to build out the transactions. +// func NewBuilder( +// avaxAddrs set.Set[ids.ShortID], +// ethAddrs set.Set[ethcommon.Address], +// backend BuilderBackend, +// ) Builder { +// return &builder{ +// avaxAddrs: avaxAddrs, +// ethAddrs: ethAddrs, +// backend: backend, +// } +// } + +// func (b *builder) GetBalance( +// options ...common.Option, +// ) (*big.Int, error) { +// var ( +// ops = common.NewOptions(options) +// ctx = ops.Context() +// addrs = ops.EthAddresses(b.ethAddrs) +// totalBalance = new(big.Int) +// ) +// for addr := range addrs { +// balance, err := b.backend.Balance(ctx, addr) +// if err != nil { +// return nil, err +// } +// totalBalance.Add(totalBalance, balance) +// } + +// return totalBalance, nil +// } + +// func (b *builder) GetImportableBalance( +// chainID ids.ID, +// options ...common.Option, +// ) (uint64, error) { +// ops := common.NewOptions(options) +// utxos, err := b.backend.UTXOs(ops.Context(), chainID) +// if err != nil { +// return 0, err +// } + +// var ( +// addrs = ops.Addresses(b.avaxAddrs) +// minIssuanceTime = ops.MinIssuanceTime() +// avaxAssetID = b.backend.AVAXAssetID() +// balance uint64 +// ) +// for _, utxo := range utxos { +// amount, _, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) +// if !ok { +// continue +// } + +// newBalance, err := math.Add64(balance, amount) +// if err != nil { +// return 0, err +// } +// balance = newBalance +// } + +// return balance, nil +// } + +// func (b *builder) NewImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedImportTx, error) { +// ops := common.NewOptions(options) +// utxos, err := b.backend.UTXOs(ops.Context(), chainID) +// if err != nil { +// return nil, err +// } + +// var ( +// addrs = ops.Addresses(b.avaxAddrs) +// minIssuanceTime = ops.MinIssuanceTime() +// avaxAssetID = b.backend.AVAXAssetID() + +// importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) +// importedAmount uint64 +// ) +// for _, utxo := range utxos { +// amount, inputSigIndices, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) +// if !ok { +// continue +// } + +// importedInputs = append(importedInputs, &avax.TransferableInput{ +// UTXOID: utxo.UTXOID, +// Asset: utxo.Asset, +// In: &secp256k1fx.TransferInput{ +// Amt: amount, +// Input: secp256k1fx.Input{ +// SigIndices: inputSigIndices, +// }, +// }, +// }) + +// newImportedAmount, err := math.Add64(importedAmount, amount) +// if err != nil { +// return nil, err +// } +// importedAmount = newImportedAmount +// } + +// utils.Sort(importedInputs) +// tx := &evm.UnsignedImportTx{ +// NetworkID: b.backend.NetworkID(), +// BlockchainID: b.backend.BlockchainID(), +// SourceChain: chainID, +// ImportedInputs: importedInputs, +// } + +// // We must initialize the bytes of the tx to calculate the initial cost +// wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} +// if err := wrappedTx.Sign(evm.Codec, nil); err != nil { +// return nil, err +// } + +// gasUsedWithoutOutput, err := tx.GasUsed(true /*=IsApricotPhase5*/) +// if err != nil { +// return nil, err +// } +// gasUsedWithOutput := gasUsedWithoutOutput + evm.EVMOutputGas + +// txFee, err := evm.CalculateDynamicFee(gasUsedWithOutput, baseFee) +// if err != nil { +// return nil, err +// } + +// if importedAmount <= txFee { +// return nil, errInsufficientFunds +// } + +// tx.Outs = []evm.EVMOutput{{ +// Address: to, +// Amount: importedAmount - txFee, +// AssetID: avaxAssetID, +// }} +// return tx, nil +// } + +// func (b *builder) NewExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedExportTx, error) { +// var ( +// avaxAssetID = b.backend.AVAXAssetID() +// exportedOutputs = make([]*avax.TransferableOutput, len(outputs)) +// exportedAmount uint64 +// ) +// for i, output := range outputs { +// exportedOutputs[i] = &avax.TransferableOutput{ +// Asset: avax.Asset{ID: avaxAssetID}, +// Out: output, +// } + +// newExportedAmount, err := math.Add64(exportedAmount, output.Amt) +// if err != nil { +// return nil, err +// } +// exportedAmount = newExportedAmount +// } + +// avax.SortTransferableOutputs(exportedOutputs, evm.Codec) +// tx := &evm.UnsignedExportTx{ +// NetworkID: b.backend.NetworkID(), +// BlockchainID: b.backend.BlockchainID(), +// DestinationChain: chainID, +// ExportedOutputs: exportedOutputs, +// } + +// // We must initialize the bytes of the tx to calculate the initial cost +// wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} +// if err := wrappedTx.Sign(evm.Codec, nil); err != nil { +// return nil, err +// } + +// cost, err := tx.GasUsed(true /*=IsApricotPhase5*/) +// if err != nil { +// return nil, err +// } + +// initialFee, err := evm.CalculateDynamicFee(cost, baseFee) +// if err != nil { +// return nil, err +// } + +// amountToConsume, err := math.Add64(exportedAmount, initialFee) +// if err != nil { +// return nil, err +// } + +// var ( +// ops = common.NewOptions(options) +// ctx = ops.Context() +// addrs = ops.EthAddresses(b.ethAddrs) +// inputs = make([]evm.EVMInput, 0, addrs.Len()) +// ) +// for addr := range addrs { +// if amountToConsume == 0 { +// break +// } + +// prevFee, err := evm.CalculateDynamicFee(cost, baseFee) +// if err != nil { +// return nil, err +// } + +// newCost := cost + evm.EVMInputGas +// newFee, err := evm.CalculateDynamicFee(newCost, baseFee) +// if err != nil { +// return nil, err +// } + +// additionalFee := newFee - prevFee + +// balance, err := b.backend.Balance(ctx, addr) +// if err != nil { +// return nil, err +// } + +// // Since the asset is AVAX, we divide by the avaxConversionRate to +// // convert back to the correct denomination of AVAX that can be +// // exported. +// avaxBalance := new(big.Int).Div(balance, avaxConversionRate).Uint64() + +// // If the balance for [addr] is insufficient to cover the additional +// // cost of adding an input to the transaction, skip adding the input +// // altogether. +// if avaxBalance <= additionalFee { +// continue +// } + +// // Update the cost for the next iteration +// cost = newCost + +// amountToConsume, err = math.Add64(amountToConsume, additionalFee) +// if err != nil { +// return nil, err +// } + +// nonce, err := b.backend.Nonce(ctx, addr) +// if err != nil { +// return nil, err +// } + +// inputAmount := math.Min(amountToConsume, avaxBalance) +// inputs = append(inputs, evm.EVMInput{ +// Address: addr, +// Amount: inputAmount, +// AssetID: avaxAssetID, +// Nonce: nonce, +// }) +// amountToConsume -= inputAmount +// } + +// if amountToConsume > 0 { +// return nil, errInsufficientFunds +// } + +// utils.Sort(inputs) +// tx.Ins = inputs +// return tx, nil +// } + +// func getSpendableAmount( +// utxo *avax.UTXO, +// addrs set.Set[ids.ShortID], +// minIssuanceTime uint64, +// avaxAssetID ids.ID, +// ) (uint64, []uint32, bool) { +// if utxo.Asset.ID != avaxAssetID { +// // Only AVAX can be imported +// return 0, nil, false +// } + +// out, ok := utxo.Out.(*secp256k1fx.TransferOutput) +// if !ok { +// // Can't import an unknown transfer output type +// return 0, nil, false +// } + +// inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) +// return out.Amt, inputSigIndices, ok +// } diff --git a/wallet/chain/c/builder_with_options.go b/wallet/chain/c/builder_with_options.go index 8416dddf9928..9b7ab8399484 100644 --- a/wallet/chain/c/builder_with_options.go +++ b/wallet/chain/c/builder_with_options.go @@ -3,81 +3,81 @@ package c -import ( - "math/big" +// import ( +// "math/big" - "github.com/ava-labs/coreth/plugin/evm" +// "github.com/ava-labs/coreth/plugin/evm" - ethcommon "github.com/ethereum/go-ethereum/common" +// ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) -var _ Builder = (*builderWithOptions)(nil) +// var _ Builder = (*builderWithOptions)(nil) -type builderWithOptions struct { - Builder - options []common.Option -} +// type builderWithOptions struct { +// Builder +// options []common.Option +// } -// NewBuilderWithOptions returns a new transaction builder that will use the -// given options by default. -// -// - [builder] is the builder that will be called to perform the underlying -// operations. -// - [options] will be provided to the builder in addition to the options -// provided in the method calls. -func NewBuilderWithOptions(builder Builder, options ...common.Option) Builder { - return &builderWithOptions{ - Builder: builder, - options: options, - } -} +// // NewBuilderWithOptions returns a new transaction builder that will use the +// // given options by default. +// // +// // - [builder] is the builder that will be called to perform the underlying +// // operations. +// // - [options] will be provided to the builder in addition to the options +// // provided in the method calls. +// func NewBuilderWithOptions(builder Builder, options ...common.Option) Builder { +// return &builderWithOptions{ +// Builder: builder, +// options: options, +// } +// } -func (b *builderWithOptions) GetBalance( - options ...common.Option, -) (*big.Int, error) { - return b.Builder.GetBalance( - common.UnionOptions(b.options, options)..., - ) -} +// func (b *builderWithOptions) GetBalance( +// options ...common.Option, +// ) (*big.Int, error) { +// return b.Builder.GetBalance( +// common.UnionOptions(b.options, options)..., +// ) +// } -func (b *builderWithOptions) GetImportableBalance( - chainID ids.ID, - options ...common.Option, -) (uint64, error) { - return b.Builder.GetImportableBalance( - chainID, - common.UnionOptions(b.options, options)..., - ) -} +// func (b *builderWithOptions) GetImportableBalance( +// chainID ids.ID, +// options ...common.Option, +// ) (uint64, error) { +// return b.Builder.GetImportableBalance( +// chainID, +// common.UnionOptions(b.options, options)..., +// ) +// } -func (b *builderWithOptions) NewImportTx( - chainID ids.ID, - to ethcommon.Address, - baseFee *big.Int, - options ...common.Option, -) (*evm.UnsignedImportTx, error) { - return b.Builder.NewImportTx( - chainID, - to, - baseFee, - common.UnionOptions(b.options, options)..., - ) -} +// func (b *builderWithOptions) NewImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedImportTx, error) { +// return b.Builder.NewImportTx( +// chainID, +// to, +// baseFee, +// common.UnionOptions(b.options, options)..., +// ) +// } -func (b *builderWithOptions) NewExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - baseFee *big.Int, - options ...common.Option, -) (*evm.UnsignedExportTx, error) { - return b.Builder.NewExportTx( - chainID, - outputs, - baseFee, - common.UnionOptions(b.options, options)..., - ) -} +// func (b *builderWithOptions) NewExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedExportTx, error) { +// return b.Builder.NewExportTx( +// chainID, +// outputs, +// baseFee, +// common.UnionOptions(b.options, options)..., +// ) +// } diff --git a/wallet/chain/c/context.go b/wallet/chain/c/context.go index d506b42f81fa..1c01d8fb55c8 100644 --- a/wallet/chain/c/context.go +++ b/wallet/chain/c/context.go @@ -3,81 +3,81 @@ package c -import ( - stdcontext "context" +// import ( +// stdcontext "context" - "github.com/ava-labs/avalanchego/api/info" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/avm" -) +// "github.com/ava-labs/avalanchego/api/info" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/vms/avm" +// ) -var _ Context = (*context)(nil) +// var _ Context = (*context)(nil) -type Context interface { - NetworkID() uint32 - BlockchainID() ids.ID - AVAXAssetID() ids.ID -} +// type Context interface { +// NetworkID() uint32 +// BlockchainID() ids.ID +// AVAXAssetID() ids.ID +// } -type context struct { - networkID uint32 - blockchainID ids.ID - avaxAssetID ids.ID -} +// type context struct { +// networkID uint32 +// blockchainID ids.ID +// avaxAssetID ids.ID +// } -func NewContextFromURI(ctx stdcontext.Context, uri string) (Context, error) { - infoClient := info.NewClient(uri) - xChainClient := avm.NewClient(uri, "X") - return NewContextFromClients(ctx, infoClient, xChainClient) -} +// func NewContextFromURI(ctx stdcontext.Context, uri string) (Context, error) { +// infoClient := info.NewClient(uri) +// xChainClient := avm.NewClient(uri, "X") +// return NewContextFromClients(ctx, infoClient, xChainClient) +// } -func NewContextFromClients( - ctx stdcontext.Context, - infoClient info.Client, - xChainClient avm.Client, -) (Context, error) { - networkID, err := infoClient.GetNetworkID(ctx) - if err != nil { - return nil, err - } +// func NewContextFromClients( +// ctx stdcontext.Context, +// infoClient info.Client, +// xChainClient avm.Client, +// ) (Context, error) { +// networkID, err := infoClient.GetNetworkID(ctx) +// if err != nil { +// return nil, err +// } - chainID, err := infoClient.GetBlockchainID(ctx, "C") - if err != nil { - return nil, err - } +// chainID, err := infoClient.GetBlockchainID(ctx, "C") +// if err != nil { +// return nil, err +// } - asset, err := xChainClient.GetAssetDescription(ctx, "AVAX") - if err != nil { - return nil, err - } +// asset, err := xChainClient.GetAssetDescription(ctx, "AVAX") +// if err != nil { +// return nil, err +// } - return NewContext( - networkID, - chainID, - asset.AssetID, - ), nil -} +// return NewContext( +// networkID, +// chainID, +// asset.AssetID, +// ), nil +// } -func NewContext( - networkID uint32, - blockchainID ids.ID, - avaxAssetID ids.ID, -) Context { - return &context{ - networkID: networkID, - blockchainID: blockchainID, - avaxAssetID: avaxAssetID, - } -} +// func NewContext( +// networkID uint32, +// blockchainID ids.ID, +// avaxAssetID ids.ID, +// ) Context { +// return &context{ +// networkID: networkID, +// blockchainID: blockchainID, +// avaxAssetID: avaxAssetID, +// } +// } -func (c *context) NetworkID() uint32 { - return c.networkID -} +// func (c *context) NetworkID() uint32 { +// return c.networkID +// } -func (c *context) BlockchainID() ids.ID { - return c.blockchainID -} +// func (c *context) BlockchainID() ids.ID { +// return c.blockchainID +// } -func (c *context) AVAXAssetID() ids.ID { - return c.avaxAssetID -} +// func (c *context) AVAXAssetID() ids.ID { +// return c.avaxAssetID +// } diff --git a/wallet/chain/c/signer.go b/wallet/chain/c/signer.go index 4fd85ed3b532..4bedc378234b 100644 --- a/wallet/chain/c/signer.go +++ b/wallet/chain/c/signer.go @@ -3,221 +3,221 @@ package c -import ( - "errors" - "fmt" - - stdcontext "context" - - "github.com/ava-labs/coreth/plugin/evm" - - ethcommon "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/avalanchego/database" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/crypto/keychain" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/hashing" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/components/verify" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" -) - -const version = 0 - -var ( - _ Signer = (*txSigner)(nil) - - errUnknownInputType = errors.New("unknown input type") - errUnknownCredentialType = errors.New("unknown credential type") - errUnknownOutputType = errors.New("unknown output type") - errInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") - - emptySig [secp256k1.SignatureLen]byte -) - -type Signer interface { - SignUnsignedAtomic(ctx stdcontext.Context, tx evm.UnsignedAtomicTx) (*evm.Tx, error) - SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error -} - -type EthKeychain interface { - // The returned Signer can provide a signature for [addr] - GetEth(addr ethcommon.Address) (keychain.Signer, bool) - // Returns the set of addresses for which the accessor keeps an associated - // signer - EthAddresses() set.Set[ethcommon.Address] -} - -type SignerBackend interface { - GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) -} - -type txSigner struct { - avaxKC keychain.Keychain - ethKC EthKeychain - backend SignerBackend -} - -func NewSigner(avaxKC keychain.Keychain, ethKC EthKeychain, backend SignerBackend) Signer { - return &txSigner{ - avaxKC: avaxKC, - ethKC: ethKC, - backend: backend, - } -} - -func (s *txSigner) SignUnsignedAtomic(ctx stdcontext.Context, utx evm.UnsignedAtomicTx) (*evm.Tx, error) { - tx := &evm.Tx{UnsignedAtomicTx: utx} - return tx, s.SignAtomic(ctx, tx) -} - -func (s *txSigner) SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error { - switch utx := tx.UnsignedAtomicTx.(type) { - case *evm.UnsignedImportTx: - signers, err := s.getImportSigners(ctx, utx.SourceChain, utx.ImportedInputs) - if err != nil { - return err - } - return sign(tx, true, signers) - case *evm.UnsignedExportTx: - signers := s.getExportSigners(utx.Ins) - return sign(tx, true, signers) - default: - return fmt.Errorf("%w: %T", errUnknownTxType, tx) - } -} - -func (s *txSigner) getImportSigners(ctx stdcontext.Context, sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { - txSigners := make([][]keychain.Signer, len(ins)) - for credIndex, transferInput := range ins { - input, ok := transferInput.In.(*secp256k1fx.TransferInput) - if !ok { - return nil, errUnknownInputType - } - - inputSigners := make([]keychain.Signer, len(input.SigIndices)) - txSigners[credIndex] = inputSigners - - utxoID := transferInput.InputID() - utxo, err := s.backend.GetUTXO(ctx, sourceChainID, utxoID) - if err == database.ErrNotFound { - // If we don't have access to the UTXO, then we can't sign this - // transaction. However, we can attempt to partially sign it. - continue - } - if err != nil { - return nil, err - } - - out, ok := utxo.Out.(*secp256k1fx.TransferOutput) - if !ok { - return nil, errUnknownOutputType - } - - for sigIndex, addrIndex := range input.SigIndices { - if addrIndex >= uint32(len(out.Addrs)) { - return nil, errInvalidUTXOSigIndex - } - - addr := out.Addrs[addrIndex] - key, ok := s.avaxKC.Get(addr) - if !ok { - // If we don't have access to the key, then we can't sign this - // transaction. However, we can attempt to partially sign it. - continue - } - inputSigners[sigIndex] = key - } - } - return txSigners, nil -} - -func (s *txSigner) getExportSigners(ins []evm.EVMInput) [][]keychain.Signer { - txSigners := make([][]keychain.Signer, len(ins)) - for credIndex, input := range ins { - inputSigners := make([]keychain.Signer, 1) - txSigners[credIndex] = inputSigners - - key, ok := s.ethKC.GetEth(input.Address) - if !ok { - // If we don't have access to the key, then we can't sign this - // transaction. However, we can attempt to partially sign it. - continue - } - inputSigners[0] = key - } - return txSigners -} - -// TODO: remove [signHash] after the ledger supports signing all transactions. -func sign(tx *evm.Tx, signHash bool, txSigners [][]keychain.Signer) error { - unsignedBytes, err := evm.Codec.Marshal(version, &tx.UnsignedAtomicTx) - if err != nil { - return fmt.Errorf("couldn't marshal unsigned tx: %w", err) - } - unsignedHash := hashing.ComputeHash256(unsignedBytes) - - if expectedLen := len(txSigners); expectedLen != len(tx.Creds) { - tx.Creds = make([]verify.Verifiable, expectedLen) - } - - sigCache := make(map[ids.ShortID][secp256k1.SignatureLen]byte) - for credIndex, inputSigners := range txSigners { - credIntf := tx.Creds[credIndex] - if credIntf == nil { - credIntf = &secp256k1fx.Credential{} - tx.Creds[credIndex] = credIntf - } - - cred, ok := credIntf.(*secp256k1fx.Credential) - if !ok { - return errUnknownCredentialType - } - if expectedLen := len(inputSigners); expectedLen != len(cred.Sigs) { - cred.Sigs = make([][secp256k1.SignatureLen]byte, expectedLen) - } - - for sigIndex, signer := range inputSigners { - if signer == nil { - // If we don't have access to the key, then we can't sign this - // transaction. However, we can attempt to partially sign it. - continue - } - addr := signer.Address() - if sig := cred.Sigs[sigIndex]; sig != emptySig { - // If this signature has already been populated, we can just - // copy the needed signature for the future. - sigCache[addr] = sig - continue - } - - if sig, exists := sigCache[addr]; exists { - // If this key has already produced a signature, we can just - // copy the previous signature. - cred.Sigs[sigIndex] = sig - continue - } - - var sig []byte - if signHash { - sig, err = signer.SignHash(unsignedHash) - } else { - sig, err = signer.Sign(unsignedBytes) - } - if err != nil { - return fmt.Errorf("problem signing tx: %w", err) - } - copy(cred.Sigs[sigIndex][:], sig) - sigCache[addr] = cred.Sigs[sigIndex] - } - } - - signedBytes, err := evm.Codec.Marshal(version, tx) - if err != nil { - return fmt.Errorf("couldn't marshal tx: %w", err) - } - tx.Initialize(unsignedBytes, signedBytes) - return nil -} +// import ( +// "errors" +// "fmt" + +// stdcontext "context" + +// "github.com/ava-labs/coreth/plugin/evm" + +// ethcommon "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/avalanchego/database" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/utils/crypto/keychain" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// "github.com/ava-labs/avalanchego/utils/hashing" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/components/verify" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// ) + +// const version = 0 + +// var ( +// _ Signer = (*txSigner)(nil) + +// errUnknownInputType = errors.New("unknown input type") +// errUnknownCredentialType = errors.New("unknown credential type") +// errUnknownOutputType = errors.New("unknown output type") +// errInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") + +// emptySig [secp256k1.SignatureLen]byte +// ) + +// type Signer interface { +// SignUnsignedAtomic(ctx stdcontext.Context, tx evm.UnsignedAtomicTx) (*evm.Tx, error) +// SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error +// } + +// type EthKeychain interface { +// // The returned Signer can provide a signature for [addr] +// GetEth(addr ethcommon.Address) (keychain.Signer, bool) +// // Returns the set of addresses for which the accessor keeps an associated +// // signer +// EthAddresses() set.Set[ethcommon.Address] +// } + +// type SignerBackend interface { +// GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) +// } + +// type txSigner struct { +// avaxKC keychain.Keychain +// ethKC EthKeychain +// backend SignerBackend +// } + +// func NewSigner(avaxKC keychain.Keychain, ethKC EthKeychain, backend SignerBackend) Signer { +// return &txSigner{ +// avaxKC: avaxKC, +// ethKC: ethKC, +// backend: backend, +// } +// } + +// func (s *txSigner) SignUnsignedAtomic(ctx stdcontext.Context, utx evm.UnsignedAtomicTx) (*evm.Tx, error) { +// tx := &evm.Tx{UnsignedAtomicTx: utx} +// return tx, s.SignAtomic(ctx, tx) +// } + +// func (s *txSigner) SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error { +// switch utx := tx.UnsignedAtomicTx.(type) { +// case *evm.UnsignedImportTx: +// signers, err := s.getImportSigners(ctx, utx.SourceChain, utx.ImportedInputs) +// if err != nil { +// return err +// } +// return sign(tx, true, signers) +// case *evm.UnsignedExportTx: +// signers := s.getExportSigners(utx.Ins) +// return sign(tx, true, signers) +// default: +// return fmt.Errorf("%w: %T", errUnknownTxType, tx) +// } +// } + +// func (s *txSigner) getImportSigners(ctx stdcontext.Context, sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { +// txSigners := make([][]keychain.Signer, len(ins)) +// for credIndex, transferInput := range ins { +// input, ok := transferInput.In.(*secp256k1fx.TransferInput) +// if !ok { +// return nil, errUnknownInputType +// } + +// inputSigners := make([]keychain.Signer, len(input.SigIndices)) +// txSigners[credIndex] = inputSigners + +// utxoID := transferInput.InputID() +// utxo, err := s.backend.GetUTXO(ctx, sourceChainID, utxoID) +// if err == database.ErrNotFound { +// // If we don't have access to the UTXO, then we can't sign this +// // transaction. However, we can attempt to partially sign it. +// continue +// } +// if err != nil { +// return nil, err +// } + +// out, ok := utxo.Out.(*secp256k1fx.TransferOutput) +// if !ok { +// return nil, errUnknownOutputType +// } + +// for sigIndex, addrIndex := range input.SigIndices { +// if addrIndex >= uint32(len(out.Addrs)) { +// return nil, errInvalidUTXOSigIndex +// } + +// addr := out.Addrs[addrIndex] +// key, ok := s.avaxKC.Get(addr) +// if !ok { +// // If we don't have access to the key, then we can't sign this +// // transaction. However, we can attempt to partially sign it. +// continue +// } +// inputSigners[sigIndex] = key +// } +// } +// return txSigners, nil +// } + +// func (s *txSigner) getExportSigners(ins []evm.EVMInput) [][]keychain.Signer { +// txSigners := make([][]keychain.Signer, len(ins)) +// for credIndex, input := range ins { +// inputSigners := make([]keychain.Signer, 1) +// txSigners[credIndex] = inputSigners + +// key, ok := s.ethKC.GetEth(input.Address) +// if !ok { +// // If we don't have access to the key, then we can't sign this +// // transaction. However, we can attempt to partially sign it. +// continue +// } +// inputSigners[0] = key +// } +// return txSigners +// } + +// // TODO: remove [signHash] after the ledger supports signing all transactions. +// func sign(tx *evm.Tx, signHash bool, txSigners [][]keychain.Signer) error { +// unsignedBytes, err := evm.Codec.Marshal(version, &tx.UnsignedAtomicTx) +// if err != nil { +// return fmt.Errorf("couldn't marshal unsigned tx: %w", err) +// } +// unsignedHash := hashing.ComputeHash256(unsignedBytes) + +// if expectedLen := len(txSigners); expectedLen != len(tx.Creds) { +// tx.Creds = make([]verify.Verifiable, expectedLen) +// } + +// sigCache := make(map[ids.ShortID][secp256k1.SignatureLen]byte) +// for credIndex, inputSigners := range txSigners { +// credIntf := tx.Creds[credIndex] +// if credIntf == nil { +// credIntf = &secp256k1fx.Credential{} +// tx.Creds[credIndex] = credIntf +// } + +// cred, ok := credIntf.(*secp256k1fx.Credential) +// if !ok { +// return errUnknownCredentialType +// } +// if expectedLen := len(inputSigners); expectedLen != len(cred.Sigs) { +// cred.Sigs = make([][secp256k1.SignatureLen]byte, expectedLen) +// } + +// for sigIndex, signer := range inputSigners { +// if signer == nil { +// // If we don't have access to the key, then we can't sign this +// // transaction. However, we can attempt to partially sign it. +// continue +// } +// addr := signer.Address() +// if sig := cred.Sigs[sigIndex]; sig != emptySig { +// // If this signature has already been populated, we can just +// // copy the needed signature for the future. +// sigCache[addr] = sig +// continue +// } + +// if sig, exists := sigCache[addr]; exists { +// // If this key has already produced a signature, we can just +// // copy the previous signature. +// cred.Sigs[sigIndex] = sig +// continue +// } + +// var sig []byte +// if signHash { +// sig, err = signer.SignHash(unsignedHash) +// } else { +// sig, err = signer.Sign(unsignedBytes) +// } +// if err != nil { +// return fmt.Errorf("problem signing tx: %w", err) +// } +// copy(cred.Sigs[sigIndex][:], sig) +// sigCache[addr] = cred.Sigs[sigIndex] +// } +// } + +// signedBytes, err := evm.Codec.Marshal(version, tx) +// if err != nil { +// return fmt.Errorf("couldn't marshal tx: %w", err) +// } +// tx.Initialize(unsignedBytes, signedBytes) +// return nil +// } diff --git a/wallet/chain/c/wallet.go b/wallet/chain/c/wallet.go index fb1a83d53dad..ebee50a9a958 100644 --- a/wallet/chain/c/wallet.go +++ b/wallet/chain/c/wallet.go @@ -3,204 +3,204 @@ package c -import ( - "errors" - "math/big" - "time" - - "github.com/ava-labs/coreth/ethclient" - "github.com/ava-labs/coreth/plugin/evm" - - ethcommon "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var ( - _ Wallet = (*wallet)(nil) - - errNotCommitted = errors.New("not committed") -) - -type Wallet interface { - Context - - // Builder returns the builder that will be used to create the transactions. - Builder() Builder - - // Signer returns the signer that will be used to sign the transactions. - Signer() Signer - - // IssueImportTx creates, signs, and issues an import transaction that - // attempts to consume all the available UTXOs and import the funds to [to]. - // - // - [chainID] specifies the chain to be importing funds from. - // - [to] specifies where to send the imported funds to. - IssueImportTx( - chainID ids.ID, - to ethcommon.Address, - options ...common.Option, - ) (*evm.Tx, error) - - // IssueExportTx creates, signs, and issues an export transaction that - // attempts to send all the provided [outputs] to the requested [chainID]. - // - // - [chainID] specifies the chain to be exporting the funds to. - // - [outputs] specifies the outputs to send to the [chainID]. - IssueExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - options ...common.Option, - ) (*evm.Tx, error) - - // IssueUnsignedTx signs and issues the unsigned tx. - IssueUnsignedAtomicTx( - utx evm.UnsignedAtomicTx, - options ...common.Option, - ) (*evm.Tx, error) - - // IssueAtomicTx issues the signed tx. - IssueAtomicTx( - tx *evm.Tx, - options ...common.Option, - ) error -} - -func NewWallet( - builder Builder, - signer Signer, - avaxClient evm.Client, - ethClient ethclient.Client, - backend Backend, -) Wallet { - return &wallet{ - Backend: backend, - builder: builder, - signer: signer, - avaxClient: avaxClient, - ethClient: ethClient, - } -} - -type wallet struct { - Backend - builder Builder - signer Signer - avaxClient evm.Client - ethClient ethclient.Client -} - -func (w *wallet) Builder() Builder { - return w.builder -} - -func (w *wallet) Signer() Signer { - return w.signer -} - -func (w *wallet) IssueImportTx( - chainID ids.ID, - to ethcommon.Address, - options ...common.Option, -) (*evm.Tx, error) { - baseFee, err := w.baseFee(options) - if err != nil { - return nil, err - } - - utx, err := w.builder.NewImportTx(chainID, to, baseFee, options...) - if err != nil { - return nil, err - } - return w.IssueUnsignedAtomicTx(utx, options...) -} - -func (w *wallet) IssueExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - options ...common.Option, -) (*evm.Tx, error) { - baseFee, err := w.baseFee(options) - if err != nil { - return nil, err - } - - utx, err := w.builder.NewExportTx(chainID, outputs, baseFee, options...) - if err != nil { - return nil, err - } - return w.IssueUnsignedAtomicTx(utx, options...) -} - -func (w *wallet) IssueUnsignedAtomicTx( - utx evm.UnsignedAtomicTx, - options ...common.Option, -) (*evm.Tx, error) { - ops := common.NewOptions(options) - ctx := ops.Context() - tx, err := w.signer.SignUnsignedAtomic(ctx, utx) - if err != nil { - return nil, err - } - - return tx, w.IssueAtomicTx(tx, options...) -} - -func (w *wallet) IssueAtomicTx( - tx *evm.Tx, - options ...common.Option, -) error { - ops := common.NewOptions(options) - ctx := ops.Context() - txID, err := w.avaxClient.IssueTx(ctx, tx.SignedBytes()) - if err != nil { - return err - } - - if f := ops.PostIssuanceFunc(); f != nil { - f(txID) - } - - if ops.AssumeDecided() { - return w.Backend.AcceptAtomicTx(ctx, tx) - } - - pollFrequency := ops.PollFrequency() - ticker := time.NewTicker(pollFrequency) - defer ticker.Stop() - - for { - status, err := w.avaxClient.GetAtomicTxStatus(ctx, txID) - if err != nil { - return err - } - - switch status { - case evm.Accepted: - return w.Backend.AcceptAtomicTx(ctx, tx) - case evm.Dropped, evm.Unknown: - return errNotCommitted - } - - // The tx is Processing. - - select { - case <-ticker.C: - case <-ctx.Done(): - return ctx.Err() - } - } -} - -func (w *wallet) baseFee(options []common.Option) (*big.Int, error) { - ops := common.NewOptions(options) - baseFee := ops.BaseFee(nil) - if baseFee != nil { - return baseFee, nil - } - - ctx := ops.Context() - return w.ethClient.EstimateBaseFee(ctx) -} +// import ( +// "errors" +// "math/big" +// "time" + +// "github.com/ava-labs/coreth/ethclient" +// "github.com/ava-labs/coreth/plugin/evm" + +// ethcommon "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var ( +// _ Wallet = (*wallet)(nil) + +// errNotCommitted = errors.New("not committed") +// ) + +// type Wallet interface { +// Context + +// // Builder returns the builder that will be used to create the transactions. +// Builder() Builder + +// // Signer returns the signer that will be used to sign the transactions. +// Signer() Signer + +// // IssueImportTx creates, signs, and issues an import transaction that +// // attempts to consume all the available UTXOs and import the funds to [to]. +// // +// // - [chainID] specifies the chain to be importing funds from. +// // - [to] specifies where to send the imported funds to. +// IssueImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// options ...common.Option, +// ) (*evm.Tx, error) + +// // IssueExportTx creates, signs, and issues an export transaction that +// // attempts to send all the provided [outputs] to the requested [chainID]. +// // +// // - [chainID] specifies the chain to be exporting the funds to. +// // - [outputs] specifies the outputs to send to the [chainID]. +// IssueExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// options ...common.Option, +// ) (*evm.Tx, error) + +// // IssueUnsignedTx signs and issues the unsigned tx. +// IssueUnsignedAtomicTx( +// utx evm.UnsignedAtomicTx, +// options ...common.Option, +// ) (*evm.Tx, error) + +// // IssueAtomicTx issues the signed tx. +// IssueAtomicTx( +// tx *evm.Tx, +// options ...common.Option, +// ) error +// } + +// func NewWallet( +// builder Builder, +// signer Signer, +// avaxClient evm.Client, +// ethClient ethclient.Client, +// backend Backend, +// ) Wallet { +// return &wallet{ +// Backend: backend, +// builder: builder, +// signer: signer, +// avaxClient: avaxClient, +// ethClient: ethClient, +// } +// } + +// type wallet struct { +// Backend +// builder Builder +// signer Signer +// avaxClient evm.Client +// ethClient ethclient.Client +// } + +// func (w *wallet) Builder() Builder { +// return w.builder +// } + +// func (w *wallet) Signer() Signer { +// return w.signer +// } + +// func (w *wallet) IssueImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// options ...common.Option, +// ) (*evm.Tx, error) { +// baseFee, err := w.baseFee(options) +// if err != nil { +// return nil, err +// } + +// utx, err := w.builder.NewImportTx(chainID, to, baseFee, options...) +// if err != nil { +// return nil, err +// } +// return w.IssueUnsignedAtomicTx(utx, options...) +// } + +// func (w *wallet) IssueExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// options ...common.Option, +// ) (*evm.Tx, error) { +// baseFee, err := w.baseFee(options) +// if err != nil { +// return nil, err +// } + +// utx, err := w.builder.NewExportTx(chainID, outputs, baseFee, options...) +// if err != nil { +// return nil, err +// } +// return w.IssueUnsignedAtomicTx(utx, options...) +// } + +// func (w *wallet) IssueUnsignedAtomicTx( +// utx evm.UnsignedAtomicTx, +// options ...common.Option, +// ) (*evm.Tx, error) { +// ops := common.NewOptions(options) +// ctx := ops.Context() +// tx, err := w.signer.SignUnsignedAtomic(ctx, utx) +// if err != nil { +// return nil, err +// } + +// return tx, w.IssueAtomicTx(tx, options...) +// } + +// func (w *wallet) IssueAtomicTx( +// tx *evm.Tx, +// options ...common.Option, +// ) error { +// ops := common.NewOptions(options) +// ctx := ops.Context() +// txID, err := w.avaxClient.IssueTx(ctx, tx.SignedBytes()) +// if err != nil { +// return err +// } + +// if f := ops.PostIssuanceFunc(); f != nil { +// f(txID) +// } + +// if ops.AssumeDecided() { +// return w.Backend.AcceptAtomicTx(ctx, tx) +// } + +// pollFrequency := ops.PollFrequency() +// ticker := time.NewTicker(pollFrequency) +// defer ticker.Stop() + +// for { +// status, err := w.avaxClient.GetAtomicTxStatus(ctx, txID) +// if err != nil { +// return err +// } + +// switch status { +// case evm.Accepted: +// return w.Backend.AcceptAtomicTx(ctx, tx) +// case evm.Dropped, evm.Unknown: +// return errNotCommitted +// } + +// // The tx is Processing. + +// select { +// case <-ticker.C: +// case <-ctx.Done(): +// return ctx.Err() +// } +// } +// } + +// func (w *wallet) baseFee(options []common.Option) (*big.Int, error) { +// ops := common.NewOptions(options) +// baseFee := ops.BaseFee(nil) +// if baseFee != nil { +// return baseFee, nil +// } + +// ctx := ops.Context() +// return w.ethClient.EstimateBaseFee(ctx) +// } diff --git a/wallet/chain/c/wallet_with_options.go b/wallet/chain/c/wallet_with_options.go index 7d6193683d49..fd69a6d4fd02 100644 --- a/wallet/chain/c/wallet_with_options.go +++ b/wallet/chain/c/wallet_with_options.go @@ -3,80 +3,80 @@ package c -import ( - "github.com/ava-labs/coreth/plugin/evm" +// import ( +// "github.com/ava-labs/coreth/plugin/evm" - ethcommon "github.com/ethereum/go-ethereum/common" +// ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) -var _ Wallet = (*walletWithOptions)(nil) +// var _ Wallet = (*walletWithOptions)(nil) -func NewWalletWithOptions( - wallet Wallet, - options ...common.Option, -) Wallet { - return &walletWithOptions{ - Wallet: wallet, - options: options, - } -} +// func NewWalletWithOptions( +// wallet Wallet, +// options ...common.Option, +// ) Wallet { +// return &walletWithOptions{ +// Wallet: wallet, +// options: options, +// } +// } -type walletWithOptions struct { - Wallet - options []common.Option -} +// type walletWithOptions struct { +// Wallet +// options []common.Option +// } -func (w *walletWithOptions) Builder() Builder { - return NewBuilderWithOptions( - w.Wallet.Builder(), - w.options..., - ) -} +// func (w *walletWithOptions) Builder() Builder { +// return NewBuilderWithOptions( +// w.Wallet.Builder(), +// w.options..., +// ) +// } -func (w *walletWithOptions) IssueImportTx( - chainID ids.ID, - to ethcommon.Address, - options ...common.Option, -) (*evm.Tx, error) { - return w.Wallet.IssueImportTx( - chainID, - to, - common.UnionOptions(w.options, options)..., - ) -} +// func (w *walletWithOptions) IssueImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// options ...common.Option, +// ) (*evm.Tx, error) { +// return w.Wallet.IssueImportTx( +// chainID, +// to, +// common.UnionOptions(w.options, options)..., +// ) +// } -func (w *walletWithOptions) IssueExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - options ...common.Option, -) (*evm.Tx, error) { - return w.Wallet.IssueExportTx( - chainID, - outputs, - common.UnionOptions(w.options, options)..., - ) -} +// func (w *walletWithOptions) IssueExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// options ...common.Option, +// ) (*evm.Tx, error) { +// return w.Wallet.IssueExportTx( +// chainID, +// outputs, +// common.UnionOptions(w.options, options)..., +// ) +// } -func (w *walletWithOptions) IssueUnsignedAtomicTx( - utx evm.UnsignedAtomicTx, - options ...common.Option, -) (*evm.Tx, error) { - return w.Wallet.IssueUnsignedAtomicTx( - utx, - common.UnionOptions(w.options, options)..., - ) -} +// func (w *walletWithOptions) IssueUnsignedAtomicTx( +// utx evm.UnsignedAtomicTx, +// options ...common.Option, +// ) (*evm.Tx, error) { +// return w.Wallet.IssueUnsignedAtomicTx( +// utx, +// common.UnionOptions(w.options, options)..., +// ) +// } -func (w *walletWithOptions) IssueAtomicTx( - tx *evm.Tx, - options ...common.Option, -) error { - return w.Wallet.IssueAtomicTx( - tx, - common.UnionOptions(w.options, options)..., - ) -} +// func (w *walletWithOptions) IssueAtomicTx( +// tx *evm.Tx, +// options ...common.Option, +// ) error { +// return w.Wallet.IssueAtomicTx( +// tx, +// common.UnionOptions(w.options, options)..., +// ) +// } diff --git a/wallet/subnet/primary/api.go b/wallet/subnet/primary/api.go index 3ac72c217884..00ebea6090fd 100644 --- a/wallet/subnet/primary/api.go +++ b/wallet/subnet/primary/api.go @@ -5,12 +5,11 @@ package primary import ( "context" - "fmt" + // "fmt" - "github.com/ava-labs/coreth/ethclient" - "github.com/ava-labs/coreth/plugin/evm" + // "github.com/ava-labs/coreth/ethclient" - "github.com/ethereum/go-ethereum/common" + // "github.com/ethereum/go-ethereum/common" "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/codec" @@ -22,7 +21,8 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/wallet/chain/c" + + // "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/x" ) @@ -59,9 +59,9 @@ type AVAXState struct { PCTX p.Context XClient avm.Client XCTX x.Context - CClient evm.Client - CCTX c.Context - UTXOs UTXOs + // CClient evm.Client + // CCTX c.Context + UTXOs UTXOs } func FetchState( @@ -75,7 +75,7 @@ func FetchState( infoClient := info.NewClient(uri) pClient := platformvm.NewClient(uri) xClient := avm.NewClient(uri, "X") - cClient := evm.NewCChainClient(uri) + // cClient := evm.NewCChainClient(uri) pCTX, err := p.NewContextFromClients(ctx, infoClient, xClient) if err != nil { @@ -87,10 +87,10 @@ func FetchState( return nil, err } - cCTX, err := c.NewContextFromClients(ctx, infoClient, xClient) - if err != nil { - return nil, err - } + // cCTX, err := c.NewContextFromClients(ctx, infoClient, xClient) + // if err != nil { + // return nil, err + // } utxos := NewUTXOs() addrList := addrs.List() @@ -109,11 +109,11 @@ func FetchState( client: xClient, codec: x.Parser.Codec(), }, - { - id: cCTX.BlockchainID(), - client: cClient, - codec: evm.Codec, - }, + // { + // id: cCTX.BlockchainID(), + // client: cClient, + // codec: evm.Codec, + // }, } for _, destinationChain := range chains { for _, sourceChain := range chains { @@ -136,52 +136,52 @@ func FetchState( PCTX: pCTX, XClient: xClient, XCTX: xCTX, - CClient: cClient, - CCTX: cCTX, - UTXOs: utxos, + // CClient: cClient, + // CCTX: cCTX, + UTXOs: utxos, }, nil } -type EthState struct { - Client ethclient.Client - Accounts map[common.Address]*c.Account -} - -func FetchEthState( - ctx context.Context, - uri string, - addrs set.Set[common.Address], -) (*EthState, error) { - path := fmt.Sprintf( - "%s/ext/%s/C/rpc", - uri, - constants.ChainAliasPrefix, - ) - client, err := ethclient.Dial(path) - if err != nil { - return nil, err - } - - accounts := make(map[common.Address]*c.Account, addrs.Len()) - for addr := range addrs { - balance, err := client.BalanceAt(ctx, addr, nil) - if err != nil { - return nil, err - } - nonce, err := client.NonceAt(ctx, addr, nil) - if err != nil { - return nil, err - } - accounts[addr] = &c.Account{ - Balance: balance, - Nonce: nonce, - } - } - return &EthState{ - Client: client, - Accounts: accounts, - }, nil -} +// type EthState struct { +// Client ethclient.Client +// Accounts map[common.Address]*c.Account +// } + +// func FetchEthState( +// ctx context.Context, +// uri string, +// addrs set.Set[common.Address], +// ) (*EthState, error) { +// path := fmt.Sprintf( +// "%s/ext/%s/C/rpc", +// uri, +// constants.ChainAliasPrefix, +// ) +// client, err := ethclient.Dial(path) +// if err != nil { +// return nil, err +// } + +// accounts := make(map[common.Address]*c.Account, addrs.Len()) +// for addr := range addrs { +// balance, err := client.BalanceAt(ctx, addr, nil) +// if err != nil { +// return nil, err +// } +// nonce, err := client.NonceAt(ctx, addr, nil) +// if err != nil { +// return nil, err +// } +// accounts[addr] = &c.Account{ +// Balance: balance, +// Nonce: nonce, +// } +// } +// return &EthState{ +// Client: client, +// Accounts: accounts, +// }, nil +// } // AddAllUTXOs fetches all the UTXOs referenced by [addresses] that were sent // from [sourceChainID] to [destinationChainID] from the [client]. It then uses diff --git a/wallet/subnet/primary/example_test.go b/wallet/subnet/primary/example_test.go index 483c049d4ac0..4a73e8c070b2 100644 --- a/wallet/subnet/primary/example_test.go +++ b/wallet/subnet/primary/example_test.go @@ -30,7 +30,7 @@ func ExampleWallet() { wallet, err := MakeWallet(ctx, &WalletConfig{ URI: LocalAPIURI, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet with: %s\n", err) diff --git a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go index d5e8ce422307..21c081d2982b 100644 --- a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go +++ b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go @@ -46,9 +46,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + // EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/examples/add-primary-validator/main.go b/wallet/subnet/primary/examples/add-primary-validator/main.go index a56dae23db3a..13c28f995f63 100644 --- a/wallet/subnet/primary/examples/add-primary-validator/main.go +++ b/wallet/subnet/primary/examples/add-primary-validator/main.go @@ -45,7 +45,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/c-chain-export/main.go b/wallet/subnet/primary/examples/c-chain-export/main.go index fec55c899feb..a6b9a0c810b8 100644 --- a/wallet/subnet/primary/examples/c-chain-export/main.go +++ b/wallet/subnet/primary/examples/c-chain-export/main.go @@ -3,70 +3,70 @@ package main -import ( - "context" - "log" - "time" +// import ( +// "context" +// "log" +// "time" - "github.com/ava-labs/avalanchego/genesis" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary" -) +// "github.com/ava-labs/avalanchego/genesis" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary" +// ) -func main() { - key := genesis.EWOQKey - uri := primary.LocalAPIURI - kc := secp256k1fx.NewKeychain(key) - avaxAddr := key.Address() +// func main() { +// key := genesis.EWOQKey +// uri := primary.LocalAPIURI +// kc := secp256k1fx.NewKeychain(key) +// avaxAddr := key.Address() - ctx := context.Background() +// ctx := context.Background() - // MakeWallet fetches the available UTXOs owned by [kc] on the network that - // [uri] is hosting. - walletSyncStartTime := time.Now() - wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, - }) - if err != nil { - log.Fatalf("failed to initialize wallet: %s\n", err) - } - log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) +// // MakeWallet fetches the available UTXOs owned by [kc] on the network that +// // [uri] is hosting. +// walletSyncStartTime := time.Now() +// wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ +// URI: uri, +// AVAXKeychain: kc, +// EthKeychain: kc, +// }) +// if err != nil { +// log.Fatalf("failed to initialize wallet: %s\n", err) +// } +// log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) - // Get the P-chain wallet - pWallet := wallet.P() - cWallet := wallet.C() +// // Get the P-chain wallet +// pWallet := wallet.P() +// cWallet := wallet.C() - // Pull out useful constants to use when issuing transactions. - cChainID := cWallet.BlockchainID() - owner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - avaxAddr, - }, - } +// // Pull out useful constants to use when issuing transactions. +// cChainID := cWallet.BlockchainID() +// owner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// avaxAddr, +// }, +// } - exportStartTime := time.Now() - exportTx, err := cWallet.IssueExportTx( - constants.PlatformChainID, - []*secp256k1fx.TransferOutput{{ - Amt: units.Avax, - OutputOwners: owner, - }}, - ) - if err != nil { - log.Fatalf("failed to issue export transaction: %s\n", err) - } - log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) +// exportStartTime := time.Now() +// exportTx, err := cWallet.IssueExportTx( +// constants.PlatformChainID, +// []*secp256k1fx.TransferOutput{{ +// Amt: units.Avax, +// OutputOwners: owner, +// }}, +// ) +// if err != nil { +// log.Fatalf("failed to issue export transaction: %s\n", err) +// } +// log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) - importStartTime := time.Now() - importTx, err := pWallet.IssueImportTx(cChainID, &owner) - if err != nil { - log.Fatalf("failed to issue import transaction: %s\n", err) - } - log.Printf("issued import %s in %s\n", importTx.ID(), time.Since(importStartTime)) -} +// importStartTime := time.Now() +// importTx, err := pWallet.IssueImportTx(cChainID, &owner) +// if err != nil { +// log.Fatalf("failed to issue import transaction: %s\n", err) +// } +// log.Printf("issued import %s in %s\n", importTx.ID(), time.Since(importStartTime)) +// } diff --git a/wallet/subnet/primary/examples/c-chain-import/main.go b/wallet/subnet/primary/examples/c-chain-import/main.go index b4dc4e603eb3..2d9b8a244cb0 100644 --- a/wallet/subnet/primary/examples/c-chain-import/main.go +++ b/wallet/subnet/primary/examples/c-chain-import/main.go @@ -3,75 +3,75 @@ package main -import ( - "context" - "log" - "time" +// import ( +// "context" +// "log" +// "time" - "github.com/ava-labs/coreth/plugin/evm" +// "github.com/ava-labs/coreth/plugin/evm" - "github.com/ava-labs/avalanchego/genesis" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary" -) +// "github.com/ava-labs/avalanchego/genesis" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary" +// ) -func main() { - key := genesis.EWOQKey - uri := primary.LocalAPIURI - kc := secp256k1fx.NewKeychain(key) - avaxAddr := key.Address() - ethAddr := evm.PublicKeyToEthAddress(key.PublicKey()) +// func main() { +// key := genesis.EWOQKey +// uri := primary.LocalAPIURI +// kc := secp256k1fx.NewKeychain(key) +// avaxAddr := key.Address() +// ethAddr := evm.PublicKeyToEthAddress(key.PublicKey()) - ctx := context.Background() +// ctx := context.Background() - // MakeWallet fetches the available UTXOs owned by [kc] on the network that - // [uri] is hosting. - walletSyncStartTime := time.Now() - wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, - }) - if err != nil { - log.Fatalf("failed to initialize wallet: %s\n", err) - } - log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) +// // MakeWallet fetches the available UTXOs owned by [kc] on the network that +// // [uri] is hosting. +// walletSyncStartTime := time.Now() +// wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ +// URI: uri, +// AVAXKeychain: kc, +// EthKeychain: kc, +// }) +// if err != nil { +// log.Fatalf("failed to initialize wallet: %s\n", err) +// } +// log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) - // Get the P-chain wallet - pWallet := wallet.P() - cWallet := wallet.C() +// // Get the P-chain wallet +// pWallet := wallet.P() +// cWallet := wallet.C() - // Pull out useful constants to use when issuing transactions. - cChainID := cWallet.BlockchainID() - avaxAssetID := cWallet.AVAXAssetID() - owner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - avaxAddr, - }, - } +// // Pull out useful constants to use when issuing transactions. +// cChainID := cWallet.BlockchainID() +// avaxAssetID := cWallet.AVAXAssetID() +// owner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// avaxAddr, +// }, +// } - exportStartTime := time.Now() - exportTx, err := pWallet.IssueExportTx(cChainID, []*avax.TransferableOutput{{ - Asset: avax.Asset{ID: avaxAssetID}, - Out: &secp256k1fx.TransferOutput{ - Amt: units.Avax, - OutputOwners: owner, - }, - }}) - if err != nil { - log.Fatalf("failed to issue export transaction: %s\n", err) - } - log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) +// exportStartTime := time.Now() +// exportTx, err := pWallet.IssueExportTx(cChainID, []*avax.TransferableOutput{{ +// Asset: avax.Asset{ID: avaxAssetID}, +// Out: &secp256k1fx.TransferOutput{ +// Amt: units.Avax, +// OutputOwners: owner, +// }, +// }}) +// if err != nil { +// log.Fatalf("failed to issue export transaction: %s\n", err) +// } +// log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) - importStartTime := time.Now() - importTx, err := cWallet.IssueImportTx(constants.PlatformChainID, ethAddr) - if err != nil { - log.Fatalf("failed to issue import transaction: %s\n", err) - } - log.Printf("issued import %s to %s in %s\n", importTx.ID(), ethAddr.Hex(), time.Since(importStartTime)) -} +// importStartTime := time.Now() +// importTx, err := cWallet.IssueImportTx(constants.PlatformChainID, ethAddr) +// if err != nil { +// log.Fatalf("failed to issue import transaction: %s\n", err) +// } +// log.Printf("issued import %s to %s in %s\n", importTx.ID(), ethAddr.Hex(), time.Since(importStartTime)) +// } diff --git a/wallet/subnet/primary/examples/create-asset/main.go b/wallet/subnet/primary/examples/create-asset/main.go index 30804f083df6..0bccfbb5fc52 100644 --- a/wallet/subnet/primary/examples/create-asset/main.go +++ b/wallet/subnet/primary/examples/create-asset/main.go @@ -30,7 +30,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/create-chain/main.go b/wallet/subnet/primary/examples/create-chain/main.go index 5e6898a1b649..521a3cca53cf 100644 --- a/wallet/subnet/primary/examples/create-chain/main.go +++ b/wallet/subnet/primary/examples/create-chain/main.go @@ -41,9 +41,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + // EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/examples/create-locked-stakeable/main.go b/wallet/subnet/primary/examples/create-locked-stakeable/main.go index e688968e9e8a..92f1b5cb0e1b 100644 --- a/wallet/subnet/primary/examples/create-locked-stakeable/main.go +++ b/wallet/subnet/primary/examples/create-locked-stakeable/main.go @@ -39,7 +39,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/create-subnet/main.go b/wallet/subnet/primary/examples/create-subnet/main.go index add98ea7931c..3e8d69bc016a 100644 --- a/wallet/subnet/primary/examples/create-subnet/main.go +++ b/wallet/subnet/primary/examples/create-subnet/main.go @@ -28,7 +28,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/remove-subnet-validator/main.go b/wallet/subnet/primary/examples/remove-subnet-validator/main.go index 2842c7c0a790..46f4b85124db 100644 --- a/wallet/subnet/primary/examples/remove-subnet-validator/main.go +++ b/wallet/subnet/primary/examples/remove-subnet-validator/main.go @@ -38,9 +38,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + // EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/wallet.go b/wallet/subnet/primary/wallet.go index 54de390d029c..ae5e4202a099 100644 --- a/wallet/subnet/primary/wallet.go +++ b/wallet/subnet/primary/wallet.go @@ -11,7 +11,8 @@ import ( "github.com/ava-labs/avalanchego/utils/crypto/keychain" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/wallet/chain/c" + + // "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/x" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -23,13 +24,13 @@ var _ Wallet = (*wallet)(nil) type Wallet interface { P() p.Wallet X() x.Wallet - C() c.Wallet + // C() c.Wallet } type wallet struct { p p.Wallet x x.Wallet - c c.Wallet + // c c.Wallet } func (w *wallet) P() p.Wallet { @@ -40,16 +41,16 @@ func (w *wallet) X() x.Wallet { return w.x } -func (w *wallet) C() c.Wallet { - return w.c -} +// func (w *wallet) C() c.Wallet { +// return w.c +// } // Creates a new default wallet -func NewWallet(p p.Wallet, x x.Wallet, c c.Wallet) Wallet { +func NewWallet(p p.Wallet, x x.Wallet /*, c c.Wallet*/) Wallet { return &wallet{ p: p, x: x, - c: c, + // c: c, } } @@ -58,7 +59,7 @@ func NewWalletWithOptions(w Wallet, options ...common.Option) Wallet { return NewWallet( p.NewWalletWithOptions(w.P(), options...), x.NewWalletWithOptions(w.X(), options...), - c.NewWalletWithOptions(w.C(), options...), + // c.NewWalletWithOptions(w.C(), options...), ) } @@ -67,7 +68,7 @@ type WalletConfig struct { URI string // required // Keys to use for signing all transactions. AVAXKeychain keychain.Keychain // required - EthKeychain c.EthKeychain // required + // EthKeychain c.EthKeychain // required // Set of P-chain transactions that the wallet should know about to be able // to generate transactions. PChainTxs map[ids.ID]*txs.Tx // optional @@ -93,11 +94,11 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { return nil, err } - ethAddrs := config.EthKeychain.EthAddresses() - ethState, err := FetchEthState(ctx, config.URI, ethAddrs) - if err != nil { - return nil, err - } + // ethAddrs := config.EthKeychain.EthAddresses() + // ethState, err := FetchEthState(ctx, config.URI, ethAddrs) + // if err != nil { + // return nil, err + // } pChainTxs := config.PChainTxs if pChainTxs == nil { @@ -127,15 +128,15 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { xBuilder := x.NewBuilder(avaxAddrs, xBackend) xSigner := x.NewSigner(config.AVAXKeychain, xBackend) - cChainID := avaxState.CCTX.BlockchainID() - cUTXOs := NewChainUTXOs(cChainID, avaxState.UTXOs) - cBackend := c.NewBackend(avaxState.CCTX, cUTXOs, ethState.Accounts) - cBuilder := c.NewBuilder(avaxAddrs, ethAddrs, cBackend) - cSigner := c.NewSigner(config.AVAXKeychain, config.EthKeychain, cBackend) + // cChainID := avaxState.CCTX.BlockchainID() + // cUTXOs := NewChainUTXOs(cChainID, avaxState.UTXOs) + // cBackend := c.NewBackend(avaxState.CCTX, cUTXOs, ethState.Accounts) + // cBuilder := c.NewBuilder(avaxAddrs, ethAddrs, cBackend) + // cSigner := c.NewSigner(config.AVAXKeychain, config.EthKeychain, cBackend) return NewWallet( p.NewWallet(pBuilder, pSigner, avaxState.PClient, pBackend), x.NewWallet(xBuilder, xSigner, avaxState.XClient, xBackend), - c.NewWallet(cBuilder, cSigner, avaxState.CClient, ethState.Client, cBackend), + // c.NewWallet(cBuilder, cSigner, avaxState.CClient, ethState.Client, cBackend), ), nil } From 586dcbcecbae1e280194722f906407f2985cc2a8 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 20 Nov 2023 10:45:28 +0100 Subject: [PATCH 03/13] bumped coreth version --- go.mod | 25 + go.sum | 76 ++ node/node.go | 4 +- tests/e2e/c/dynamic_fees.go | 326 +++---- tests/e2e/c/interchain_workflow.go | 320 +++---- tests/e2e/p/interchain_workflow.go | 444 +++++----- tests/e2e/x/interchain_workflow.go | 296 +++---- tests/fixture/e2e/helpers.go | 123 ++- tests/fixture/testnet/config.go | 56 +- vms/example/xsvm/cmd/chain/create/cmd.go | 6 +- wallet/chain/c/backend.go | 300 +++---- wallet/chain/c/builder.go | 792 +++++++++--------- wallet/chain/c/builder_with_options.go | 136 +-- wallet/chain/c/context.go | 130 +-- wallet/chain/c/signer.go | 436 +++++----- wallet/chain/c/wallet.go | 402 ++++----- wallet/chain/c/wallet_with_options.go | 134 +-- wallet/subnet/primary/api.go | 122 +-- wallet/subnet/primary/example_test.go | 2 +- .../add-permissioned-subnet-validator/main.go | 6 +- .../examples/add-primary-validator/main.go | 2 +- .../primary/examples/c-chain-export/main.go | 118 +-- .../primary/examples/c-chain-import/main.go | 126 +-- .../primary/examples/create-asset/main.go | 2 +- .../primary/examples/create-chain/main.go | 6 +- .../examples/create-locked-stakeable/main.go | 2 +- .../primary/examples/create-subnet/main.go | 2 +- .../examples/remove-subnet-validator/main.go | 6 +- wallet/subnet/primary/wallet.go | 43 +- 29 files changed, 2270 insertions(+), 2173 deletions(-) diff --git a/go.mod b/go.mod index 23b752198fdd..78f8eb50182e 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 + github.com/ava-labs/coreth v0.12.9-rc.0.0.20231120093327-25efed25b396 github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 @@ -74,6 +75,7 @@ require ( github.com/BurntSushi/toml v1.2.1 // indirect github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect + github.com/VictoriaMetrics/fastcache v1.10.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect @@ -81,26 +83,44 @@ require ( github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/redact v1.1.3 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/deckarep/golang-set/v2 v2.1.0 // indirect + github.com/dlclark/regexp2 v1.7.0 // indirect + github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 // indirect + github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect github.com/frankban/quicktest v1.14.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/getsentry/sentry-go v0.18.0 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect + github.com/go-stack/stack v1.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/go-cmp v0.5.9 // indirect + github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect + github.com/google/uuid v1.3.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 // indirect + github.com/hashicorp/go-bexpr v0.1.10 // indirect + github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e // indirect github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/klauspost/compress v1.15.15 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/magiconair/properties v1.8.6 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mitchellh/pointerstructure v1.2.0 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -108,12 +128,17 @@ require ( github.com/prometheus/common v0.39.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sanity-io/litter v1.5.1 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/status-im/keycard-go v0.2.0 // indirect github.com/subosito/gotenv v1.3.0 // indirect github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tklauser/numcpus v0.2.2 // indirect + github.com/tyler-smith/go-bip39 v1.1.0 // indirect + github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect diff --git a/go.sum b/go.sum index 2ae152b17faf..e6f45f1305a7 100644 --- a/go.sum +++ b/go.sum @@ -56,12 +56,18 @@ github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cq github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= +github.com/VictoriaMetrics/fastcache v1.10.0 h1:5hDJnLsKLpnUEToub7ETuRu8RCkb40woBZAUiKonXzY= +github.com/VictoriaMetrics/fastcache v1.10.0/go.mod h1:tjiYeEfYXCqacuvYw/7UoDIeJaNxq6132xHICNP77w8= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/ava-labs/coreth v0.12.9-rc.0.0.20231120093327-25efed25b396 h1:q8wdwg2osP5xs+hj681FU8IDsE/ZrE58tFKXl5NbXJc= +github.com/ava-labs/coreth v0.12.9-rc.0.0.20231120093327-25efed25b396/go.mod h1:lAjiEbIj6wQSELIday+toGa2bMkA0birr3h6O2C4mY8= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= @@ -96,13 +102,18 @@ github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46f github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw= github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA= @@ -134,12 +145,16 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= +github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= @@ -150,6 +165,14 @@ github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6ps github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= +github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 h1:+3HCtB74++ClLy8GgjUQYeC8R4ILzVcIe8+5edAJJnE= +github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= +github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= +github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -166,6 +189,8 @@ github.com/ethereum/go-ethereum v1.12.0 h1:bdnhLPtqETd4m3mS8BGMNvBTf36bO5bx/hxE2 github.com/ethereum/go-ethereum v1.12.0/go.mod h1:/oo2X/dZLJjf2mJ6YT9wcWxa4nNJDBKDBU6sFIpx1Gs= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -174,6 +199,8 @@ github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmV github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= @@ -197,7 +224,11 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= +github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= @@ -282,10 +313,14 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= @@ -306,11 +341,17 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 h1:kr3j8iIMR4ywO/O0rvksXaJvauGGCMg2zAZIiNZ9uIQ= github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0/go.mod h1:ummNFgdgLhhX7aIiy35vVmQNS0rWXknfPE0qe6fmFXg= +github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e h1:pIYdhNkDh+YENVNi3gto8n9hAmRxKxoar0iE6BLucjw= +github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e/go.mod h1:j9cQbcqHQujT0oKJ38PylVfqohClLr3CvDC+Qcg+lhU= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c h1:DZfsyhDK1hnSS5lH8l+JggqzEleHteTYfutAiVlSUM8= @@ -322,6 +363,7 @@ github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3 github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -363,6 +405,7 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -370,6 +413,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= @@ -380,11 +424,17 @@ github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPK github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= @@ -393,8 +443,11 @@ github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -413,6 +466,8 @@ github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -480,6 +535,8 @@ github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sanity-io/litter v1.5.1 h1:dwnrSypP6q56o3lFxTU+t2fwQ9A+U5qrXVO4Qg9KwVU= github.com/sanity-io/litter v1.5.1/go.mod h1:5Z71SvaYy5kcGtyglXOC9rrUi3c1E8CamFWjQsazTh0= @@ -515,6 +572,8 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= +github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= +github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -546,10 +605,14 @@ github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZF github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE= github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa h1:5SqCsI/2Qya2bCzK15ozrqo2sZxkh0FHynJZOTVoV6Q= +github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= @@ -561,6 +624,8 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= @@ -570,6 +635,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= @@ -665,6 +731,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -710,6 +777,7 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -733,6 +801,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -797,8 +866,12 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -815,6 +888,7 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -878,6 +952,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1002,6 +1077,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= diff --git a/node/node.go b/node/node.go index 98d697a66359..06544e8f9e6b 100644 --- a/node/node.go +++ b/node/node.go @@ -25,7 +25,7 @@ import ( "go.uber.org/zap" - // coreth "github.com/ava-labs/coreth/plugin/evm" + coreth "github.com/ava-labs/coreth/plugin/evm" "github.com/ava-labs/avalanchego/api/admin" "github.com/ava-labs/avalanchego/api/auth" @@ -1094,7 +1094,7 @@ func (n *Node) initVMs() error { CreateAssetTxFee: n.Config.CreateAssetTxFee, }, }), - // vmRegisterer.Register(context.TODO(), constants.EVMID, &coreth.Factory{}), + vmRegisterer.Register(context.TODO(), constants.EVMID, &coreth.Factory{}), n.VMManager.RegisterFactory(context.TODO(), secp256k1fx.ID, &secp256k1fx.Factory{}), n.VMManager.RegisterFactory(context.TODO(), nftfx.ID, &nftfx.Factory{}), n.VMManager.RegisterFactory(context.TODO(), propertyfx.ID, &propertyfx.Factory{}), diff --git a/tests/e2e/c/dynamic_fees.go b/tests/e2e/c/dynamic_fees.go index 8748dda7451d..8f15b6d43caf 100644 --- a/tests/e2e/c/dynamic_fees.go +++ b/tests/e2e/c/dynamic_fees.go @@ -3,166 +3,166 @@ package c -// import ( -// "math/big" -// "strings" - -// ginkgo "github.com/onsi/ginkgo/v2" - -// "github.com/stretchr/testify/require" - -// "github.com/ethereum/go-ethereum/accounts/abi" -// "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/coreth/core/types" -// "github.com/ava-labs/coreth/params" -// "github.com/ava-labs/coreth/plugin/evm" - -// "github.com/ava-labs/avalanchego/tests" -// "github.com/ava-labs/avalanchego/tests/e2e" -// "github.com/ava-labs/avalanchego/tests/fixture/testnet" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// ) - -// // This test uses the compiled bin for `hashing.sol` as -// // well as its ABI contained in `hashing_contract.go`. - -// var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { -// require := require.New(ginkgo.GinkgoT()) - -// // Need a gas limit much larger than the standard 21_000 to enable -// // the contract to induce a gas price increase -// const largeGasLimit = uint64(8_000_000) - -// // TODO(marun) What is the significance of this value? -// gasTip := big.NewInt(1000 * params.GWei) - -// ginkgo.It("should ensure that the gas price is affected by load", func() { -// ginkgo.By("creating a new private network to ensure isolation from other tests") -// privateNetwork := e2e.Env.NewPrivateNetwork() - -// ginkgo.By("allocating a pre-funded key") -// key := privateNetwork.GetConfig().FundedKeys[0] -// ethAddress := evm.GetEthAddress(key) - -// ginkgo.By("initializing a coreth client") -// node := privateNetwork.GetNodes()[0] -// nodeURI := testnet.NodeURI{ -// NodeID: node.GetID(), -// URI: node.GetProcessContext().URI, -// } -// ethClient := e2e.NewEthClient(nodeURI) - -// ginkgo.By("initializing a transaction signer") -// cChainID, err := ethClient.ChainID(e2e.DefaultContext()) -// require.NoError(err) -// signer := types.NewEIP155Signer(cChainID) -// ecdsaKey := key.ToECDSA() -// sign := func(tx *types.Transaction) *types.Transaction { -// signedTx, err := types.SignTx(tx, signer, ecdsaKey) -// require.NoError(err) -// return signedTx -// } - -// var contractAddress common.Address -// ginkgo.By("deploying an expensive contract", func() { -// // Create transaction -// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) -// require.NoError(err) -// compiledContract := common.Hex2Bytes(hashingCompiledContract) -// tx := types.NewTx(&types.LegacyTx{ -// Nonce: nonce, -// GasPrice: gasTip, -// Gas: largeGasLimit, -// Value: common.Big0, -// Data: compiledContract, -// }) - -// // Send the transaction and wait for acceptance -// signedTx := sign(tx) -// receipt := e2e.SendEthTransaction(ethClient, signedTx) - -// contractAddress = receipt.ContractAddress -// }) - -// var gasPrice *big.Int -// ginkgo.By("calling the expensive contract repeatedly until a gas price increase is detected", func() { -// // Evaluate the bytes representation of the contract -// hashingABI, err := abi.JSON(strings.NewReader(hashingABIJson)) -// require.NoError(err) -// contractData, err := hashingABI.Pack("hashIt") -// require.NoError(err) - -// var initialGasPrice *big.Int -// e2e.Eventually(func() bool { -// // Check the gas price -// var err error -// gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) -// require.NoError(err) -// if initialGasPrice == nil { -// initialGasPrice = gasPrice -// tests.Outf("{{blue}}initial gas price is %v{{/}}\n", initialGasPrice) -// } else if gasPrice.Cmp(initialGasPrice) > 0 { -// // Gas price has increased -// tests.Outf("{{blue}}gas price has increased to %v{{/}}\n", gasPrice) -// return true -// } - -// // Create the transaction -// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) -// require.NoError(err) -// tx := types.NewTx(&types.LegacyTx{ -// Nonce: nonce, -// GasPrice: gasTip, -// Gas: largeGasLimit, -// To: &contractAddress, -// Value: common.Big0, -// Data: contractData, -// }) - -// // Send the transaction and wait for acceptance -// signedTx := sign(tx) -// _ = e2e.SendEthTransaction(ethClient, signedTx) - -// // The gas price will be checked at the start of the next iteration -// return false -// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price increase before timeout") -// }) - -// ginkgo.By("waiting for the gas price to decrease...", func() { -// initialGasPrice := gasPrice -// e2e.Eventually(func() bool { -// var err error -// gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) -// require.NoError(err) -// tests.Outf("{{blue}}.{{/}}") -// return initialGasPrice.Cmp(gasPrice) > 0 -// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price decrease before timeout") -// tests.Outf("\n{{blue}}gas price has decreased to %v{{/}}\n", gasPrice) -// }) - -// ginkgo.By("sending funds at the current gas price", func() { -// // Create a recipient address -// recipientKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) -// recipientEthAddress := evm.GetEthAddress(recipientKey) - -// // Create transaction -// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) -// require.NoError(err) -// tx := types.NewTx(&types.LegacyTx{ -// Nonce: nonce, -// GasPrice: gasPrice, -// Gas: e2e.DefaultGasLimit, -// To: &recipientEthAddress, -// Value: common.Big0, -// }) - -// // Send the transaction and wait for acceptance -// signedTx := sign(tx) -// _ = e2e.SendEthTransaction(ethClient, signedTx) -// }) - -// e2e.CheckBootstrapIsPossible(privateNetwork) -// }) -// }) +import ( + "math/big" + "strings" + + ginkgo "github.com/onsi/ginkgo/v2" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm" + + "github.com/ava-labs/avalanchego/tests" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/testnet" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +) + +// This test uses the compiled bin for `hashing.sol` as +// well as its ABI contained in `hashing_contract.go`. + +var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { + require := require.New(ginkgo.GinkgoT()) + + // Need a gas limit much larger than the standard 21_000 to enable + // the contract to induce a gas price increase + const largeGasLimit = uint64(8_000_000) + + // TODO(marun) What is the significance of this value? + gasTip := big.NewInt(1000 * params.GWei) + + ginkgo.It("should ensure that the gas price is affected by load", func() { + ginkgo.By("creating a new private network to ensure isolation from other tests") + privateNetwork := e2e.Env.NewPrivateNetwork() + + ginkgo.By("allocating a pre-funded key") + key := privateNetwork.GetConfig().FundedKeys[0] + ethAddress := evm.GetEthAddress(key) + + ginkgo.By("initializing a coreth client") + node := privateNetwork.GetNodes()[0] + nodeURI := testnet.NodeURI{ + NodeID: node.GetID(), + URI: node.GetProcessContext().URI, + } + ethClient := e2e.NewEthClient(nodeURI) + + ginkgo.By("initializing a transaction signer") + cChainID, err := ethClient.ChainID(e2e.DefaultContext()) + require.NoError(err) + signer := types.NewEIP155Signer(cChainID) + ecdsaKey := key.ToECDSA() + sign := func(tx *types.Transaction) *types.Transaction { + signedTx, err := types.SignTx(tx, signer, ecdsaKey) + require.NoError(err) + return signedTx + } + + var contractAddress common.Address + ginkgo.By("deploying an expensive contract", func() { + // Create transaction + nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) + require.NoError(err) + compiledContract := common.Hex2Bytes(hashingCompiledContract) + tx := types.NewTx(&types.LegacyTx{ + Nonce: nonce, + GasPrice: gasTip, + Gas: largeGasLimit, + Value: common.Big0, + Data: compiledContract, + }) + + // Send the transaction and wait for acceptance + signedTx := sign(tx) + receipt := e2e.SendEthTransaction(ethClient, signedTx) + + contractAddress = receipt.ContractAddress + }) + + var gasPrice *big.Int + ginkgo.By("calling the expensive contract repeatedly until a gas price increase is detected", func() { + // Evaluate the bytes representation of the contract + hashingABI, err := abi.JSON(strings.NewReader(hashingABIJson)) + require.NoError(err) + contractData, err := hashingABI.Pack("hashIt") + require.NoError(err) + + var initialGasPrice *big.Int + e2e.Eventually(func() bool { + // Check the gas price + var err error + gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) + require.NoError(err) + if initialGasPrice == nil { + initialGasPrice = gasPrice + tests.Outf("{{blue}}initial gas price is %v{{/}}\n", initialGasPrice) + } else if gasPrice.Cmp(initialGasPrice) > 0 { + // Gas price has increased + tests.Outf("{{blue}}gas price has increased to %v{{/}}\n", gasPrice) + return true + } + + // Create the transaction + nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) + require.NoError(err) + tx := types.NewTx(&types.LegacyTx{ + Nonce: nonce, + GasPrice: gasTip, + Gas: largeGasLimit, + To: &contractAddress, + Value: common.Big0, + Data: contractData, + }) + + // Send the transaction and wait for acceptance + signedTx := sign(tx) + _ = e2e.SendEthTransaction(ethClient, signedTx) + + // The gas price will be checked at the start of the next iteration + return false + }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price increase before timeout") + }) + + ginkgo.By("waiting for the gas price to decrease...", func() { + initialGasPrice := gasPrice + e2e.Eventually(func() bool { + var err error + gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) + require.NoError(err) + tests.Outf("{{blue}}.{{/}}") + return initialGasPrice.Cmp(gasPrice) > 0 + }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price decrease before timeout") + tests.Outf("\n{{blue}}gas price has decreased to %v{{/}}\n", gasPrice) + }) + + ginkgo.By("sending funds at the current gas price", func() { + // Create a recipient address + recipientKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + recipientEthAddress := evm.GetEthAddress(recipientKey) + + // Create transaction + nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) + require.NoError(err) + tx := types.NewTx(&types.LegacyTx{ + Nonce: nonce, + GasPrice: gasPrice, + Gas: e2e.DefaultGasLimit, + To: &recipientEthAddress, + Value: common.Big0, + }) + + // Send the transaction and wait for acceptance + signedTx := sign(tx) + _ = e2e.SendEthTransaction(ethClient, signedTx) + }) + + e2e.CheckBootstrapIsPossible(privateNetwork) + }) +}) diff --git a/tests/e2e/c/interchain_workflow.go b/tests/e2e/c/interchain_workflow.go index c5af17c750bf..2c9bd198ec39 100644 --- a/tests/e2e/c/interchain_workflow.go +++ b/tests/e2e/c/interchain_workflow.go @@ -3,163 +3,163 @@ package c -// import ( -// "math/big" - -// ginkgo "github.com/onsi/ginkgo/v2" - -// "github.com/stretchr/testify/require" - -// "github.com/ava-labs/coreth/core/types" -// "github.com/ava-labs/coreth/plugin/evm" - -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/tests/e2e" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var _ = e2e.DescribeCChain("[Interchain Workflow]", func() { -// require := require.New(ginkgo.GinkgoT()) - -// const txAmount = 10 * units.Avax // Arbitrary amount to send and transfer - -// ginkgo.It("should ensure that funds can be transferred from the C-Chain to the X-Chain and the P-Chain", func() { -// ginkgo.By("initializing a new eth client") -// // Select a random node URI to use for both the eth client and -// // the wallet to avoid having to verify that all nodes are at -// // the same height before initializing the wallet. -// nodeURI := e2e.Env.GetRandomNodeURI() -// ethClient := e2e.NewEthClient(nodeURI) - -// ginkgo.By("allocating a pre-funded key to send from and a recipient key to deliver to") -// senderKey := e2e.Env.AllocateFundedKey() -// senderEthAddress := evm.GetEthAddress(senderKey) -// recipientKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) -// recipientEthAddress := evm.GetEthAddress(recipientKey) - -// ginkgo.By("sending funds from one address to another on the C-Chain", func() { -// // Create transaction -// acceptedNonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), senderEthAddress) -// require.NoError(err) -// gasPrice := e2e.SuggestGasPrice(ethClient) -// tx := types.NewTransaction( -// acceptedNonce, -// recipientEthAddress, -// big.NewInt(int64(txAmount)), -// e2e.DefaultGasLimit, -// gasPrice, -// nil, -// ) - -// // Sign transaction -// cChainID, err := ethClient.ChainID(e2e.DefaultContext()) -// require.NoError(err) -// signer := types.NewEIP155Signer(cChainID) -// signedTx, err := types.SignTx(tx, signer, senderKey.ToECDSA()) -// require.NoError(err) - -// _ = e2e.SendEthTransaction(ethClient, signedTx) - -// ginkgo.By("waiting for the C-Chain recipient address to have received the sent funds") -// e2e.Eventually(func() bool { -// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) -// require.NoError(err) -// return balance.Cmp(big.NewInt(0)) > 0 -// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see funds delivered before timeout") -// }) - -// // Wallet must be initialized after sending funds on the -// // C-Chain with the same node URI to ensure wallet state -// // matches on-chain state. -// ginkgo.By("initializing a keychain and associated wallet") -// keychain := secp256k1fx.NewKeychain(senderKey, recipientKey) -// baseWallet := e2e.NewWallet(keychain, nodeURI) -// xWallet := baseWallet.X() -// cWallet := baseWallet.C() -// pWallet := baseWallet.P() - -// ginkgo.By("defining common configuration") -// avaxAssetID := xWallet.AVAXAssetID() -// // Use the same owner for import funds to X-Chain and P-Chain -// recipientOwner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// recipientKey.Address(), -// }, -// } -// // Use the same outputs for both X-Chain and P-Chain exports -// exportOutputs := []*secp256k1fx.TransferOutput{ -// { -// Amt: txAmount, -// OutputOwners: secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// keychain.Keys[0].Address(), -// }, -// }, -// }, -// } - -// ginkgo.By("exporting AVAX from the C-Chain to the X-Chain", func() { -// _, err := cWallet.IssueExportTx( -// xWallet.BlockchainID(), -// exportOutputs, -// e2e.WithDefaultContext(), -// e2e.WithSuggestedGasPrice(ethClient), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("importing AVAX from the C-Chain to the X-Chain", func() { -// _, err := xWallet.IssueImportTx( -// cWallet.BlockchainID(), -// &recipientOwner, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { -// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// ginkgo.By("exporting AVAX from the C-Chain to the P-Chain", func() { -// _, err := cWallet.IssueExportTx( -// constants.PlatformChainID, -// exportOutputs, -// e2e.WithDefaultContext(), -// e2e.WithSuggestedGasPrice(ethClient), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("importing AVAX from the C-Chain to the P-Chain", func() { -// _, err = pWallet.IssueImportTx( -// cWallet.BlockchainID(), -// &recipientOwner, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { -// balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) -// }) -// }) +import ( + "math/big" + + ginkgo "github.com/onsi/ginkgo/v2" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/coreth/plugin/evm" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var _ = e2e.DescribeCChain("[Interchain Workflow]", func() { + require := require.New(ginkgo.GinkgoT()) + + const txAmount = 10 * units.Avax // Arbitrary amount to send and transfer + + ginkgo.It("should ensure that funds can be transferred from the C-Chain to the X-Chain and the P-Chain", func() { + ginkgo.By("initializing a new eth client") + // Select a random node URI to use for both the eth client and + // the wallet to avoid having to verify that all nodes are at + // the same height before initializing the wallet. + nodeURI := e2e.Env.GetRandomNodeURI() + ethClient := e2e.NewEthClient(nodeURI) + + ginkgo.By("allocating a pre-funded key to send from and a recipient key to deliver to") + senderKey := e2e.Env.AllocateFundedKey() + senderEthAddress := evm.GetEthAddress(senderKey) + recipientKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + recipientEthAddress := evm.GetEthAddress(recipientKey) + + ginkgo.By("sending funds from one address to another on the C-Chain", func() { + // Create transaction + acceptedNonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), senderEthAddress) + require.NoError(err) + gasPrice := e2e.SuggestGasPrice(ethClient) + tx := types.NewTransaction( + acceptedNonce, + recipientEthAddress, + big.NewInt(int64(txAmount)), + e2e.DefaultGasLimit, + gasPrice, + nil, + ) + + // Sign transaction + cChainID, err := ethClient.ChainID(e2e.DefaultContext()) + require.NoError(err) + signer := types.NewEIP155Signer(cChainID) + signedTx, err := types.SignTx(tx, signer, senderKey.ToECDSA()) + require.NoError(err) + + _ = e2e.SendEthTransaction(ethClient, signedTx) + + ginkgo.By("waiting for the C-Chain recipient address to have received the sent funds") + e2e.Eventually(func() bool { + balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) + require.NoError(err) + return balance.Cmp(big.NewInt(0)) > 0 + }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see funds delivered before timeout") + }) + + // Wallet must be initialized after sending funds on the + // C-Chain with the same node URI to ensure wallet state + // matches on-chain state. + ginkgo.By("initializing a keychain and associated wallet") + keychain := secp256k1fx.NewKeychain(senderKey, recipientKey) + baseWallet := e2e.NewWallet(keychain, nodeURI) + xWallet := baseWallet.X() + cWallet := baseWallet.C() + pWallet := baseWallet.P() + + ginkgo.By("defining common configuration") + avaxAssetID := xWallet.AVAXAssetID() + // Use the same owner for import funds to X-Chain and P-Chain + recipientOwner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + recipientKey.Address(), + }, + } + // Use the same outputs for both X-Chain and P-Chain exports + exportOutputs := []*secp256k1fx.TransferOutput{ + { + Amt: txAmount, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + keychain.Keys[0].Address(), + }, + }, + }, + } + + ginkgo.By("exporting AVAX from the C-Chain to the X-Chain", func() { + _, err := cWallet.IssueExportTx( + xWallet.BlockchainID(), + exportOutputs, + e2e.WithDefaultContext(), + e2e.WithSuggestedGasPrice(ethClient), + ) + require.NoError(err) + }) + + ginkgo.By("importing AVAX from the C-Chain to the X-Chain", func() { + _, err := xWallet.IssueImportTx( + cWallet.BlockchainID(), + &recipientOwner, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { + balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + ginkgo.By("exporting AVAX from the C-Chain to the P-Chain", func() { + _, err := cWallet.IssueExportTx( + constants.PlatformChainID, + exportOutputs, + e2e.WithDefaultContext(), + e2e.WithSuggestedGasPrice(ethClient), + ) + require.NoError(err) + }) + + ginkgo.By("importing AVAX from the C-Chain to the P-Chain", func() { + _, err = pWallet.IssueImportTx( + cWallet.BlockchainID(), + &recipientOwner, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { + balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) + }) +}) diff --git a/tests/e2e/p/interchain_workflow.go b/tests/e2e/p/interchain_workflow.go index e90e0382e286..44a6912715ef 100644 --- a/tests/e2e/p/interchain_workflow.go +++ b/tests/e2e/p/interchain_workflow.go @@ -3,225 +3,225 @@ package p -// import ( -// "math/big" -// "time" - -// ginkgo "github.com/onsi/ginkgo/v2" - -// "github.com/spf13/cast" - -// "github.com/stretchr/testify/require" - -// "github.com/ava-labs/coreth/plugin/evm" - -// "github.com/ava-labs/avalanchego/api/info" -// "github.com/ava-labs/avalanchego/config" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/tests/e2e" -// "github.com/ava-labs/avalanchego/tests/fixture/testnet" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/platformvm/reward" -// "github.com/ava-labs/avalanchego/vms/platformvm/txs" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { -// require := require.New(ginkgo.GinkgoT()) - -// const ( -// transferAmount = 10 * units.Avax -// weight = 2_000 * units.Avax // Used for both validation and delegation -// ) - -// ginkgo.It("should ensure that funds can be transferred from the P-Chain to the X-Chain and the C-Chain", func() { -// network := e2e.Env.GetNetwork() - -// ginkgo.By("checking that the network has a compatible minimum stake duration", func() { -// minStakeDuration := cast.ToDuration(network.GetConfig().DefaultFlags[config.MinStakeDurationKey]) -// require.Equal(testnet.DefaultMinStakeDuration, minStakeDuration) -// }) - -// ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") -// recipientKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) -// keychain := e2e.Env.NewKeychain(1) -// keychain.Add(recipientKey) -// nodeURI := e2e.Env.GetRandomNodeURI() -// baseWallet := e2e.Env.NewWallet(keychain, nodeURI) -// xWallet := baseWallet.X() -// cWallet := baseWallet.C() -// pWallet := baseWallet.P() - -// ginkgo.By("defining common configuration") -// recipientEthAddress := evm.GetEthAddress(recipientKey) -// avaxAssetID := xWallet.AVAXAssetID() -// // Use the same owner for sending to X-Chain and importing funds to P-Chain -// recipientOwner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// recipientKey.Address(), -// }, -// } -// // Use the same outputs for both X-Chain and C-Chain exports -// exportOutputs := []*avax.TransferableOutput{ -// { -// Asset: avax.Asset{ -// ID: avaxAssetID, -// }, -// Out: &secp256k1fx.TransferOutput{ -// Amt: transferAmount, -// OutputOwners: secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// keychain.Keys[0].Address(), -// }, -// }, -// }, -// }, -// } - -// ginkgo.By("adding new node and waiting for it to report healthy") -// node := e2e.AddEphemeralNode(network, testnet.FlagsMap{}) -// e2e.WaitForHealthy(node) - -// ginkgo.By("retrieving new node's id and pop") -// infoClient := info.NewClient(node.GetProcessContext().URI) -// nodeID, nodePOP, err := infoClient.GetNodeID(e2e.DefaultContext()) -// require.NoError(err) - -// ginkgo.By("adding the new node as a validator", func() { -// startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) -// // Validation duration doesn't actually matter to this -// // test - it is only ensuring that adding a validator -// // doesn't break interchain transfer. -// endTime := startTime.Add(30 * time.Second) - -// rewardKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) - -// const ( -// delegationPercent = 0.10 // 10% -// delegationShare = reward.PercentDenominator * delegationPercent -// ) - -// _, err = pWallet.IssueAddPermissionlessValidatorTx( -// &txs.SubnetValidator{ -// Validator: txs.Validator{ -// NodeID: nodeID, -// Start: uint64(startTime.Unix()), -// End: uint64(endTime.Unix()), -// Wght: weight, -// }, -// Subnet: constants.PrimaryNetworkID, -// }, -// nodePOP, -// pWallet.AVAXAssetID(), -// &secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{rewardKey.Address()}, -// }, -// &secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{rewardKey.Address()}, -// }, -// delegationShare, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("adding a delegator to the new node", func() { -// startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) -// // Delegation duration doesn't actually matter to this -// // test - it is only ensuring that adding a delegator -// // doesn't break interchain transfer. -// endTime := startTime.Add(15 * time.Second) - -// rewardKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) - -// _, err = pWallet.IssueAddPermissionlessDelegatorTx( -// &txs.SubnetValidator{ -// Validator: txs.Validator{ -// NodeID: nodeID, -// Start: uint64(startTime.Unix()), -// End: uint64(endTime.Unix()), -// Wght: weight, -// }, -// Subnet: constants.PrimaryNetworkID, -// }, -// pWallet.AVAXAssetID(), -// &secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{rewardKey.Address()}, -// }, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("exporting AVAX from the P-Chain to the X-Chain", func() { -// _, err := pWallet.IssueExportTx( -// xWallet.BlockchainID(), -// exportOutputs, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("importing AVAX from the P-Chain to the X-Chain", func() { -// _, err := xWallet.IssueImportTx( -// constants.PlatformChainID, -// &recipientOwner, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { -// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// ginkgo.By("exporting AVAX from the P-Chain to the C-Chain", func() { -// _, err := pWallet.IssueExportTx( -// cWallet.BlockchainID(), -// exportOutputs, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("initializing a new eth client") -// ethClient := e2e.NewEthClient(nodeURI) - -// ginkgo.By("importing AVAX from the P-Chain to the C-Chain", func() { -// _, err := cWallet.IssueImportTx( -// constants.PlatformChainID, -// recipientEthAddress, -// e2e.WithDefaultContext(), -// e2e.WithSuggestedGasPrice(ethClient), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") -// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) -// require.NoError(err) -// require.Positive(balance.Cmp(big.NewInt(0))) - -// ginkgo.By("stopping validator node to free up resources for a bootstrap check") -// require.NoError(node.Stop()) - -// e2e.CheckBootstrapIsPossible(network) -// }) -// }) +import ( + "math/big" + "time" + + ginkgo "github.com/onsi/ginkgo/v2" + + "github.com/spf13/cast" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/coreth/plugin/evm" + + "github.com/ava-labs/avalanchego/api/info" + "github.com/ava-labs/avalanchego/config" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/testnet" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/platformvm/reward" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { + require := require.New(ginkgo.GinkgoT()) + + const ( + transferAmount = 10 * units.Avax + weight = 2_000 * units.Avax // Used for both validation and delegation + ) + + ginkgo.It("should ensure that funds can be transferred from the P-Chain to the X-Chain and the C-Chain", func() { + network := e2e.Env.GetNetwork() + + ginkgo.By("checking that the network has a compatible minimum stake duration", func() { + minStakeDuration := cast.ToDuration(network.GetConfig().DefaultFlags[config.MinStakeDurationKey]) + require.Equal(testnet.DefaultMinStakeDuration, minStakeDuration) + }) + + ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") + recipientKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + keychain := e2e.Env.NewKeychain(1) + keychain.Add(recipientKey) + nodeURI := e2e.Env.GetRandomNodeURI() + baseWallet := e2e.NewWallet(keychain, nodeURI) + xWallet := baseWallet.X() + cWallet := baseWallet.C() + pWallet := baseWallet.P() + + ginkgo.By("defining common configuration") + recipientEthAddress := evm.GetEthAddress(recipientKey) + avaxAssetID := xWallet.AVAXAssetID() + // Use the same owner for sending to X-Chain and importing funds to P-Chain + recipientOwner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + recipientKey.Address(), + }, + } + // Use the same outputs for both X-Chain and C-Chain exports + exportOutputs := []*avax.TransferableOutput{ + { + Asset: avax.Asset{ + ID: avaxAssetID, + }, + Out: &secp256k1fx.TransferOutput{ + Amt: transferAmount, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + keychain.Keys[0].Address(), + }, + }, + }, + }, + } + + ginkgo.By("adding new node and waiting for it to report healthy") + node := e2e.AddEphemeralNode(network, testnet.FlagsMap{}) + e2e.WaitForHealthy(node) + + ginkgo.By("retrieving new node's id and pop") + infoClient := info.NewClient(node.GetProcessContext().URI) + nodeID, nodePOP, err := infoClient.GetNodeID(e2e.DefaultContext()) + require.NoError(err) + + ginkgo.By("adding the new node as a validator", func() { + startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) + // Validation duration doesn't actually matter to this + // test - it is only ensuring that adding a validator + // doesn't break interchain transfer. + endTime := startTime.Add(30 * time.Second) + + rewardKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + + const ( + delegationPercent = 0.10 // 10% + delegationShare = reward.PercentDenominator * delegationPercent + ) + + _, err = pWallet.IssueAddPermissionlessValidatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(endTime.Unix()), + Wght: weight, + }, + Subnet: constants.PrimaryNetworkID, + }, + nodePOP, + pWallet.AVAXAssetID(), + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardKey.Address()}, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardKey.Address()}, + }, + delegationShare, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("adding a delegator to the new node", func() { + startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) + // Delegation duration doesn't actually matter to this + // test - it is only ensuring that adding a delegator + // doesn't break interchain transfer. + endTime := startTime.Add(15 * time.Second) + + rewardKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + + _, err = pWallet.IssueAddPermissionlessDelegatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(endTime.Unix()), + Wght: weight, + }, + Subnet: constants.PrimaryNetworkID, + }, + pWallet.AVAXAssetID(), + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardKey.Address()}, + }, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("exporting AVAX from the P-Chain to the X-Chain", func() { + _, err := pWallet.IssueExportTx( + xWallet.BlockchainID(), + exportOutputs, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("importing AVAX from the P-Chain to the X-Chain", func() { + _, err := xWallet.IssueImportTx( + constants.PlatformChainID, + &recipientOwner, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { + balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + ginkgo.By("exporting AVAX from the P-Chain to the C-Chain", func() { + _, err := pWallet.IssueExportTx( + cWallet.BlockchainID(), + exportOutputs, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("initializing a new eth client") + ethClient := e2e.NewEthClient(nodeURI) + + ginkgo.By("importing AVAX from the P-Chain to the C-Chain", func() { + _, err := cWallet.IssueImportTx( + constants.PlatformChainID, + recipientEthAddress, + e2e.WithDefaultContext(), + e2e.WithSuggestedGasPrice(ethClient), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") + balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) + require.NoError(err) + require.Positive(balance.Cmp(big.NewInt(0))) + + ginkgo.By("stopping validator node to free up resources for a bootstrap check") + require.NoError(node.Stop()) + + e2e.CheckBootstrapIsPossible(network) + }) +}) diff --git a/tests/e2e/x/interchain_workflow.go b/tests/e2e/x/interchain_workflow.go index d738e55a7f7a..f0c2951feb84 100644 --- a/tests/e2e/x/interchain_workflow.go +++ b/tests/e2e/x/interchain_workflow.go @@ -3,151 +3,151 @@ package x -// import ( -// "math/big" - -// ginkgo "github.com/onsi/ginkgo/v2" - -// "github.com/stretchr/testify/require" - -// "github.com/ava-labs/coreth/plugin/evm" - -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/tests/e2e" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var _ = e2e.DescribeXChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { -// require := require.New(ginkgo.GinkgoT()) - -// const transferAmount = 10 * units.Avax - -// ginkgo.It("should ensure that funds can be transferred from the X-Chain to the C-Chain and the P-Chain", func() { -// nodeURI := e2e.Env.GetRandomNodeURI() - -// ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") -// recipientKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) -// keychain := e2e.Env.NewKeychain(1) -// keychain.Add(recipientKey) -// baseWallet := e2e.Env.NewWallet(keychain, nodeURI) -// xWallet := baseWallet.X() -// cWallet := baseWallet.C() -// pWallet := baseWallet.P() - -// ginkgo.By("defining common configuration") -// recipientEthAddress := evm.GetEthAddress(recipientKey) -// avaxAssetID := xWallet.AVAXAssetID() -// // Use the same owner for sending to X-Chain and importing funds to P-Chain -// recipientOwner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// recipientKey.Address(), -// }, -// } -// // Use the same outputs for both C-Chain and P-Chain exports -// exportOutputs := []*avax.TransferableOutput{ -// { -// Asset: avax.Asset{ -// ID: avaxAssetID, -// }, -// Out: &secp256k1fx.TransferOutput{ -// Amt: transferAmount, -// OutputOwners: secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// keychain.Keys[0].Address(), -// }, -// }, -// }, -// }, -// } - -// ginkgo.By("sending funds from one address to another on the X-Chain", func() { -// _, err = xWallet.IssueBaseTx( -// []*avax.TransferableOutput{{ -// Asset: avax.Asset{ -// ID: avaxAssetID, -// }, -// Out: &secp256k1fx.TransferOutput{ -// Amt: transferAmount, -// OutputOwners: recipientOwner, -// }, -// }}, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the X-Chain recipient address has received the sent funds", func() { -// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// ginkgo.By("exporting AVAX from the X-Chain to the C-Chain", func() { -// _, err := xWallet.IssueExportTx( -// cWallet.BlockchainID(), -// exportOutputs, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("initializing a new eth client") -// ethClient := e2e.NewEthClient(nodeURI) - -// ginkgo.By("importing AVAX from the X-Chain to the C-Chain", func() { -// _, err := cWallet.IssueImportTx( -// xWallet.BlockchainID(), -// recipientEthAddress, -// e2e.WithDefaultContext(), -// e2e.WithSuggestedGasPrice(ethClient), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") -// e2e.Eventually(func() bool { -// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) -// require.NoError(err) -// return balance.Cmp(big.NewInt(0)) > 0 -// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see recipient address funded before timeout") - -// ginkgo.By("exporting AVAX from the X-Chain to the P-Chain", func() { -// _, err := xWallet.IssueExportTx( -// constants.PlatformChainID, -// exportOutputs, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("importing AVAX from the X-Chain to the P-Chain", func() { -// _, err := pWallet.IssueImportTx( -// xWallet.BlockchainID(), -// &recipientOwner, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { -// balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) -// }) -// }) +import ( + "math/big" + + ginkgo "github.com/onsi/ginkgo/v2" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/coreth/plugin/evm" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var _ = e2e.DescribeXChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { + require := require.New(ginkgo.GinkgoT()) + + const transferAmount = 10 * units.Avax + + ginkgo.It("should ensure that funds can be transferred from the X-Chain to the C-Chain and the P-Chain", func() { + nodeURI := e2e.Env.GetRandomNodeURI() + + ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") + recipientKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + keychain := e2e.Env.NewKeychain(1) + keychain.Add(recipientKey) + baseWallet := e2e.NewWallet(keychain, nodeURI) + xWallet := baseWallet.X() + cWallet := baseWallet.C() + pWallet := baseWallet.P() + + ginkgo.By("defining common configuration") + recipientEthAddress := evm.GetEthAddress(recipientKey) + avaxAssetID := xWallet.AVAXAssetID() + // Use the same owner for sending to X-Chain and importing funds to P-Chain + recipientOwner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + recipientKey.Address(), + }, + } + // Use the same outputs for both C-Chain and P-Chain exports + exportOutputs := []*avax.TransferableOutput{ + { + Asset: avax.Asset{ + ID: avaxAssetID, + }, + Out: &secp256k1fx.TransferOutput{ + Amt: transferAmount, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + keychain.Keys[0].Address(), + }, + }, + }, + }, + } + + ginkgo.By("sending funds from one address to another on the X-Chain", func() { + _, err = xWallet.IssueBaseTx( + []*avax.TransferableOutput{{ + Asset: avax.Asset{ + ID: avaxAssetID, + }, + Out: &secp256k1fx.TransferOutput{ + Amt: transferAmount, + OutputOwners: recipientOwner, + }, + }}, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the X-Chain recipient address has received the sent funds", func() { + balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + ginkgo.By("exporting AVAX from the X-Chain to the C-Chain", func() { + _, err := xWallet.IssueExportTx( + cWallet.BlockchainID(), + exportOutputs, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("initializing a new eth client") + ethClient := e2e.NewEthClient(nodeURI) + + ginkgo.By("importing AVAX from the X-Chain to the C-Chain", func() { + _, err := cWallet.IssueImportTx( + xWallet.BlockchainID(), + recipientEthAddress, + e2e.WithDefaultContext(), + e2e.WithSuggestedGasPrice(ethClient), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") + e2e.Eventually(func() bool { + balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) + require.NoError(err) + return balance.Cmp(big.NewInt(0)) > 0 + }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see recipient address funded before timeout") + + ginkgo.By("exporting AVAX from the X-Chain to the P-Chain", func() { + _, err := xWallet.IssueExportTx( + constants.PlatformChainID, + exportOutputs, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("importing AVAX from the X-Chain to the P-Chain", func() { + _, err := pWallet.IssueImportTx( + xWallet.BlockchainID(), + &recipientOwner, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { + balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) + }) +}) diff --git a/tests/fixture/e2e/helpers.go b/tests/fixture/e2e/helpers.go index 8e497cf398c0..15da611324e0 100644 --- a/tests/fixture/e2e/helpers.go +++ b/tests/fixture/e2e/helpers.go @@ -5,23 +5,20 @@ package e2e import ( "context" - - // "errors" - // "fmt" - // "math/big" - + "errors" + "fmt" + "math/big" "os" - - // "strings" + "strings" "time" ginkgo "github.com/onsi/ginkgo/v2" "github.com/stretchr/testify/require" - // "github.com/ava-labs/coreth/core/types" - // "github.com/ava-labs/coreth/ethclient" - // "github.com/ava-labs/coreth/interfaces" + "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/coreth/ethclient" + "github.com/ava-labs/coreth/interfaces" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/tests" @@ -70,7 +67,7 @@ func NewWallet(keychain *secp256k1fx.Keychain, nodeURI testnet.NodeURI) primary. baseWallet, err := primary.MakeWallet(DefaultContext(), &primary.WalletConfig{ URI: nodeURI.URI, AVAXKeychain: keychain, - // EthKeychain: keychain, + EthKeychain: keychain, }) require.NoError(ginkgo.GinkgoT(), err) return primary.NewWalletWithOptions( @@ -83,15 +80,15 @@ func NewWallet(keychain *secp256k1fx.Keychain, nodeURI testnet.NodeURI) primary. ) } -// // Create a new eth client targeting the specified node URI. -// func NewEthClient(nodeURI testnet.NodeURI) ethclient.Client { -// tests.Outf("{{blue}} initializing a new eth client for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) -// nodeAddress := strings.Split(nodeURI.URI, "//")[1] -// uri := fmt.Sprintf("ws://%s/ext/bc/C/ws", nodeAddress) -// client, err := ethclient.Dial(uri) -// require.NoError(ginkgo.GinkgoT(), err) -// return client -// } +// Create a new eth client targeting the specified node URI. +func NewEthClient(nodeURI testnet.NodeURI) ethclient.Client { + tests.Outf("{{blue}} initializing a new eth client for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) + nodeAddress := strings.Split(nodeURI.URI, "//")[1] + uri := fmt.Sprintf("ws://%s/ext/bc/C/ws", nodeAddress) + client, err := ethclient.Dial(uri) + require.NoError(ginkgo.GinkgoT(), err) + return client +} // Helper simplifying use of a timed context by canceling the context on ginkgo teardown. func ContextWithTimeout(duration time.Duration) context.Context { @@ -155,49 +152,49 @@ func WaitForHealthy(node testnet.Node) { require.NoError(ginkgo.GinkgoT(), testnet.WaitForHealthy(ctx, node)) } -// // Sends an eth transaction, waits for the transaction receipt to be issued -// // and checks that the receipt indicates success. -// func SendEthTransaction(ethClient ethclient.Client, signedTx *types.Transaction) *types.Receipt { -// require := require.New(ginkgo.GinkgoT()) - -// txID := signedTx.Hash() -// tests.Outf(" sending eth transaction with ID: %s\n", txID) - -// require.NoError(ethClient.SendTransaction(DefaultContext(), signedTx)) - -// // Wait for the receipt -// var receipt *types.Receipt -// Eventually(func() bool { -// var err error -// receipt, err = ethClient.TransactionReceipt(DefaultContext(), txID) -// if errors.Is(err, interfaces.NotFound) { -// return false // Transaction is still pending -// } -// require.NoError(err) -// return true -// }, DefaultTimeout, DefaultPollingInterval, "failed to see transaction acceptance before timeout") - -// require.Equal(receipt.Status, types.ReceiptStatusSuccessful) -// return receipt -// } - -// // Determines the suggested gas price for the configured client that will -// // maximize the chances of transaction acceptance. -// func SuggestGasPrice(ethClient ethclient.Client) *big.Int { -// gasPrice, err := ethClient.SuggestGasPrice(DefaultContext()) -// require.NoError(ginkgo.GinkgoT(), err) -// // Double the suggested gas price to maximize the chances of -// // acceptance. Maybe this can be revisited pending resolution of -// // https://github.com/ava-labs/coreth/issues/314. -// gasPrice.Add(gasPrice, gasPrice) -// return gasPrice -// } - -// // Helper simplifying use via an option of a gas price appropriate for testing. -// func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { -// baseFee := SuggestGasPrice(ethClient) -// return common.WithBaseFee(baseFee) -// } +// Sends an eth transaction, waits for the transaction receipt to be issued +// and checks that the receipt indicates success. +func SendEthTransaction(ethClient ethclient.Client, signedTx *types.Transaction) *types.Receipt { + require := require.New(ginkgo.GinkgoT()) + + txID := signedTx.Hash() + tests.Outf(" sending eth transaction with ID: %s\n", txID) + + require.NoError(ethClient.SendTransaction(DefaultContext(), signedTx)) + + // Wait for the receipt + var receipt *types.Receipt + Eventually(func() bool { + var err error + receipt, err = ethClient.TransactionReceipt(DefaultContext(), txID) + if errors.Is(err, interfaces.NotFound) { + return false // Transaction is still pending + } + require.NoError(err) + return true + }, DefaultTimeout, DefaultPollingInterval, "failed to see transaction acceptance before timeout") + + require.Equal(receipt.Status, types.ReceiptStatusSuccessful) + return receipt +} + +// Determines the suggested gas price for the configured client that will +// maximize the chances of transaction acceptance. +func SuggestGasPrice(ethClient ethclient.Client) *big.Int { + gasPrice, err := ethClient.SuggestGasPrice(DefaultContext()) + require.NoError(ginkgo.GinkgoT(), err) + // Double the suggested gas price to maximize the chances of + // acceptance. Maybe this can be revisited pending resolution of + // https://github.com/ava-labs/coreth/issues/314. + gasPrice.Add(gasPrice, gasPrice) + return gasPrice +} + +// Helper simplifying use via an option of a gas price appropriate for testing. +func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { + baseFee := SuggestGasPrice(ethClient) + return common.WithBaseFee(baseFee) +} // Verify that a new node can bootstrap into the network. func CheckBootstrapIsPossible(network testnet.Network) { diff --git a/tests/fixture/testnet/config.go b/tests/fixture/testnet/config.go index c2e27bbff116..425aa646a690 100644 --- a/tests/fixture/testnet/config.go +++ b/tests/fixture/testnet/config.go @@ -15,9 +15,9 @@ import ( "github.com/spf13/cast" - // "github.com/ava-labs/coreth/core" - // "github.com/ava-labs/coreth/params" - // "github.com/ava-labs/coreth/plugin/evm" + "github.com/ava-labs/coreth/core" + "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm" "github.com/ava-labs/avalanchego/config" "github.com/ava-labs/avalanchego/genesis" @@ -143,15 +143,15 @@ func (c *NetworkConfig) EnsureGenesis(networkID uint32, validatorIDs []ids.NodeI // Ensure pre-funded keys have arbitrary large balances on both chains to support testing xChainBalances := make(XChainBalanceMap, len(c.FundedKeys)) - // cChainBalances := make(core.GenesisAlloc, len(c.FundedKeys)) - // for _, key := range c.FundedKeys { - // xChainBalances[key.Address()] = DefaultFundedKeyXChainAmount - // cChainBalances[evm.GetEthAddress(key)] = core.GenesisAccount{ - // Balance: DefaultFundedKeyCChainAmount, - // } - // } - - genesis, err := NewTestGenesis(networkID, xChainBalances /*, cChainBalances*/, validatorIDs) + cChainBalances := make(core.GenesisAlloc, len(c.FundedKeys)) + for _, key := range c.FundedKeys { + xChainBalances[key.Address()] = DefaultFundedKeyXChainAmount + cChainBalances[evm.GetEthAddress(key)] = core.GenesisAccount{ + Balance: DefaultFundedKeyCChainAmount, + } + } + + genesis, err := NewTestGenesis(networkID, xChainBalances, cChainBalances, validatorIDs) if err != nil { return err } @@ -311,7 +311,7 @@ type XChainBalanceMap map[ids.ShortID]uint64 func NewTestGenesis( networkID uint32, xChainBalances XChainBalanceMap, - // cChainBalances core.GenesisAlloc, + cChainBalances core.GenesisAlloc, validatorIDs []ids.NodeID, ) (*genesis.UnparsedConfig, error) { // Validate inputs @@ -322,7 +322,7 @@ func NewTestGenesis( if len(validatorIDs) == 0 { return nil, errMissingValidatorsForGenesis } - if len(xChainBalances) == 0 /*|| len(cChainBalances) == 0*/ { + if len(xChainBalances) == 0 || len(cChainBalances) == 0 { return nil, errMissingBalancesForGenesis } @@ -394,20 +394,20 @@ func NewTestGenesis( ) } - // // Define C-Chain genesis - // cChainGenesis := &core.Genesis{ - // Config: ¶ms.ChainConfig{ - // ChainID: big.NewInt(43112), // Arbitrary chain ID is arbitrary - // }, - // Difficulty: big.NewInt(0), // Difficulty is a mandatory field - // GasLimit: DefaultGasLimit, - // Alloc: cChainBalances, - // } - // cChainGenesisBytes, err := json.Marshal(cChainGenesis) - // if err != nil { - // return nil, fmt.Errorf("failed to marshal C-Chain genesis: %w", err) - // } - // config.CChainGenesis = string(cChainGenesisBytes) + // Define C-Chain genesis + cChainGenesis := &core.Genesis{ + Config: ¶ms.ChainConfig{ + ChainID: big.NewInt(43112), // Arbitrary chain ID is arbitrary + }, + Difficulty: big.NewInt(0), // Difficulty is a mandatory field + GasLimit: DefaultGasLimit, + Alloc: cChainBalances, + } + cChainGenesisBytes, err := json.Marshal(cChainGenesis) + if err != nil { + return nil, fmt.Errorf("failed to marshal C-Chain genesis: %w", err) + } + config.CChainGenesis = string(cChainGenesisBytes) // Give staking rewards for initial validators to a random address. Any testing of staking rewards // will be easier to perform with nodes other than the initial validators since the timing of diff --git a/vms/example/xsvm/cmd/chain/create/cmd.go b/vms/example/xsvm/cmd/chain/create/cmd.go index 043b4298dcdf..1f00491a4ce6 100644 --- a/vms/example/xsvm/cmd/chain/create/cmd.go +++ b/vms/example/xsvm/cmd/chain/create/cmd.go @@ -42,9 +42,9 @@ func createFunc(c *cobra.Command, args []string) error { // that [uri] is hosting. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: config.URI, - AVAXKeychain: kc, - // EthKeychain: kc, + URI: config.URI, + AVAXKeychain: kc, + EthKeychain: kc, PChainTxsToFetch: set.Of(config.SubnetID), }) if err != nil { diff --git a/wallet/chain/c/backend.go b/wallet/chain/c/backend.go index b88c8c643bc3..0a735116b646 100644 --- a/wallet/chain/c/backend.go +++ b/wallet/chain/c/backend.go @@ -3,153 +3,153 @@ package c -// import ( -// "errors" -// "fmt" -// "math/big" -// "sync" - -// stdcontext "context" - -// "github.com/ava-labs/coreth/plugin/evm" - -// ethcommon "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/avalanchego/database" -// "github.com/ava-labs/avalanchego/utils/math" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var ( -// _ Backend = (*backend)(nil) - -// errUnknownTxType = errors.New("unknown tx type") -// ) - -// // Backend defines the full interface required to support a C-chain wallet. -// type Backend interface { -// common.ChainUTXOs -// BuilderBackend -// SignerBackend - -// AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error -// } - -// type backend struct { -// Context -// common.ChainUTXOs - -// accountsLock sync.RWMutex -// accounts map[ethcommon.Address]*Account -// } - -// type Account struct { -// Balance *big.Int -// Nonce uint64 -// } - -// func NewBackend( -// ctx Context, -// utxos common.ChainUTXOs, -// accounts map[ethcommon.Address]*Account, -// ) Backend { -// return &backend{ -// Context: ctx, -// ChainUTXOs: utxos, -// accounts: accounts, -// } -// } - -// func (b *backend) AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error { -// switch tx := tx.UnsignedAtomicTx.(type) { -// case *evm.UnsignedImportTx: -// for _, input := range tx.ImportedInputs { -// utxoID := input.InputID() -// if err := b.RemoveUTXO(ctx, tx.SourceChain, utxoID); err != nil { -// return err -// } -// } - -// b.accountsLock.Lock() -// defer b.accountsLock.Unlock() - -// for _, output := range tx.Outs { -// account, ok := b.accounts[output.Address] -// if !ok { -// continue -// } - -// balance := new(big.Int).SetUint64(output.Amount) -// balance.Mul(balance, avaxConversionRate) -// account.Balance.Add(account.Balance, balance) -// } -// case *evm.UnsignedExportTx: -// txID := tx.ID() -// for i, out := range tx.ExportedOutputs { -// err := b.AddUTXO( -// ctx, -// tx.DestinationChain, -// &avax.UTXO{ -// UTXOID: avax.UTXOID{ -// TxID: txID, -// OutputIndex: uint32(i), -// }, -// Asset: avax.Asset{ID: out.AssetID()}, -// Out: out.Out, -// }, -// ) -// if err != nil { -// return err -// } -// } - -// b.accountsLock.Lock() -// defer b.accountsLock.Unlock() - -// for _, input := range tx.Ins { -// account, ok := b.accounts[input.Address] -// if !ok { -// continue -// } - -// balance := new(big.Int).SetUint64(input.Amount) -// balance.Mul(balance, avaxConversionRate) -// if account.Balance.Cmp(balance) == -1 { -// return errInsufficientFunds -// } -// account.Balance.Sub(account.Balance, balance) - -// newNonce, err := math.Add64(input.Nonce, 1) -// if err != nil { -// return err -// } -// account.Nonce = newNonce -// } -// default: -// return fmt.Errorf("%w: %T", errUnknownTxType, tx) -// } -// return nil -// } - -// func (b *backend) Balance(_ stdcontext.Context, addr ethcommon.Address) (*big.Int, error) { -// b.accountsLock.RLock() -// defer b.accountsLock.RUnlock() - -// account, exists := b.accounts[addr] -// if !exists { -// return nil, database.ErrNotFound -// } -// return account.Balance, nil -// } - -// func (b *backend) Nonce(_ stdcontext.Context, addr ethcommon.Address) (uint64, error) { -// b.accountsLock.RLock() -// defer b.accountsLock.RUnlock() - -// account, exists := b.accounts[addr] -// if !exists { -// return 0, database.ErrNotFound -// } -// return account.Nonce, nil -// } +import ( + "errors" + "fmt" + "math/big" + "sync" + + stdcontext "context" + + "github.com/ava-labs/coreth/plugin/evm" + + ethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/avalanchego/database" + "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var ( + _ Backend = (*backend)(nil) + + errUnknownTxType = errors.New("unknown tx type") +) + +// Backend defines the full interface required to support a C-chain wallet. +type Backend interface { + common.ChainUTXOs + BuilderBackend + SignerBackend + + AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error +} + +type backend struct { + Context + common.ChainUTXOs + + accountsLock sync.RWMutex + accounts map[ethcommon.Address]*Account +} + +type Account struct { + Balance *big.Int + Nonce uint64 +} + +func NewBackend( + ctx Context, + utxos common.ChainUTXOs, + accounts map[ethcommon.Address]*Account, +) Backend { + return &backend{ + Context: ctx, + ChainUTXOs: utxos, + accounts: accounts, + } +} + +func (b *backend) AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error { + switch tx := tx.UnsignedAtomicTx.(type) { + case *evm.UnsignedImportTx: + for _, input := range tx.ImportedInputs { + utxoID := input.InputID() + if err := b.RemoveUTXO(ctx, tx.SourceChain, utxoID); err != nil { + return err + } + } + + b.accountsLock.Lock() + defer b.accountsLock.Unlock() + + for _, output := range tx.Outs { + account, ok := b.accounts[output.Address] + if !ok { + continue + } + + balance := new(big.Int).SetUint64(output.Amount) + balance.Mul(balance, avaxConversionRate) + account.Balance.Add(account.Balance, balance) + } + case *evm.UnsignedExportTx: + txID := tx.ID() + for i, out := range tx.ExportedOutputs { + err := b.AddUTXO( + ctx, + tx.DestinationChain, + &avax.UTXO{ + UTXOID: avax.UTXOID{ + TxID: txID, + OutputIndex: uint32(i), + }, + Asset: avax.Asset{ID: out.AssetID()}, + Out: out.Out, + }, + ) + if err != nil { + return err + } + } + + b.accountsLock.Lock() + defer b.accountsLock.Unlock() + + for _, input := range tx.Ins { + account, ok := b.accounts[input.Address] + if !ok { + continue + } + + balance := new(big.Int).SetUint64(input.Amount) + balance.Mul(balance, avaxConversionRate) + if account.Balance.Cmp(balance) == -1 { + return errInsufficientFunds + } + account.Balance.Sub(account.Balance, balance) + + newNonce, err := math.Add64(input.Nonce, 1) + if err != nil { + return err + } + account.Nonce = newNonce + } + default: + return fmt.Errorf("%w: %T", errUnknownTxType, tx) + } + return nil +} + +func (b *backend) Balance(_ stdcontext.Context, addr ethcommon.Address) (*big.Int, error) { + b.accountsLock.RLock() + defer b.accountsLock.RUnlock() + + account, exists := b.accounts[addr] + if !exists { + return nil, database.ErrNotFound + } + return account.Balance, nil +} + +func (b *backend) Nonce(_ stdcontext.Context, addr ethcommon.Address) (uint64, error) { + b.accountsLock.RLock() + defer b.accountsLock.RUnlock() + + account, exists := b.accounts[addr] + if !exists { + return 0, database.ErrNotFound + } + return account.Nonce, nil +} diff --git a/wallet/chain/c/builder.go b/wallet/chain/c/builder.go index c51d2647777e..d2d088e88a53 100644 --- a/wallet/chain/c/builder.go +++ b/wallet/chain/c/builder.go @@ -3,399 +3,399 @@ package c -// import ( -// "errors" -// "math/big" - -// stdcontext "context" - -// "github.com/ava-labs/coreth/plugin/evm" - -// ethcommon "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/utils" -// "github.com/ava-labs/avalanchego/utils/math" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// const avaxConversionRateInt = 1_000_000_000 - -// var ( -// _ Builder = (*builder)(nil) - -// errInsufficientFunds = errors.New("insufficient funds") - -// // avaxConversionRate is the conversion rate between the smallest -// // denomination on the X-Chain and P-chain, 1 nAVAX, and the smallest -// // denomination on the C-Chain 1 wei. Where 1 nAVAX = 1 gWei. -// // -// // This is only required for AVAX because the denomination of 1 AVAX is 9 -// // decimal places on the X and P chains, but is 18 decimal places within the -// // EVM. -// avaxConversionRate = big.NewInt(avaxConversionRateInt) -// ) - -// // Builder provides a convenient interface for building unsigned C-chain -// // transactions. -// type Builder interface { -// // GetBalance calculates the amount of AVAX that this builder has control -// // over. -// GetBalance( -// options ...common.Option, -// ) (*big.Int, error) - -// // GetImportableBalance calculates the amount of AVAX that this builder -// // could import from the provided chain. -// // -// // - [chainID] specifies the chain the funds are from. -// GetImportableBalance( -// chainID ids.ID, -// options ...common.Option, -// ) (uint64, error) - -// // NewImportTx creates an import transaction that attempts to consume all -// // the available UTXOs and import the funds to [to]. -// // -// // - [chainID] specifies the chain to be importing funds from. -// // - [to] specifies where to send the imported funds to. -// // - [baseFee] specifies the fee price willing to be paid by this tx. -// NewImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedImportTx, error) - -// // NewExportTx creates an export transaction that attempts to send all the -// // provided [outputs] to the requested [chainID]. -// // -// // - [chainID] specifies the chain to be exporting the funds to. -// // - [outputs] specifies the outputs to send to the [chainID]. -// // - [baseFee] specifies the fee price willing to be paid by this tx. -// NewExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedExportTx, error) -// } - -// // BuilderBackend specifies the required information needed to build unsigned -// // C-chain transactions. -// type BuilderBackend interface { -// Context - -// UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) -// Balance(ctx stdcontext.Context, addr ethcommon.Address) (*big.Int, error) -// Nonce(ctx stdcontext.Context, addr ethcommon.Address) (uint64, error) -// } - -// type builder struct { -// avaxAddrs set.Set[ids.ShortID] -// ethAddrs set.Set[ethcommon.Address] -// backend BuilderBackend -// } - -// // NewBuilder returns a new transaction builder. -// // -// // - [avaxAddrs] is the set of addresses in the AVAX format that the builder -// // assumes can be used when signing the transactions in the future. -// // - [ethAddrs] is the set of addresses in the Eth format that the builder -// // assumes can be used when signing the transactions in the future. -// // - [backend] provides the required access to the chain's context and state -// // to build out the transactions. -// func NewBuilder( -// avaxAddrs set.Set[ids.ShortID], -// ethAddrs set.Set[ethcommon.Address], -// backend BuilderBackend, -// ) Builder { -// return &builder{ -// avaxAddrs: avaxAddrs, -// ethAddrs: ethAddrs, -// backend: backend, -// } -// } - -// func (b *builder) GetBalance( -// options ...common.Option, -// ) (*big.Int, error) { -// var ( -// ops = common.NewOptions(options) -// ctx = ops.Context() -// addrs = ops.EthAddresses(b.ethAddrs) -// totalBalance = new(big.Int) -// ) -// for addr := range addrs { -// balance, err := b.backend.Balance(ctx, addr) -// if err != nil { -// return nil, err -// } -// totalBalance.Add(totalBalance, balance) -// } - -// return totalBalance, nil -// } - -// func (b *builder) GetImportableBalance( -// chainID ids.ID, -// options ...common.Option, -// ) (uint64, error) { -// ops := common.NewOptions(options) -// utxos, err := b.backend.UTXOs(ops.Context(), chainID) -// if err != nil { -// return 0, err -// } - -// var ( -// addrs = ops.Addresses(b.avaxAddrs) -// minIssuanceTime = ops.MinIssuanceTime() -// avaxAssetID = b.backend.AVAXAssetID() -// balance uint64 -// ) -// for _, utxo := range utxos { -// amount, _, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) -// if !ok { -// continue -// } - -// newBalance, err := math.Add64(balance, amount) -// if err != nil { -// return 0, err -// } -// balance = newBalance -// } - -// return balance, nil -// } - -// func (b *builder) NewImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedImportTx, error) { -// ops := common.NewOptions(options) -// utxos, err := b.backend.UTXOs(ops.Context(), chainID) -// if err != nil { -// return nil, err -// } - -// var ( -// addrs = ops.Addresses(b.avaxAddrs) -// minIssuanceTime = ops.MinIssuanceTime() -// avaxAssetID = b.backend.AVAXAssetID() - -// importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) -// importedAmount uint64 -// ) -// for _, utxo := range utxos { -// amount, inputSigIndices, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) -// if !ok { -// continue -// } - -// importedInputs = append(importedInputs, &avax.TransferableInput{ -// UTXOID: utxo.UTXOID, -// Asset: utxo.Asset, -// In: &secp256k1fx.TransferInput{ -// Amt: amount, -// Input: secp256k1fx.Input{ -// SigIndices: inputSigIndices, -// }, -// }, -// }) - -// newImportedAmount, err := math.Add64(importedAmount, amount) -// if err != nil { -// return nil, err -// } -// importedAmount = newImportedAmount -// } - -// utils.Sort(importedInputs) -// tx := &evm.UnsignedImportTx{ -// NetworkID: b.backend.NetworkID(), -// BlockchainID: b.backend.BlockchainID(), -// SourceChain: chainID, -// ImportedInputs: importedInputs, -// } - -// // We must initialize the bytes of the tx to calculate the initial cost -// wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} -// if err := wrappedTx.Sign(evm.Codec, nil); err != nil { -// return nil, err -// } - -// gasUsedWithoutOutput, err := tx.GasUsed(true /*=IsApricotPhase5*/) -// if err != nil { -// return nil, err -// } -// gasUsedWithOutput := gasUsedWithoutOutput + evm.EVMOutputGas - -// txFee, err := evm.CalculateDynamicFee(gasUsedWithOutput, baseFee) -// if err != nil { -// return nil, err -// } - -// if importedAmount <= txFee { -// return nil, errInsufficientFunds -// } - -// tx.Outs = []evm.EVMOutput{{ -// Address: to, -// Amount: importedAmount - txFee, -// AssetID: avaxAssetID, -// }} -// return tx, nil -// } - -// func (b *builder) NewExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedExportTx, error) { -// var ( -// avaxAssetID = b.backend.AVAXAssetID() -// exportedOutputs = make([]*avax.TransferableOutput, len(outputs)) -// exportedAmount uint64 -// ) -// for i, output := range outputs { -// exportedOutputs[i] = &avax.TransferableOutput{ -// Asset: avax.Asset{ID: avaxAssetID}, -// Out: output, -// } - -// newExportedAmount, err := math.Add64(exportedAmount, output.Amt) -// if err != nil { -// return nil, err -// } -// exportedAmount = newExportedAmount -// } - -// avax.SortTransferableOutputs(exportedOutputs, evm.Codec) -// tx := &evm.UnsignedExportTx{ -// NetworkID: b.backend.NetworkID(), -// BlockchainID: b.backend.BlockchainID(), -// DestinationChain: chainID, -// ExportedOutputs: exportedOutputs, -// } - -// // We must initialize the bytes of the tx to calculate the initial cost -// wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} -// if err := wrappedTx.Sign(evm.Codec, nil); err != nil { -// return nil, err -// } - -// cost, err := tx.GasUsed(true /*=IsApricotPhase5*/) -// if err != nil { -// return nil, err -// } - -// initialFee, err := evm.CalculateDynamicFee(cost, baseFee) -// if err != nil { -// return nil, err -// } - -// amountToConsume, err := math.Add64(exportedAmount, initialFee) -// if err != nil { -// return nil, err -// } - -// var ( -// ops = common.NewOptions(options) -// ctx = ops.Context() -// addrs = ops.EthAddresses(b.ethAddrs) -// inputs = make([]evm.EVMInput, 0, addrs.Len()) -// ) -// for addr := range addrs { -// if amountToConsume == 0 { -// break -// } - -// prevFee, err := evm.CalculateDynamicFee(cost, baseFee) -// if err != nil { -// return nil, err -// } - -// newCost := cost + evm.EVMInputGas -// newFee, err := evm.CalculateDynamicFee(newCost, baseFee) -// if err != nil { -// return nil, err -// } - -// additionalFee := newFee - prevFee - -// balance, err := b.backend.Balance(ctx, addr) -// if err != nil { -// return nil, err -// } - -// // Since the asset is AVAX, we divide by the avaxConversionRate to -// // convert back to the correct denomination of AVAX that can be -// // exported. -// avaxBalance := new(big.Int).Div(balance, avaxConversionRate).Uint64() - -// // If the balance for [addr] is insufficient to cover the additional -// // cost of adding an input to the transaction, skip adding the input -// // altogether. -// if avaxBalance <= additionalFee { -// continue -// } - -// // Update the cost for the next iteration -// cost = newCost - -// amountToConsume, err = math.Add64(amountToConsume, additionalFee) -// if err != nil { -// return nil, err -// } - -// nonce, err := b.backend.Nonce(ctx, addr) -// if err != nil { -// return nil, err -// } - -// inputAmount := math.Min(amountToConsume, avaxBalance) -// inputs = append(inputs, evm.EVMInput{ -// Address: addr, -// Amount: inputAmount, -// AssetID: avaxAssetID, -// Nonce: nonce, -// }) -// amountToConsume -= inputAmount -// } - -// if amountToConsume > 0 { -// return nil, errInsufficientFunds -// } - -// utils.Sort(inputs) -// tx.Ins = inputs -// return tx, nil -// } - -// func getSpendableAmount( -// utxo *avax.UTXO, -// addrs set.Set[ids.ShortID], -// minIssuanceTime uint64, -// avaxAssetID ids.ID, -// ) (uint64, []uint32, bool) { -// if utxo.Asset.ID != avaxAssetID { -// // Only AVAX can be imported -// return 0, nil, false -// } - -// out, ok := utxo.Out.(*secp256k1fx.TransferOutput) -// if !ok { -// // Can't import an unknown transfer output type -// return 0, nil, false -// } - -// inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) -// return out.Amt, inputSigIndices, ok -// } +import ( + "errors" + "math/big" + + stdcontext "context" + + "github.com/ava-labs/coreth/plugin/evm" + + ethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils" + "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +const avaxConversionRateInt = 1_000_000_000 + +var ( + _ Builder = (*builder)(nil) + + errInsufficientFunds = errors.New("insufficient funds") + + // avaxConversionRate is the conversion rate between the smallest + // denomination on the X-Chain and P-chain, 1 nAVAX, and the smallest + // denomination on the C-Chain 1 wei. Where 1 nAVAX = 1 gWei. + // + // This is only required for AVAX because the denomination of 1 AVAX is 9 + // decimal places on the X and P chains, but is 18 decimal places within the + // EVM. + avaxConversionRate = big.NewInt(avaxConversionRateInt) +) + +// Builder provides a convenient interface for building unsigned C-chain +// transactions. +type Builder interface { + // GetBalance calculates the amount of AVAX that this builder has control + // over. + GetBalance( + options ...common.Option, + ) (*big.Int, error) + + // GetImportableBalance calculates the amount of AVAX that this builder + // could import from the provided chain. + // + // - [chainID] specifies the chain the funds are from. + GetImportableBalance( + chainID ids.ID, + options ...common.Option, + ) (uint64, error) + + // NewImportTx creates an import transaction that attempts to consume all + // the available UTXOs and import the funds to [to]. + // + // - [chainID] specifies the chain to be importing funds from. + // - [to] specifies where to send the imported funds to. + // - [baseFee] specifies the fee price willing to be paid by this tx. + NewImportTx( + chainID ids.ID, + to ethcommon.Address, + baseFee *big.Int, + options ...common.Option, + ) (*evm.UnsignedImportTx, error) + + // NewExportTx creates an export transaction that attempts to send all the + // provided [outputs] to the requested [chainID]. + // + // - [chainID] specifies the chain to be exporting the funds to. + // - [outputs] specifies the outputs to send to the [chainID]. + // - [baseFee] specifies the fee price willing to be paid by this tx. + NewExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + baseFee *big.Int, + options ...common.Option, + ) (*evm.UnsignedExportTx, error) +} + +// BuilderBackend specifies the required information needed to build unsigned +// C-chain transactions. +type BuilderBackend interface { + Context + + UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) + Balance(ctx stdcontext.Context, addr ethcommon.Address) (*big.Int, error) + Nonce(ctx stdcontext.Context, addr ethcommon.Address) (uint64, error) +} + +type builder struct { + avaxAddrs set.Set[ids.ShortID] + ethAddrs set.Set[ethcommon.Address] + backend BuilderBackend +} + +// NewBuilder returns a new transaction builder. +// +// - [avaxAddrs] is the set of addresses in the AVAX format that the builder +// assumes can be used when signing the transactions in the future. +// - [ethAddrs] is the set of addresses in the Eth format that the builder +// assumes can be used when signing the transactions in the future. +// - [backend] provides the required access to the chain's context and state +// to build out the transactions. +func NewBuilder( + avaxAddrs set.Set[ids.ShortID], + ethAddrs set.Set[ethcommon.Address], + backend BuilderBackend, +) Builder { + return &builder{ + avaxAddrs: avaxAddrs, + ethAddrs: ethAddrs, + backend: backend, + } +} + +func (b *builder) GetBalance( + options ...common.Option, +) (*big.Int, error) { + var ( + ops = common.NewOptions(options) + ctx = ops.Context() + addrs = ops.EthAddresses(b.ethAddrs) + totalBalance = new(big.Int) + ) + for addr := range addrs { + balance, err := b.backend.Balance(ctx, addr) + if err != nil { + return nil, err + } + totalBalance.Add(totalBalance, balance) + } + + return totalBalance, nil +} + +func (b *builder) GetImportableBalance( + chainID ids.ID, + options ...common.Option, +) (uint64, error) { + ops := common.NewOptions(options) + utxos, err := b.backend.UTXOs(ops.Context(), chainID) + if err != nil { + return 0, err + } + + var ( + addrs = ops.Addresses(b.avaxAddrs) + minIssuanceTime = ops.MinIssuanceTime() + avaxAssetID = b.backend.AVAXAssetID() + balance uint64 + ) + for _, utxo := range utxos { + amount, _, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) + if !ok { + continue + } + + newBalance, err := math.Add64(balance, amount) + if err != nil { + return 0, err + } + balance = newBalance + } + + return balance, nil +} + +func (b *builder) NewImportTx( + chainID ids.ID, + to ethcommon.Address, + baseFee *big.Int, + options ...common.Option, +) (*evm.UnsignedImportTx, error) { + ops := common.NewOptions(options) + utxos, err := b.backend.UTXOs(ops.Context(), chainID) + if err != nil { + return nil, err + } + + var ( + addrs = ops.Addresses(b.avaxAddrs) + minIssuanceTime = ops.MinIssuanceTime() + avaxAssetID = b.backend.AVAXAssetID() + + importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) + importedAmount uint64 + ) + for _, utxo := range utxos { + amount, inputSigIndices, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) + if !ok { + continue + } + + importedInputs = append(importedInputs, &avax.TransferableInput{ + UTXOID: utxo.UTXOID, + Asset: utxo.Asset, + In: &secp256k1fx.TransferInput{ + Amt: amount, + Input: secp256k1fx.Input{ + SigIndices: inputSigIndices, + }, + }, + }) + + newImportedAmount, err := math.Add64(importedAmount, amount) + if err != nil { + return nil, err + } + importedAmount = newImportedAmount + } + + utils.Sort(importedInputs) + tx := &evm.UnsignedImportTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: b.backend.BlockchainID(), + SourceChain: chainID, + ImportedInputs: importedInputs, + } + + // We must initialize the bytes of the tx to calculate the initial cost + wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} + if err := wrappedTx.Sign(evm.Codec, nil); err != nil { + return nil, err + } + + gasUsedWithoutOutput, err := tx.GasUsed(true /*=IsApricotPhase5*/) + if err != nil { + return nil, err + } + gasUsedWithOutput := gasUsedWithoutOutput + evm.EVMOutputGas + + txFee, err := evm.CalculateDynamicFee(gasUsedWithOutput, baseFee) + if err != nil { + return nil, err + } + + if importedAmount <= txFee { + return nil, errInsufficientFunds + } + + tx.Outs = []evm.EVMOutput{{ + Address: to, + Amount: importedAmount - txFee, + AssetID: avaxAssetID, + }} + return tx, nil +} + +func (b *builder) NewExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + baseFee *big.Int, + options ...common.Option, +) (*evm.UnsignedExportTx, error) { + var ( + avaxAssetID = b.backend.AVAXAssetID() + exportedOutputs = make([]*avax.TransferableOutput, len(outputs)) + exportedAmount uint64 + ) + for i, output := range outputs { + exportedOutputs[i] = &avax.TransferableOutput{ + Asset: avax.Asset{ID: avaxAssetID}, + Out: output, + } + + newExportedAmount, err := math.Add64(exportedAmount, output.Amt) + if err != nil { + return nil, err + } + exportedAmount = newExportedAmount + } + + avax.SortTransferableOutputs(exportedOutputs, evm.Codec) + tx := &evm.UnsignedExportTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: b.backend.BlockchainID(), + DestinationChain: chainID, + ExportedOutputs: exportedOutputs, + } + + // We must initialize the bytes of the tx to calculate the initial cost + wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} + if err := wrappedTx.Sign(evm.Codec, nil); err != nil { + return nil, err + } + + cost, err := tx.GasUsed(true /*=IsApricotPhase5*/) + if err != nil { + return nil, err + } + + initialFee, err := evm.CalculateDynamicFee(cost, baseFee) + if err != nil { + return nil, err + } + + amountToConsume, err := math.Add64(exportedAmount, initialFee) + if err != nil { + return nil, err + } + + var ( + ops = common.NewOptions(options) + ctx = ops.Context() + addrs = ops.EthAddresses(b.ethAddrs) + inputs = make([]evm.EVMInput, 0, addrs.Len()) + ) + for addr := range addrs { + if amountToConsume == 0 { + break + } + + prevFee, err := evm.CalculateDynamicFee(cost, baseFee) + if err != nil { + return nil, err + } + + newCost := cost + evm.EVMInputGas + newFee, err := evm.CalculateDynamicFee(newCost, baseFee) + if err != nil { + return nil, err + } + + additionalFee := newFee - prevFee + + balance, err := b.backend.Balance(ctx, addr) + if err != nil { + return nil, err + } + + // Since the asset is AVAX, we divide by the avaxConversionRate to + // convert back to the correct denomination of AVAX that can be + // exported. + avaxBalance := new(big.Int).Div(balance, avaxConversionRate).Uint64() + + // If the balance for [addr] is insufficient to cover the additional + // cost of adding an input to the transaction, skip adding the input + // altogether. + if avaxBalance <= additionalFee { + continue + } + + // Update the cost for the next iteration + cost = newCost + + amountToConsume, err = math.Add64(amountToConsume, additionalFee) + if err != nil { + return nil, err + } + + nonce, err := b.backend.Nonce(ctx, addr) + if err != nil { + return nil, err + } + + inputAmount := math.Min(amountToConsume, avaxBalance) + inputs = append(inputs, evm.EVMInput{ + Address: addr, + Amount: inputAmount, + AssetID: avaxAssetID, + Nonce: nonce, + }) + amountToConsume -= inputAmount + } + + if amountToConsume > 0 { + return nil, errInsufficientFunds + } + + utils.Sort(inputs) + tx.Ins = inputs + return tx, nil +} + +func getSpendableAmount( + utxo *avax.UTXO, + addrs set.Set[ids.ShortID], + minIssuanceTime uint64, + avaxAssetID ids.ID, +) (uint64, []uint32, bool) { + if utxo.Asset.ID != avaxAssetID { + // Only AVAX can be imported + return 0, nil, false + } + + out, ok := utxo.Out.(*secp256k1fx.TransferOutput) + if !ok { + // Can't import an unknown transfer output type + return 0, nil, false + } + + inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) + return out.Amt, inputSigIndices, ok +} diff --git a/wallet/chain/c/builder_with_options.go b/wallet/chain/c/builder_with_options.go index 9b7ab8399484..8416dddf9928 100644 --- a/wallet/chain/c/builder_with_options.go +++ b/wallet/chain/c/builder_with_options.go @@ -3,81 +3,81 @@ package c -// import ( -// "math/big" +import ( + "math/big" -// "github.com/ava-labs/coreth/plugin/evm" + "github.com/ava-labs/coreth/plugin/evm" -// ethcommon "github.com/ethereum/go-ethereum/common" + ethcommon "github.com/ethereum/go-ethereum/common" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) -// var _ Builder = (*builderWithOptions)(nil) +var _ Builder = (*builderWithOptions)(nil) -// type builderWithOptions struct { -// Builder -// options []common.Option -// } +type builderWithOptions struct { + Builder + options []common.Option +} -// // NewBuilderWithOptions returns a new transaction builder that will use the -// // given options by default. -// // -// // - [builder] is the builder that will be called to perform the underlying -// // operations. -// // - [options] will be provided to the builder in addition to the options -// // provided in the method calls. -// func NewBuilderWithOptions(builder Builder, options ...common.Option) Builder { -// return &builderWithOptions{ -// Builder: builder, -// options: options, -// } -// } +// NewBuilderWithOptions returns a new transaction builder that will use the +// given options by default. +// +// - [builder] is the builder that will be called to perform the underlying +// operations. +// - [options] will be provided to the builder in addition to the options +// provided in the method calls. +func NewBuilderWithOptions(builder Builder, options ...common.Option) Builder { + return &builderWithOptions{ + Builder: builder, + options: options, + } +} -// func (b *builderWithOptions) GetBalance( -// options ...common.Option, -// ) (*big.Int, error) { -// return b.Builder.GetBalance( -// common.UnionOptions(b.options, options)..., -// ) -// } +func (b *builderWithOptions) GetBalance( + options ...common.Option, +) (*big.Int, error) { + return b.Builder.GetBalance( + common.UnionOptions(b.options, options)..., + ) +} -// func (b *builderWithOptions) GetImportableBalance( -// chainID ids.ID, -// options ...common.Option, -// ) (uint64, error) { -// return b.Builder.GetImportableBalance( -// chainID, -// common.UnionOptions(b.options, options)..., -// ) -// } +func (b *builderWithOptions) GetImportableBalance( + chainID ids.ID, + options ...common.Option, +) (uint64, error) { + return b.Builder.GetImportableBalance( + chainID, + common.UnionOptions(b.options, options)..., + ) +} -// func (b *builderWithOptions) NewImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedImportTx, error) { -// return b.Builder.NewImportTx( -// chainID, -// to, -// baseFee, -// common.UnionOptions(b.options, options)..., -// ) -// } +func (b *builderWithOptions) NewImportTx( + chainID ids.ID, + to ethcommon.Address, + baseFee *big.Int, + options ...common.Option, +) (*evm.UnsignedImportTx, error) { + return b.Builder.NewImportTx( + chainID, + to, + baseFee, + common.UnionOptions(b.options, options)..., + ) +} -// func (b *builderWithOptions) NewExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedExportTx, error) { -// return b.Builder.NewExportTx( -// chainID, -// outputs, -// baseFee, -// common.UnionOptions(b.options, options)..., -// ) -// } +func (b *builderWithOptions) NewExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + baseFee *big.Int, + options ...common.Option, +) (*evm.UnsignedExportTx, error) { + return b.Builder.NewExportTx( + chainID, + outputs, + baseFee, + common.UnionOptions(b.options, options)..., + ) +} diff --git a/wallet/chain/c/context.go b/wallet/chain/c/context.go index 1c01d8fb55c8..d506b42f81fa 100644 --- a/wallet/chain/c/context.go +++ b/wallet/chain/c/context.go @@ -3,81 +3,81 @@ package c -// import ( -// stdcontext "context" +import ( + stdcontext "context" -// "github.com/ava-labs/avalanchego/api/info" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/vms/avm" -// ) + "github.com/ava-labs/avalanchego/api/info" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/avm" +) -// var _ Context = (*context)(nil) +var _ Context = (*context)(nil) -// type Context interface { -// NetworkID() uint32 -// BlockchainID() ids.ID -// AVAXAssetID() ids.ID -// } +type Context interface { + NetworkID() uint32 + BlockchainID() ids.ID + AVAXAssetID() ids.ID +} -// type context struct { -// networkID uint32 -// blockchainID ids.ID -// avaxAssetID ids.ID -// } +type context struct { + networkID uint32 + blockchainID ids.ID + avaxAssetID ids.ID +} -// func NewContextFromURI(ctx stdcontext.Context, uri string) (Context, error) { -// infoClient := info.NewClient(uri) -// xChainClient := avm.NewClient(uri, "X") -// return NewContextFromClients(ctx, infoClient, xChainClient) -// } +func NewContextFromURI(ctx stdcontext.Context, uri string) (Context, error) { + infoClient := info.NewClient(uri) + xChainClient := avm.NewClient(uri, "X") + return NewContextFromClients(ctx, infoClient, xChainClient) +} -// func NewContextFromClients( -// ctx stdcontext.Context, -// infoClient info.Client, -// xChainClient avm.Client, -// ) (Context, error) { -// networkID, err := infoClient.GetNetworkID(ctx) -// if err != nil { -// return nil, err -// } +func NewContextFromClients( + ctx stdcontext.Context, + infoClient info.Client, + xChainClient avm.Client, +) (Context, error) { + networkID, err := infoClient.GetNetworkID(ctx) + if err != nil { + return nil, err + } -// chainID, err := infoClient.GetBlockchainID(ctx, "C") -// if err != nil { -// return nil, err -// } + chainID, err := infoClient.GetBlockchainID(ctx, "C") + if err != nil { + return nil, err + } -// asset, err := xChainClient.GetAssetDescription(ctx, "AVAX") -// if err != nil { -// return nil, err -// } + asset, err := xChainClient.GetAssetDescription(ctx, "AVAX") + if err != nil { + return nil, err + } -// return NewContext( -// networkID, -// chainID, -// asset.AssetID, -// ), nil -// } + return NewContext( + networkID, + chainID, + asset.AssetID, + ), nil +} -// func NewContext( -// networkID uint32, -// blockchainID ids.ID, -// avaxAssetID ids.ID, -// ) Context { -// return &context{ -// networkID: networkID, -// blockchainID: blockchainID, -// avaxAssetID: avaxAssetID, -// } -// } +func NewContext( + networkID uint32, + blockchainID ids.ID, + avaxAssetID ids.ID, +) Context { + return &context{ + networkID: networkID, + blockchainID: blockchainID, + avaxAssetID: avaxAssetID, + } +} -// func (c *context) NetworkID() uint32 { -// return c.networkID -// } +func (c *context) NetworkID() uint32 { + return c.networkID +} -// func (c *context) BlockchainID() ids.ID { -// return c.blockchainID -// } +func (c *context) BlockchainID() ids.ID { + return c.blockchainID +} -// func (c *context) AVAXAssetID() ids.ID { -// return c.avaxAssetID -// } +func (c *context) AVAXAssetID() ids.ID { + return c.avaxAssetID +} diff --git a/wallet/chain/c/signer.go b/wallet/chain/c/signer.go index 4bedc378234b..4fd85ed3b532 100644 --- a/wallet/chain/c/signer.go +++ b/wallet/chain/c/signer.go @@ -3,221 +3,221 @@ package c -// import ( -// "errors" -// "fmt" - -// stdcontext "context" - -// "github.com/ava-labs/coreth/plugin/evm" - -// ethcommon "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/avalanchego/database" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/utils/crypto/keychain" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// "github.com/ava-labs/avalanchego/utils/hashing" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/components/verify" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// ) - -// const version = 0 - -// var ( -// _ Signer = (*txSigner)(nil) - -// errUnknownInputType = errors.New("unknown input type") -// errUnknownCredentialType = errors.New("unknown credential type") -// errUnknownOutputType = errors.New("unknown output type") -// errInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") - -// emptySig [secp256k1.SignatureLen]byte -// ) - -// type Signer interface { -// SignUnsignedAtomic(ctx stdcontext.Context, tx evm.UnsignedAtomicTx) (*evm.Tx, error) -// SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error -// } - -// type EthKeychain interface { -// // The returned Signer can provide a signature for [addr] -// GetEth(addr ethcommon.Address) (keychain.Signer, bool) -// // Returns the set of addresses for which the accessor keeps an associated -// // signer -// EthAddresses() set.Set[ethcommon.Address] -// } - -// type SignerBackend interface { -// GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) -// } - -// type txSigner struct { -// avaxKC keychain.Keychain -// ethKC EthKeychain -// backend SignerBackend -// } - -// func NewSigner(avaxKC keychain.Keychain, ethKC EthKeychain, backend SignerBackend) Signer { -// return &txSigner{ -// avaxKC: avaxKC, -// ethKC: ethKC, -// backend: backend, -// } -// } - -// func (s *txSigner) SignUnsignedAtomic(ctx stdcontext.Context, utx evm.UnsignedAtomicTx) (*evm.Tx, error) { -// tx := &evm.Tx{UnsignedAtomicTx: utx} -// return tx, s.SignAtomic(ctx, tx) -// } - -// func (s *txSigner) SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error { -// switch utx := tx.UnsignedAtomicTx.(type) { -// case *evm.UnsignedImportTx: -// signers, err := s.getImportSigners(ctx, utx.SourceChain, utx.ImportedInputs) -// if err != nil { -// return err -// } -// return sign(tx, true, signers) -// case *evm.UnsignedExportTx: -// signers := s.getExportSigners(utx.Ins) -// return sign(tx, true, signers) -// default: -// return fmt.Errorf("%w: %T", errUnknownTxType, tx) -// } -// } - -// func (s *txSigner) getImportSigners(ctx stdcontext.Context, sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { -// txSigners := make([][]keychain.Signer, len(ins)) -// for credIndex, transferInput := range ins { -// input, ok := transferInput.In.(*secp256k1fx.TransferInput) -// if !ok { -// return nil, errUnknownInputType -// } - -// inputSigners := make([]keychain.Signer, len(input.SigIndices)) -// txSigners[credIndex] = inputSigners - -// utxoID := transferInput.InputID() -// utxo, err := s.backend.GetUTXO(ctx, sourceChainID, utxoID) -// if err == database.ErrNotFound { -// // If we don't have access to the UTXO, then we can't sign this -// // transaction. However, we can attempt to partially sign it. -// continue -// } -// if err != nil { -// return nil, err -// } - -// out, ok := utxo.Out.(*secp256k1fx.TransferOutput) -// if !ok { -// return nil, errUnknownOutputType -// } - -// for sigIndex, addrIndex := range input.SigIndices { -// if addrIndex >= uint32(len(out.Addrs)) { -// return nil, errInvalidUTXOSigIndex -// } - -// addr := out.Addrs[addrIndex] -// key, ok := s.avaxKC.Get(addr) -// if !ok { -// // If we don't have access to the key, then we can't sign this -// // transaction. However, we can attempt to partially sign it. -// continue -// } -// inputSigners[sigIndex] = key -// } -// } -// return txSigners, nil -// } - -// func (s *txSigner) getExportSigners(ins []evm.EVMInput) [][]keychain.Signer { -// txSigners := make([][]keychain.Signer, len(ins)) -// for credIndex, input := range ins { -// inputSigners := make([]keychain.Signer, 1) -// txSigners[credIndex] = inputSigners - -// key, ok := s.ethKC.GetEth(input.Address) -// if !ok { -// // If we don't have access to the key, then we can't sign this -// // transaction. However, we can attempt to partially sign it. -// continue -// } -// inputSigners[0] = key -// } -// return txSigners -// } - -// // TODO: remove [signHash] after the ledger supports signing all transactions. -// func sign(tx *evm.Tx, signHash bool, txSigners [][]keychain.Signer) error { -// unsignedBytes, err := evm.Codec.Marshal(version, &tx.UnsignedAtomicTx) -// if err != nil { -// return fmt.Errorf("couldn't marshal unsigned tx: %w", err) -// } -// unsignedHash := hashing.ComputeHash256(unsignedBytes) - -// if expectedLen := len(txSigners); expectedLen != len(tx.Creds) { -// tx.Creds = make([]verify.Verifiable, expectedLen) -// } - -// sigCache := make(map[ids.ShortID][secp256k1.SignatureLen]byte) -// for credIndex, inputSigners := range txSigners { -// credIntf := tx.Creds[credIndex] -// if credIntf == nil { -// credIntf = &secp256k1fx.Credential{} -// tx.Creds[credIndex] = credIntf -// } - -// cred, ok := credIntf.(*secp256k1fx.Credential) -// if !ok { -// return errUnknownCredentialType -// } -// if expectedLen := len(inputSigners); expectedLen != len(cred.Sigs) { -// cred.Sigs = make([][secp256k1.SignatureLen]byte, expectedLen) -// } - -// for sigIndex, signer := range inputSigners { -// if signer == nil { -// // If we don't have access to the key, then we can't sign this -// // transaction. However, we can attempt to partially sign it. -// continue -// } -// addr := signer.Address() -// if sig := cred.Sigs[sigIndex]; sig != emptySig { -// // If this signature has already been populated, we can just -// // copy the needed signature for the future. -// sigCache[addr] = sig -// continue -// } - -// if sig, exists := sigCache[addr]; exists { -// // If this key has already produced a signature, we can just -// // copy the previous signature. -// cred.Sigs[sigIndex] = sig -// continue -// } - -// var sig []byte -// if signHash { -// sig, err = signer.SignHash(unsignedHash) -// } else { -// sig, err = signer.Sign(unsignedBytes) -// } -// if err != nil { -// return fmt.Errorf("problem signing tx: %w", err) -// } -// copy(cred.Sigs[sigIndex][:], sig) -// sigCache[addr] = cred.Sigs[sigIndex] -// } -// } - -// signedBytes, err := evm.Codec.Marshal(version, tx) -// if err != nil { -// return fmt.Errorf("couldn't marshal tx: %w", err) -// } -// tx.Initialize(unsignedBytes, signedBytes) -// return nil -// } +import ( + "errors" + "fmt" + + stdcontext "context" + + "github.com/ava-labs/coreth/plugin/evm" + + ethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/avalanchego/database" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/crypto/keychain" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/hashing" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/components/verify" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" +) + +const version = 0 + +var ( + _ Signer = (*txSigner)(nil) + + errUnknownInputType = errors.New("unknown input type") + errUnknownCredentialType = errors.New("unknown credential type") + errUnknownOutputType = errors.New("unknown output type") + errInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") + + emptySig [secp256k1.SignatureLen]byte +) + +type Signer interface { + SignUnsignedAtomic(ctx stdcontext.Context, tx evm.UnsignedAtomicTx) (*evm.Tx, error) + SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error +} + +type EthKeychain interface { + // The returned Signer can provide a signature for [addr] + GetEth(addr ethcommon.Address) (keychain.Signer, bool) + // Returns the set of addresses for which the accessor keeps an associated + // signer + EthAddresses() set.Set[ethcommon.Address] +} + +type SignerBackend interface { + GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) +} + +type txSigner struct { + avaxKC keychain.Keychain + ethKC EthKeychain + backend SignerBackend +} + +func NewSigner(avaxKC keychain.Keychain, ethKC EthKeychain, backend SignerBackend) Signer { + return &txSigner{ + avaxKC: avaxKC, + ethKC: ethKC, + backend: backend, + } +} + +func (s *txSigner) SignUnsignedAtomic(ctx stdcontext.Context, utx evm.UnsignedAtomicTx) (*evm.Tx, error) { + tx := &evm.Tx{UnsignedAtomicTx: utx} + return tx, s.SignAtomic(ctx, tx) +} + +func (s *txSigner) SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error { + switch utx := tx.UnsignedAtomicTx.(type) { + case *evm.UnsignedImportTx: + signers, err := s.getImportSigners(ctx, utx.SourceChain, utx.ImportedInputs) + if err != nil { + return err + } + return sign(tx, true, signers) + case *evm.UnsignedExportTx: + signers := s.getExportSigners(utx.Ins) + return sign(tx, true, signers) + default: + return fmt.Errorf("%w: %T", errUnknownTxType, tx) + } +} + +func (s *txSigner) getImportSigners(ctx stdcontext.Context, sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { + txSigners := make([][]keychain.Signer, len(ins)) + for credIndex, transferInput := range ins { + input, ok := transferInput.In.(*secp256k1fx.TransferInput) + if !ok { + return nil, errUnknownInputType + } + + inputSigners := make([]keychain.Signer, len(input.SigIndices)) + txSigners[credIndex] = inputSigners + + utxoID := transferInput.InputID() + utxo, err := s.backend.GetUTXO(ctx, sourceChainID, utxoID) + if err == database.ErrNotFound { + // If we don't have access to the UTXO, then we can't sign this + // transaction. However, we can attempt to partially sign it. + continue + } + if err != nil { + return nil, err + } + + out, ok := utxo.Out.(*secp256k1fx.TransferOutput) + if !ok { + return nil, errUnknownOutputType + } + + for sigIndex, addrIndex := range input.SigIndices { + if addrIndex >= uint32(len(out.Addrs)) { + return nil, errInvalidUTXOSigIndex + } + + addr := out.Addrs[addrIndex] + key, ok := s.avaxKC.Get(addr) + if !ok { + // If we don't have access to the key, then we can't sign this + // transaction. However, we can attempt to partially sign it. + continue + } + inputSigners[sigIndex] = key + } + } + return txSigners, nil +} + +func (s *txSigner) getExportSigners(ins []evm.EVMInput) [][]keychain.Signer { + txSigners := make([][]keychain.Signer, len(ins)) + for credIndex, input := range ins { + inputSigners := make([]keychain.Signer, 1) + txSigners[credIndex] = inputSigners + + key, ok := s.ethKC.GetEth(input.Address) + if !ok { + // If we don't have access to the key, then we can't sign this + // transaction. However, we can attempt to partially sign it. + continue + } + inputSigners[0] = key + } + return txSigners +} + +// TODO: remove [signHash] after the ledger supports signing all transactions. +func sign(tx *evm.Tx, signHash bool, txSigners [][]keychain.Signer) error { + unsignedBytes, err := evm.Codec.Marshal(version, &tx.UnsignedAtomicTx) + if err != nil { + return fmt.Errorf("couldn't marshal unsigned tx: %w", err) + } + unsignedHash := hashing.ComputeHash256(unsignedBytes) + + if expectedLen := len(txSigners); expectedLen != len(tx.Creds) { + tx.Creds = make([]verify.Verifiable, expectedLen) + } + + sigCache := make(map[ids.ShortID][secp256k1.SignatureLen]byte) + for credIndex, inputSigners := range txSigners { + credIntf := tx.Creds[credIndex] + if credIntf == nil { + credIntf = &secp256k1fx.Credential{} + tx.Creds[credIndex] = credIntf + } + + cred, ok := credIntf.(*secp256k1fx.Credential) + if !ok { + return errUnknownCredentialType + } + if expectedLen := len(inputSigners); expectedLen != len(cred.Sigs) { + cred.Sigs = make([][secp256k1.SignatureLen]byte, expectedLen) + } + + for sigIndex, signer := range inputSigners { + if signer == nil { + // If we don't have access to the key, then we can't sign this + // transaction. However, we can attempt to partially sign it. + continue + } + addr := signer.Address() + if sig := cred.Sigs[sigIndex]; sig != emptySig { + // If this signature has already been populated, we can just + // copy the needed signature for the future. + sigCache[addr] = sig + continue + } + + if sig, exists := sigCache[addr]; exists { + // If this key has already produced a signature, we can just + // copy the previous signature. + cred.Sigs[sigIndex] = sig + continue + } + + var sig []byte + if signHash { + sig, err = signer.SignHash(unsignedHash) + } else { + sig, err = signer.Sign(unsignedBytes) + } + if err != nil { + return fmt.Errorf("problem signing tx: %w", err) + } + copy(cred.Sigs[sigIndex][:], sig) + sigCache[addr] = cred.Sigs[sigIndex] + } + } + + signedBytes, err := evm.Codec.Marshal(version, tx) + if err != nil { + return fmt.Errorf("couldn't marshal tx: %w", err) + } + tx.Initialize(unsignedBytes, signedBytes) + return nil +} diff --git a/wallet/chain/c/wallet.go b/wallet/chain/c/wallet.go index ebee50a9a958..fb1a83d53dad 100644 --- a/wallet/chain/c/wallet.go +++ b/wallet/chain/c/wallet.go @@ -3,204 +3,204 @@ package c -// import ( -// "errors" -// "math/big" -// "time" - -// "github.com/ava-labs/coreth/ethclient" -// "github.com/ava-labs/coreth/plugin/evm" - -// ethcommon "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var ( -// _ Wallet = (*wallet)(nil) - -// errNotCommitted = errors.New("not committed") -// ) - -// type Wallet interface { -// Context - -// // Builder returns the builder that will be used to create the transactions. -// Builder() Builder - -// // Signer returns the signer that will be used to sign the transactions. -// Signer() Signer - -// // IssueImportTx creates, signs, and issues an import transaction that -// // attempts to consume all the available UTXOs and import the funds to [to]. -// // -// // - [chainID] specifies the chain to be importing funds from. -// // - [to] specifies where to send the imported funds to. -// IssueImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// options ...common.Option, -// ) (*evm.Tx, error) - -// // IssueExportTx creates, signs, and issues an export transaction that -// // attempts to send all the provided [outputs] to the requested [chainID]. -// // -// // - [chainID] specifies the chain to be exporting the funds to. -// // - [outputs] specifies the outputs to send to the [chainID]. -// IssueExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// options ...common.Option, -// ) (*evm.Tx, error) - -// // IssueUnsignedTx signs and issues the unsigned tx. -// IssueUnsignedAtomicTx( -// utx evm.UnsignedAtomicTx, -// options ...common.Option, -// ) (*evm.Tx, error) - -// // IssueAtomicTx issues the signed tx. -// IssueAtomicTx( -// tx *evm.Tx, -// options ...common.Option, -// ) error -// } - -// func NewWallet( -// builder Builder, -// signer Signer, -// avaxClient evm.Client, -// ethClient ethclient.Client, -// backend Backend, -// ) Wallet { -// return &wallet{ -// Backend: backend, -// builder: builder, -// signer: signer, -// avaxClient: avaxClient, -// ethClient: ethClient, -// } -// } - -// type wallet struct { -// Backend -// builder Builder -// signer Signer -// avaxClient evm.Client -// ethClient ethclient.Client -// } - -// func (w *wallet) Builder() Builder { -// return w.builder -// } - -// func (w *wallet) Signer() Signer { -// return w.signer -// } - -// func (w *wallet) IssueImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// options ...common.Option, -// ) (*evm.Tx, error) { -// baseFee, err := w.baseFee(options) -// if err != nil { -// return nil, err -// } - -// utx, err := w.builder.NewImportTx(chainID, to, baseFee, options...) -// if err != nil { -// return nil, err -// } -// return w.IssueUnsignedAtomicTx(utx, options...) -// } - -// func (w *wallet) IssueExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// options ...common.Option, -// ) (*evm.Tx, error) { -// baseFee, err := w.baseFee(options) -// if err != nil { -// return nil, err -// } - -// utx, err := w.builder.NewExportTx(chainID, outputs, baseFee, options...) -// if err != nil { -// return nil, err -// } -// return w.IssueUnsignedAtomicTx(utx, options...) -// } - -// func (w *wallet) IssueUnsignedAtomicTx( -// utx evm.UnsignedAtomicTx, -// options ...common.Option, -// ) (*evm.Tx, error) { -// ops := common.NewOptions(options) -// ctx := ops.Context() -// tx, err := w.signer.SignUnsignedAtomic(ctx, utx) -// if err != nil { -// return nil, err -// } - -// return tx, w.IssueAtomicTx(tx, options...) -// } - -// func (w *wallet) IssueAtomicTx( -// tx *evm.Tx, -// options ...common.Option, -// ) error { -// ops := common.NewOptions(options) -// ctx := ops.Context() -// txID, err := w.avaxClient.IssueTx(ctx, tx.SignedBytes()) -// if err != nil { -// return err -// } - -// if f := ops.PostIssuanceFunc(); f != nil { -// f(txID) -// } - -// if ops.AssumeDecided() { -// return w.Backend.AcceptAtomicTx(ctx, tx) -// } - -// pollFrequency := ops.PollFrequency() -// ticker := time.NewTicker(pollFrequency) -// defer ticker.Stop() - -// for { -// status, err := w.avaxClient.GetAtomicTxStatus(ctx, txID) -// if err != nil { -// return err -// } - -// switch status { -// case evm.Accepted: -// return w.Backend.AcceptAtomicTx(ctx, tx) -// case evm.Dropped, evm.Unknown: -// return errNotCommitted -// } - -// // The tx is Processing. - -// select { -// case <-ticker.C: -// case <-ctx.Done(): -// return ctx.Err() -// } -// } -// } - -// func (w *wallet) baseFee(options []common.Option) (*big.Int, error) { -// ops := common.NewOptions(options) -// baseFee := ops.BaseFee(nil) -// if baseFee != nil { -// return baseFee, nil -// } - -// ctx := ops.Context() -// return w.ethClient.EstimateBaseFee(ctx) -// } +import ( + "errors" + "math/big" + "time" + + "github.com/ava-labs/coreth/ethclient" + "github.com/ava-labs/coreth/plugin/evm" + + ethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var ( + _ Wallet = (*wallet)(nil) + + errNotCommitted = errors.New("not committed") +) + +type Wallet interface { + Context + + // Builder returns the builder that will be used to create the transactions. + Builder() Builder + + // Signer returns the signer that will be used to sign the transactions. + Signer() Signer + + // IssueImportTx creates, signs, and issues an import transaction that + // attempts to consume all the available UTXOs and import the funds to [to]. + // + // - [chainID] specifies the chain to be importing funds from. + // - [to] specifies where to send the imported funds to. + IssueImportTx( + chainID ids.ID, + to ethcommon.Address, + options ...common.Option, + ) (*evm.Tx, error) + + // IssueExportTx creates, signs, and issues an export transaction that + // attempts to send all the provided [outputs] to the requested [chainID]. + // + // - [chainID] specifies the chain to be exporting the funds to. + // - [outputs] specifies the outputs to send to the [chainID]. + IssueExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + options ...common.Option, + ) (*evm.Tx, error) + + // IssueUnsignedTx signs and issues the unsigned tx. + IssueUnsignedAtomicTx( + utx evm.UnsignedAtomicTx, + options ...common.Option, + ) (*evm.Tx, error) + + // IssueAtomicTx issues the signed tx. + IssueAtomicTx( + tx *evm.Tx, + options ...common.Option, + ) error +} + +func NewWallet( + builder Builder, + signer Signer, + avaxClient evm.Client, + ethClient ethclient.Client, + backend Backend, +) Wallet { + return &wallet{ + Backend: backend, + builder: builder, + signer: signer, + avaxClient: avaxClient, + ethClient: ethClient, + } +} + +type wallet struct { + Backend + builder Builder + signer Signer + avaxClient evm.Client + ethClient ethclient.Client +} + +func (w *wallet) Builder() Builder { + return w.builder +} + +func (w *wallet) Signer() Signer { + return w.signer +} + +func (w *wallet) IssueImportTx( + chainID ids.ID, + to ethcommon.Address, + options ...common.Option, +) (*evm.Tx, error) { + baseFee, err := w.baseFee(options) + if err != nil { + return nil, err + } + + utx, err := w.builder.NewImportTx(chainID, to, baseFee, options...) + if err != nil { + return nil, err + } + return w.IssueUnsignedAtomicTx(utx, options...) +} + +func (w *wallet) IssueExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + options ...common.Option, +) (*evm.Tx, error) { + baseFee, err := w.baseFee(options) + if err != nil { + return nil, err + } + + utx, err := w.builder.NewExportTx(chainID, outputs, baseFee, options...) + if err != nil { + return nil, err + } + return w.IssueUnsignedAtomicTx(utx, options...) +} + +func (w *wallet) IssueUnsignedAtomicTx( + utx evm.UnsignedAtomicTx, + options ...common.Option, +) (*evm.Tx, error) { + ops := common.NewOptions(options) + ctx := ops.Context() + tx, err := w.signer.SignUnsignedAtomic(ctx, utx) + if err != nil { + return nil, err + } + + return tx, w.IssueAtomicTx(tx, options...) +} + +func (w *wallet) IssueAtomicTx( + tx *evm.Tx, + options ...common.Option, +) error { + ops := common.NewOptions(options) + ctx := ops.Context() + txID, err := w.avaxClient.IssueTx(ctx, tx.SignedBytes()) + if err != nil { + return err + } + + if f := ops.PostIssuanceFunc(); f != nil { + f(txID) + } + + if ops.AssumeDecided() { + return w.Backend.AcceptAtomicTx(ctx, tx) + } + + pollFrequency := ops.PollFrequency() + ticker := time.NewTicker(pollFrequency) + defer ticker.Stop() + + for { + status, err := w.avaxClient.GetAtomicTxStatus(ctx, txID) + if err != nil { + return err + } + + switch status { + case evm.Accepted: + return w.Backend.AcceptAtomicTx(ctx, tx) + case evm.Dropped, evm.Unknown: + return errNotCommitted + } + + // The tx is Processing. + + select { + case <-ticker.C: + case <-ctx.Done(): + return ctx.Err() + } + } +} + +func (w *wallet) baseFee(options []common.Option) (*big.Int, error) { + ops := common.NewOptions(options) + baseFee := ops.BaseFee(nil) + if baseFee != nil { + return baseFee, nil + } + + ctx := ops.Context() + return w.ethClient.EstimateBaseFee(ctx) +} diff --git a/wallet/chain/c/wallet_with_options.go b/wallet/chain/c/wallet_with_options.go index fd69a6d4fd02..7d6193683d49 100644 --- a/wallet/chain/c/wallet_with_options.go +++ b/wallet/chain/c/wallet_with_options.go @@ -3,80 +3,80 @@ package c -// import ( -// "github.com/ava-labs/coreth/plugin/evm" +import ( + "github.com/ava-labs/coreth/plugin/evm" -// ethcommon "github.com/ethereum/go-ethereum/common" + ethcommon "github.com/ethereum/go-ethereum/common" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) -// var _ Wallet = (*walletWithOptions)(nil) +var _ Wallet = (*walletWithOptions)(nil) -// func NewWalletWithOptions( -// wallet Wallet, -// options ...common.Option, -// ) Wallet { -// return &walletWithOptions{ -// Wallet: wallet, -// options: options, -// } -// } +func NewWalletWithOptions( + wallet Wallet, + options ...common.Option, +) Wallet { + return &walletWithOptions{ + Wallet: wallet, + options: options, + } +} -// type walletWithOptions struct { -// Wallet -// options []common.Option -// } +type walletWithOptions struct { + Wallet + options []common.Option +} -// func (w *walletWithOptions) Builder() Builder { -// return NewBuilderWithOptions( -// w.Wallet.Builder(), -// w.options..., -// ) -// } +func (w *walletWithOptions) Builder() Builder { + return NewBuilderWithOptions( + w.Wallet.Builder(), + w.options..., + ) +} -// func (w *walletWithOptions) IssueImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// options ...common.Option, -// ) (*evm.Tx, error) { -// return w.Wallet.IssueImportTx( -// chainID, -// to, -// common.UnionOptions(w.options, options)..., -// ) -// } +func (w *walletWithOptions) IssueImportTx( + chainID ids.ID, + to ethcommon.Address, + options ...common.Option, +) (*evm.Tx, error) { + return w.Wallet.IssueImportTx( + chainID, + to, + common.UnionOptions(w.options, options)..., + ) +} -// func (w *walletWithOptions) IssueExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// options ...common.Option, -// ) (*evm.Tx, error) { -// return w.Wallet.IssueExportTx( -// chainID, -// outputs, -// common.UnionOptions(w.options, options)..., -// ) -// } +func (w *walletWithOptions) IssueExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + options ...common.Option, +) (*evm.Tx, error) { + return w.Wallet.IssueExportTx( + chainID, + outputs, + common.UnionOptions(w.options, options)..., + ) +} -// func (w *walletWithOptions) IssueUnsignedAtomicTx( -// utx evm.UnsignedAtomicTx, -// options ...common.Option, -// ) (*evm.Tx, error) { -// return w.Wallet.IssueUnsignedAtomicTx( -// utx, -// common.UnionOptions(w.options, options)..., -// ) -// } +func (w *walletWithOptions) IssueUnsignedAtomicTx( + utx evm.UnsignedAtomicTx, + options ...common.Option, +) (*evm.Tx, error) { + return w.Wallet.IssueUnsignedAtomicTx( + utx, + common.UnionOptions(w.options, options)..., + ) +} -// func (w *walletWithOptions) IssueAtomicTx( -// tx *evm.Tx, -// options ...common.Option, -// ) error { -// return w.Wallet.IssueAtomicTx( -// tx, -// common.UnionOptions(w.options, options)..., -// ) -// } +func (w *walletWithOptions) IssueAtomicTx( + tx *evm.Tx, + options ...common.Option, +) error { + return w.Wallet.IssueAtomicTx( + tx, + common.UnionOptions(w.options, options)..., + ) +} diff --git a/wallet/subnet/primary/api.go b/wallet/subnet/primary/api.go index 00ebea6090fd..3ac72c217884 100644 --- a/wallet/subnet/primary/api.go +++ b/wallet/subnet/primary/api.go @@ -5,11 +5,12 @@ package primary import ( "context" - // "fmt" + "fmt" - // "github.com/ava-labs/coreth/ethclient" + "github.com/ava-labs/coreth/ethclient" + "github.com/ava-labs/coreth/plugin/evm" - // "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common" "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/codec" @@ -21,8 +22,7 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - - // "github.com/ava-labs/avalanchego/wallet/chain/c" + "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/x" ) @@ -59,9 +59,9 @@ type AVAXState struct { PCTX p.Context XClient avm.Client XCTX x.Context - // CClient evm.Client - // CCTX c.Context - UTXOs UTXOs + CClient evm.Client + CCTX c.Context + UTXOs UTXOs } func FetchState( @@ -75,7 +75,7 @@ func FetchState( infoClient := info.NewClient(uri) pClient := platformvm.NewClient(uri) xClient := avm.NewClient(uri, "X") - // cClient := evm.NewCChainClient(uri) + cClient := evm.NewCChainClient(uri) pCTX, err := p.NewContextFromClients(ctx, infoClient, xClient) if err != nil { @@ -87,10 +87,10 @@ func FetchState( return nil, err } - // cCTX, err := c.NewContextFromClients(ctx, infoClient, xClient) - // if err != nil { - // return nil, err - // } + cCTX, err := c.NewContextFromClients(ctx, infoClient, xClient) + if err != nil { + return nil, err + } utxos := NewUTXOs() addrList := addrs.List() @@ -109,11 +109,11 @@ func FetchState( client: xClient, codec: x.Parser.Codec(), }, - // { - // id: cCTX.BlockchainID(), - // client: cClient, - // codec: evm.Codec, - // }, + { + id: cCTX.BlockchainID(), + client: cClient, + codec: evm.Codec, + }, } for _, destinationChain := range chains { for _, sourceChain := range chains { @@ -136,52 +136,52 @@ func FetchState( PCTX: pCTX, XClient: xClient, XCTX: xCTX, - // CClient: cClient, - // CCTX: cCTX, - UTXOs: utxos, + CClient: cClient, + CCTX: cCTX, + UTXOs: utxos, }, nil } -// type EthState struct { -// Client ethclient.Client -// Accounts map[common.Address]*c.Account -// } - -// func FetchEthState( -// ctx context.Context, -// uri string, -// addrs set.Set[common.Address], -// ) (*EthState, error) { -// path := fmt.Sprintf( -// "%s/ext/%s/C/rpc", -// uri, -// constants.ChainAliasPrefix, -// ) -// client, err := ethclient.Dial(path) -// if err != nil { -// return nil, err -// } - -// accounts := make(map[common.Address]*c.Account, addrs.Len()) -// for addr := range addrs { -// balance, err := client.BalanceAt(ctx, addr, nil) -// if err != nil { -// return nil, err -// } -// nonce, err := client.NonceAt(ctx, addr, nil) -// if err != nil { -// return nil, err -// } -// accounts[addr] = &c.Account{ -// Balance: balance, -// Nonce: nonce, -// } -// } -// return &EthState{ -// Client: client, -// Accounts: accounts, -// }, nil -// } +type EthState struct { + Client ethclient.Client + Accounts map[common.Address]*c.Account +} + +func FetchEthState( + ctx context.Context, + uri string, + addrs set.Set[common.Address], +) (*EthState, error) { + path := fmt.Sprintf( + "%s/ext/%s/C/rpc", + uri, + constants.ChainAliasPrefix, + ) + client, err := ethclient.Dial(path) + if err != nil { + return nil, err + } + + accounts := make(map[common.Address]*c.Account, addrs.Len()) + for addr := range addrs { + balance, err := client.BalanceAt(ctx, addr, nil) + if err != nil { + return nil, err + } + nonce, err := client.NonceAt(ctx, addr, nil) + if err != nil { + return nil, err + } + accounts[addr] = &c.Account{ + Balance: balance, + Nonce: nonce, + } + } + return &EthState{ + Client: client, + Accounts: accounts, + }, nil +} // AddAllUTXOs fetches all the UTXOs referenced by [addresses] that were sent // from [sourceChainID] to [destinationChainID] from the [client]. It then uses diff --git a/wallet/subnet/primary/example_test.go b/wallet/subnet/primary/example_test.go index 4a73e8c070b2..483c049d4ac0 100644 --- a/wallet/subnet/primary/example_test.go +++ b/wallet/subnet/primary/example_test.go @@ -30,7 +30,7 @@ func ExampleWallet() { wallet, err := MakeWallet(ctx, &WalletConfig{ URI: LocalAPIURI, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet with: %s\n", err) diff --git a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go index 21c081d2982b..d5e8ce422307 100644 --- a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go +++ b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go @@ -46,9 +46,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - // EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/examples/add-primary-validator/main.go b/wallet/subnet/primary/examples/add-primary-validator/main.go index 13c28f995f63..a56dae23db3a 100644 --- a/wallet/subnet/primary/examples/add-primary-validator/main.go +++ b/wallet/subnet/primary/examples/add-primary-validator/main.go @@ -45,7 +45,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/c-chain-export/main.go b/wallet/subnet/primary/examples/c-chain-export/main.go index a6b9a0c810b8..fec55c899feb 100644 --- a/wallet/subnet/primary/examples/c-chain-export/main.go +++ b/wallet/subnet/primary/examples/c-chain-export/main.go @@ -3,70 +3,70 @@ package main -// import ( -// "context" -// "log" -// "time" +import ( + "context" + "log" + "time" -// "github.com/ava-labs/avalanchego/genesis" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary" -// ) + "github.com/ava-labs/avalanchego/genesis" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary" +) -// func main() { -// key := genesis.EWOQKey -// uri := primary.LocalAPIURI -// kc := secp256k1fx.NewKeychain(key) -// avaxAddr := key.Address() +func main() { + key := genesis.EWOQKey + uri := primary.LocalAPIURI + kc := secp256k1fx.NewKeychain(key) + avaxAddr := key.Address() -// ctx := context.Background() + ctx := context.Background() -// // MakeWallet fetches the available UTXOs owned by [kc] on the network that -// // [uri] is hosting. -// walletSyncStartTime := time.Now() -// wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ -// URI: uri, -// AVAXKeychain: kc, -// EthKeychain: kc, -// }) -// if err != nil { -// log.Fatalf("failed to initialize wallet: %s\n", err) -// } -// log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) + // MakeWallet fetches the available UTXOs owned by [kc] on the network that + // [uri] is hosting. + walletSyncStartTime := time.Now() + wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, + }) + if err != nil { + log.Fatalf("failed to initialize wallet: %s\n", err) + } + log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) -// // Get the P-chain wallet -// pWallet := wallet.P() -// cWallet := wallet.C() + // Get the P-chain wallet + pWallet := wallet.P() + cWallet := wallet.C() -// // Pull out useful constants to use when issuing transactions. -// cChainID := cWallet.BlockchainID() -// owner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// avaxAddr, -// }, -// } + // Pull out useful constants to use when issuing transactions. + cChainID := cWallet.BlockchainID() + owner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + avaxAddr, + }, + } -// exportStartTime := time.Now() -// exportTx, err := cWallet.IssueExportTx( -// constants.PlatformChainID, -// []*secp256k1fx.TransferOutput{{ -// Amt: units.Avax, -// OutputOwners: owner, -// }}, -// ) -// if err != nil { -// log.Fatalf("failed to issue export transaction: %s\n", err) -// } -// log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) + exportStartTime := time.Now() + exportTx, err := cWallet.IssueExportTx( + constants.PlatformChainID, + []*secp256k1fx.TransferOutput{{ + Amt: units.Avax, + OutputOwners: owner, + }}, + ) + if err != nil { + log.Fatalf("failed to issue export transaction: %s\n", err) + } + log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) -// importStartTime := time.Now() -// importTx, err := pWallet.IssueImportTx(cChainID, &owner) -// if err != nil { -// log.Fatalf("failed to issue import transaction: %s\n", err) -// } -// log.Printf("issued import %s in %s\n", importTx.ID(), time.Since(importStartTime)) -// } + importStartTime := time.Now() + importTx, err := pWallet.IssueImportTx(cChainID, &owner) + if err != nil { + log.Fatalf("failed to issue import transaction: %s\n", err) + } + log.Printf("issued import %s in %s\n", importTx.ID(), time.Since(importStartTime)) +} diff --git a/wallet/subnet/primary/examples/c-chain-import/main.go b/wallet/subnet/primary/examples/c-chain-import/main.go index 2d9b8a244cb0..b4dc4e603eb3 100644 --- a/wallet/subnet/primary/examples/c-chain-import/main.go +++ b/wallet/subnet/primary/examples/c-chain-import/main.go @@ -3,75 +3,75 @@ package main -// import ( -// "context" -// "log" -// "time" +import ( + "context" + "log" + "time" -// "github.com/ava-labs/coreth/plugin/evm" + "github.com/ava-labs/coreth/plugin/evm" -// "github.com/ava-labs/avalanchego/genesis" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary" -// ) + "github.com/ava-labs/avalanchego/genesis" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary" +) -// func main() { -// key := genesis.EWOQKey -// uri := primary.LocalAPIURI -// kc := secp256k1fx.NewKeychain(key) -// avaxAddr := key.Address() -// ethAddr := evm.PublicKeyToEthAddress(key.PublicKey()) +func main() { + key := genesis.EWOQKey + uri := primary.LocalAPIURI + kc := secp256k1fx.NewKeychain(key) + avaxAddr := key.Address() + ethAddr := evm.PublicKeyToEthAddress(key.PublicKey()) -// ctx := context.Background() + ctx := context.Background() -// // MakeWallet fetches the available UTXOs owned by [kc] on the network that -// // [uri] is hosting. -// walletSyncStartTime := time.Now() -// wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ -// URI: uri, -// AVAXKeychain: kc, -// EthKeychain: kc, -// }) -// if err != nil { -// log.Fatalf("failed to initialize wallet: %s\n", err) -// } -// log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) + // MakeWallet fetches the available UTXOs owned by [kc] on the network that + // [uri] is hosting. + walletSyncStartTime := time.Now() + wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, + }) + if err != nil { + log.Fatalf("failed to initialize wallet: %s\n", err) + } + log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) -// // Get the P-chain wallet -// pWallet := wallet.P() -// cWallet := wallet.C() + // Get the P-chain wallet + pWallet := wallet.P() + cWallet := wallet.C() -// // Pull out useful constants to use when issuing transactions. -// cChainID := cWallet.BlockchainID() -// avaxAssetID := cWallet.AVAXAssetID() -// owner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// avaxAddr, -// }, -// } + // Pull out useful constants to use when issuing transactions. + cChainID := cWallet.BlockchainID() + avaxAssetID := cWallet.AVAXAssetID() + owner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + avaxAddr, + }, + } -// exportStartTime := time.Now() -// exportTx, err := pWallet.IssueExportTx(cChainID, []*avax.TransferableOutput{{ -// Asset: avax.Asset{ID: avaxAssetID}, -// Out: &secp256k1fx.TransferOutput{ -// Amt: units.Avax, -// OutputOwners: owner, -// }, -// }}) -// if err != nil { -// log.Fatalf("failed to issue export transaction: %s\n", err) -// } -// log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) + exportStartTime := time.Now() + exportTx, err := pWallet.IssueExportTx(cChainID, []*avax.TransferableOutput{{ + Asset: avax.Asset{ID: avaxAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: units.Avax, + OutputOwners: owner, + }, + }}) + if err != nil { + log.Fatalf("failed to issue export transaction: %s\n", err) + } + log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) -// importStartTime := time.Now() -// importTx, err := cWallet.IssueImportTx(constants.PlatformChainID, ethAddr) -// if err != nil { -// log.Fatalf("failed to issue import transaction: %s\n", err) -// } -// log.Printf("issued import %s to %s in %s\n", importTx.ID(), ethAddr.Hex(), time.Since(importStartTime)) -// } + importStartTime := time.Now() + importTx, err := cWallet.IssueImportTx(constants.PlatformChainID, ethAddr) + if err != nil { + log.Fatalf("failed to issue import transaction: %s\n", err) + } + log.Printf("issued import %s to %s in %s\n", importTx.ID(), ethAddr.Hex(), time.Since(importStartTime)) +} diff --git a/wallet/subnet/primary/examples/create-asset/main.go b/wallet/subnet/primary/examples/create-asset/main.go index 0bccfbb5fc52..30804f083df6 100644 --- a/wallet/subnet/primary/examples/create-asset/main.go +++ b/wallet/subnet/primary/examples/create-asset/main.go @@ -30,7 +30,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/create-chain/main.go b/wallet/subnet/primary/examples/create-chain/main.go index 521a3cca53cf..5e6898a1b649 100644 --- a/wallet/subnet/primary/examples/create-chain/main.go +++ b/wallet/subnet/primary/examples/create-chain/main.go @@ -41,9 +41,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - // EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/examples/create-locked-stakeable/main.go b/wallet/subnet/primary/examples/create-locked-stakeable/main.go index 92f1b5cb0e1b..e688968e9e8a 100644 --- a/wallet/subnet/primary/examples/create-locked-stakeable/main.go +++ b/wallet/subnet/primary/examples/create-locked-stakeable/main.go @@ -39,7 +39,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/create-subnet/main.go b/wallet/subnet/primary/examples/create-subnet/main.go index 3e8d69bc016a..add98ea7931c 100644 --- a/wallet/subnet/primary/examples/create-subnet/main.go +++ b/wallet/subnet/primary/examples/create-subnet/main.go @@ -28,7 +28,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/remove-subnet-validator/main.go b/wallet/subnet/primary/examples/remove-subnet-validator/main.go index 46f4b85124db..2842c7c0a790 100644 --- a/wallet/subnet/primary/examples/remove-subnet-validator/main.go +++ b/wallet/subnet/primary/examples/remove-subnet-validator/main.go @@ -38,9 +38,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - // EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/wallet.go b/wallet/subnet/primary/wallet.go index ae5e4202a099..54de390d029c 100644 --- a/wallet/subnet/primary/wallet.go +++ b/wallet/subnet/primary/wallet.go @@ -11,8 +11,7 @@ import ( "github.com/ava-labs/avalanchego/utils/crypto/keychain" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - - // "github.com/ava-labs/avalanchego/wallet/chain/c" + "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/x" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -24,13 +23,13 @@ var _ Wallet = (*wallet)(nil) type Wallet interface { P() p.Wallet X() x.Wallet - // C() c.Wallet + C() c.Wallet } type wallet struct { p p.Wallet x x.Wallet - // c c.Wallet + c c.Wallet } func (w *wallet) P() p.Wallet { @@ -41,16 +40,16 @@ func (w *wallet) X() x.Wallet { return w.x } -// func (w *wallet) C() c.Wallet { -// return w.c -// } +func (w *wallet) C() c.Wallet { + return w.c +} // Creates a new default wallet -func NewWallet(p p.Wallet, x x.Wallet /*, c c.Wallet*/) Wallet { +func NewWallet(p p.Wallet, x x.Wallet, c c.Wallet) Wallet { return &wallet{ p: p, x: x, - // c: c, + c: c, } } @@ -59,7 +58,7 @@ func NewWalletWithOptions(w Wallet, options ...common.Option) Wallet { return NewWallet( p.NewWalletWithOptions(w.P(), options...), x.NewWalletWithOptions(w.X(), options...), - // c.NewWalletWithOptions(w.C(), options...), + c.NewWalletWithOptions(w.C(), options...), ) } @@ -68,7 +67,7 @@ type WalletConfig struct { URI string // required // Keys to use for signing all transactions. AVAXKeychain keychain.Keychain // required - // EthKeychain c.EthKeychain // required + EthKeychain c.EthKeychain // required // Set of P-chain transactions that the wallet should know about to be able // to generate transactions. PChainTxs map[ids.ID]*txs.Tx // optional @@ -94,11 +93,11 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { return nil, err } - // ethAddrs := config.EthKeychain.EthAddresses() - // ethState, err := FetchEthState(ctx, config.URI, ethAddrs) - // if err != nil { - // return nil, err - // } + ethAddrs := config.EthKeychain.EthAddresses() + ethState, err := FetchEthState(ctx, config.URI, ethAddrs) + if err != nil { + return nil, err + } pChainTxs := config.PChainTxs if pChainTxs == nil { @@ -128,15 +127,15 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { xBuilder := x.NewBuilder(avaxAddrs, xBackend) xSigner := x.NewSigner(config.AVAXKeychain, xBackend) - // cChainID := avaxState.CCTX.BlockchainID() - // cUTXOs := NewChainUTXOs(cChainID, avaxState.UTXOs) - // cBackend := c.NewBackend(avaxState.CCTX, cUTXOs, ethState.Accounts) - // cBuilder := c.NewBuilder(avaxAddrs, ethAddrs, cBackend) - // cSigner := c.NewSigner(config.AVAXKeychain, config.EthKeychain, cBackend) + cChainID := avaxState.CCTX.BlockchainID() + cUTXOs := NewChainUTXOs(cChainID, avaxState.UTXOs) + cBackend := c.NewBackend(avaxState.CCTX, cUTXOs, ethState.Accounts) + cBuilder := c.NewBuilder(avaxAddrs, ethAddrs, cBackend) + cSigner := c.NewSigner(config.AVAXKeychain, config.EthKeychain, cBackend) return NewWallet( p.NewWallet(pBuilder, pSigner, avaxState.PClient, pBackend), x.NewWallet(xBuilder, xSigner, avaxState.XClient, xBackend), - // c.NewWallet(cBuilder, cSigner, avaxState.CClient, ethState.Client, cBackend), + c.NewWallet(cBuilder, cSigner, avaxState.CClient, ethState.Client, cBackend), ), nil } From b34e974908d87a526457002525e4b12f6307c0c5 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 30 Oct 2023 08:28:32 +0100 Subject: [PATCH 04/13] temporarily cut coreth dependency --- go.mod | 25 - go.sum | 76 -- node/node.go | 4 +- tests/e2e/c/dynamic_fees.go | 326 +++---- tests/e2e/c/interchain_workflow.go | 320 +++---- tests/e2e/p/interchain_workflow.go | 444 +++++----- tests/e2e/x/interchain_workflow.go | 296 +++---- tests/fixture/e2e/helpers.go | 123 +-- tests/fixture/testnet/config.go | 56 +- vms/example/xsvm/cmd/chain/create/cmd.go | 6 +- wallet/chain/c/backend.go | 300 +++---- wallet/chain/c/builder.go | 792 +++++++++--------- wallet/chain/c/builder_with_options.go | 136 +-- wallet/chain/c/context.go | 130 +-- wallet/chain/c/signer.go | 436 +++++----- wallet/chain/c/wallet.go | 402 ++++----- wallet/chain/c/wallet_with_options.go | 134 +-- wallet/subnet/primary/api.go | 122 +-- wallet/subnet/primary/example_test.go | 2 +- .../add-permissioned-subnet-validator/main.go | 6 +- .../examples/add-primary-validator/main.go | 2 +- .../primary/examples/c-chain-export/main.go | 118 +-- .../primary/examples/c-chain-import/main.go | 126 +-- .../primary/examples/create-asset/main.go | 2 +- .../primary/examples/create-chain/main.go | 6 +- .../examples/create-locked-stakeable/main.go | 2 +- .../primary/examples/create-subnet/main.go | 2 +- .../examples/remove-subnet-validator/main.go | 6 +- wallet/subnet/primary/wallet.go | 43 +- 29 files changed, 2173 insertions(+), 2270 deletions(-) diff --git a/go.mod b/go.mod index f5dfa499d1d5..23b752198fdd 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,6 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 - github.com/ava-labs/coreth v0.12.9-rc.5 github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 @@ -75,7 +74,6 @@ require ( github.com/BurntSushi/toml v1.2.1 // indirect github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect - github.com/VictoriaMetrics/fastcache v1.10.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect @@ -83,44 +81,26 @@ require ( github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/redact v1.1.3 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/deckarep/golang-set/v2 v2.1.0 // indirect - github.com/dlclark/regexp2 v1.7.0 // indirect - github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 // indirect - github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect github.com/frankban/quicktest v1.14.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/getsentry/sentry-go v0.18.0 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect - github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect - github.com/go-stack/stack v1.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/go-cmp v0.5.9 // indirect - github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect - github.com/google/uuid v1.3.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 // indirect - github.com/hashicorp/go-bexpr v0.1.10 // indirect - github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e // indirect github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/klauspost/compress v1.15.15 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/magiconair/properties v1.8.6 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect - github.com/mattn/go-runewidth v0.0.9 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/mitchellh/pointerstructure v1.2.0 // indirect - github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -128,17 +108,12 @@ require ( github.com/prometheus/common v0.39.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sanity-io/litter v1.5.1 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/status-im/keycard-go v0.2.0 // indirect github.com/subosito/gotenv v1.3.0 // indirect github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tklauser/numcpus v0.2.2 // indirect - github.com/tyler-smith/go-bip39 v1.1.0 // indirect - github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa // indirect - github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect diff --git a/go.sum b/go.sum index 35141a6c1638..2ae152b17faf 100644 --- a/go.sum +++ b/go.sum @@ -56,18 +56,12 @@ github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cq github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= -github.com/VictoriaMetrics/fastcache v1.10.0 h1:5hDJnLsKLpnUEToub7ETuRu8RCkb40woBZAUiKonXzY= -github.com/VictoriaMetrics/fastcache v1.10.0/go.mod h1:tjiYeEfYXCqacuvYw/7UoDIeJaNxq6132xHICNP77w8= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/coreth v0.12.9-rc.5 h1:xYBgNm1uOPfUdUNm8+fS8ellHnEd4qfFNb6uZHo9tqI= -github.com/ava-labs/coreth v0.12.9-rc.5/go.mod h1:rECKQfGFDeodrwGPlJSvFUJDbVr30jSMIVjQLi6pNX4= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= @@ -102,18 +96,13 @@ github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46f github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw= github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA= @@ -145,16 +134,12 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= -github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= @@ -165,14 +150,6 @@ github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6ps github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= -github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= -github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 h1:+3HCtB74++ClLy8GgjUQYeC8R4ILzVcIe8+5edAJJnE= -github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= -github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= -github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -189,8 +166,6 @@ github.com/ethereum/go-ethereum v1.12.0 h1:bdnhLPtqETd4m3mS8BGMNvBTf36bO5bx/hxE2 github.com/ethereum/go-ethereum v1.12.0/go.mod h1:/oo2X/dZLJjf2mJ6YT9wcWxa4nNJDBKDBU6sFIpx1Gs= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -199,8 +174,6 @@ github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmV github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= -github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= -github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= @@ -224,11 +197,7 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= -github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= -github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= @@ -313,14 +282,10 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= -github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= @@ -341,17 +306,11 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 h1:kr3j8iIMR4ywO/O0rvksXaJvauGGCMg2zAZIiNZ9uIQ= github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0/go.mod h1:ummNFgdgLhhX7aIiy35vVmQNS0rWXknfPE0qe6fmFXg= -github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= -github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e h1:pIYdhNkDh+YENVNi3gto8n9hAmRxKxoar0iE6BLucjw= -github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e/go.mod h1:j9cQbcqHQujT0oKJ38PylVfqohClLr3CvDC+Qcg+lhU= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c h1:DZfsyhDK1hnSS5lH8l+JggqzEleHteTYfutAiVlSUM8= @@ -363,7 +322,6 @@ github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3 github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -405,7 +363,6 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -413,7 +370,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= @@ -424,17 +380,11 @@ github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPK github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= @@ -443,11 +393,8 @@ github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= -github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -466,8 +413,6 @@ github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= -github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -535,8 +480,6 @@ github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sanity-io/litter v1.5.1 h1:dwnrSypP6q56o3lFxTU+t2fwQ9A+U5qrXVO4Qg9KwVU= github.com/sanity-io/litter v1.5.1/go.mod h1:5Z71SvaYy5kcGtyglXOC9rrUi3c1E8CamFWjQsazTh0= @@ -572,8 +515,6 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= -github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= -github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -605,14 +546,10 @@ github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZF github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE= github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE= -github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= -github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa h1:5SqCsI/2Qya2bCzK15ozrqo2sZxkh0FHynJZOTVoV6Q= -github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= @@ -624,8 +561,6 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= @@ -635,7 +570,6 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= @@ -731,7 +665,6 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -777,7 +710,6 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -801,7 +733,6 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -866,12 +797,8 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -888,7 +815,6 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -952,7 +878,6 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1077,7 +1002,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= diff --git a/node/node.go b/node/node.go index 06544e8f9e6b..98d697a66359 100644 --- a/node/node.go +++ b/node/node.go @@ -25,7 +25,7 @@ import ( "go.uber.org/zap" - coreth "github.com/ava-labs/coreth/plugin/evm" + // coreth "github.com/ava-labs/coreth/plugin/evm" "github.com/ava-labs/avalanchego/api/admin" "github.com/ava-labs/avalanchego/api/auth" @@ -1094,7 +1094,7 @@ func (n *Node) initVMs() error { CreateAssetTxFee: n.Config.CreateAssetTxFee, }, }), - vmRegisterer.Register(context.TODO(), constants.EVMID, &coreth.Factory{}), + // vmRegisterer.Register(context.TODO(), constants.EVMID, &coreth.Factory{}), n.VMManager.RegisterFactory(context.TODO(), secp256k1fx.ID, &secp256k1fx.Factory{}), n.VMManager.RegisterFactory(context.TODO(), nftfx.ID, &nftfx.Factory{}), n.VMManager.RegisterFactory(context.TODO(), propertyfx.ID, &propertyfx.Factory{}), diff --git a/tests/e2e/c/dynamic_fees.go b/tests/e2e/c/dynamic_fees.go index 8f15b6d43caf..8748dda7451d 100644 --- a/tests/e2e/c/dynamic_fees.go +++ b/tests/e2e/c/dynamic_fees.go @@ -3,166 +3,166 @@ package c -import ( - "math/big" - "strings" - - ginkgo "github.com/onsi/ginkgo/v2" - - "github.com/stretchr/testify/require" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/plugin/evm" - - "github.com/ava-labs/avalanchego/tests" - "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/tests/fixture/testnet" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -) - -// This test uses the compiled bin for `hashing.sol` as -// well as its ABI contained in `hashing_contract.go`. - -var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { - require := require.New(ginkgo.GinkgoT()) - - // Need a gas limit much larger than the standard 21_000 to enable - // the contract to induce a gas price increase - const largeGasLimit = uint64(8_000_000) - - // TODO(marun) What is the significance of this value? - gasTip := big.NewInt(1000 * params.GWei) - - ginkgo.It("should ensure that the gas price is affected by load", func() { - ginkgo.By("creating a new private network to ensure isolation from other tests") - privateNetwork := e2e.Env.NewPrivateNetwork() - - ginkgo.By("allocating a pre-funded key") - key := privateNetwork.GetConfig().FundedKeys[0] - ethAddress := evm.GetEthAddress(key) - - ginkgo.By("initializing a coreth client") - node := privateNetwork.GetNodes()[0] - nodeURI := testnet.NodeURI{ - NodeID: node.GetID(), - URI: node.GetProcessContext().URI, - } - ethClient := e2e.NewEthClient(nodeURI) - - ginkgo.By("initializing a transaction signer") - cChainID, err := ethClient.ChainID(e2e.DefaultContext()) - require.NoError(err) - signer := types.NewEIP155Signer(cChainID) - ecdsaKey := key.ToECDSA() - sign := func(tx *types.Transaction) *types.Transaction { - signedTx, err := types.SignTx(tx, signer, ecdsaKey) - require.NoError(err) - return signedTx - } - - var contractAddress common.Address - ginkgo.By("deploying an expensive contract", func() { - // Create transaction - nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) - require.NoError(err) - compiledContract := common.Hex2Bytes(hashingCompiledContract) - tx := types.NewTx(&types.LegacyTx{ - Nonce: nonce, - GasPrice: gasTip, - Gas: largeGasLimit, - Value: common.Big0, - Data: compiledContract, - }) - - // Send the transaction and wait for acceptance - signedTx := sign(tx) - receipt := e2e.SendEthTransaction(ethClient, signedTx) - - contractAddress = receipt.ContractAddress - }) - - var gasPrice *big.Int - ginkgo.By("calling the expensive contract repeatedly until a gas price increase is detected", func() { - // Evaluate the bytes representation of the contract - hashingABI, err := abi.JSON(strings.NewReader(hashingABIJson)) - require.NoError(err) - contractData, err := hashingABI.Pack("hashIt") - require.NoError(err) - - var initialGasPrice *big.Int - e2e.Eventually(func() bool { - // Check the gas price - var err error - gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) - require.NoError(err) - if initialGasPrice == nil { - initialGasPrice = gasPrice - tests.Outf("{{blue}}initial gas price is %v{{/}}\n", initialGasPrice) - } else if gasPrice.Cmp(initialGasPrice) > 0 { - // Gas price has increased - tests.Outf("{{blue}}gas price has increased to %v{{/}}\n", gasPrice) - return true - } - - // Create the transaction - nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) - require.NoError(err) - tx := types.NewTx(&types.LegacyTx{ - Nonce: nonce, - GasPrice: gasTip, - Gas: largeGasLimit, - To: &contractAddress, - Value: common.Big0, - Data: contractData, - }) - - // Send the transaction and wait for acceptance - signedTx := sign(tx) - _ = e2e.SendEthTransaction(ethClient, signedTx) - - // The gas price will be checked at the start of the next iteration - return false - }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price increase before timeout") - }) - - ginkgo.By("waiting for the gas price to decrease...", func() { - initialGasPrice := gasPrice - e2e.Eventually(func() bool { - var err error - gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) - require.NoError(err) - tests.Outf("{{blue}}.{{/}}") - return initialGasPrice.Cmp(gasPrice) > 0 - }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price decrease before timeout") - tests.Outf("\n{{blue}}gas price has decreased to %v{{/}}\n", gasPrice) - }) - - ginkgo.By("sending funds at the current gas price", func() { - // Create a recipient address - recipientKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - recipientEthAddress := evm.GetEthAddress(recipientKey) - - // Create transaction - nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) - require.NoError(err) - tx := types.NewTx(&types.LegacyTx{ - Nonce: nonce, - GasPrice: gasPrice, - Gas: e2e.DefaultGasLimit, - To: &recipientEthAddress, - Value: common.Big0, - }) - - // Send the transaction and wait for acceptance - signedTx := sign(tx) - _ = e2e.SendEthTransaction(ethClient, signedTx) - }) - - e2e.CheckBootstrapIsPossible(privateNetwork) - }) -}) +// import ( +// "math/big" +// "strings" + +// ginkgo "github.com/onsi/ginkgo/v2" + +// "github.com/stretchr/testify/require" + +// "github.com/ethereum/go-ethereum/accounts/abi" +// "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/coreth/core/types" +// "github.com/ava-labs/coreth/params" +// "github.com/ava-labs/coreth/plugin/evm" + +// "github.com/ava-labs/avalanchego/tests" +// "github.com/ava-labs/avalanchego/tests/e2e" +// "github.com/ava-labs/avalanchego/tests/fixture/testnet" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// ) + +// // This test uses the compiled bin for `hashing.sol` as +// // well as its ABI contained in `hashing_contract.go`. + +// var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { +// require := require.New(ginkgo.GinkgoT()) + +// // Need a gas limit much larger than the standard 21_000 to enable +// // the contract to induce a gas price increase +// const largeGasLimit = uint64(8_000_000) + +// // TODO(marun) What is the significance of this value? +// gasTip := big.NewInt(1000 * params.GWei) + +// ginkgo.It("should ensure that the gas price is affected by load", func() { +// ginkgo.By("creating a new private network to ensure isolation from other tests") +// privateNetwork := e2e.Env.NewPrivateNetwork() + +// ginkgo.By("allocating a pre-funded key") +// key := privateNetwork.GetConfig().FundedKeys[0] +// ethAddress := evm.GetEthAddress(key) + +// ginkgo.By("initializing a coreth client") +// node := privateNetwork.GetNodes()[0] +// nodeURI := testnet.NodeURI{ +// NodeID: node.GetID(), +// URI: node.GetProcessContext().URI, +// } +// ethClient := e2e.NewEthClient(nodeURI) + +// ginkgo.By("initializing a transaction signer") +// cChainID, err := ethClient.ChainID(e2e.DefaultContext()) +// require.NoError(err) +// signer := types.NewEIP155Signer(cChainID) +// ecdsaKey := key.ToECDSA() +// sign := func(tx *types.Transaction) *types.Transaction { +// signedTx, err := types.SignTx(tx, signer, ecdsaKey) +// require.NoError(err) +// return signedTx +// } + +// var contractAddress common.Address +// ginkgo.By("deploying an expensive contract", func() { +// // Create transaction +// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) +// require.NoError(err) +// compiledContract := common.Hex2Bytes(hashingCompiledContract) +// tx := types.NewTx(&types.LegacyTx{ +// Nonce: nonce, +// GasPrice: gasTip, +// Gas: largeGasLimit, +// Value: common.Big0, +// Data: compiledContract, +// }) + +// // Send the transaction and wait for acceptance +// signedTx := sign(tx) +// receipt := e2e.SendEthTransaction(ethClient, signedTx) + +// contractAddress = receipt.ContractAddress +// }) + +// var gasPrice *big.Int +// ginkgo.By("calling the expensive contract repeatedly until a gas price increase is detected", func() { +// // Evaluate the bytes representation of the contract +// hashingABI, err := abi.JSON(strings.NewReader(hashingABIJson)) +// require.NoError(err) +// contractData, err := hashingABI.Pack("hashIt") +// require.NoError(err) + +// var initialGasPrice *big.Int +// e2e.Eventually(func() bool { +// // Check the gas price +// var err error +// gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) +// require.NoError(err) +// if initialGasPrice == nil { +// initialGasPrice = gasPrice +// tests.Outf("{{blue}}initial gas price is %v{{/}}\n", initialGasPrice) +// } else if gasPrice.Cmp(initialGasPrice) > 0 { +// // Gas price has increased +// tests.Outf("{{blue}}gas price has increased to %v{{/}}\n", gasPrice) +// return true +// } + +// // Create the transaction +// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) +// require.NoError(err) +// tx := types.NewTx(&types.LegacyTx{ +// Nonce: nonce, +// GasPrice: gasTip, +// Gas: largeGasLimit, +// To: &contractAddress, +// Value: common.Big0, +// Data: contractData, +// }) + +// // Send the transaction and wait for acceptance +// signedTx := sign(tx) +// _ = e2e.SendEthTransaction(ethClient, signedTx) + +// // The gas price will be checked at the start of the next iteration +// return false +// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price increase before timeout") +// }) + +// ginkgo.By("waiting for the gas price to decrease...", func() { +// initialGasPrice := gasPrice +// e2e.Eventually(func() bool { +// var err error +// gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) +// require.NoError(err) +// tests.Outf("{{blue}}.{{/}}") +// return initialGasPrice.Cmp(gasPrice) > 0 +// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price decrease before timeout") +// tests.Outf("\n{{blue}}gas price has decreased to %v{{/}}\n", gasPrice) +// }) + +// ginkgo.By("sending funds at the current gas price", func() { +// // Create a recipient address +// recipientKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) +// recipientEthAddress := evm.GetEthAddress(recipientKey) + +// // Create transaction +// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) +// require.NoError(err) +// tx := types.NewTx(&types.LegacyTx{ +// Nonce: nonce, +// GasPrice: gasPrice, +// Gas: e2e.DefaultGasLimit, +// To: &recipientEthAddress, +// Value: common.Big0, +// }) + +// // Send the transaction and wait for acceptance +// signedTx := sign(tx) +// _ = e2e.SendEthTransaction(ethClient, signedTx) +// }) + +// e2e.CheckBootstrapIsPossible(privateNetwork) +// }) +// }) diff --git a/tests/e2e/c/interchain_workflow.go b/tests/e2e/c/interchain_workflow.go index 2c9bd198ec39..c5af17c750bf 100644 --- a/tests/e2e/c/interchain_workflow.go +++ b/tests/e2e/c/interchain_workflow.go @@ -3,163 +3,163 @@ package c -import ( - "math/big" - - ginkgo "github.com/onsi/ginkgo/v2" - - "github.com/stretchr/testify/require" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/plugin/evm" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var _ = e2e.DescribeCChain("[Interchain Workflow]", func() { - require := require.New(ginkgo.GinkgoT()) - - const txAmount = 10 * units.Avax // Arbitrary amount to send and transfer - - ginkgo.It("should ensure that funds can be transferred from the C-Chain to the X-Chain and the P-Chain", func() { - ginkgo.By("initializing a new eth client") - // Select a random node URI to use for both the eth client and - // the wallet to avoid having to verify that all nodes are at - // the same height before initializing the wallet. - nodeURI := e2e.Env.GetRandomNodeURI() - ethClient := e2e.NewEthClient(nodeURI) - - ginkgo.By("allocating a pre-funded key to send from and a recipient key to deliver to") - senderKey := e2e.Env.AllocateFundedKey() - senderEthAddress := evm.GetEthAddress(senderKey) - recipientKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - recipientEthAddress := evm.GetEthAddress(recipientKey) - - ginkgo.By("sending funds from one address to another on the C-Chain", func() { - // Create transaction - acceptedNonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), senderEthAddress) - require.NoError(err) - gasPrice := e2e.SuggestGasPrice(ethClient) - tx := types.NewTransaction( - acceptedNonce, - recipientEthAddress, - big.NewInt(int64(txAmount)), - e2e.DefaultGasLimit, - gasPrice, - nil, - ) - - // Sign transaction - cChainID, err := ethClient.ChainID(e2e.DefaultContext()) - require.NoError(err) - signer := types.NewEIP155Signer(cChainID) - signedTx, err := types.SignTx(tx, signer, senderKey.ToECDSA()) - require.NoError(err) - - _ = e2e.SendEthTransaction(ethClient, signedTx) - - ginkgo.By("waiting for the C-Chain recipient address to have received the sent funds") - e2e.Eventually(func() bool { - balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) - require.NoError(err) - return balance.Cmp(big.NewInt(0)) > 0 - }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see funds delivered before timeout") - }) - - // Wallet must be initialized after sending funds on the - // C-Chain with the same node URI to ensure wallet state - // matches on-chain state. - ginkgo.By("initializing a keychain and associated wallet") - keychain := secp256k1fx.NewKeychain(senderKey, recipientKey) - baseWallet := e2e.NewWallet(keychain, nodeURI) - xWallet := baseWallet.X() - cWallet := baseWallet.C() - pWallet := baseWallet.P() - - ginkgo.By("defining common configuration") - avaxAssetID := xWallet.AVAXAssetID() - // Use the same owner for import funds to X-Chain and P-Chain - recipientOwner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - recipientKey.Address(), - }, - } - // Use the same outputs for both X-Chain and P-Chain exports - exportOutputs := []*secp256k1fx.TransferOutput{ - { - Amt: txAmount, - OutputOwners: secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - keychain.Keys[0].Address(), - }, - }, - }, - } - - ginkgo.By("exporting AVAX from the C-Chain to the X-Chain", func() { - _, err := cWallet.IssueExportTx( - xWallet.BlockchainID(), - exportOutputs, - e2e.WithDefaultContext(), - e2e.WithSuggestedGasPrice(ethClient), - ) - require.NoError(err) - }) - - ginkgo.By("importing AVAX from the C-Chain to the X-Chain", func() { - _, err := xWallet.IssueImportTx( - cWallet.BlockchainID(), - &recipientOwner, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { - balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - ginkgo.By("exporting AVAX from the C-Chain to the P-Chain", func() { - _, err := cWallet.IssueExportTx( - constants.PlatformChainID, - exportOutputs, - e2e.WithDefaultContext(), - e2e.WithSuggestedGasPrice(ethClient), - ) - require.NoError(err) - }) - - ginkgo.By("importing AVAX from the C-Chain to the P-Chain", func() { - _, err = pWallet.IssueImportTx( - cWallet.BlockchainID(), - &recipientOwner, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { - balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) - }) -}) +// import ( +// "math/big" + +// ginkgo "github.com/onsi/ginkgo/v2" + +// "github.com/stretchr/testify/require" + +// "github.com/ava-labs/coreth/core/types" +// "github.com/ava-labs/coreth/plugin/evm" + +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/tests/e2e" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var _ = e2e.DescribeCChain("[Interchain Workflow]", func() { +// require := require.New(ginkgo.GinkgoT()) + +// const txAmount = 10 * units.Avax // Arbitrary amount to send and transfer + +// ginkgo.It("should ensure that funds can be transferred from the C-Chain to the X-Chain and the P-Chain", func() { +// ginkgo.By("initializing a new eth client") +// // Select a random node URI to use for both the eth client and +// // the wallet to avoid having to verify that all nodes are at +// // the same height before initializing the wallet. +// nodeURI := e2e.Env.GetRandomNodeURI() +// ethClient := e2e.NewEthClient(nodeURI) + +// ginkgo.By("allocating a pre-funded key to send from and a recipient key to deliver to") +// senderKey := e2e.Env.AllocateFundedKey() +// senderEthAddress := evm.GetEthAddress(senderKey) +// recipientKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) +// recipientEthAddress := evm.GetEthAddress(recipientKey) + +// ginkgo.By("sending funds from one address to another on the C-Chain", func() { +// // Create transaction +// acceptedNonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), senderEthAddress) +// require.NoError(err) +// gasPrice := e2e.SuggestGasPrice(ethClient) +// tx := types.NewTransaction( +// acceptedNonce, +// recipientEthAddress, +// big.NewInt(int64(txAmount)), +// e2e.DefaultGasLimit, +// gasPrice, +// nil, +// ) + +// // Sign transaction +// cChainID, err := ethClient.ChainID(e2e.DefaultContext()) +// require.NoError(err) +// signer := types.NewEIP155Signer(cChainID) +// signedTx, err := types.SignTx(tx, signer, senderKey.ToECDSA()) +// require.NoError(err) + +// _ = e2e.SendEthTransaction(ethClient, signedTx) + +// ginkgo.By("waiting for the C-Chain recipient address to have received the sent funds") +// e2e.Eventually(func() bool { +// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) +// require.NoError(err) +// return balance.Cmp(big.NewInt(0)) > 0 +// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see funds delivered before timeout") +// }) + +// // Wallet must be initialized after sending funds on the +// // C-Chain with the same node URI to ensure wallet state +// // matches on-chain state. +// ginkgo.By("initializing a keychain and associated wallet") +// keychain := secp256k1fx.NewKeychain(senderKey, recipientKey) +// baseWallet := e2e.NewWallet(keychain, nodeURI) +// xWallet := baseWallet.X() +// cWallet := baseWallet.C() +// pWallet := baseWallet.P() + +// ginkgo.By("defining common configuration") +// avaxAssetID := xWallet.AVAXAssetID() +// // Use the same owner for import funds to X-Chain and P-Chain +// recipientOwner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// recipientKey.Address(), +// }, +// } +// // Use the same outputs for both X-Chain and P-Chain exports +// exportOutputs := []*secp256k1fx.TransferOutput{ +// { +// Amt: txAmount, +// OutputOwners: secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// keychain.Keys[0].Address(), +// }, +// }, +// }, +// } + +// ginkgo.By("exporting AVAX from the C-Chain to the X-Chain", func() { +// _, err := cWallet.IssueExportTx( +// xWallet.BlockchainID(), +// exportOutputs, +// e2e.WithDefaultContext(), +// e2e.WithSuggestedGasPrice(ethClient), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("importing AVAX from the C-Chain to the X-Chain", func() { +// _, err := xWallet.IssueImportTx( +// cWallet.BlockchainID(), +// &recipientOwner, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { +// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// ginkgo.By("exporting AVAX from the C-Chain to the P-Chain", func() { +// _, err := cWallet.IssueExportTx( +// constants.PlatformChainID, +// exportOutputs, +// e2e.WithDefaultContext(), +// e2e.WithSuggestedGasPrice(ethClient), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("importing AVAX from the C-Chain to the P-Chain", func() { +// _, err = pWallet.IssueImportTx( +// cWallet.BlockchainID(), +// &recipientOwner, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { +// balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) +// }) +// }) diff --git a/tests/e2e/p/interchain_workflow.go b/tests/e2e/p/interchain_workflow.go index 44a6912715ef..e90e0382e286 100644 --- a/tests/e2e/p/interchain_workflow.go +++ b/tests/e2e/p/interchain_workflow.go @@ -3,225 +3,225 @@ package p -import ( - "math/big" - "time" - - ginkgo "github.com/onsi/ginkgo/v2" - - "github.com/spf13/cast" - - "github.com/stretchr/testify/require" - - "github.com/ava-labs/coreth/plugin/evm" - - "github.com/ava-labs/avalanchego/api/info" - "github.com/ava-labs/avalanchego/config" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/tests/fixture/testnet" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/platformvm/reward" - "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { - require := require.New(ginkgo.GinkgoT()) - - const ( - transferAmount = 10 * units.Avax - weight = 2_000 * units.Avax // Used for both validation and delegation - ) - - ginkgo.It("should ensure that funds can be transferred from the P-Chain to the X-Chain and the C-Chain", func() { - network := e2e.Env.GetNetwork() - - ginkgo.By("checking that the network has a compatible minimum stake duration", func() { - minStakeDuration := cast.ToDuration(network.GetConfig().DefaultFlags[config.MinStakeDurationKey]) - require.Equal(testnet.DefaultMinStakeDuration, minStakeDuration) - }) - - ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") - recipientKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - keychain := e2e.Env.NewKeychain(1) - keychain.Add(recipientKey) - nodeURI := e2e.Env.GetRandomNodeURI() - baseWallet := e2e.NewWallet(keychain, nodeURI) - xWallet := baseWallet.X() - cWallet := baseWallet.C() - pWallet := baseWallet.P() - - ginkgo.By("defining common configuration") - recipientEthAddress := evm.GetEthAddress(recipientKey) - avaxAssetID := xWallet.AVAXAssetID() - // Use the same owner for sending to X-Chain and importing funds to P-Chain - recipientOwner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - recipientKey.Address(), - }, - } - // Use the same outputs for both X-Chain and C-Chain exports - exportOutputs := []*avax.TransferableOutput{ - { - Asset: avax.Asset{ - ID: avaxAssetID, - }, - Out: &secp256k1fx.TransferOutput{ - Amt: transferAmount, - OutputOwners: secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - keychain.Keys[0].Address(), - }, - }, - }, - }, - } - - ginkgo.By("adding new node and waiting for it to report healthy") - node := e2e.AddEphemeralNode(network, testnet.FlagsMap{}) - e2e.WaitForHealthy(node) - - ginkgo.By("retrieving new node's id and pop") - infoClient := info.NewClient(node.GetProcessContext().URI) - nodeID, nodePOP, err := infoClient.GetNodeID(e2e.DefaultContext()) - require.NoError(err) - - ginkgo.By("adding the new node as a validator", func() { - startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) - // Validation duration doesn't actually matter to this - // test - it is only ensuring that adding a validator - // doesn't break interchain transfer. - endTime := startTime.Add(30 * time.Second) - - rewardKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - - const ( - delegationPercent = 0.10 // 10% - delegationShare = reward.PercentDenominator * delegationPercent - ) - - _, err = pWallet.IssueAddPermissionlessValidatorTx( - &txs.SubnetValidator{ - Validator: txs.Validator{ - NodeID: nodeID, - Start: uint64(startTime.Unix()), - End: uint64(endTime.Unix()), - Wght: weight, - }, - Subnet: constants.PrimaryNetworkID, - }, - nodePOP, - pWallet.AVAXAssetID(), - &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{rewardKey.Address()}, - }, - &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{rewardKey.Address()}, - }, - delegationShare, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("adding a delegator to the new node", func() { - startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) - // Delegation duration doesn't actually matter to this - // test - it is only ensuring that adding a delegator - // doesn't break interchain transfer. - endTime := startTime.Add(15 * time.Second) - - rewardKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - - _, err = pWallet.IssueAddPermissionlessDelegatorTx( - &txs.SubnetValidator{ - Validator: txs.Validator{ - NodeID: nodeID, - Start: uint64(startTime.Unix()), - End: uint64(endTime.Unix()), - Wght: weight, - }, - Subnet: constants.PrimaryNetworkID, - }, - pWallet.AVAXAssetID(), - &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{rewardKey.Address()}, - }, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("exporting AVAX from the P-Chain to the X-Chain", func() { - _, err := pWallet.IssueExportTx( - xWallet.BlockchainID(), - exportOutputs, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("importing AVAX from the P-Chain to the X-Chain", func() { - _, err := xWallet.IssueImportTx( - constants.PlatformChainID, - &recipientOwner, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { - balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - ginkgo.By("exporting AVAX from the P-Chain to the C-Chain", func() { - _, err := pWallet.IssueExportTx( - cWallet.BlockchainID(), - exportOutputs, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("initializing a new eth client") - ethClient := e2e.NewEthClient(nodeURI) - - ginkgo.By("importing AVAX from the P-Chain to the C-Chain", func() { - _, err := cWallet.IssueImportTx( - constants.PlatformChainID, - recipientEthAddress, - e2e.WithDefaultContext(), - e2e.WithSuggestedGasPrice(ethClient), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") - balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) - require.NoError(err) - require.Positive(balance.Cmp(big.NewInt(0))) - - ginkgo.By("stopping validator node to free up resources for a bootstrap check") - require.NoError(node.Stop()) - - e2e.CheckBootstrapIsPossible(network) - }) -}) +// import ( +// "math/big" +// "time" + +// ginkgo "github.com/onsi/ginkgo/v2" + +// "github.com/spf13/cast" + +// "github.com/stretchr/testify/require" + +// "github.com/ava-labs/coreth/plugin/evm" + +// "github.com/ava-labs/avalanchego/api/info" +// "github.com/ava-labs/avalanchego/config" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/tests/e2e" +// "github.com/ava-labs/avalanchego/tests/fixture/testnet" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/platformvm/reward" +// "github.com/ava-labs/avalanchego/vms/platformvm/txs" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { +// require := require.New(ginkgo.GinkgoT()) + +// const ( +// transferAmount = 10 * units.Avax +// weight = 2_000 * units.Avax // Used for both validation and delegation +// ) + +// ginkgo.It("should ensure that funds can be transferred from the P-Chain to the X-Chain and the C-Chain", func() { +// network := e2e.Env.GetNetwork() + +// ginkgo.By("checking that the network has a compatible minimum stake duration", func() { +// minStakeDuration := cast.ToDuration(network.GetConfig().DefaultFlags[config.MinStakeDurationKey]) +// require.Equal(testnet.DefaultMinStakeDuration, minStakeDuration) +// }) + +// ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") +// recipientKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) +// keychain := e2e.Env.NewKeychain(1) +// keychain.Add(recipientKey) +// nodeURI := e2e.Env.GetRandomNodeURI() +// baseWallet := e2e.Env.NewWallet(keychain, nodeURI) +// xWallet := baseWallet.X() +// cWallet := baseWallet.C() +// pWallet := baseWallet.P() + +// ginkgo.By("defining common configuration") +// recipientEthAddress := evm.GetEthAddress(recipientKey) +// avaxAssetID := xWallet.AVAXAssetID() +// // Use the same owner for sending to X-Chain and importing funds to P-Chain +// recipientOwner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// recipientKey.Address(), +// }, +// } +// // Use the same outputs for both X-Chain and C-Chain exports +// exportOutputs := []*avax.TransferableOutput{ +// { +// Asset: avax.Asset{ +// ID: avaxAssetID, +// }, +// Out: &secp256k1fx.TransferOutput{ +// Amt: transferAmount, +// OutputOwners: secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// keychain.Keys[0].Address(), +// }, +// }, +// }, +// }, +// } + +// ginkgo.By("adding new node and waiting for it to report healthy") +// node := e2e.AddEphemeralNode(network, testnet.FlagsMap{}) +// e2e.WaitForHealthy(node) + +// ginkgo.By("retrieving new node's id and pop") +// infoClient := info.NewClient(node.GetProcessContext().URI) +// nodeID, nodePOP, err := infoClient.GetNodeID(e2e.DefaultContext()) +// require.NoError(err) + +// ginkgo.By("adding the new node as a validator", func() { +// startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) +// // Validation duration doesn't actually matter to this +// // test - it is only ensuring that adding a validator +// // doesn't break interchain transfer. +// endTime := startTime.Add(30 * time.Second) + +// rewardKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) + +// const ( +// delegationPercent = 0.10 // 10% +// delegationShare = reward.PercentDenominator * delegationPercent +// ) + +// _, err = pWallet.IssueAddPermissionlessValidatorTx( +// &txs.SubnetValidator{ +// Validator: txs.Validator{ +// NodeID: nodeID, +// Start: uint64(startTime.Unix()), +// End: uint64(endTime.Unix()), +// Wght: weight, +// }, +// Subnet: constants.PrimaryNetworkID, +// }, +// nodePOP, +// pWallet.AVAXAssetID(), +// &secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{rewardKey.Address()}, +// }, +// &secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{rewardKey.Address()}, +// }, +// delegationShare, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("adding a delegator to the new node", func() { +// startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) +// // Delegation duration doesn't actually matter to this +// // test - it is only ensuring that adding a delegator +// // doesn't break interchain transfer. +// endTime := startTime.Add(15 * time.Second) + +// rewardKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) + +// _, err = pWallet.IssueAddPermissionlessDelegatorTx( +// &txs.SubnetValidator{ +// Validator: txs.Validator{ +// NodeID: nodeID, +// Start: uint64(startTime.Unix()), +// End: uint64(endTime.Unix()), +// Wght: weight, +// }, +// Subnet: constants.PrimaryNetworkID, +// }, +// pWallet.AVAXAssetID(), +// &secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{rewardKey.Address()}, +// }, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("exporting AVAX from the P-Chain to the X-Chain", func() { +// _, err := pWallet.IssueExportTx( +// xWallet.BlockchainID(), +// exportOutputs, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("importing AVAX from the P-Chain to the X-Chain", func() { +// _, err := xWallet.IssueImportTx( +// constants.PlatformChainID, +// &recipientOwner, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { +// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// ginkgo.By("exporting AVAX from the P-Chain to the C-Chain", func() { +// _, err := pWallet.IssueExportTx( +// cWallet.BlockchainID(), +// exportOutputs, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("initializing a new eth client") +// ethClient := e2e.NewEthClient(nodeURI) + +// ginkgo.By("importing AVAX from the P-Chain to the C-Chain", func() { +// _, err := cWallet.IssueImportTx( +// constants.PlatformChainID, +// recipientEthAddress, +// e2e.WithDefaultContext(), +// e2e.WithSuggestedGasPrice(ethClient), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") +// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) +// require.NoError(err) +// require.Positive(balance.Cmp(big.NewInt(0))) + +// ginkgo.By("stopping validator node to free up resources for a bootstrap check") +// require.NoError(node.Stop()) + +// e2e.CheckBootstrapIsPossible(network) +// }) +// }) diff --git a/tests/e2e/x/interchain_workflow.go b/tests/e2e/x/interchain_workflow.go index f0c2951feb84..d738e55a7f7a 100644 --- a/tests/e2e/x/interchain_workflow.go +++ b/tests/e2e/x/interchain_workflow.go @@ -3,151 +3,151 @@ package x -import ( - "math/big" - - ginkgo "github.com/onsi/ginkgo/v2" - - "github.com/stretchr/testify/require" - - "github.com/ava-labs/coreth/plugin/evm" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var _ = e2e.DescribeXChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { - require := require.New(ginkgo.GinkgoT()) - - const transferAmount = 10 * units.Avax - - ginkgo.It("should ensure that funds can be transferred from the X-Chain to the C-Chain and the P-Chain", func() { - nodeURI := e2e.Env.GetRandomNodeURI() - - ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") - recipientKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - keychain := e2e.Env.NewKeychain(1) - keychain.Add(recipientKey) - baseWallet := e2e.NewWallet(keychain, nodeURI) - xWallet := baseWallet.X() - cWallet := baseWallet.C() - pWallet := baseWallet.P() - - ginkgo.By("defining common configuration") - recipientEthAddress := evm.GetEthAddress(recipientKey) - avaxAssetID := xWallet.AVAXAssetID() - // Use the same owner for sending to X-Chain and importing funds to P-Chain - recipientOwner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - recipientKey.Address(), - }, - } - // Use the same outputs for both C-Chain and P-Chain exports - exportOutputs := []*avax.TransferableOutput{ - { - Asset: avax.Asset{ - ID: avaxAssetID, - }, - Out: &secp256k1fx.TransferOutput{ - Amt: transferAmount, - OutputOwners: secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - keychain.Keys[0].Address(), - }, - }, - }, - }, - } - - ginkgo.By("sending funds from one address to another on the X-Chain", func() { - _, err = xWallet.IssueBaseTx( - []*avax.TransferableOutput{{ - Asset: avax.Asset{ - ID: avaxAssetID, - }, - Out: &secp256k1fx.TransferOutput{ - Amt: transferAmount, - OutputOwners: recipientOwner, - }, - }}, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the X-Chain recipient address has received the sent funds", func() { - balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - ginkgo.By("exporting AVAX from the X-Chain to the C-Chain", func() { - _, err := xWallet.IssueExportTx( - cWallet.BlockchainID(), - exportOutputs, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("initializing a new eth client") - ethClient := e2e.NewEthClient(nodeURI) - - ginkgo.By("importing AVAX from the X-Chain to the C-Chain", func() { - _, err := cWallet.IssueImportTx( - xWallet.BlockchainID(), - recipientEthAddress, - e2e.WithDefaultContext(), - e2e.WithSuggestedGasPrice(ethClient), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") - e2e.Eventually(func() bool { - balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) - require.NoError(err) - return balance.Cmp(big.NewInt(0)) > 0 - }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see recipient address funded before timeout") - - ginkgo.By("exporting AVAX from the X-Chain to the P-Chain", func() { - _, err := xWallet.IssueExportTx( - constants.PlatformChainID, - exportOutputs, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("importing AVAX from the X-Chain to the P-Chain", func() { - _, err := pWallet.IssueImportTx( - xWallet.BlockchainID(), - &recipientOwner, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { - balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) - }) -}) +// import ( +// "math/big" + +// ginkgo "github.com/onsi/ginkgo/v2" + +// "github.com/stretchr/testify/require" + +// "github.com/ava-labs/coreth/plugin/evm" + +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/tests/e2e" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var _ = e2e.DescribeXChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { +// require := require.New(ginkgo.GinkgoT()) + +// const transferAmount = 10 * units.Avax + +// ginkgo.It("should ensure that funds can be transferred from the X-Chain to the C-Chain and the P-Chain", func() { +// nodeURI := e2e.Env.GetRandomNodeURI() + +// ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") +// recipientKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) +// keychain := e2e.Env.NewKeychain(1) +// keychain.Add(recipientKey) +// baseWallet := e2e.Env.NewWallet(keychain, nodeURI) +// xWallet := baseWallet.X() +// cWallet := baseWallet.C() +// pWallet := baseWallet.P() + +// ginkgo.By("defining common configuration") +// recipientEthAddress := evm.GetEthAddress(recipientKey) +// avaxAssetID := xWallet.AVAXAssetID() +// // Use the same owner for sending to X-Chain and importing funds to P-Chain +// recipientOwner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// recipientKey.Address(), +// }, +// } +// // Use the same outputs for both C-Chain and P-Chain exports +// exportOutputs := []*avax.TransferableOutput{ +// { +// Asset: avax.Asset{ +// ID: avaxAssetID, +// }, +// Out: &secp256k1fx.TransferOutput{ +// Amt: transferAmount, +// OutputOwners: secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// keychain.Keys[0].Address(), +// }, +// }, +// }, +// }, +// } + +// ginkgo.By("sending funds from one address to another on the X-Chain", func() { +// _, err = xWallet.IssueBaseTx( +// []*avax.TransferableOutput{{ +// Asset: avax.Asset{ +// ID: avaxAssetID, +// }, +// Out: &secp256k1fx.TransferOutput{ +// Amt: transferAmount, +// OutputOwners: recipientOwner, +// }, +// }}, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the X-Chain recipient address has received the sent funds", func() { +// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// ginkgo.By("exporting AVAX from the X-Chain to the C-Chain", func() { +// _, err := xWallet.IssueExportTx( +// cWallet.BlockchainID(), +// exportOutputs, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("initializing a new eth client") +// ethClient := e2e.NewEthClient(nodeURI) + +// ginkgo.By("importing AVAX from the X-Chain to the C-Chain", func() { +// _, err := cWallet.IssueImportTx( +// xWallet.BlockchainID(), +// recipientEthAddress, +// e2e.WithDefaultContext(), +// e2e.WithSuggestedGasPrice(ethClient), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") +// e2e.Eventually(func() bool { +// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) +// require.NoError(err) +// return balance.Cmp(big.NewInt(0)) > 0 +// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see recipient address funded before timeout") + +// ginkgo.By("exporting AVAX from the X-Chain to the P-Chain", func() { +// _, err := xWallet.IssueExportTx( +// constants.PlatformChainID, +// exportOutputs, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("importing AVAX from the X-Chain to the P-Chain", func() { +// _, err := pWallet.IssueImportTx( +// xWallet.BlockchainID(), +// &recipientOwner, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { +// balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) +// }) +// }) diff --git a/tests/fixture/e2e/helpers.go b/tests/fixture/e2e/helpers.go index 15da611324e0..8e497cf398c0 100644 --- a/tests/fixture/e2e/helpers.go +++ b/tests/fixture/e2e/helpers.go @@ -5,20 +5,23 @@ package e2e import ( "context" - "errors" - "fmt" - "math/big" + + // "errors" + // "fmt" + // "math/big" + "os" - "strings" + + // "strings" "time" ginkgo "github.com/onsi/ginkgo/v2" "github.com/stretchr/testify/require" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/ethclient" - "github.com/ava-labs/coreth/interfaces" + // "github.com/ava-labs/coreth/core/types" + // "github.com/ava-labs/coreth/ethclient" + // "github.com/ava-labs/coreth/interfaces" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/tests" @@ -67,7 +70,7 @@ func NewWallet(keychain *secp256k1fx.Keychain, nodeURI testnet.NodeURI) primary. baseWallet, err := primary.MakeWallet(DefaultContext(), &primary.WalletConfig{ URI: nodeURI.URI, AVAXKeychain: keychain, - EthKeychain: keychain, + // EthKeychain: keychain, }) require.NoError(ginkgo.GinkgoT(), err) return primary.NewWalletWithOptions( @@ -80,15 +83,15 @@ func NewWallet(keychain *secp256k1fx.Keychain, nodeURI testnet.NodeURI) primary. ) } -// Create a new eth client targeting the specified node URI. -func NewEthClient(nodeURI testnet.NodeURI) ethclient.Client { - tests.Outf("{{blue}} initializing a new eth client for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) - nodeAddress := strings.Split(nodeURI.URI, "//")[1] - uri := fmt.Sprintf("ws://%s/ext/bc/C/ws", nodeAddress) - client, err := ethclient.Dial(uri) - require.NoError(ginkgo.GinkgoT(), err) - return client -} +// // Create a new eth client targeting the specified node URI. +// func NewEthClient(nodeURI testnet.NodeURI) ethclient.Client { +// tests.Outf("{{blue}} initializing a new eth client for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) +// nodeAddress := strings.Split(nodeURI.URI, "//")[1] +// uri := fmt.Sprintf("ws://%s/ext/bc/C/ws", nodeAddress) +// client, err := ethclient.Dial(uri) +// require.NoError(ginkgo.GinkgoT(), err) +// return client +// } // Helper simplifying use of a timed context by canceling the context on ginkgo teardown. func ContextWithTimeout(duration time.Duration) context.Context { @@ -152,49 +155,49 @@ func WaitForHealthy(node testnet.Node) { require.NoError(ginkgo.GinkgoT(), testnet.WaitForHealthy(ctx, node)) } -// Sends an eth transaction, waits for the transaction receipt to be issued -// and checks that the receipt indicates success. -func SendEthTransaction(ethClient ethclient.Client, signedTx *types.Transaction) *types.Receipt { - require := require.New(ginkgo.GinkgoT()) - - txID := signedTx.Hash() - tests.Outf(" sending eth transaction with ID: %s\n", txID) - - require.NoError(ethClient.SendTransaction(DefaultContext(), signedTx)) - - // Wait for the receipt - var receipt *types.Receipt - Eventually(func() bool { - var err error - receipt, err = ethClient.TransactionReceipt(DefaultContext(), txID) - if errors.Is(err, interfaces.NotFound) { - return false // Transaction is still pending - } - require.NoError(err) - return true - }, DefaultTimeout, DefaultPollingInterval, "failed to see transaction acceptance before timeout") - - require.Equal(receipt.Status, types.ReceiptStatusSuccessful) - return receipt -} - -// Determines the suggested gas price for the configured client that will -// maximize the chances of transaction acceptance. -func SuggestGasPrice(ethClient ethclient.Client) *big.Int { - gasPrice, err := ethClient.SuggestGasPrice(DefaultContext()) - require.NoError(ginkgo.GinkgoT(), err) - // Double the suggested gas price to maximize the chances of - // acceptance. Maybe this can be revisited pending resolution of - // https://github.com/ava-labs/coreth/issues/314. - gasPrice.Add(gasPrice, gasPrice) - return gasPrice -} - -// Helper simplifying use via an option of a gas price appropriate for testing. -func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { - baseFee := SuggestGasPrice(ethClient) - return common.WithBaseFee(baseFee) -} +// // Sends an eth transaction, waits for the transaction receipt to be issued +// // and checks that the receipt indicates success. +// func SendEthTransaction(ethClient ethclient.Client, signedTx *types.Transaction) *types.Receipt { +// require := require.New(ginkgo.GinkgoT()) + +// txID := signedTx.Hash() +// tests.Outf(" sending eth transaction with ID: %s\n", txID) + +// require.NoError(ethClient.SendTransaction(DefaultContext(), signedTx)) + +// // Wait for the receipt +// var receipt *types.Receipt +// Eventually(func() bool { +// var err error +// receipt, err = ethClient.TransactionReceipt(DefaultContext(), txID) +// if errors.Is(err, interfaces.NotFound) { +// return false // Transaction is still pending +// } +// require.NoError(err) +// return true +// }, DefaultTimeout, DefaultPollingInterval, "failed to see transaction acceptance before timeout") + +// require.Equal(receipt.Status, types.ReceiptStatusSuccessful) +// return receipt +// } + +// // Determines the suggested gas price for the configured client that will +// // maximize the chances of transaction acceptance. +// func SuggestGasPrice(ethClient ethclient.Client) *big.Int { +// gasPrice, err := ethClient.SuggestGasPrice(DefaultContext()) +// require.NoError(ginkgo.GinkgoT(), err) +// // Double the suggested gas price to maximize the chances of +// // acceptance. Maybe this can be revisited pending resolution of +// // https://github.com/ava-labs/coreth/issues/314. +// gasPrice.Add(gasPrice, gasPrice) +// return gasPrice +// } + +// // Helper simplifying use via an option of a gas price appropriate for testing. +// func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { +// baseFee := SuggestGasPrice(ethClient) +// return common.WithBaseFee(baseFee) +// } // Verify that a new node can bootstrap into the network. func CheckBootstrapIsPossible(network testnet.Network) { diff --git a/tests/fixture/testnet/config.go b/tests/fixture/testnet/config.go index 425aa646a690..c2e27bbff116 100644 --- a/tests/fixture/testnet/config.go +++ b/tests/fixture/testnet/config.go @@ -15,9 +15,9 @@ import ( "github.com/spf13/cast" - "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/plugin/evm" + // "github.com/ava-labs/coreth/core" + // "github.com/ava-labs/coreth/params" + // "github.com/ava-labs/coreth/plugin/evm" "github.com/ava-labs/avalanchego/config" "github.com/ava-labs/avalanchego/genesis" @@ -143,15 +143,15 @@ func (c *NetworkConfig) EnsureGenesis(networkID uint32, validatorIDs []ids.NodeI // Ensure pre-funded keys have arbitrary large balances on both chains to support testing xChainBalances := make(XChainBalanceMap, len(c.FundedKeys)) - cChainBalances := make(core.GenesisAlloc, len(c.FundedKeys)) - for _, key := range c.FundedKeys { - xChainBalances[key.Address()] = DefaultFundedKeyXChainAmount - cChainBalances[evm.GetEthAddress(key)] = core.GenesisAccount{ - Balance: DefaultFundedKeyCChainAmount, - } - } - - genesis, err := NewTestGenesis(networkID, xChainBalances, cChainBalances, validatorIDs) + // cChainBalances := make(core.GenesisAlloc, len(c.FundedKeys)) + // for _, key := range c.FundedKeys { + // xChainBalances[key.Address()] = DefaultFundedKeyXChainAmount + // cChainBalances[evm.GetEthAddress(key)] = core.GenesisAccount{ + // Balance: DefaultFundedKeyCChainAmount, + // } + // } + + genesis, err := NewTestGenesis(networkID, xChainBalances /*, cChainBalances*/, validatorIDs) if err != nil { return err } @@ -311,7 +311,7 @@ type XChainBalanceMap map[ids.ShortID]uint64 func NewTestGenesis( networkID uint32, xChainBalances XChainBalanceMap, - cChainBalances core.GenesisAlloc, + // cChainBalances core.GenesisAlloc, validatorIDs []ids.NodeID, ) (*genesis.UnparsedConfig, error) { // Validate inputs @@ -322,7 +322,7 @@ func NewTestGenesis( if len(validatorIDs) == 0 { return nil, errMissingValidatorsForGenesis } - if len(xChainBalances) == 0 || len(cChainBalances) == 0 { + if len(xChainBalances) == 0 /*|| len(cChainBalances) == 0*/ { return nil, errMissingBalancesForGenesis } @@ -394,20 +394,20 @@ func NewTestGenesis( ) } - // Define C-Chain genesis - cChainGenesis := &core.Genesis{ - Config: ¶ms.ChainConfig{ - ChainID: big.NewInt(43112), // Arbitrary chain ID is arbitrary - }, - Difficulty: big.NewInt(0), // Difficulty is a mandatory field - GasLimit: DefaultGasLimit, - Alloc: cChainBalances, - } - cChainGenesisBytes, err := json.Marshal(cChainGenesis) - if err != nil { - return nil, fmt.Errorf("failed to marshal C-Chain genesis: %w", err) - } - config.CChainGenesis = string(cChainGenesisBytes) + // // Define C-Chain genesis + // cChainGenesis := &core.Genesis{ + // Config: ¶ms.ChainConfig{ + // ChainID: big.NewInt(43112), // Arbitrary chain ID is arbitrary + // }, + // Difficulty: big.NewInt(0), // Difficulty is a mandatory field + // GasLimit: DefaultGasLimit, + // Alloc: cChainBalances, + // } + // cChainGenesisBytes, err := json.Marshal(cChainGenesis) + // if err != nil { + // return nil, fmt.Errorf("failed to marshal C-Chain genesis: %w", err) + // } + // config.CChainGenesis = string(cChainGenesisBytes) // Give staking rewards for initial validators to a random address. Any testing of staking rewards // will be easier to perform with nodes other than the initial validators since the timing of diff --git a/vms/example/xsvm/cmd/chain/create/cmd.go b/vms/example/xsvm/cmd/chain/create/cmd.go index 1f00491a4ce6..043b4298dcdf 100644 --- a/vms/example/xsvm/cmd/chain/create/cmd.go +++ b/vms/example/xsvm/cmd/chain/create/cmd.go @@ -42,9 +42,9 @@ func createFunc(c *cobra.Command, args []string) error { // that [uri] is hosting. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: config.URI, - AVAXKeychain: kc, - EthKeychain: kc, + URI: config.URI, + AVAXKeychain: kc, + // EthKeychain: kc, PChainTxsToFetch: set.Of(config.SubnetID), }) if err != nil { diff --git a/wallet/chain/c/backend.go b/wallet/chain/c/backend.go index 0a735116b646..b88c8c643bc3 100644 --- a/wallet/chain/c/backend.go +++ b/wallet/chain/c/backend.go @@ -3,153 +3,153 @@ package c -import ( - "errors" - "fmt" - "math/big" - "sync" - - stdcontext "context" - - "github.com/ava-labs/coreth/plugin/evm" - - ethcommon "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/avalanchego/database" - "github.com/ava-labs/avalanchego/utils/math" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var ( - _ Backend = (*backend)(nil) - - errUnknownTxType = errors.New("unknown tx type") -) - -// Backend defines the full interface required to support a C-chain wallet. -type Backend interface { - common.ChainUTXOs - BuilderBackend - SignerBackend - - AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error -} - -type backend struct { - Context - common.ChainUTXOs - - accountsLock sync.RWMutex - accounts map[ethcommon.Address]*Account -} - -type Account struct { - Balance *big.Int - Nonce uint64 -} - -func NewBackend( - ctx Context, - utxos common.ChainUTXOs, - accounts map[ethcommon.Address]*Account, -) Backend { - return &backend{ - Context: ctx, - ChainUTXOs: utxos, - accounts: accounts, - } -} - -func (b *backend) AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error { - switch tx := tx.UnsignedAtomicTx.(type) { - case *evm.UnsignedImportTx: - for _, input := range tx.ImportedInputs { - utxoID := input.InputID() - if err := b.RemoveUTXO(ctx, tx.SourceChain, utxoID); err != nil { - return err - } - } - - b.accountsLock.Lock() - defer b.accountsLock.Unlock() - - for _, output := range tx.Outs { - account, ok := b.accounts[output.Address] - if !ok { - continue - } - - balance := new(big.Int).SetUint64(output.Amount) - balance.Mul(balance, avaxConversionRate) - account.Balance.Add(account.Balance, balance) - } - case *evm.UnsignedExportTx: - txID := tx.ID() - for i, out := range tx.ExportedOutputs { - err := b.AddUTXO( - ctx, - tx.DestinationChain, - &avax.UTXO{ - UTXOID: avax.UTXOID{ - TxID: txID, - OutputIndex: uint32(i), - }, - Asset: avax.Asset{ID: out.AssetID()}, - Out: out.Out, - }, - ) - if err != nil { - return err - } - } - - b.accountsLock.Lock() - defer b.accountsLock.Unlock() - - for _, input := range tx.Ins { - account, ok := b.accounts[input.Address] - if !ok { - continue - } - - balance := new(big.Int).SetUint64(input.Amount) - balance.Mul(balance, avaxConversionRate) - if account.Balance.Cmp(balance) == -1 { - return errInsufficientFunds - } - account.Balance.Sub(account.Balance, balance) - - newNonce, err := math.Add64(input.Nonce, 1) - if err != nil { - return err - } - account.Nonce = newNonce - } - default: - return fmt.Errorf("%w: %T", errUnknownTxType, tx) - } - return nil -} - -func (b *backend) Balance(_ stdcontext.Context, addr ethcommon.Address) (*big.Int, error) { - b.accountsLock.RLock() - defer b.accountsLock.RUnlock() - - account, exists := b.accounts[addr] - if !exists { - return nil, database.ErrNotFound - } - return account.Balance, nil -} - -func (b *backend) Nonce(_ stdcontext.Context, addr ethcommon.Address) (uint64, error) { - b.accountsLock.RLock() - defer b.accountsLock.RUnlock() - - account, exists := b.accounts[addr] - if !exists { - return 0, database.ErrNotFound - } - return account.Nonce, nil -} +// import ( +// "errors" +// "fmt" +// "math/big" +// "sync" + +// stdcontext "context" + +// "github.com/ava-labs/coreth/plugin/evm" + +// ethcommon "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/avalanchego/database" +// "github.com/ava-labs/avalanchego/utils/math" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var ( +// _ Backend = (*backend)(nil) + +// errUnknownTxType = errors.New("unknown tx type") +// ) + +// // Backend defines the full interface required to support a C-chain wallet. +// type Backend interface { +// common.ChainUTXOs +// BuilderBackend +// SignerBackend + +// AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error +// } + +// type backend struct { +// Context +// common.ChainUTXOs + +// accountsLock sync.RWMutex +// accounts map[ethcommon.Address]*Account +// } + +// type Account struct { +// Balance *big.Int +// Nonce uint64 +// } + +// func NewBackend( +// ctx Context, +// utxos common.ChainUTXOs, +// accounts map[ethcommon.Address]*Account, +// ) Backend { +// return &backend{ +// Context: ctx, +// ChainUTXOs: utxos, +// accounts: accounts, +// } +// } + +// func (b *backend) AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error { +// switch tx := tx.UnsignedAtomicTx.(type) { +// case *evm.UnsignedImportTx: +// for _, input := range tx.ImportedInputs { +// utxoID := input.InputID() +// if err := b.RemoveUTXO(ctx, tx.SourceChain, utxoID); err != nil { +// return err +// } +// } + +// b.accountsLock.Lock() +// defer b.accountsLock.Unlock() + +// for _, output := range tx.Outs { +// account, ok := b.accounts[output.Address] +// if !ok { +// continue +// } + +// balance := new(big.Int).SetUint64(output.Amount) +// balance.Mul(balance, avaxConversionRate) +// account.Balance.Add(account.Balance, balance) +// } +// case *evm.UnsignedExportTx: +// txID := tx.ID() +// for i, out := range tx.ExportedOutputs { +// err := b.AddUTXO( +// ctx, +// tx.DestinationChain, +// &avax.UTXO{ +// UTXOID: avax.UTXOID{ +// TxID: txID, +// OutputIndex: uint32(i), +// }, +// Asset: avax.Asset{ID: out.AssetID()}, +// Out: out.Out, +// }, +// ) +// if err != nil { +// return err +// } +// } + +// b.accountsLock.Lock() +// defer b.accountsLock.Unlock() + +// for _, input := range tx.Ins { +// account, ok := b.accounts[input.Address] +// if !ok { +// continue +// } + +// balance := new(big.Int).SetUint64(input.Amount) +// balance.Mul(balance, avaxConversionRate) +// if account.Balance.Cmp(balance) == -1 { +// return errInsufficientFunds +// } +// account.Balance.Sub(account.Balance, balance) + +// newNonce, err := math.Add64(input.Nonce, 1) +// if err != nil { +// return err +// } +// account.Nonce = newNonce +// } +// default: +// return fmt.Errorf("%w: %T", errUnknownTxType, tx) +// } +// return nil +// } + +// func (b *backend) Balance(_ stdcontext.Context, addr ethcommon.Address) (*big.Int, error) { +// b.accountsLock.RLock() +// defer b.accountsLock.RUnlock() + +// account, exists := b.accounts[addr] +// if !exists { +// return nil, database.ErrNotFound +// } +// return account.Balance, nil +// } + +// func (b *backend) Nonce(_ stdcontext.Context, addr ethcommon.Address) (uint64, error) { +// b.accountsLock.RLock() +// defer b.accountsLock.RUnlock() + +// account, exists := b.accounts[addr] +// if !exists { +// return 0, database.ErrNotFound +// } +// return account.Nonce, nil +// } diff --git a/wallet/chain/c/builder.go b/wallet/chain/c/builder.go index d2d088e88a53..c51d2647777e 100644 --- a/wallet/chain/c/builder.go +++ b/wallet/chain/c/builder.go @@ -3,399 +3,399 @@ package c -import ( - "errors" - "math/big" - - stdcontext "context" - - "github.com/ava-labs/coreth/plugin/evm" - - ethcommon "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils" - "github.com/ava-labs/avalanchego/utils/math" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -const avaxConversionRateInt = 1_000_000_000 - -var ( - _ Builder = (*builder)(nil) - - errInsufficientFunds = errors.New("insufficient funds") - - // avaxConversionRate is the conversion rate between the smallest - // denomination on the X-Chain and P-chain, 1 nAVAX, and the smallest - // denomination on the C-Chain 1 wei. Where 1 nAVAX = 1 gWei. - // - // This is only required for AVAX because the denomination of 1 AVAX is 9 - // decimal places on the X and P chains, but is 18 decimal places within the - // EVM. - avaxConversionRate = big.NewInt(avaxConversionRateInt) -) - -// Builder provides a convenient interface for building unsigned C-chain -// transactions. -type Builder interface { - // GetBalance calculates the amount of AVAX that this builder has control - // over. - GetBalance( - options ...common.Option, - ) (*big.Int, error) - - // GetImportableBalance calculates the amount of AVAX that this builder - // could import from the provided chain. - // - // - [chainID] specifies the chain the funds are from. - GetImportableBalance( - chainID ids.ID, - options ...common.Option, - ) (uint64, error) - - // NewImportTx creates an import transaction that attempts to consume all - // the available UTXOs and import the funds to [to]. - // - // - [chainID] specifies the chain to be importing funds from. - // - [to] specifies where to send the imported funds to. - // - [baseFee] specifies the fee price willing to be paid by this tx. - NewImportTx( - chainID ids.ID, - to ethcommon.Address, - baseFee *big.Int, - options ...common.Option, - ) (*evm.UnsignedImportTx, error) - - // NewExportTx creates an export transaction that attempts to send all the - // provided [outputs] to the requested [chainID]. - // - // - [chainID] specifies the chain to be exporting the funds to. - // - [outputs] specifies the outputs to send to the [chainID]. - // - [baseFee] specifies the fee price willing to be paid by this tx. - NewExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - baseFee *big.Int, - options ...common.Option, - ) (*evm.UnsignedExportTx, error) -} - -// BuilderBackend specifies the required information needed to build unsigned -// C-chain transactions. -type BuilderBackend interface { - Context - - UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) - Balance(ctx stdcontext.Context, addr ethcommon.Address) (*big.Int, error) - Nonce(ctx stdcontext.Context, addr ethcommon.Address) (uint64, error) -} - -type builder struct { - avaxAddrs set.Set[ids.ShortID] - ethAddrs set.Set[ethcommon.Address] - backend BuilderBackend -} - -// NewBuilder returns a new transaction builder. -// -// - [avaxAddrs] is the set of addresses in the AVAX format that the builder -// assumes can be used when signing the transactions in the future. -// - [ethAddrs] is the set of addresses in the Eth format that the builder -// assumes can be used when signing the transactions in the future. -// - [backend] provides the required access to the chain's context and state -// to build out the transactions. -func NewBuilder( - avaxAddrs set.Set[ids.ShortID], - ethAddrs set.Set[ethcommon.Address], - backend BuilderBackend, -) Builder { - return &builder{ - avaxAddrs: avaxAddrs, - ethAddrs: ethAddrs, - backend: backend, - } -} - -func (b *builder) GetBalance( - options ...common.Option, -) (*big.Int, error) { - var ( - ops = common.NewOptions(options) - ctx = ops.Context() - addrs = ops.EthAddresses(b.ethAddrs) - totalBalance = new(big.Int) - ) - for addr := range addrs { - balance, err := b.backend.Balance(ctx, addr) - if err != nil { - return nil, err - } - totalBalance.Add(totalBalance, balance) - } - - return totalBalance, nil -} - -func (b *builder) GetImportableBalance( - chainID ids.ID, - options ...common.Option, -) (uint64, error) { - ops := common.NewOptions(options) - utxos, err := b.backend.UTXOs(ops.Context(), chainID) - if err != nil { - return 0, err - } - - var ( - addrs = ops.Addresses(b.avaxAddrs) - minIssuanceTime = ops.MinIssuanceTime() - avaxAssetID = b.backend.AVAXAssetID() - balance uint64 - ) - for _, utxo := range utxos { - amount, _, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) - if !ok { - continue - } - - newBalance, err := math.Add64(balance, amount) - if err != nil { - return 0, err - } - balance = newBalance - } - - return balance, nil -} - -func (b *builder) NewImportTx( - chainID ids.ID, - to ethcommon.Address, - baseFee *big.Int, - options ...common.Option, -) (*evm.UnsignedImportTx, error) { - ops := common.NewOptions(options) - utxos, err := b.backend.UTXOs(ops.Context(), chainID) - if err != nil { - return nil, err - } - - var ( - addrs = ops.Addresses(b.avaxAddrs) - minIssuanceTime = ops.MinIssuanceTime() - avaxAssetID = b.backend.AVAXAssetID() - - importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) - importedAmount uint64 - ) - for _, utxo := range utxos { - amount, inputSigIndices, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) - if !ok { - continue - } - - importedInputs = append(importedInputs, &avax.TransferableInput{ - UTXOID: utxo.UTXOID, - Asset: utxo.Asset, - In: &secp256k1fx.TransferInput{ - Amt: amount, - Input: secp256k1fx.Input{ - SigIndices: inputSigIndices, - }, - }, - }) - - newImportedAmount, err := math.Add64(importedAmount, amount) - if err != nil { - return nil, err - } - importedAmount = newImportedAmount - } - - utils.Sort(importedInputs) - tx := &evm.UnsignedImportTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: b.backend.BlockchainID(), - SourceChain: chainID, - ImportedInputs: importedInputs, - } - - // We must initialize the bytes of the tx to calculate the initial cost - wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} - if err := wrappedTx.Sign(evm.Codec, nil); err != nil { - return nil, err - } - - gasUsedWithoutOutput, err := tx.GasUsed(true /*=IsApricotPhase5*/) - if err != nil { - return nil, err - } - gasUsedWithOutput := gasUsedWithoutOutput + evm.EVMOutputGas - - txFee, err := evm.CalculateDynamicFee(gasUsedWithOutput, baseFee) - if err != nil { - return nil, err - } - - if importedAmount <= txFee { - return nil, errInsufficientFunds - } - - tx.Outs = []evm.EVMOutput{{ - Address: to, - Amount: importedAmount - txFee, - AssetID: avaxAssetID, - }} - return tx, nil -} - -func (b *builder) NewExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - baseFee *big.Int, - options ...common.Option, -) (*evm.UnsignedExportTx, error) { - var ( - avaxAssetID = b.backend.AVAXAssetID() - exportedOutputs = make([]*avax.TransferableOutput, len(outputs)) - exportedAmount uint64 - ) - for i, output := range outputs { - exportedOutputs[i] = &avax.TransferableOutput{ - Asset: avax.Asset{ID: avaxAssetID}, - Out: output, - } - - newExportedAmount, err := math.Add64(exportedAmount, output.Amt) - if err != nil { - return nil, err - } - exportedAmount = newExportedAmount - } - - avax.SortTransferableOutputs(exportedOutputs, evm.Codec) - tx := &evm.UnsignedExportTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: b.backend.BlockchainID(), - DestinationChain: chainID, - ExportedOutputs: exportedOutputs, - } - - // We must initialize the bytes of the tx to calculate the initial cost - wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} - if err := wrappedTx.Sign(evm.Codec, nil); err != nil { - return nil, err - } - - cost, err := tx.GasUsed(true /*=IsApricotPhase5*/) - if err != nil { - return nil, err - } - - initialFee, err := evm.CalculateDynamicFee(cost, baseFee) - if err != nil { - return nil, err - } - - amountToConsume, err := math.Add64(exportedAmount, initialFee) - if err != nil { - return nil, err - } - - var ( - ops = common.NewOptions(options) - ctx = ops.Context() - addrs = ops.EthAddresses(b.ethAddrs) - inputs = make([]evm.EVMInput, 0, addrs.Len()) - ) - for addr := range addrs { - if amountToConsume == 0 { - break - } - - prevFee, err := evm.CalculateDynamicFee(cost, baseFee) - if err != nil { - return nil, err - } - - newCost := cost + evm.EVMInputGas - newFee, err := evm.CalculateDynamicFee(newCost, baseFee) - if err != nil { - return nil, err - } - - additionalFee := newFee - prevFee - - balance, err := b.backend.Balance(ctx, addr) - if err != nil { - return nil, err - } - - // Since the asset is AVAX, we divide by the avaxConversionRate to - // convert back to the correct denomination of AVAX that can be - // exported. - avaxBalance := new(big.Int).Div(balance, avaxConversionRate).Uint64() - - // If the balance for [addr] is insufficient to cover the additional - // cost of adding an input to the transaction, skip adding the input - // altogether. - if avaxBalance <= additionalFee { - continue - } - - // Update the cost for the next iteration - cost = newCost - - amountToConsume, err = math.Add64(amountToConsume, additionalFee) - if err != nil { - return nil, err - } - - nonce, err := b.backend.Nonce(ctx, addr) - if err != nil { - return nil, err - } - - inputAmount := math.Min(amountToConsume, avaxBalance) - inputs = append(inputs, evm.EVMInput{ - Address: addr, - Amount: inputAmount, - AssetID: avaxAssetID, - Nonce: nonce, - }) - amountToConsume -= inputAmount - } - - if amountToConsume > 0 { - return nil, errInsufficientFunds - } - - utils.Sort(inputs) - tx.Ins = inputs - return tx, nil -} - -func getSpendableAmount( - utxo *avax.UTXO, - addrs set.Set[ids.ShortID], - minIssuanceTime uint64, - avaxAssetID ids.ID, -) (uint64, []uint32, bool) { - if utxo.Asset.ID != avaxAssetID { - // Only AVAX can be imported - return 0, nil, false - } - - out, ok := utxo.Out.(*secp256k1fx.TransferOutput) - if !ok { - // Can't import an unknown transfer output type - return 0, nil, false - } - - inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) - return out.Amt, inputSigIndices, ok -} +// import ( +// "errors" +// "math/big" + +// stdcontext "context" + +// "github.com/ava-labs/coreth/plugin/evm" + +// ethcommon "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/utils" +// "github.com/ava-labs/avalanchego/utils/math" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// const avaxConversionRateInt = 1_000_000_000 + +// var ( +// _ Builder = (*builder)(nil) + +// errInsufficientFunds = errors.New("insufficient funds") + +// // avaxConversionRate is the conversion rate between the smallest +// // denomination on the X-Chain and P-chain, 1 nAVAX, and the smallest +// // denomination on the C-Chain 1 wei. Where 1 nAVAX = 1 gWei. +// // +// // This is only required for AVAX because the denomination of 1 AVAX is 9 +// // decimal places on the X and P chains, but is 18 decimal places within the +// // EVM. +// avaxConversionRate = big.NewInt(avaxConversionRateInt) +// ) + +// // Builder provides a convenient interface for building unsigned C-chain +// // transactions. +// type Builder interface { +// // GetBalance calculates the amount of AVAX that this builder has control +// // over. +// GetBalance( +// options ...common.Option, +// ) (*big.Int, error) + +// // GetImportableBalance calculates the amount of AVAX that this builder +// // could import from the provided chain. +// // +// // - [chainID] specifies the chain the funds are from. +// GetImportableBalance( +// chainID ids.ID, +// options ...common.Option, +// ) (uint64, error) + +// // NewImportTx creates an import transaction that attempts to consume all +// // the available UTXOs and import the funds to [to]. +// // +// // - [chainID] specifies the chain to be importing funds from. +// // - [to] specifies where to send the imported funds to. +// // - [baseFee] specifies the fee price willing to be paid by this tx. +// NewImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedImportTx, error) + +// // NewExportTx creates an export transaction that attempts to send all the +// // provided [outputs] to the requested [chainID]. +// // +// // - [chainID] specifies the chain to be exporting the funds to. +// // - [outputs] specifies the outputs to send to the [chainID]. +// // - [baseFee] specifies the fee price willing to be paid by this tx. +// NewExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedExportTx, error) +// } + +// // BuilderBackend specifies the required information needed to build unsigned +// // C-chain transactions. +// type BuilderBackend interface { +// Context + +// UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) +// Balance(ctx stdcontext.Context, addr ethcommon.Address) (*big.Int, error) +// Nonce(ctx stdcontext.Context, addr ethcommon.Address) (uint64, error) +// } + +// type builder struct { +// avaxAddrs set.Set[ids.ShortID] +// ethAddrs set.Set[ethcommon.Address] +// backend BuilderBackend +// } + +// // NewBuilder returns a new transaction builder. +// // +// // - [avaxAddrs] is the set of addresses in the AVAX format that the builder +// // assumes can be used when signing the transactions in the future. +// // - [ethAddrs] is the set of addresses in the Eth format that the builder +// // assumes can be used when signing the transactions in the future. +// // - [backend] provides the required access to the chain's context and state +// // to build out the transactions. +// func NewBuilder( +// avaxAddrs set.Set[ids.ShortID], +// ethAddrs set.Set[ethcommon.Address], +// backend BuilderBackend, +// ) Builder { +// return &builder{ +// avaxAddrs: avaxAddrs, +// ethAddrs: ethAddrs, +// backend: backend, +// } +// } + +// func (b *builder) GetBalance( +// options ...common.Option, +// ) (*big.Int, error) { +// var ( +// ops = common.NewOptions(options) +// ctx = ops.Context() +// addrs = ops.EthAddresses(b.ethAddrs) +// totalBalance = new(big.Int) +// ) +// for addr := range addrs { +// balance, err := b.backend.Balance(ctx, addr) +// if err != nil { +// return nil, err +// } +// totalBalance.Add(totalBalance, balance) +// } + +// return totalBalance, nil +// } + +// func (b *builder) GetImportableBalance( +// chainID ids.ID, +// options ...common.Option, +// ) (uint64, error) { +// ops := common.NewOptions(options) +// utxos, err := b.backend.UTXOs(ops.Context(), chainID) +// if err != nil { +// return 0, err +// } + +// var ( +// addrs = ops.Addresses(b.avaxAddrs) +// minIssuanceTime = ops.MinIssuanceTime() +// avaxAssetID = b.backend.AVAXAssetID() +// balance uint64 +// ) +// for _, utxo := range utxos { +// amount, _, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) +// if !ok { +// continue +// } + +// newBalance, err := math.Add64(balance, amount) +// if err != nil { +// return 0, err +// } +// balance = newBalance +// } + +// return balance, nil +// } + +// func (b *builder) NewImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedImportTx, error) { +// ops := common.NewOptions(options) +// utxos, err := b.backend.UTXOs(ops.Context(), chainID) +// if err != nil { +// return nil, err +// } + +// var ( +// addrs = ops.Addresses(b.avaxAddrs) +// minIssuanceTime = ops.MinIssuanceTime() +// avaxAssetID = b.backend.AVAXAssetID() + +// importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) +// importedAmount uint64 +// ) +// for _, utxo := range utxos { +// amount, inputSigIndices, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) +// if !ok { +// continue +// } + +// importedInputs = append(importedInputs, &avax.TransferableInput{ +// UTXOID: utxo.UTXOID, +// Asset: utxo.Asset, +// In: &secp256k1fx.TransferInput{ +// Amt: amount, +// Input: secp256k1fx.Input{ +// SigIndices: inputSigIndices, +// }, +// }, +// }) + +// newImportedAmount, err := math.Add64(importedAmount, amount) +// if err != nil { +// return nil, err +// } +// importedAmount = newImportedAmount +// } + +// utils.Sort(importedInputs) +// tx := &evm.UnsignedImportTx{ +// NetworkID: b.backend.NetworkID(), +// BlockchainID: b.backend.BlockchainID(), +// SourceChain: chainID, +// ImportedInputs: importedInputs, +// } + +// // We must initialize the bytes of the tx to calculate the initial cost +// wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} +// if err := wrappedTx.Sign(evm.Codec, nil); err != nil { +// return nil, err +// } + +// gasUsedWithoutOutput, err := tx.GasUsed(true /*=IsApricotPhase5*/) +// if err != nil { +// return nil, err +// } +// gasUsedWithOutput := gasUsedWithoutOutput + evm.EVMOutputGas + +// txFee, err := evm.CalculateDynamicFee(gasUsedWithOutput, baseFee) +// if err != nil { +// return nil, err +// } + +// if importedAmount <= txFee { +// return nil, errInsufficientFunds +// } + +// tx.Outs = []evm.EVMOutput{{ +// Address: to, +// Amount: importedAmount - txFee, +// AssetID: avaxAssetID, +// }} +// return tx, nil +// } + +// func (b *builder) NewExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedExportTx, error) { +// var ( +// avaxAssetID = b.backend.AVAXAssetID() +// exportedOutputs = make([]*avax.TransferableOutput, len(outputs)) +// exportedAmount uint64 +// ) +// for i, output := range outputs { +// exportedOutputs[i] = &avax.TransferableOutput{ +// Asset: avax.Asset{ID: avaxAssetID}, +// Out: output, +// } + +// newExportedAmount, err := math.Add64(exportedAmount, output.Amt) +// if err != nil { +// return nil, err +// } +// exportedAmount = newExportedAmount +// } + +// avax.SortTransferableOutputs(exportedOutputs, evm.Codec) +// tx := &evm.UnsignedExportTx{ +// NetworkID: b.backend.NetworkID(), +// BlockchainID: b.backend.BlockchainID(), +// DestinationChain: chainID, +// ExportedOutputs: exportedOutputs, +// } + +// // We must initialize the bytes of the tx to calculate the initial cost +// wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} +// if err := wrappedTx.Sign(evm.Codec, nil); err != nil { +// return nil, err +// } + +// cost, err := tx.GasUsed(true /*=IsApricotPhase5*/) +// if err != nil { +// return nil, err +// } + +// initialFee, err := evm.CalculateDynamicFee(cost, baseFee) +// if err != nil { +// return nil, err +// } + +// amountToConsume, err := math.Add64(exportedAmount, initialFee) +// if err != nil { +// return nil, err +// } + +// var ( +// ops = common.NewOptions(options) +// ctx = ops.Context() +// addrs = ops.EthAddresses(b.ethAddrs) +// inputs = make([]evm.EVMInput, 0, addrs.Len()) +// ) +// for addr := range addrs { +// if amountToConsume == 0 { +// break +// } + +// prevFee, err := evm.CalculateDynamicFee(cost, baseFee) +// if err != nil { +// return nil, err +// } + +// newCost := cost + evm.EVMInputGas +// newFee, err := evm.CalculateDynamicFee(newCost, baseFee) +// if err != nil { +// return nil, err +// } + +// additionalFee := newFee - prevFee + +// balance, err := b.backend.Balance(ctx, addr) +// if err != nil { +// return nil, err +// } + +// // Since the asset is AVAX, we divide by the avaxConversionRate to +// // convert back to the correct denomination of AVAX that can be +// // exported. +// avaxBalance := new(big.Int).Div(balance, avaxConversionRate).Uint64() + +// // If the balance for [addr] is insufficient to cover the additional +// // cost of adding an input to the transaction, skip adding the input +// // altogether. +// if avaxBalance <= additionalFee { +// continue +// } + +// // Update the cost for the next iteration +// cost = newCost + +// amountToConsume, err = math.Add64(amountToConsume, additionalFee) +// if err != nil { +// return nil, err +// } + +// nonce, err := b.backend.Nonce(ctx, addr) +// if err != nil { +// return nil, err +// } + +// inputAmount := math.Min(amountToConsume, avaxBalance) +// inputs = append(inputs, evm.EVMInput{ +// Address: addr, +// Amount: inputAmount, +// AssetID: avaxAssetID, +// Nonce: nonce, +// }) +// amountToConsume -= inputAmount +// } + +// if amountToConsume > 0 { +// return nil, errInsufficientFunds +// } + +// utils.Sort(inputs) +// tx.Ins = inputs +// return tx, nil +// } + +// func getSpendableAmount( +// utxo *avax.UTXO, +// addrs set.Set[ids.ShortID], +// minIssuanceTime uint64, +// avaxAssetID ids.ID, +// ) (uint64, []uint32, bool) { +// if utxo.Asset.ID != avaxAssetID { +// // Only AVAX can be imported +// return 0, nil, false +// } + +// out, ok := utxo.Out.(*secp256k1fx.TransferOutput) +// if !ok { +// // Can't import an unknown transfer output type +// return 0, nil, false +// } + +// inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) +// return out.Amt, inputSigIndices, ok +// } diff --git a/wallet/chain/c/builder_with_options.go b/wallet/chain/c/builder_with_options.go index 8416dddf9928..9b7ab8399484 100644 --- a/wallet/chain/c/builder_with_options.go +++ b/wallet/chain/c/builder_with_options.go @@ -3,81 +3,81 @@ package c -import ( - "math/big" +// import ( +// "math/big" - "github.com/ava-labs/coreth/plugin/evm" +// "github.com/ava-labs/coreth/plugin/evm" - ethcommon "github.com/ethereum/go-ethereum/common" +// ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) -var _ Builder = (*builderWithOptions)(nil) +// var _ Builder = (*builderWithOptions)(nil) -type builderWithOptions struct { - Builder - options []common.Option -} +// type builderWithOptions struct { +// Builder +// options []common.Option +// } -// NewBuilderWithOptions returns a new transaction builder that will use the -// given options by default. -// -// - [builder] is the builder that will be called to perform the underlying -// operations. -// - [options] will be provided to the builder in addition to the options -// provided in the method calls. -func NewBuilderWithOptions(builder Builder, options ...common.Option) Builder { - return &builderWithOptions{ - Builder: builder, - options: options, - } -} +// // NewBuilderWithOptions returns a new transaction builder that will use the +// // given options by default. +// // +// // - [builder] is the builder that will be called to perform the underlying +// // operations. +// // - [options] will be provided to the builder in addition to the options +// // provided in the method calls. +// func NewBuilderWithOptions(builder Builder, options ...common.Option) Builder { +// return &builderWithOptions{ +// Builder: builder, +// options: options, +// } +// } -func (b *builderWithOptions) GetBalance( - options ...common.Option, -) (*big.Int, error) { - return b.Builder.GetBalance( - common.UnionOptions(b.options, options)..., - ) -} +// func (b *builderWithOptions) GetBalance( +// options ...common.Option, +// ) (*big.Int, error) { +// return b.Builder.GetBalance( +// common.UnionOptions(b.options, options)..., +// ) +// } -func (b *builderWithOptions) GetImportableBalance( - chainID ids.ID, - options ...common.Option, -) (uint64, error) { - return b.Builder.GetImportableBalance( - chainID, - common.UnionOptions(b.options, options)..., - ) -} +// func (b *builderWithOptions) GetImportableBalance( +// chainID ids.ID, +// options ...common.Option, +// ) (uint64, error) { +// return b.Builder.GetImportableBalance( +// chainID, +// common.UnionOptions(b.options, options)..., +// ) +// } -func (b *builderWithOptions) NewImportTx( - chainID ids.ID, - to ethcommon.Address, - baseFee *big.Int, - options ...common.Option, -) (*evm.UnsignedImportTx, error) { - return b.Builder.NewImportTx( - chainID, - to, - baseFee, - common.UnionOptions(b.options, options)..., - ) -} +// func (b *builderWithOptions) NewImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedImportTx, error) { +// return b.Builder.NewImportTx( +// chainID, +// to, +// baseFee, +// common.UnionOptions(b.options, options)..., +// ) +// } -func (b *builderWithOptions) NewExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - baseFee *big.Int, - options ...common.Option, -) (*evm.UnsignedExportTx, error) { - return b.Builder.NewExportTx( - chainID, - outputs, - baseFee, - common.UnionOptions(b.options, options)..., - ) -} +// func (b *builderWithOptions) NewExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedExportTx, error) { +// return b.Builder.NewExportTx( +// chainID, +// outputs, +// baseFee, +// common.UnionOptions(b.options, options)..., +// ) +// } diff --git a/wallet/chain/c/context.go b/wallet/chain/c/context.go index d506b42f81fa..1c01d8fb55c8 100644 --- a/wallet/chain/c/context.go +++ b/wallet/chain/c/context.go @@ -3,81 +3,81 @@ package c -import ( - stdcontext "context" +// import ( +// stdcontext "context" - "github.com/ava-labs/avalanchego/api/info" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/avm" -) +// "github.com/ava-labs/avalanchego/api/info" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/vms/avm" +// ) -var _ Context = (*context)(nil) +// var _ Context = (*context)(nil) -type Context interface { - NetworkID() uint32 - BlockchainID() ids.ID - AVAXAssetID() ids.ID -} +// type Context interface { +// NetworkID() uint32 +// BlockchainID() ids.ID +// AVAXAssetID() ids.ID +// } -type context struct { - networkID uint32 - blockchainID ids.ID - avaxAssetID ids.ID -} +// type context struct { +// networkID uint32 +// blockchainID ids.ID +// avaxAssetID ids.ID +// } -func NewContextFromURI(ctx stdcontext.Context, uri string) (Context, error) { - infoClient := info.NewClient(uri) - xChainClient := avm.NewClient(uri, "X") - return NewContextFromClients(ctx, infoClient, xChainClient) -} +// func NewContextFromURI(ctx stdcontext.Context, uri string) (Context, error) { +// infoClient := info.NewClient(uri) +// xChainClient := avm.NewClient(uri, "X") +// return NewContextFromClients(ctx, infoClient, xChainClient) +// } -func NewContextFromClients( - ctx stdcontext.Context, - infoClient info.Client, - xChainClient avm.Client, -) (Context, error) { - networkID, err := infoClient.GetNetworkID(ctx) - if err != nil { - return nil, err - } +// func NewContextFromClients( +// ctx stdcontext.Context, +// infoClient info.Client, +// xChainClient avm.Client, +// ) (Context, error) { +// networkID, err := infoClient.GetNetworkID(ctx) +// if err != nil { +// return nil, err +// } - chainID, err := infoClient.GetBlockchainID(ctx, "C") - if err != nil { - return nil, err - } +// chainID, err := infoClient.GetBlockchainID(ctx, "C") +// if err != nil { +// return nil, err +// } - asset, err := xChainClient.GetAssetDescription(ctx, "AVAX") - if err != nil { - return nil, err - } +// asset, err := xChainClient.GetAssetDescription(ctx, "AVAX") +// if err != nil { +// return nil, err +// } - return NewContext( - networkID, - chainID, - asset.AssetID, - ), nil -} +// return NewContext( +// networkID, +// chainID, +// asset.AssetID, +// ), nil +// } -func NewContext( - networkID uint32, - blockchainID ids.ID, - avaxAssetID ids.ID, -) Context { - return &context{ - networkID: networkID, - blockchainID: blockchainID, - avaxAssetID: avaxAssetID, - } -} +// func NewContext( +// networkID uint32, +// blockchainID ids.ID, +// avaxAssetID ids.ID, +// ) Context { +// return &context{ +// networkID: networkID, +// blockchainID: blockchainID, +// avaxAssetID: avaxAssetID, +// } +// } -func (c *context) NetworkID() uint32 { - return c.networkID -} +// func (c *context) NetworkID() uint32 { +// return c.networkID +// } -func (c *context) BlockchainID() ids.ID { - return c.blockchainID -} +// func (c *context) BlockchainID() ids.ID { +// return c.blockchainID +// } -func (c *context) AVAXAssetID() ids.ID { - return c.avaxAssetID -} +// func (c *context) AVAXAssetID() ids.ID { +// return c.avaxAssetID +// } diff --git a/wallet/chain/c/signer.go b/wallet/chain/c/signer.go index 4fd85ed3b532..4bedc378234b 100644 --- a/wallet/chain/c/signer.go +++ b/wallet/chain/c/signer.go @@ -3,221 +3,221 @@ package c -import ( - "errors" - "fmt" - - stdcontext "context" - - "github.com/ava-labs/coreth/plugin/evm" - - ethcommon "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/avalanchego/database" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/crypto/keychain" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/hashing" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/components/verify" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" -) - -const version = 0 - -var ( - _ Signer = (*txSigner)(nil) - - errUnknownInputType = errors.New("unknown input type") - errUnknownCredentialType = errors.New("unknown credential type") - errUnknownOutputType = errors.New("unknown output type") - errInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") - - emptySig [secp256k1.SignatureLen]byte -) - -type Signer interface { - SignUnsignedAtomic(ctx stdcontext.Context, tx evm.UnsignedAtomicTx) (*evm.Tx, error) - SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error -} - -type EthKeychain interface { - // The returned Signer can provide a signature for [addr] - GetEth(addr ethcommon.Address) (keychain.Signer, bool) - // Returns the set of addresses for which the accessor keeps an associated - // signer - EthAddresses() set.Set[ethcommon.Address] -} - -type SignerBackend interface { - GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) -} - -type txSigner struct { - avaxKC keychain.Keychain - ethKC EthKeychain - backend SignerBackend -} - -func NewSigner(avaxKC keychain.Keychain, ethKC EthKeychain, backend SignerBackend) Signer { - return &txSigner{ - avaxKC: avaxKC, - ethKC: ethKC, - backend: backend, - } -} - -func (s *txSigner) SignUnsignedAtomic(ctx stdcontext.Context, utx evm.UnsignedAtomicTx) (*evm.Tx, error) { - tx := &evm.Tx{UnsignedAtomicTx: utx} - return tx, s.SignAtomic(ctx, tx) -} - -func (s *txSigner) SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error { - switch utx := tx.UnsignedAtomicTx.(type) { - case *evm.UnsignedImportTx: - signers, err := s.getImportSigners(ctx, utx.SourceChain, utx.ImportedInputs) - if err != nil { - return err - } - return sign(tx, true, signers) - case *evm.UnsignedExportTx: - signers := s.getExportSigners(utx.Ins) - return sign(tx, true, signers) - default: - return fmt.Errorf("%w: %T", errUnknownTxType, tx) - } -} - -func (s *txSigner) getImportSigners(ctx stdcontext.Context, sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { - txSigners := make([][]keychain.Signer, len(ins)) - for credIndex, transferInput := range ins { - input, ok := transferInput.In.(*secp256k1fx.TransferInput) - if !ok { - return nil, errUnknownInputType - } - - inputSigners := make([]keychain.Signer, len(input.SigIndices)) - txSigners[credIndex] = inputSigners - - utxoID := transferInput.InputID() - utxo, err := s.backend.GetUTXO(ctx, sourceChainID, utxoID) - if err == database.ErrNotFound { - // If we don't have access to the UTXO, then we can't sign this - // transaction. However, we can attempt to partially sign it. - continue - } - if err != nil { - return nil, err - } - - out, ok := utxo.Out.(*secp256k1fx.TransferOutput) - if !ok { - return nil, errUnknownOutputType - } - - for sigIndex, addrIndex := range input.SigIndices { - if addrIndex >= uint32(len(out.Addrs)) { - return nil, errInvalidUTXOSigIndex - } - - addr := out.Addrs[addrIndex] - key, ok := s.avaxKC.Get(addr) - if !ok { - // If we don't have access to the key, then we can't sign this - // transaction. However, we can attempt to partially sign it. - continue - } - inputSigners[sigIndex] = key - } - } - return txSigners, nil -} - -func (s *txSigner) getExportSigners(ins []evm.EVMInput) [][]keychain.Signer { - txSigners := make([][]keychain.Signer, len(ins)) - for credIndex, input := range ins { - inputSigners := make([]keychain.Signer, 1) - txSigners[credIndex] = inputSigners - - key, ok := s.ethKC.GetEth(input.Address) - if !ok { - // If we don't have access to the key, then we can't sign this - // transaction. However, we can attempt to partially sign it. - continue - } - inputSigners[0] = key - } - return txSigners -} - -// TODO: remove [signHash] after the ledger supports signing all transactions. -func sign(tx *evm.Tx, signHash bool, txSigners [][]keychain.Signer) error { - unsignedBytes, err := evm.Codec.Marshal(version, &tx.UnsignedAtomicTx) - if err != nil { - return fmt.Errorf("couldn't marshal unsigned tx: %w", err) - } - unsignedHash := hashing.ComputeHash256(unsignedBytes) - - if expectedLen := len(txSigners); expectedLen != len(tx.Creds) { - tx.Creds = make([]verify.Verifiable, expectedLen) - } - - sigCache := make(map[ids.ShortID][secp256k1.SignatureLen]byte) - for credIndex, inputSigners := range txSigners { - credIntf := tx.Creds[credIndex] - if credIntf == nil { - credIntf = &secp256k1fx.Credential{} - tx.Creds[credIndex] = credIntf - } - - cred, ok := credIntf.(*secp256k1fx.Credential) - if !ok { - return errUnknownCredentialType - } - if expectedLen := len(inputSigners); expectedLen != len(cred.Sigs) { - cred.Sigs = make([][secp256k1.SignatureLen]byte, expectedLen) - } - - for sigIndex, signer := range inputSigners { - if signer == nil { - // If we don't have access to the key, then we can't sign this - // transaction. However, we can attempt to partially sign it. - continue - } - addr := signer.Address() - if sig := cred.Sigs[sigIndex]; sig != emptySig { - // If this signature has already been populated, we can just - // copy the needed signature for the future. - sigCache[addr] = sig - continue - } - - if sig, exists := sigCache[addr]; exists { - // If this key has already produced a signature, we can just - // copy the previous signature. - cred.Sigs[sigIndex] = sig - continue - } - - var sig []byte - if signHash { - sig, err = signer.SignHash(unsignedHash) - } else { - sig, err = signer.Sign(unsignedBytes) - } - if err != nil { - return fmt.Errorf("problem signing tx: %w", err) - } - copy(cred.Sigs[sigIndex][:], sig) - sigCache[addr] = cred.Sigs[sigIndex] - } - } - - signedBytes, err := evm.Codec.Marshal(version, tx) - if err != nil { - return fmt.Errorf("couldn't marshal tx: %w", err) - } - tx.Initialize(unsignedBytes, signedBytes) - return nil -} +// import ( +// "errors" +// "fmt" + +// stdcontext "context" + +// "github.com/ava-labs/coreth/plugin/evm" + +// ethcommon "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/avalanchego/database" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/utils/crypto/keychain" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// "github.com/ava-labs/avalanchego/utils/hashing" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/components/verify" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// ) + +// const version = 0 + +// var ( +// _ Signer = (*txSigner)(nil) + +// errUnknownInputType = errors.New("unknown input type") +// errUnknownCredentialType = errors.New("unknown credential type") +// errUnknownOutputType = errors.New("unknown output type") +// errInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") + +// emptySig [secp256k1.SignatureLen]byte +// ) + +// type Signer interface { +// SignUnsignedAtomic(ctx stdcontext.Context, tx evm.UnsignedAtomicTx) (*evm.Tx, error) +// SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error +// } + +// type EthKeychain interface { +// // The returned Signer can provide a signature for [addr] +// GetEth(addr ethcommon.Address) (keychain.Signer, bool) +// // Returns the set of addresses for which the accessor keeps an associated +// // signer +// EthAddresses() set.Set[ethcommon.Address] +// } + +// type SignerBackend interface { +// GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) +// } + +// type txSigner struct { +// avaxKC keychain.Keychain +// ethKC EthKeychain +// backend SignerBackend +// } + +// func NewSigner(avaxKC keychain.Keychain, ethKC EthKeychain, backend SignerBackend) Signer { +// return &txSigner{ +// avaxKC: avaxKC, +// ethKC: ethKC, +// backend: backend, +// } +// } + +// func (s *txSigner) SignUnsignedAtomic(ctx stdcontext.Context, utx evm.UnsignedAtomicTx) (*evm.Tx, error) { +// tx := &evm.Tx{UnsignedAtomicTx: utx} +// return tx, s.SignAtomic(ctx, tx) +// } + +// func (s *txSigner) SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error { +// switch utx := tx.UnsignedAtomicTx.(type) { +// case *evm.UnsignedImportTx: +// signers, err := s.getImportSigners(ctx, utx.SourceChain, utx.ImportedInputs) +// if err != nil { +// return err +// } +// return sign(tx, true, signers) +// case *evm.UnsignedExportTx: +// signers := s.getExportSigners(utx.Ins) +// return sign(tx, true, signers) +// default: +// return fmt.Errorf("%w: %T", errUnknownTxType, tx) +// } +// } + +// func (s *txSigner) getImportSigners(ctx stdcontext.Context, sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { +// txSigners := make([][]keychain.Signer, len(ins)) +// for credIndex, transferInput := range ins { +// input, ok := transferInput.In.(*secp256k1fx.TransferInput) +// if !ok { +// return nil, errUnknownInputType +// } + +// inputSigners := make([]keychain.Signer, len(input.SigIndices)) +// txSigners[credIndex] = inputSigners + +// utxoID := transferInput.InputID() +// utxo, err := s.backend.GetUTXO(ctx, sourceChainID, utxoID) +// if err == database.ErrNotFound { +// // If we don't have access to the UTXO, then we can't sign this +// // transaction. However, we can attempt to partially sign it. +// continue +// } +// if err != nil { +// return nil, err +// } + +// out, ok := utxo.Out.(*secp256k1fx.TransferOutput) +// if !ok { +// return nil, errUnknownOutputType +// } + +// for sigIndex, addrIndex := range input.SigIndices { +// if addrIndex >= uint32(len(out.Addrs)) { +// return nil, errInvalidUTXOSigIndex +// } + +// addr := out.Addrs[addrIndex] +// key, ok := s.avaxKC.Get(addr) +// if !ok { +// // If we don't have access to the key, then we can't sign this +// // transaction. However, we can attempt to partially sign it. +// continue +// } +// inputSigners[sigIndex] = key +// } +// } +// return txSigners, nil +// } + +// func (s *txSigner) getExportSigners(ins []evm.EVMInput) [][]keychain.Signer { +// txSigners := make([][]keychain.Signer, len(ins)) +// for credIndex, input := range ins { +// inputSigners := make([]keychain.Signer, 1) +// txSigners[credIndex] = inputSigners + +// key, ok := s.ethKC.GetEth(input.Address) +// if !ok { +// // If we don't have access to the key, then we can't sign this +// // transaction. However, we can attempt to partially sign it. +// continue +// } +// inputSigners[0] = key +// } +// return txSigners +// } + +// // TODO: remove [signHash] after the ledger supports signing all transactions. +// func sign(tx *evm.Tx, signHash bool, txSigners [][]keychain.Signer) error { +// unsignedBytes, err := evm.Codec.Marshal(version, &tx.UnsignedAtomicTx) +// if err != nil { +// return fmt.Errorf("couldn't marshal unsigned tx: %w", err) +// } +// unsignedHash := hashing.ComputeHash256(unsignedBytes) + +// if expectedLen := len(txSigners); expectedLen != len(tx.Creds) { +// tx.Creds = make([]verify.Verifiable, expectedLen) +// } + +// sigCache := make(map[ids.ShortID][secp256k1.SignatureLen]byte) +// for credIndex, inputSigners := range txSigners { +// credIntf := tx.Creds[credIndex] +// if credIntf == nil { +// credIntf = &secp256k1fx.Credential{} +// tx.Creds[credIndex] = credIntf +// } + +// cred, ok := credIntf.(*secp256k1fx.Credential) +// if !ok { +// return errUnknownCredentialType +// } +// if expectedLen := len(inputSigners); expectedLen != len(cred.Sigs) { +// cred.Sigs = make([][secp256k1.SignatureLen]byte, expectedLen) +// } + +// for sigIndex, signer := range inputSigners { +// if signer == nil { +// // If we don't have access to the key, then we can't sign this +// // transaction. However, we can attempt to partially sign it. +// continue +// } +// addr := signer.Address() +// if sig := cred.Sigs[sigIndex]; sig != emptySig { +// // If this signature has already been populated, we can just +// // copy the needed signature for the future. +// sigCache[addr] = sig +// continue +// } + +// if sig, exists := sigCache[addr]; exists { +// // If this key has already produced a signature, we can just +// // copy the previous signature. +// cred.Sigs[sigIndex] = sig +// continue +// } + +// var sig []byte +// if signHash { +// sig, err = signer.SignHash(unsignedHash) +// } else { +// sig, err = signer.Sign(unsignedBytes) +// } +// if err != nil { +// return fmt.Errorf("problem signing tx: %w", err) +// } +// copy(cred.Sigs[sigIndex][:], sig) +// sigCache[addr] = cred.Sigs[sigIndex] +// } +// } + +// signedBytes, err := evm.Codec.Marshal(version, tx) +// if err != nil { +// return fmt.Errorf("couldn't marshal tx: %w", err) +// } +// tx.Initialize(unsignedBytes, signedBytes) +// return nil +// } diff --git a/wallet/chain/c/wallet.go b/wallet/chain/c/wallet.go index fb1a83d53dad..ebee50a9a958 100644 --- a/wallet/chain/c/wallet.go +++ b/wallet/chain/c/wallet.go @@ -3,204 +3,204 @@ package c -import ( - "errors" - "math/big" - "time" - - "github.com/ava-labs/coreth/ethclient" - "github.com/ava-labs/coreth/plugin/evm" - - ethcommon "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var ( - _ Wallet = (*wallet)(nil) - - errNotCommitted = errors.New("not committed") -) - -type Wallet interface { - Context - - // Builder returns the builder that will be used to create the transactions. - Builder() Builder - - // Signer returns the signer that will be used to sign the transactions. - Signer() Signer - - // IssueImportTx creates, signs, and issues an import transaction that - // attempts to consume all the available UTXOs and import the funds to [to]. - // - // - [chainID] specifies the chain to be importing funds from. - // - [to] specifies where to send the imported funds to. - IssueImportTx( - chainID ids.ID, - to ethcommon.Address, - options ...common.Option, - ) (*evm.Tx, error) - - // IssueExportTx creates, signs, and issues an export transaction that - // attempts to send all the provided [outputs] to the requested [chainID]. - // - // - [chainID] specifies the chain to be exporting the funds to. - // - [outputs] specifies the outputs to send to the [chainID]. - IssueExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - options ...common.Option, - ) (*evm.Tx, error) - - // IssueUnsignedTx signs and issues the unsigned tx. - IssueUnsignedAtomicTx( - utx evm.UnsignedAtomicTx, - options ...common.Option, - ) (*evm.Tx, error) - - // IssueAtomicTx issues the signed tx. - IssueAtomicTx( - tx *evm.Tx, - options ...common.Option, - ) error -} - -func NewWallet( - builder Builder, - signer Signer, - avaxClient evm.Client, - ethClient ethclient.Client, - backend Backend, -) Wallet { - return &wallet{ - Backend: backend, - builder: builder, - signer: signer, - avaxClient: avaxClient, - ethClient: ethClient, - } -} - -type wallet struct { - Backend - builder Builder - signer Signer - avaxClient evm.Client - ethClient ethclient.Client -} - -func (w *wallet) Builder() Builder { - return w.builder -} - -func (w *wallet) Signer() Signer { - return w.signer -} - -func (w *wallet) IssueImportTx( - chainID ids.ID, - to ethcommon.Address, - options ...common.Option, -) (*evm.Tx, error) { - baseFee, err := w.baseFee(options) - if err != nil { - return nil, err - } - - utx, err := w.builder.NewImportTx(chainID, to, baseFee, options...) - if err != nil { - return nil, err - } - return w.IssueUnsignedAtomicTx(utx, options...) -} - -func (w *wallet) IssueExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - options ...common.Option, -) (*evm.Tx, error) { - baseFee, err := w.baseFee(options) - if err != nil { - return nil, err - } - - utx, err := w.builder.NewExportTx(chainID, outputs, baseFee, options...) - if err != nil { - return nil, err - } - return w.IssueUnsignedAtomicTx(utx, options...) -} - -func (w *wallet) IssueUnsignedAtomicTx( - utx evm.UnsignedAtomicTx, - options ...common.Option, -) (*evm.Tx, error) { - ops := common.NewOptions(options) - ctx := ops.Context() - tx, err := w.signer.SignUnsignedAtomic(ctx, utx) - if err != nil { - return nil, err - } - - return tx, w.IssueAtomicTx(tx, options...) -} - -func (w *wallet) IssueAtomicTx( - tx *evm.Tx, - options ...common.Option, -) error { - ops := common.NewOptions(options) - ctx := ops.Context() - txID, err := w.avaxClient.IssueTx(ctx, tx.SignedBytes()) - if err != nil { - return err - } - - if f := ops.PostIssuanceFunc(); f != nil { - f(txID) - } - - if ops.AssumeDecided() { - return w.Backend.AcceptAtomicTx(ctx, tx) - } - - pollFrequency := ops.PollFrequency() - ticker := time.NewTicker(pollFrequency) - defer ticker.Stop() - - for { - status, err := w.avaxClient.GetAtomicTxStatus(ctx, txID) - if err != nil { - return err - } - - switch status { - case evm.Accepted: - return w.Backend.AcceptAtomicTx(ctx, tx) - case evm.Dropped, evm.Unknown: - return errNotCommitted - } - - // The tx is Processing. - - select { - case <-ticker.C: - case <-ctx.Done(): - return ctx.Err() - } - } -} - -func (w *wallet) baseFee(options []common.Option) (*big.Int, error) { - ops := common.NewOptions(options) - baseFee := ops.BaseFee(nil) - if baseFee != nil { - return baseFee, nil - } - - ctx := ops.Context() - return w.ethClient.EstimateBaseFee(ctx) -} +// import ( +// "errors" +// "math/big" +// "time" + +// "github.com/ava-labs/coreth/ethclient" +// "github.com/ava-labs/coreth/plugin/evm" + +// ethcommon "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var ( +// _ Wallet = (*wallet)(nil) + +// errNotCommitted = errors.New("not committed") +// ) + +// type Wallet interface { +// Context + +// // Builder returns the builder that will be used to create the transactions. +// Builder() Builder + +// // Signer returns the signer that will be used to sign the transactions. +// Signer() Signer + +// // IssueImportTx creates, signs, and issues an import transaction that +// // attempts to consume all the available UTXOs and import the funds to [to]. +// // +// // - [chainID] specifies the chain to be importing funds from. +// // - [to] specifies where to send the imported funds to. +// IssueImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// options ...common.Option, +// ) (*evm.Tx, error) + +// // IssueExportTx creates, signs, and issues an export transaction that +// // attempts to send all the provided [outputs] to the requested [chainID]. +// // +// // - [chainID] specifies the chain to be exporting the funds to. +// // - [outputs] specifies the outputs to send to the [chainID]. +// IssueExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// options ...common.Option, +// ) (*evm.Tx, error) + +// // IssueUnsignedTx signs and issues the unsigned tx. +// IssueUnsignedAtomicTx( +// utx evm.UnsignedAtomicTx, +// options ...common.Option, +// ) (*evm.Tx, error) + +// // IssueAtomicTx issues the signed tx. +// IssueAtomicTx( +// tx *evm.Tx, +// options ...common.Option, +// ) error +// } + +// func NewWallet( +// builder Builder, +// signer Signer, +// avaxClient evm.Client, +// ethClient ethclient.Client, +// backend Backend, +// ) Wallet { +// return &wallet{ +// Backend: backend, +// builder: builder, +// signer: signer, +// avaxClient: avaxClient, +// ethClient: ethClient, +// } +// } + +// type wallet struct { +// Backend +// builder Builder +// signer Signer +// avaxClient evm.Client +// ethClient ethclient.Client +// } + +// func (w *wallet) Builder() Builder { +// return w.builder +// } + +// func (w *wallet) Signer() Signer { +// return w.signer +// } + +// func (w *wallet) IssueImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// options ...common.Option, +// ) (*evm.Tx, error) { +// baseFee, err := w.baseFee(options) +// if err != nil { +// return nil, err +// } + +// utx, err := w.builder.NewImportTx(chainID, to, baseFee, options...) +// if err != nil { +// return nil, err +// } +// return w.IssueUnsignedAtomicTx(utx, options...) +// } + +// func (w *wallet) IssueExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// options ...common.Option, +// ) (*evm.Tx, error) { +// baseFee, err := w.baseFee(options) +// if err != nil { +// return nil, err +// } + +// utx, err := w.builder.NewExportTx(chainID, outputs, baseFee, options...) +// if err != nil { +// return nil, err +// } +// return w.IssueUnsignedAtomicTx(utx, options...) +// } + +// func (w *wallet) IssueUnsignedAtomicTx( +// utx evm.UnsignedAtomicTx, +// options ...common.Option, +// ) (*evm.Tx, error) { +// ops := common.NewOptions(options) +// ctx := ops.Context() +// tx, err := w.signer.SignUnsignedAtomic(ctx, utx) +// if err != nil { +// return nil, err +// } + +// return tx, w.IssueAtomicTx(tx, options...) +// } + +// func (w *wallet) IssueAtomicTx( +// tx *evm.Tx, +// options ...common.Option, +// ) error { +// ops := common.NewOptions(options) +// ctx := ops.Context() +// txID, err := w.avaxClient.IssueTx(ctx, tx.SignedBytes()) +// if err != nil { +// return err +// } + +// if f := ops.PostIssuanceFunc(); f != nil { +// f(txID) +// } + +// if ops.AssumeDecided() { +// return w.Backend.AcceptAtomicTx(ctx, tx) +// } + +// pollFrequency := ops.PollFrequency() +// ticker := time.NewTicker(pollFrequency) +// defer ticker.Stop() + +// for { +// status, err := w.avaxClient.GetAtomicTxStatus(ctx, txID) +// if err != nil { +// return err +// } + +// switch status { +// case evm.Accepted: +// return w.Backend.AcceptAtomicTx(ctx, tx) +// case evm.Dropped, evm.Unknown: +// return errNotCommitted +// } + +// // The tx is Processing. + +// select { +// case <-ticker.C: +// case <-ctx.Done(): +// return ctx.Err() +// } +// } +// } + +// func (w *wallet) baseFee(options []common.Option) (*big.Int, error) { +// ops := common.NewOptions(options) +// baseFee := ops.BaseFee(nil) +// if baseFee != nil { +// return baseFee, nil +// } + +// ctx := ops.Context() +// return w.ethClient.EstimateBaseFee(ctx) +// } diff --git a/wallet/chain/c/wallet_with_options.go b/wallet/chain/c/wallet_with_options.go index 7d6193683d49..fd69a6d4fd02 100644 --- a/wallet/chain/c/wallet_with_options.go +++ b/wallet/chain/c/wallet_with_options.go @@ -3,80 +3,80 @@ package c -import ( - "github.com/ava-labs/coreth/plugin/evm" +// import ( +// "github.com/ava-labs/coreth/plugin/evm" - ethcommon "github.com/ethereum/go-ethereum/common" +// ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) -var _ Wallet = (*walletWithOptions)(nil) +// var _ Wallet = (*walletWithOptions)(nil) -func NewWalletWithOptions( - wallet Wallet, - options ...common.Option, -) Wallet { - return &walletWithOptions{ - Wallet: wallet, - options: options, - } -} +// func NewWalletWithOptions( +// wallet Wallet, +// options ...common.Option, +// ) Wallet { +// return &walletWithOptions{ +// Wallet: wallet, +// options: options, +// } +// } -type walletWithOptions struct { - Wallet - options []common.Option -} +// type walletWithOptions struct { +// Wallet +// options []common.Option +// } -func (w *walletWithOptions) Builder() Builder { - return NewBuilderWithOptions( - w.Wallet.Builder(), - w.options..., - ) -} +// func (w *walletWithOptions) Builder() Builder { +// return NewBuilderWithOptions( +// w.Wallet.Builder(), +// w.options..., +// ) +// } -func (w *walletWithOptions) IssueImportTx( - chainID ids.ID, - to ethcommon.Address, - options ...common.Option, -) (*evm.Tx, error) { - return w.Wallet.IssueImportTx( - chainID, - to, - common.UnionOptions(w.options, options)..., - ) -} +// func (w *walletWithOptions) IssueImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// options ...common.Option, +// ) (*evm.Tx, error) { +// return w.Wallet.IssueImportTx( +// chainID, +// to, +// common.UnionOptions(w.options, options)..., +// ) +// } -func (w *walletWithOptions) IssueExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - options ...common.Option, -) (*evm.Tx, error) { - return w.Wallet.IssueExportTx( - chainID, - outputs, - common.UnionOptions(w.options, options)..., - ) -} +// func (w *walletWithOptions) IssueExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// options ...common.Option, +// ) (*evm.Tx, error) { +// return w.Wallet.IssueExportTx( +// chainID, +// outputs, +// common.UnionOptions(w.options, options)..., +// ) +// } -func (w *walletWithOptions) IssueUnsignedAtomicTx( - utx evm.UnsignedAtomicTx, - options ...common.Option, -) (*evm.Tx, error) { - return w.Wallet.IssueUnsignedAtomicTx( - utx, - common.UnionOptions(w.options, options)..., - ) -} +// func (w *walletWithOptions) IssueUnsignedAtomicTx( +// utx evm.UnsignedAtomicTx, +// options ...common.Option, +// ) (*evm.Tx, error) { +// return w.Wallet.IssueUnsignedAtomicTx( +// utx, +// common.UnionOptions(w.options, options)..., +// ) +// } -func (w *walletWithOptions) IssueAtomicTx( - tx *evm.Tx, - options ...common.Option, -) error { - return w.Wallet.IssueAtomicTx( - tx, - common.UnionOptions(w.options, options)..., - ) -} +// func (w *walletWithOptions) IssueAtomicTx( +// tx *evm.Tx, +// options ...common.Option, +// ) error { +// return w.Wallet.IssueAtomicTx( +// tx, +// common.UnionOptions(w.options, options)..., +// ) +// } diff --git a/wallet/subnet/primary/api.go b/wallet/subnet/primary/api.go index 3ac72c217884..00ebea6090fd 100644 --- a/wallet/subnet/primary/api.go +++ b/wallet/subnet/primary/api.go @@ -5,12 +5,11 @@ package primary import ( "context" - "fmt" + // "fmt" - "github.com/ava-labs/coreth/ethclient" - "github.com/ava-labs/coreth/plugin/evm" + // "github.com/ava-labs/coreth/ethclient" - "github.com/ethereum/go-ethereum/common" + // "github.com/ethereum/go-ethereum/common" "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/codec" @@ -22,7 +21,8 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/wallet/chain/c" + + // "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/x" ) @@ -59,9 +59,9 @@ type AVAXState struct { PCTX p.Context XClient avm.Client XCTX x.Context - CClient evm.Client - CCTX c.Context - UTXOs UTXOs + // CClient evm.Client + // CCTX c.Context + UTXOs UTXOs } func FetchState( @@ -75,7 +75,7 @@ func FetchState( infoClient := info.NewClient(uri) pClient := platformvm.NewClient(uri) xClient := avm.NewClient(uri, "X") - cClient := evm.NewCChainClient(uri) + // cClient := evm.NewCChainClient(uri) pCTX, err := p.NewContextFromClients(ctx, infoClient, xClient) if err != nil { @@ -87,10 +87,10 @@ func FetchState( return nil, err } - cCTX, err := c.NewContextFromClients(ctx, infoClient, xClient) - if err != nil { - return nil, err - } + // cCTX, err := c.NewContextFromClients(ctx, infoClient, xClient) + // if err != nil { + // return nil, err + // } utxos := NewUTXOs() addrList := addrs.List() @@ -109,11 +109,11 @@ func FetchState( client: xClient, codec: x.Parser.Codec(), }, - { - id: cCTX.BlockchainID(), - client: cClient, - codec: evm.Codec, - }, + // { + // id: cCTX.BlockchainID(), + // client: cClient, + // codec: evm.Codec, + // }, } for _, destinationChain := range chains { for _, sourceChain := range chains { @@ -136,52 +136,52 @@ func FetchState( PCTX: pCTX, XClient: xClient, XCTX: xCTX, - CClient: cClient, - CCTX: cCTX, - UTXOs: utxos, + // CClient: cClient, + // CCTX: cCTX, + UTXOs: utxos, }, nil } -type EthState struct { - Client ethclient.Client - Accounts map[common.Address]*c.Account -} - -func FetchEthState( - ctx context.Context, - uri string, - addrs set.Set[common.Address], -) (*EthState, error) { - path := fmt.Sprintf( - "%s/ext/%s/C/rpc", - uri, - constants.ChainAliasPrefix, - ) - client, err := ethclient.Dial(path) - if err != nil { - return nil, err - } - - accounts := make(map[common.Address]*c.Account, addrs.Len()) - for addr := range addrs { - balance, err := client.BalanceAt(ctx, addr, nil) - if err != nil { - return nil, err - } - nonce, err := client.NonceAt(ctx, addr, nil) - if err != nil { - return nil, err - } - accounts[addr] = &c.Account{ - Balance: balance, - Nonce: nonce, - } - } - return &EthState{ - Client: client, - Accounts: accounts, - }, nil -} +// type EthState struct { +// Client ethclient.Client +// Accounts map[common.Address]*c.Account +// } + +// func FetchEthState( +// ctx context.Context, +// uri string, +// addrs set.Set[common.Address], +// ) (*EthState, error) { +// path := fmt.Sprintf( +// "%s/ext/%s/C/rpc", +// uri, +// constants.ChainAliasPrefix, +// ) +// client, err := ethclient.Dial(path) +// if err != nil { +// return nil, err +// } + +// accounts := make(map[common.Address]*c.Account, addrs.Len()) +// for addr := range addrs { +// balance, err := client.BalanceAt(ctx, addr, nil) +// if err != nil { +// return nil, err +// } +// nonce, err := client.NonceAt(ctx, addr, nil) +// if err != nil { +// return nil, err +// } +// accounts[addr] = &c.Account{ +// Balance: balance, +// Nonce: nonce, +// } +// } +// return &EthState{ +// Client: client, +// Accounts: accounts, +// }, nil +// } // AddAllUTXOs fetches all the UTXOs referenced by [addresses] that were sent // from [sourceChainID] to [destinationChainID] from the [client]. It then uses diff --git a/wallet/subnet/primary/example_test.go b/wallet/subnet/primary/example_test.go index 483c049d4ac0..4a73e8c070b2 100644 --- a/wallet/subnet/primary/example_test.go +++ b/wallet/subnet/primary/example_test.go @@ -30,7 +30,7 @@ func ExampleWallet() { wallet, err := MakeWallet(ctx, &WalletConfig{ URI: LocalAPIURI, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet with: %s\n", err) diff --git a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go index d5e8ce422307..21c081d2982b 100644 --- a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go +++ b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go @@ -46,9 +46,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + // EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/examples/add-primary-validator/main.go b/wallet/subnet/primary/examples/add-primary-validator/main.go index a56dae23db3a..13c28f995f63 100644 --- a/wallet/subnet/primary/examples/add-primary-validator/main.go +++ b/wallet/subnet/primary/examples/add-primary-validator/main.go @@ -45,7 +45,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/c-chain-export/main.go b/wallet/subnet/primary/examples/c-chain-export/main.go index fec55c899feb..a6b9a0c810b8 100644 --- a/wallet/subnet/primary/examples/c-chain-export/main.go +++ b/wallet/subnet/primary/examples/c-chain-export/main.go @@ -3,70 +3,70 @@ package main -import ( - "context" - "log" - "time" +// import ( +// "context" +// "log" +// "time" - "github.com/ava-labs/avalanchego/genesis" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary" -) +// "github.com/ava-labs/avalanchego/genesis" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary" +// ) -func main() { - key := genesis.EWOQKey - uri := primary.LocalAPIURI - kc := secp256k1fx.NewKeychain(key) - avaxAddr := key.Address() +// func main() { +// key := genesis.EWOQKey +// uri := primary.LocalAPIURI +// kc := secp256k1fx.NewKeychain(key) +// avaxAddr := key.Address() - ctx := context.Background() +// ctx := context.Background() - // MakeWallet fetches the available UTXOs owned by [kc] on the network that - // [uri] is hosting. - walletSyncStartTime := time.Now() - wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, - }) - if err != nil { - log.Fatalf("failed to initialize wallet: %s\n", err) - } - log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) +// // MakeWallet fetches the available UTXOs owned by [kc] on the network that +// // [uri] is hosting. +// walletSyncStartTime := time.Now() +// wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ +// URI: uri, +// AVAXKeychain: kc, +// EthKeychain: kc, +// }) +// if err != nil { +// log.Fatalf("failed to initialize wallet: %s\n", err) +// } +// log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) - // Get the P-chain wallet - pWallet := wallet.P() - cWallet := wallet.C() +// // Get the P-chain wallet +// pWallet := wallet.P() +// cWallet := wallet.C() - // Pull out useful constants to use when issuing transactions. - cChainID := cWallet.BlockchainID() - owner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - avaxAddr, - }, - } +// // Pull out useful constants to use when issuing transactions. +// cChainID := cWallet.BlockchainID() +// owner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// avaxAddr, +// }, +// } - exportStartTime := time.Now() - exportTx, err := cWallet.IssueExportTx( - constants.PlatformChainID, - []*secp256k1fx.TransferOutput{{ - Amt: units.Avax, - OutputOwners: owner, - }}, - ) - if err != nil { - log.Fatalf("failed to issue export transaction: %s\n", err) - } - log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) +// exportStartTime := time.Now() +// exportTx, err := cWallet.IssueExportTx( +// constants.PlatformChainID, +// []*secp256k1fx.TransferOutput{{ +// Amt: units.Avax, +// OutputOwners: owner, +// }}, +// ) +// if err != nil { +// log.Fatalf("failed to issue export transaction: %s\n", err) +// } +// log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) - importStartTime := time.Now() - importTx, err := pWallet.IssueImportTx(cChainID, &owner) - if err != nil { - log.Fatalf("failed to issue import transaction: %s\n", err) - } - log.Printf("issued import %s in %s\n", importTx.ID(), time.Since(importStartTime)) -} +// importStartTime := time.Now() +// importTx, err := pWallet.IssueImportTx(cChainID, &owner) +// if err != nil { +// log.Fatalf("failed to issue import transaction: %s\n", err) +// } +// log.Printf("issued import %s in %s\n", importTx.ID(), time.Since(importStartTime)) +// } diff --git a/wallet/subnet/primary/examples/c-chain-import/main.go b/wallet/subnet/primary/examples/c-chain-import/main.go index b4dc4e603eb3..2d9b8a244cb0 100644 --- a/wallet/subnet/primary/examples/c-chain-import/main.go +++ b/wallet/subnet/primary/examples/c-chain-import/main.go @@ -3,75 +3,75 @@ package main -import ( - "context" - "log" - "time" +// import ( +// "context" +// "log" +// "time" - "github.com/ava-labs/coreth/plugin/evm" +// "github.com/ava-labs/coreth/plugin/evm" - "github.com/ava-labs/avalanchego/genesis" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary" -) +// "github.com/ava-labs/avalanchego/genesis" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary" +// ) -func main() { - key := genesis.EWOQKey - uri := primary.LocalAPIURI - kc := secp256k1fx.NewKeychain(key) - avaxAddr := key.Address() - ethAddr := evm.PublicKeyToEthAddress(key.PublicKey()) +// func main() { +// key := genesis.EWOQKey +// uri := primary.LocalAPIURI +// kc := secp256k1fx.NewKeychain(key) +// avaxAddr := key.Address() +// ethAddr := evm.PublicKeyToEthAddress(key.PublicKey()) - ctx := context.Background() +// ctx := context.Background() - // MakeWallet fetches the available UTXOs owned by [kc] on the network that - // [uri] is hosting. - walletSyncStartTime := time.Now() - wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, - }) - if err != nil { - log.Fatalf("failed to initialize wallet: %s\n", err) - } - log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) +// // MakeWallet fetches the available UTXOs owned by [kc] on the network that +// // [uri] is hosting. +// walletSyncStartTime := time.Now() +// wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ +// URI: uri, +// AVAXKeychain: kc, +// EthKeychain: kc, +// }) +// if err != nil { +// log.Fatalf("failed to initialize wallet: %s\n", err) +// } +// log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) - // Get the P-chain wallet - pWallet := wallet.P() - cWallet := wallet.C() +// // Get the P-chain wallet +// pWallet := wallet.P() +// cWallet := wallet.C() - // Pull out useful constants to use when issuing transactions. - cChainID := cWallet.BlockchainID() - avaxAssetID := cWallet.AVAXAssetID() - owner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - avaxAddr, - }, - } +// // Pull out useful constants to use when issuing transactions. +// cChainID := cWallet.BlockchainID() +// avaxAssetID := cWallet.AVAXAssetID() +// owner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// avaxAddr, +// }, +// } - exportStartTime := time.Now() - exportTx, err := pWallet.IssueExportTx(cChainID, []*avax.TransferableOutput{{ - Asset: avax.Asset{ID: avaxAssetID}, - Out: &secp256k1fx.TransferOutput{ - Amt: units.Avax, - OutputOwners: owner, - }, - }}) - if err != nil { - log.Fatalf("failed to issue export transaction: %s\n", err) - } - log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) +// exportStartTime := time.Now() +// exportTx, err := pWallet.IssueExportTx(cChainID, []*avax.TransferableOutput{{ +// Asset: avax.Asset{ID: avaxAssetID}, +// Out: &secp256k1fx.TransferOutput{ +// Amt: units.Avax, +// OutputOwners: owner, +// }, +// }}) +// if err != nil { +// log.Fatalf("failed to issue export transaction: %s\n", err) +// } +// log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) - importStartTime := time.Now() - importTx, err := cWallet.IssueImportTx(constants.PlatformChainID, ethAddr) - if err != nil { - log.Fatalf("failed to issue import transaction: %s\n", err) - } - log.Printf("issued import %s to %s in %s\n", importTx.ID(), ethAddr.Hex(), time.Since(importStartTime)) -} +// importStartTime := time.Now() +// importTx, err := cWallet.IssueImportTx(constants.PlatformChainID, ethAddr) +// if err != nil { +// log.Fatalf("failed to issue import transaction: %s\n", err) +// } +// log.Printf("issued import %s to %s in %s\n", importTx.ID(), ethAddr.Hex(), time.Since(importStartTime)) +// } diff --git a/wallet/subnet/primary/examples/create-asset/main.go b/wallet/subnet/primary/examples/create-asset/main.go index 30804f083df6..0bccfbb5fc52 100644 --- a/wallet/subnet/primary/examples/create-asset/main.go +++ b/wallet/subnet/primary/examples/create-asset/main.go @@ -30,7 +30,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/create-chain/main.go b/wallet/subnet/primary/examples/create-chain/main.go index 5e6898a1b649..521a3cca53cf 100644 --- a/wallet/subnet/primary/examples/create-chain/main.go +++ b/wallet/subnet/primary/examples/create-chain/main.go @@ -41,9 +41,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + // EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/examples/create-locked-stakeable/main.go b/wallet/subnet/primary/examples/create-locked-stakeable/main.go index e688968e9e8a..92f1b5cb0e1b 100644 --- a/wallet/subnet/primary/examples/create-locked-stakeable/main.go +++ b/wallet/subnet/primary/examples/create-locked-stakeable/main.go @@ -39,7 +39,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/create-subnet/main.go b/wallet/subnet/primary/examples/create-subnet/main.go index add98ea7931c..3e8d69bc016a 100644 --- a/wallet/subnet/primary/examples/create-subnet/main.go +++ b/wallet/subnet/primary/examples/create-subnet/main.go @@ -28,7 +28,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/remove-subnet-validator/main.go b/wallet/subnet/primary/examples/remove-subnet-validator/main.go index 2842c7c0a790..46f4b85124db 100644 --- a/wallet/subnet/primary/examples/remove-subnet-validator/main.go +++ b/wallet/subnet/primary/examples/remove-subnet-validator/main.go @@ -38,9 +38,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + // EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/wallet.go b/wallet/subnet/primary/wallet.go index 54de390d029c..ae5e4202a099 100644 --- a/wallet/subnet/primary/wallet.go +++ b/wallet/subnet/primary/wallet.go @@ -11,7 +11,8 @@ import ( "github.com/ava-labs/avalanchego/utils/crypto/keychain" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/wallet/chain/c" + + // "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/x" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -23,13 +24,13 @@ var _ Wallet = (*wallet)(nil) type Wallet interface { P() p.Wallet X() x.Wallet - C() c.Wallet + // C() c.Wallet } type wallet struct { p p.Wallet x x.Wallet - c c.Wallet + // c c.Wallet } func (w *wallet) P() p.Wallet { @@ -40,16 +41,16 @@ func (w *wallet) X() x.Wallet { return w.x } -func (w *wallet) C() c.Wallet { - return w.c -} +// func (w *wallet) C() c.Wallet { +// return w.c +// } // Creates a new default wallet -func NewWallet(p p.Wallet, x x.Wallet, c c.Wallet) Wallet { +func NewWallet(p p.Wallet, x x.Wallet /*, c c.Wallet*/) Wallet { return &wallet{ p: p, x: x, - c: c, + // c: c, } } @@ -58,7 +59,7 @@ func NewWalletWithOptions(w Wallet, options ...common.Option) Wallet { return NewWallet( p.NewWalletWithOptions(w.P(), options...), x.NewWalletWithOptions(w.X(), options...), - c.NewWalletWithOptions(w.C(), options...), + // c.NewWalletWithOptions(w.C(), options...), ) } @@ -67,7 +68,7 @@ type WalletConfig struct { URI string // required // Keys to use for signing all transactions. AVAXKeychain keychain.Keychain // required - EthKeychain c.EthKeychain // required + // EthKeychain c.EthKeychain // required // Set of P-chain transactions that the wallet should know about to be able // to generate transactions. PChainTxs map[ids.ID]*txs.Tx // optional @@ -93,11 +94,11 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { return nil, err } - ethAddrs := config.EthKeychain.EthAddresses() - ethState, err := FetchEthState(ctx, config.URI, ethAddrs) - if err != nil { - return nil, err - } + // ethAddrs := config.EthKeychain.EthAddresses() + // ethState, err := FetchEthState(ctx, config.URI, ethAddrs) + // if err != nil { + // return nil, err + // } pChainTxs := config.PChainTxs if pChainTxs == nil { @@ -127,15 +128,15 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { xBuilder := x.NewBuilder(avaxAddrs, xBackend) xSigner := x.NewSigner(config.AVAXKeychain, xBackend) - cChainID := avaxState.CCTX.BlockchainID() - cUTXOs := NewChainUTXOs(cChainID, avaxState.UTXOs) - cBackend := c.NewBackend(avaxState.CCTX, cUTXOs, ethState.Accounts) - cBuilder := c.NewBuilder(avaxAddrs, ethAddrs, cBackend) - cSigner := c.NewSigner(config.AVAXKeychain, config.EthKeychain, cBackend) + // cChainID := avaxState.CCTX.BlockchainID() + // cUTXOs := NewChainUTXOs(cChainID, avaxState.UTXOs) + // cBackend := c.NewBackend(avaxState.CCTX, cUTXOs, ethState.Accounts) + // cBuilder := c.NewBuilder(avaxAddrs, ethAddrs, cBackend) + // cSigner := c.NewSigner(config.AVAXKeychain, config.EthKeychain, cBackend) return NewWallet( p.NewWallet(pBuilder, pSigner, avaxState.PClient, pBackend), x.NewWallet(xBuilder, xSigner, avaxState.XClient, xBackend), - c.NewWallet(cBuilder, cSigner, avaxState.CClient, ethState.Client, cBackend), + // c.NewWallet(cBuilder, cSigner, avaxState.CClient, ethState.Client, cBackend), ), nil } From e8fe105120e4387b30de34c00d8c39d379e820eb Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 23 Nov 2023 10:44:37 +0100 Subject: [PATCH 05/13] bumped coreth version --- go.mod | 25 + go.sum | 76 ++ node/node.go | 4 +- tests/e2e/c/dynamic_fees.go | 326 +++---- tests/e2e/c/interchain_workflow.go | 320 +++---- tests/e2e/p/interchain_workflow.go | 444 +++++----- tests/e2e/x/interchain_workflow.go | 296 +++---- tests/fixture/e2e/helpers.go | 123 ++- tests/fixture/testnet/config.go | 56 +- vms/example/xsvm/cmd/chain/create/cmd.go | 6 +- wallet/chain/c/backend.go | 300 +++---- wallet/chain/c/builder.go | 792 +++++++++--------- wallet/chain/c/builder_with_options.go | 136 +-- wallet/chain/c/context.go | 130 +-- wallet/chain/c/signer.go | 436 +++++----- wallet/chain/c/wallet.go | 402 ++++----- wallet/chain/c/wallet_with_options.go | 134 +-- wallet/subnet/primary/api.go | 122 +-- wallet/subnet/primary/example_test.go | 2 +- .../add-permissioned-subnet-validator/main.go | 6 +- .../examples/add-primary-validator/main.go | 2 +- .../primary/examples/c-chain-export/main.go | 118 +-- .../primary/examples/c-chain-import/main.go | 126 +-- .../primary/examples/create-asset/main.go | 2 +- .../primary/examples/create-chain/main.go | 6 +- .../examples/create-locked-stakeable/main.go | 2 +- .../primary/examples/create-subnet/main.go | 2 +- .../examples/remove-subnet-validator/main.go | 6 +- wallet/subnet/primary/wallet.go | 43 +- 29 files changed, 2270 insertions(+), 2173 deletions(-) diff --git a/go.mod b/go.mod index 23b752198fdd..be6bbc8b23ee 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 + github.com/ava-labs/coreth v0.12.9-rc.5.0.20231123093038-4cb2ebecb2ee github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 @@ -74,6 +75,7 @@ require ( github.com/BurntSushi/toml v1.2.1 // indirect github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect + github.com/VictoriaMetrics/fastcache v1.10.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect @@ -81,26 +83,44 @@ require ( github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/redact v1.1.3 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/deckarep/golang-set/v2 v2.1.0 // indirect + github.com/dlclark/regexp2 v1.7.0 // indirect + github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 // indirect + github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect github.com/frankban/quicktest v1.14.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/getsentry/sentry-go v0.18.0 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect + github.com/go-stack/stack v1.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/go-cmp v0.5.9 // indirect + github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect + github.com/google/uuid v1.3.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 // indirect + github.com/hashicorp/go-bexpr v0.1.10 // indirect + github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e // indirect github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/klauspost/compress v1.15.15 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/magiconair/properties v1.8.6 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mitchellh/pointerstructure v1.2.0 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -108,12 +128,17 @@ require ( github.com/prometheus/common v0.39.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sanity-io/litter v1.5.1 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/status-im/keycard-go v0.2.0 // indirect github.com/subosito/gotenv v1.3.0 // indirect github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tklauser/numcpus v0.2.2 // indirect + github.com/tyler-smith/go-bip39 v1.1.0 // indirect + github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect diff --git a/go.sum b/go.sum index 2ae152b17faf..520209856794 100644 --- a/go.sum +++ b/go.sum @@ -56,12 +56,18 @@ github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cq github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= +github.com/VictoriaMetrics/fastcache v1.10.0 h1:5hDJnLsKLpnUEToub7ETuRu8RCkb40woBZAUiKonXzY= +github.com/VictoriaMetrics/fastcache v1.10.0/go.mod h1:tjiYeEfYXCqacuvYw/7UoDIeJaNxq6132xHICNP77w8= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/ava-labs/coreth v0.12.9-rc.5.0.20231123093038-4cb2ebecb2ee h1:qH7KPqaLWCZsU2VWoT+B7eDR8JCZB9d3JLg8/CPGCCI= +github.com/ava-labs/coreth v0.12.9-rc.5.0.20231123093038-4cb2ebecb2ee/go.mod h1:lAjiEbIj6wQSELIday+toGa2bMkA0birr3h6O2C4mY8= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= @@ -96,13 +102,18 @@ github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46f github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw= github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA= @@ -134,12 +145,16 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= +github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= @@ -150,6 +165,14 @@ github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6ps github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= +github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 h1:+3HCtB74++ClLy8GgjUQYeC8R4ILzVcIe8+5edAJJnE= +github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= +github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= +github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -166,6 +189,8 @@ github.com/ethereum/go-ethereum v1.12.0 h1:bdnhLPtqETd4m3mS8BGMNvBTf36bO5bx/hxE2 github.com/ethereum/go-ethereum v1.12.0/go.mod h1:/oo2X/dZLJjf2mJ6YT9wcWxa4nNJDBKDBU6sFIpx1Gs= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -174,6 +199,8 @@ github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmV github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= @@ -197,7 +224,11 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= +github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= @@ -282,10 +313,14 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= @@ -306,11 +341,17 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 h1:kr3j8iIMR4ywO/O0rvksXaJvauGGCMg2zAZIiNZ9uIQ= github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0/go.mod h1:ummNFgdgLhhX7aIiy35vVmQNS0rWXknfPE0qe6fmFXg= +github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e h1:pIYdhNkDh+YENVNi3gto8n9hAmRxKxoar0iE6BLucjw= +github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e/go.mod h1:j9cQbcqHQujT0oKJ38PylVfqohClLr3CvDC+Qcg+lhU= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c h1:DZfsyhDK1hnSS5lH8l+JggqzEleHteTYfutAiVlSUM8= @@ -322,6 +363,7 @@ github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3 github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -363,6 +405,7 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -370,6 +413,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= @@ -380,11 +424,17 @@ github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPK github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= @@ -393,8 +443,11 @@ github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -413,6 +466,8 @@ github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -480,6 +535,8 @@ github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sanity-io/litter v1.5.1 h1:dwnrSypP6q56o3lFxTU+t2fwQ9A+U5qrXVO4Qg9KwVU= github.com/sanity-io/litter v1.5.1/go.mod h1:5Z71SvaYy5kcGtyglXOC9rrUi3c1E8CamFWjQsazTh0= @@ -515,6 +572,8 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= +github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= +github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -546,10 +605,14 @@ github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZF github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE= github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa h1:5SqCsI/2Qya2bCzK15ozrqo2sZxkh0FHynJZOTVoV6Q= +github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= @@ -561,6 +624,8 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= @@ -570,6 +635,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= @@ -665,6 +731,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -710,6 +777,7 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -733,6 +801,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -797,8 +866,12 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -815,6 +888,7 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -878,6 +952,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1002,6 +1077,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= diff --git a/node/node.go b/node/node.go index 98d697a66359..06544e8f9e6b 100644 --- a/node/node.go +++ b/node/node.go @@ -25,7 +25,7 @@ import ( "go.uber.org/zap" - // coreth "github.com/ava-labs/coreth/plugin/evm" + coreth "github.com/ava-labs/coreth/plugin/evm" "github.com/ava-labs/avalanchego/api/admin" "github.com/ava-labs/avalanchego/api/auth" @@ -1094,7 +1094,7 @@ func (n *Node) initVMs() error { CreateAssetTxFee: n.Config.CreateAssetTxFee, }, }), - // vmRegisterer.Register(context.TODO(), constants.EVMID, &coreth.Factory{}), + vmRegisterer.Register(context.TODO(), constants.EVMID, &coreth.Factory{}), n.VMManager.RegisterFactory(context.TODO(), secp256k1fx.ID, &secp256k1fx.Factory{}), n.VMManager.RegisterFactory(context.TODO(), nftfx.ID, &nftfx.Factory{}), n.VMManager.RegisterFactory(context.TODO(), propertyfx.ID, &propertyfx.Factory{}), diff --git a/tests/e2e/c/dynamic_fees.go b/tests/e2e/c/dynamic_fees.go index 8748dda7451d..8f15b6d43caf 100644 --- a/tests/e2e/c/dynamic_fees.go +++ b/tests/e2e/c/dynamic_fees.go @@ -3,166 +3,166 @@ package c -// import ( -// "math/big" -// "strings" - -// ginkgo "github.com/onsi/ginkgo/v2" - -// "github.com/stretchr/testify/require" - -// "github.com/ethereum/go-ethereum/accounts/abi" -// "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/coreth/core/types" -// "github.com/ava-labs/coreth/params" -// "github.com/ava-labs/coreth/plugin/evm" - -// "github.com/ava-labs/avalanchego/tests" -// "github.com/ava-labs/avalanchego/tests/e2e" -// "github.com/ava-labs/avalanchego/tests/fixture/testnet" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// ) - -// // This test uses the compiled bin for `hashing.sol` as -// // well as its ABI contained in `hashing_contract.go`. - -// var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { -// require := require.New(ginkgo.GinkgoT()) - -// // Need a gas limit much larger than the standard 21_000 to enable -// // the contract to induce a gas price increase -// const largeGasLimit = uint64(8_000_000) - -// // TODO(marun) What is the significance of this value? -// gasTip := big.NewInt(1000 * params.GWei) - -// ginkgo.It("should ensure that the gas price is affected by load", func() { -// ginkgo.By("creating a new private network to ensure isolation from other tests") -// privateNetwork := e2e.Env.NewPrivateNetwork() - -// ginkgo.By("allocating a pre-funded key") -// key := privateNetwork.GetConfig().FundedKeys[0] -// ethAddress := evm.GetEthAddress(key) - -// ginkgo.By("initializing a coreth client") -// node := privateNetwork.GetNodes()[0] -// nodeURI := testnet.NodeURI{ -// NodeID: node.GetID(), -// URI: node.GetProcessContext().URI, -// } -// ethClient := e2e.NewEthClient(nodeURI) - -// ginkgo.By("initializing a transaction signer") -// cChainID, err := ethClient.ChainID(e2e.DefaultContext()) -// require.NoError(err) -// signer := types.NewEIP155Signer(cChainID) -// ecdsaKey := key.ToECDSA() -// sign := func(tx *types.Transaction) *types.Transaction { -// signedTx, err := types.SignTx(tx, signer, ecdsaKey) -// require.NoError(err) -// return signedTx -// } - -// var contractAddress common.Address -// ginkgo.By("deploying an expensive contract", func() { -// // Create transaction -// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) -// require.NoError(err) -// compiledContract := common.Hex2Bytes(hashingCompiledContract) -// tx := types.NewTx(&types.LegacyTx{ -// Nonce: nonce, -// GasPrice: gasTip, -// Gas: largeGasLimit, -// Value: common.Big0, -// Data: compiledContract, -// }) - -// // Send the transaction and wait for acceptance -// signedTx := sign(tx) -// receipt := e2e.SendEthTransaction(ethClient, signedTx) - -// contractAddress = receipt.ContractAddress -// }) - -// var gasPrice *big.Int -// ginkgo.By("calling the expensive contract repeatedly until a gas price increase is detected", func() { -// // Evaluate the bytes representation of the contract -// hashingABI, err := abi.JSON(strings.NewReader(hashingABIJson)) -// require.NoError(err) -// contractData, err := hashingABI.Pack("hashIt") -// require.NoError(err) - -// var initialGasPrice *big.Int -// e2e.Eventually(func() bool { -// // Check the gas price -// var err error -// gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) -// require.NoError(err) -// if initialGasPrice == nil { -// initialGasPrice = gasPrice -// tests.Outf("{{blue}}initial gas price is %v{{/}}\n", initialGasPrice) -// } else if gasPrice.Cmp(initialGasPrice) > 0 { -// // Gas price has increased -// tests.Outf("{{blue}}gas price has increased to %v{{/}}\n", gasPrice) -// return true -// } - -// // Create the transaction -// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) -// require.NoError(err) -// tx := types.NewTx(&types.LegacyTx{ -// Nonce: nonce, -// GasPrice: gasTip, -// Gas: largeGasLimit, -// To: &contractAddress, -// Value: common.Big0, -// Data: contractData, -// }) - -// // Send the transaction and wait for acceptance -// signedTx := sign(tx) -// _ = e2e.SendEthTransaction(ethClient, signedTx) - -// // The gas price will be checked at the start of the next iteration -// return false -// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price increase before timeout") -// }) - -// ginkgo.By("waiting for the gas price to decrease...", func() { -// initialGasPrice := gasPrice -// e2e.Eventually(func() bool { -// var err error -// gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) -// require.NoError(err) -// tests.Outf("{{blue}}.{{/}}") -// return initialGasPrice.Cmp(gasPrice) > 0 -// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price decrease before timeout") -// tests.Outf("\n{{blue}}gas price has decreased to %v{{/}}\n", gasPrice) -// }) - -// ginkgo.By("sending funds at the current gas price", func() { -// // Create a recipient address -// recipientKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) -// recipientEthAddress := evm.GetEthAddress(recipientKey) - -// // Create transaction -// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) -// require.NoError(err) -// tx := types.NewTx(&types.LegacyTx{ -// Nonce: nonce, -// GasPrice: gasPrice, -// Gas: e2e.DefaultGasLimit, -// To: &recipientEthAddress, -// Value: common.Big0, -// }) - -// // Send the transaction and wait for acceptance -// signedTx := sign(tx) -// _ = e2e.SendEthTransaction(ethClient, signedTx) -// }) - -// e2e.CheckBootstrapIsPossible(privateNetwork) -// }) -// }) +import ( + "math/big" + "strings" + + ginkgo "github.com/onsi/ginkgo/v2" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm" + + "github.com/ava-labs/avalanchego/tests" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/testnet" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +) + +// This test uses the compiled bin for `hashing.sol` as +// well as its ABI contained in `hashing_contract.go`. + +var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { + require := require.New(ginkgo.GinkgoT()) + + // Need a gas limit much larger than the standard 21_000 to enable + // the contract to induce a gas price increase + const largeGasLimit = uint64(8_000_000) + + // TODO(marun) What is the significance of this value? + gasTip := big.NewInt(1000 * params.GWei) + + ginkgo.It("should ensure that the gas price is affected by load", func() { + ginkgo.By("creating a new private network to ensure isolation from other tests") + privateNetwork := e2e.Env.NewPrivateNetwork() + + ginkgo.By("allocating a pre-funded key") + key := privateNetwork.GetConfig().FundedKeys[0] + ethAddress := evm.GetEthAddress(key) + + ginkgo.By("initializing a coreth client") + node := privateNetwork.GetNodes()[0] + nodeURI := testnet.NodeURI{ + NodeID: node.GetID(), + URI: node.GetProcessContext().URI, + } + ethClient := e2e.NewEthClient(nodeURI) + + ginkgo.By("initializing a transaction signer") + cChainID, err := ethClient.ChainID(e2e.DefaultContext()) + require.NoError(err) + signer := types.NewEIP155Signer(cChainID) + ecdsaKey := key.ToECDSA() + sign := func(tx *types.Transaction) *types.Transaction { + signedTx, err := types.SignTx(tx, signer, ecdsaKey) + require.NoError(err) + return signedTx + } + + var contractAddress common.Address + ginkgo.By("deploying an expensive contract", func() { + // Create transaction + nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) + require.NoError(err) + compiledContract := common.Hex2Bytes(hashingCompiledContract) + tx := types.NewTx(&types.LegacyTx{ + Nonce: nonce, + GasPrice: gasTip, + Gas: largeGasLimit, + Value: common.Big0, + Data: compiledContract, + }) + + // Send the transaction and wait for acceptance + signedTx := sign(tx) + receipt := e2e.SendEthTransaction(ethClient, signedTx) + + contractAddress = receipt.ContractAddress + }) + + var gasPrice *big.Int + ginkgo.By("calling the expensive contract repeatedly until a gas price increase is detected", func() { + // Evaluate the bytes representation of the contract + hashingABI, err := abi.JSON(strings.NewReader(hashingABIJson)) + require.NoError(err) + contractData, err := hashingABI.Pack("hashIt") + require.NoError(err) + + var initialGasPrice *big.Int + e2e.Eventually(func() bool { + // Check the gas price + var err error + gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) + require.NoError(err) + if initialGasPrice == nil { + initialGasPrice = gasPrice + tests.Outf("{{blue}}initial gas price is %v{{/}}\n", initialGasPrice) + } else if gasPrice.Cmp(initialGasPrice) > 0 { + // Gas price has increased + tests.Outf("{{blue}}gas price has increased to %v{{/}}\n", gasPrice) + return true + } + + // Create the transaction + nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) + require.NoError(err) + tx := types.NewTx(&types.LegacyTx{ + Nonce: nonce, + GasPrice: gasTip, + Gas: largeGasLimit, + To: &contractAddress, + Value: common.Big0, + Data: contractData, + }) + + // Send the transaction and wait for acceptance + signedTx := sign(tx) + _ = e2e.SendEthTransaction(ethClient, signedTx) + + // The gas price will be checked at the start of the next iteration + return false + }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price increase before timeout") + }) + + ginkgo.By("waiting for the gas price to decrease...", func() { + initialGasPrice := gasPrice + e2e.Eventually(func() bool { + var err error + gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) + require.NoError(err) + tests.Outf("{{blue}}.{{/}}") + return initialGasPrice.Cmp(gasPrice) > 0 + }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price decrease before timeout") + tests.Outf("\n{{blue}}gas price has decreased to %v{{/}}\n", gasPrice) + }) + + ginkgo.By("sending funds at the current gas price", func() { + // Create a recipient address + recipientKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + recipientEthAddress := evm.GetEthAddress(recipientKey) + + // Create transaction + nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) + require.NoError(err) + tx := types.NewTx(&types.LegacyTx{ + Nonce: nonce, + GasPrice: gasPrice, + Gas: e2e.DefaultGasLimit, + To: &recipientEthAddress, + Value: common.Big0, + }) + + // Send the transaction and wait for acceptance + signedTx := sign(tx) + _ = e2e.SendEthTransaction(ethClient, signedTx) + }) + + e2e.CheckBootstrapIsPossible(privateNetwork) + }) +}) diff --git a/tests/e2e/c/interchain_workflow.go b/tests/e2e/c/interchain_workflow.go index c5af17c750bf..2c9bd198ec39 100644 --- a/tests/e2e/c/interchain_workflow.go +++ b/tests/e2e/c/interchain_workflow.go @@ -3,163 +3,163 @@ package c -// import ( -// "math/big" - -// ginkgo "github.com/onsi/ginkgo/v2" - -// "github.com/stretchr/testify/require" - -// "github.com/ava-labs/coreth/core/types" -// "github.com/ava-labs/coreth/plugin/evm" - -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/tests/e2e" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var _ = e2e.DescribeCChain("[Interchain Workflow]", func() { -// require := require.New(ginkgo.GinkgoT()) - -// const txAmount = 10 * units.Avax // Arbitrary amount to send and transfer - -// ginkgo.It("should ensure that funds can be transferred from the C-Chain to the X-Chain and the P-Chain", func() { -// ginkgo.By("initializing a new eth client") -// // Select a random node URI to use for both the eth client and -// // the wallet to avoid having to verify that all nodes are at -// // the same height before initializing the wallet. -// nodeURI := e2e.Env.GetRandomNodeURI() -// ethClient := e2e.NewEthClient(nodeURI) - -// ginkgo.By("allocating a pre-funded key to send from and a recipient key to deliver to") -// senderKey := e2e.Env.AllocateFundedKey() -// senderEthAddress := evm.GetEthAddress(senderKey) -// recipientKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) -// recipientEthAddress := evm.GetEthAddress(recipientKey) - -// ginkgo.By("sending funds from one address to another on the C-Chain", func() { -// // Create transaction -// acceptedNonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), senderEthAddress) -// require.NoError(err) -// gasPrice := e2e.SuggestGasPrice(ethClient) -// tx := types.NewTransaction( -// acceptedNonce, -// recipientEthAddress, -// big.NewInt(int64(txAmount)), -// e2e.DefaultGasLimit, -// gasPrice, -// nil, -// ) - -// // Sign transaction -// cChainID, err := ethClient.ChainID(e2e.DefaultContext()) -// require.NoError(err) -// signer := types.NewEIP155Signer(cChainID) -// signedTx, err := types.SignTx(tx, signer, senderKey.ToECDSA()) -// require.NoError(err) - -// _ = e2e.SendEthTransaction(ethClient, signedTx) - -// ginkgo.By("waiting for the C-Chain recipient address to have received the sent funds") -// e2e.Eventually(func() bool { -// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) -// require.NoError(err) -// return balance.Cmp(big.NewInt(0)) > 0 -// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see funds delivered before timeout") -// }) - -// // Wallet must be initialized after sending funds on the -// // C-Chain with the same node URI to ensure wallet state -// // matches on-chain state. -// ginkgo.By("initializing a keychain and associated wallet") -// keychain := secp256k1fx.NewKeychain(senderKey, recipientKey) -// baseWallet := e2e.NewWallet(keychain, nodeURI) -// xWallet := baseWallet.X() -// cWallet := baseWallet.C() -// pWallet := baseWallet.P() - -// ginkgo.By("defining common configuration") -// avaxAssetID := xWallet.AVAXAssetID() -// // Use the same owner for import funds to X-Chain and P-Chain -// recipientOwner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// recipientKey.Address(), -// }, -// } -// // Use the same outputs for both X-Chain and P-Chain exports -// exportOutputs := []*secp256k1fx.TransferOutput{ -// { -// Amt: txAmount, -// OutputOwners: secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// keychain.Keys[0].Address(), -// }, -// }, -// }, -// } - -// ginkgo.By("exporting AVAX from the C-Chain to the X-Chain", func() { -// _, err := cWallet.IssueExportTx( -// xWallet.BlockchainID(), -// exportOutputs, -// e2e.WithDefaultContext(), -// e2e.WithSuggestedGasPrice(ethClient), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("importing AVAX from the C-Chain to the X-Chain", func() { -// _, err := xWallet.IssueImportTx( -// cWallet.BlockchainID(), -// &recipientOwner, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { -// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// ginkgo.By("exporting AVAX from the C-Chain to the P-Chain", func() { -// _, err := cWallet.IssueExportTx( -// constants.PlatformChainID, -// exportOutputs, -// e2e.WithDefaultContext(), -// e2e.WithSuggestedGasPrice(ethClient), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("importing AVAX from the C-Chain to the P-Chain", func() { -// _, err = pWallet.IssueImportTx( -// cWallet.BlockchainID(), -// &recipientOwner, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { -// balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) -// }) -// }) +import ( + "math/big" + + ginkgo "github.com/onsi/ginkgo/v2" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/coreth/plugin/evm" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var _ = e2e.DescribeCChain("[Interchain Workflow]", func() { + require := require.New(ginkgo.GinkgoT()) + + const txAmount = 10 * units.Avax // Arbitrary amount to send and transfer + + ginkgo.It("should ensure that funds can be transferred from the C-Chain to the X-Chain and the P-Chain", func() { + ginkgo.By("initializing a new eth client") + // Select a random node URI to use for both the eth client and + // the wallet to avoid having to verify that all nodes are at + // the same height before initializing the wallet. + nodeURI := e2e.Env.GetRandomNodeURI() + ethClient := e2e.NewEthClient(nodeURI) + + ginkgo.By("allocating a pre-funded key to send from and a recipient key to deliver to") + senderKey := e2e.Env.AllocateFundedKey() + senderEthAddress := evm.GetEthAddress(senderKey) + recipientKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + recipientEthAddress := evm.GetEthAddress(recipientKey) + + ginkgo.By("sending funds from one address to another on the C-Chain", func() { + // Create transaction + acceptedNonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), senderEthAddress) + require.NoError(err) + gasPrice := e2e.SuggestGasPrice(ethClient) + tx := types.NewTransaction( + acceptedNonce, + recipientEthAddress, + big.NewInt(int64(txAmount)), + e2e.DefaultGasLimit, + gasPrice, + nil, + ) + + // Sign transaction + cChainID, err := ethClient.ChainID(e2e.DefaultContext()) + require.NoError(err) + signer := types.NewEIP155Signer(cChainID) + signedTx, err := types.SignTx(tx, signer, senderKey.ToECDSA()) + require.NoError(err) + + _ = e2e.SendEthTransaction(ethClient, signedTx) + + ginkgo.By("waiting for the C-Chain recipient address to have received the sent funds") + e2e.Eventually(func() bool { + balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) + require.NoError(err) + return balance.Cmp(big.NewInt(0)) > 0 + }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see funds delivered before timeout") + }) + + // Wallet must be initialized after sending funds on the + // C-Chain with the same node URI to ensure wallet state + // matches on-chain state. + ginkgo.By("initializing a keychain and associated wallet") + keychain := secp256k1fx.NewKeychain(senderKey, recipientKey) + baseWallet := e2e.NewWallet(keychain, nodeURI) + xWallet := baseWallet.X() + cWallet := baseWallet.C() + pWallet := baseWallet.P() + + ginkgo.By("defining common configuration") + avaxAssetID := xWallet.AVAXAssetID() + // Use the same owner for import funds to X-Chain and P-Chain + recipientOwner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + recipientKey.Address(), + }, + } + // Use the same outputs for both X-Chain and P-Chain exports + exportOutputs := []*secp256k1fx.TransferOutput{ + { + Amt: txAmount, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + keychain.Keys[0].Address(), + }, + }, + }, + } + + ginkgo.By("exporting AVAX from the C-Chain to the X-Chain", func() { + _, err := cWallet.IssueExportTx( + xWallet.BlockchainID(), + exportOutputs, + e2e.WithDefaultContext(), + e2e.WithSuggestedGasPrice(ethClient), + ) + require.NoError(err) + }) + + ginkgo.By("importing AVAX from the C-Chain to the X-Chain", func() { + _, err := xWallet.IssueImportTx( + cWallet.BlockchainID(), + &recipientOwner, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { + balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + ginkgo.By("exporting AVAX from the C-Chain to the P-Chain", func() { + _, err := cWallet.IssueExportTx( + constants.PlatformChainID, + exportOutputs, + e2e.WithDefaultContext(), + e2e.WithSuggestedGasPrice(ethClient), + ) + require.NoError(err) + }) + + ginkgo.By("importing AVAX from the C-Chain to the P-Chain", func() { + _, err = pWallet.IssueImportTx( + cWallet.BlockchainID(), + &recipientOwner, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { + balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) + }) +}) diff --git a/tests/e2e/p/interchain_workflow.go b/tests/e2e/p/interchain_workflow.go index e90e0382e286..44a6912715ef 100644 --- a/tests/e2e/p/interchain_workflow.go +++ b/tests/e2e/p/interchain_workflow.go @@ -3,225 +3,225 @@ package p -// import ( -// "math/big" -// "time" - -// ginkgo "github.com/onsi/ginkgo/v2" - -// "github.com/spf13/cast" - -// "github.com/stretchr/testify/require" - -// "github.com/ava-labs/coreth/plugin/evm" - -// "github.com/ava-labs/avalanchego/api/info" -// "github.com/ava-labs/avalanchego/config" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/tests/e2e" -// "github.com/ava-labs/avalanchego/tests/fixture/testnet" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/platformvm/reward" -// "github.com/ava-labs/avalanchego/vms/platformvm/txs" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { -// require := require.New(ginkgo.GinkgoT()) - -// const ( -// transferAmount = 10 * units.Avax -// weight = 2_000 * units.Avax // Used for both validation and delegation -// ) - -// ginkgo.It("should ensure that funds can be transferred from the P-Chain to the X-Chain and the C-Chain", func() { -// network := e2e.Env.GetNetwork() - -// ginkgo.By("checking that the network has a compatible minimum stake duration", func() { -// minStakeDuration := cast.ToDuration(network.GetConfig().DefaultFlags[config.MinStakeDurationKey]) -// require.Equal(testnet.DefaultMinStakeDuration, minStakeDuration) -// }) - -// ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") -// recipientKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) -// keychain := e2e.Env.NewKeychain(1) -// keychain.Add(recipientKey) -// nodeURI := e2e.Env.GetRandomNodeURI() -// baseWallet := e2e.Env.NewWallet(keychain, nodeURI) -// xWallet := baseWallet.X() -// cWallet := baseWallet.C() -// pWallet := baseWallet.P() - -// ginkgo.By("defining common configuration") -// recipientEthAddress := evm.GetEthAddress(recipientKey) -// avaxAssetID := xWallet.AVAXAssetID() -// // Use the same owner for sending to X-Chain and importing funds to P-Chain -// recipientOwner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// recipientKey.Address(), -// }, -// } -// // Use the same outputs for both X-Chain and C-Chain exports -// exportOutputs := []*avax.TransferableOutput{ -// { -// Asset: avax.Asset{ -// ID: avaxAssetID, -// }, -// Out: &secp256k1fx.TransferOutput{ -// Amt: transferAmount, -// OutputOwners: secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// keychain.Keys[0].Address(), -// }, -// }, -// }, -// }, -// } - -// ginkgo.By("adding new node and waiting for it to report healthy") -// node := e2e.AddEphemeralNode(network, testnet.FlagsMap{}) -// e2e.WaitForHealthy(node) - -// ginkgo.By("retrieving new node's id and pop") -// infoClient := info.NewClient(node.GetProcessContext().URI) -// nodeID, nodePOP, err := infoClient.GetNodeID(e2e.DefaultContext()) -// require.NoError(err) - -// ginkgo.By("adding the new node as a validator", func() { -// startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) -// // Validation duration doesn't actually matter to this -// // test - it is only ensuring that adding a validator -// // doesn't break interchain transfer. -// endTime := startTime.Add(30 * time.Second) - -// rewardKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) - -// const ( -// delegationPercent = 0.10 // 10% -// delegationShare = reward.PercentDenominator * delegationPercent -// ) - -// _, err = pWallet.IssueAddPermissionlessValidatorTx( -// &txs.SubnetValidator{ -// Validator: txs.Validator{ -// NodeID: nodeID, -// Start: uint64(startTime.Unix()), -// End: uint64(endTime.Unix()), -// Wght: weight, -// }, -// Subnet: constants.PrimaryNetworkID, -// }, -// nodePOP, -// pWallet.AVAXAssetID(), -// &secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{rewardKey.Address()}, -// }, -// &secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{rewardKey.Address()}, -// }, -// delegationShare, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("adding a delegator to the new node", func() { -// startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) -// // Delegation duration doesn't actually matter to this -// // test - it is only ensuring that adding a delegator -// // doesn't break interchain transfer. -// endTime := startTime.Add(15 * time.Second) - -// rewardKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) - -// _, err = pWallet.IssueAddPermissionlessDelegatorTx( -// &txs.SubnetValidator{ -// Validator: txs.Validator{ -// NodeID: nodeID, -// Start: uint64(startTime.Unix()), -// End: uint64(endTime.Unix()), -// Wght: weight, -// }, -// Subnet: constants.PrimaryNetworkID, -// }, -// pWallet.AVAXAssetID(), -// &secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{rewardKey.Address()}, -// }, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("exporting AVAX from the P-Chain to the X-Chain", func() { -// _, err := pWallet.IssueExportTx( -// xWallet.BlockchainID(), -// exportOutputs, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("importing AVAX from the P-Chain to the X-Chain", func() { -// _, err := xWallet.IssueImportTx( -// constants.PlatformChainID, -// &recipientOwner, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { -// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// ginkgo.By("exporting AVAX from the P-Chain to the C-Chain", func() { -// _, err := pWallet.IssueExportTx( -// cWallet.BlockchainID(), -// exportOutputs, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("initializing a new eth client") -// ethClient := e2e.NewEthClient(nodeURI) - -// ginkgo.By("importing AVAX from the P-Chain to the C-Chain", func() { -// _, err := cWallet.IssueImportTx( -// constants.PlatformChainID, -// recipientEthAddress, -// e2e.WithDefaultContext(), -// e2e.WithSuggestedGasPrice(ethClient), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") -// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) -// require.NoError(err) -// require.Positive(balance.Cmp(big.NewInt(0))) - -// ginkgo.By("stopping validator node to free up resources for a bootstrap check") -// require.NoError(node.Stop()) - -// e2e.CheckBootstrapIsPossible(network) -// }) -// }) +import ( + "math/big" + "time" + + ginkgo "github.com/onsi/ginkgo/v2" + + "github.com/spf13/cast" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/coreth/plugin/evm" + + "github.com/ava-labs/avalanchego/api/info" + "github.com/ava-labs/avalanchego/config" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/testnet" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/platformvm/reward" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { + require := require.New(ginkgo.GinkgoT()) + + const ( + transferAmount = 10 * units.Avax + weight = 2_000 * units.Avax // Used for both validation and delegation + ) + + ginkgo.It("should ensure that funds can be transferred from the P-Chain to the X-Chain and the C-Chain", func() { + network := e2e.Env.GetNetwork() + + ginkgo.By("checking that the network has a compatible minimum stake duration", func() { + minStakeDuration := cast.ToDuration(network.GetConfig().DefaultFlags[config.MinStakeDurationKey]) + require.Equal(testnet.DefaultMinStakeDuration, minStakeDuration) + }) + + ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") + recipientKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + keychain := e2e.Env.NewKeychain(1) + keychain.Add(recipientKey) + nodeURI := e2e.Env.GetRandomNodeURI() + baseWallet := e2e.NewWallet(keychain, nodeURI) + xWallet := baseWallet.X() + cWallet := baseWallet.C() + pWallet := baseWallet.P() + + ginkgo.By("defining common configuration") + recipientEthAddress := evm.GetEthAddress(recipientKey) + avaxAssetID := xWallet.AVAXAssetID() + // Use the same owner for sending to X-Chain and importing funds to P-Chain + recipientOwner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + recipientKey.Address(), + }, + } + // Use the same outputs for both X-Chain and C-Chain exports + exportOutputs := []*avax.TransferableOutput{ + { + Asset: avax.Asset{ + ID: avaxAssetID, + }, + Out: &secp256k1fx.TransferOutput{ + Amt: transferAmount, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + keychain.Keys[0].Address(), + }, + }, + }, + }, + } + + ginkgo.By("adding new node and waiting for it to report healthy") + node := e2e.AddEphemeralNode(network, testnet.FlagsMap{}) + e2e.WaitForHealthy(node) + + ginkgo.By("retrieving new node's id and pop") + infoClient := info.NewClient(node.GetProcessContext().URI) + nodeID, nodePOP, err := infoClient.GetNodeID(e2e.DefaultContext()) + require.NoError(err) + + ginkgo.By("adding the new node as a validator", func() { + startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) + // Validation duration doesn't actually matter to this + // test - it is only ensuring that adding a validator + // doesn't break interchain transfer. + endTime := startTime.Add(30 * time.Second) + + rewardKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + + const ( + delegationPercent = 0.10 // 10% + delegationShare = reward.PercentDenominator * delegationPercent + ) + + _, err = pWallet.IssueAddPermissionlessValidatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(endTime.Unix()), + Wght: weight, + }, + Subnet: constants.PrimaryNetworkID, + }, + nodePOP, + pWallet.AVAXAssetID(), + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardKey.Address()}, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardKey.Address()}, + }, + delegationShare, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("adding a delegator to the new node", func() { + startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) + // Delegation duration doesn't actually matter to this + // test - it is only ensuring that adding a delegator + // doesn't break interchain transfer. + endTime := startTime.Add(15 * time.Second) + + rewardKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + + _, err = pWallet.IssueAddPermissionlessDelegatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(endTime.Unix()), + Wght: weight, + }, + Subnet: constants.PrimaryNetworkID, + }, + pWallet.AVAXAssetID(), + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardKey.Address()}, + }, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("exporting AVAX from the P-Chain to the X-Chain", func() { + _, err := pWallet.IssueExportTx( + xWallet.BlockchainID(), + exportOutputs, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("importing AVAX from the P-Chain to the X-Chain", func() { + _, err := xWallet.IssueImportTx( + constants.PlatformChainID, + &recipientOwner, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { + balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + ginkgo.By("exporting AVAX from the P-Chain to the C-Chain", func() { + _, err := pWallet.IssueExportTx( + cWallet.BlockchainID(), + exportOutputs, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("initializing a new eth client") + ethClient := e2e.NewEthClient(nodeURI) + + ginkgo.By("importing AVAX from the P-Chain to the C-Chain", func() { + _, err := cWallet.IssueImportTx( + constants.PlatformChainID, + recipientEthAddress, + e2e.WithDefaultContext(), + e2e.WithSuggestedGasPrice(ethClient), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") + balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) + require.NoError(err) + require.Positive(balance.Cmp(big.NewInt(0))) + + ginkgo.By("stopping validator node to free up resources for a bootstrap check") + require.NoError(node.Stop()) + + e2e.CheckBootstrapIsPossible(network) + }) +}) diff --git a/tests/e2e/x/interchain_workflow.go b/tests/e2e/x/interchain_workflow.go index d738e55a7f7a..f0c2951feb84 100644 --- a/tests/e2e/x/interchain_workflow.go +++ b/tests/e2e/x/interchain_workflow.go @@ -3,151 +3,151 @@ package x -// import ( -// "math/big" - -// ginkgo "github.com/onsi/ginkgo/v2" - -// "github.com/stretchr/testify/require" - -// "github.com/ava-labs/coreth/plugin/evm" - -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/tests/e2e" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var _ = e2e.DescribeXChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { -// require := require.New(ginkgo.GinkgoT()) - -// const transferAmount = 10 * units.Avax - -// ginkgo.It("should ensure that funds can be transferred from the X-Chain to the C-Chain and the P-Chain", func() { -// nodeURI := e2e.Env.GetRandomNodeURI() - -// ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") -// recipientKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) -// keychain := e2e.Env.NewKeychain(1) -// keychain.Add(recipientKey) -// baseWallet := e2e.Env.NewWallet(keychain, nodeURI) -// xWallet := baseWallet.X() -// cWallet := baseWallet.C() -// pWallet := baseWallet.P() - -// ginkgo.By("defining common configuration") -// recipientEthAddress := evm.GetEthAddress(recipientKey) -// avaxAssetID := xWallet.AVAXAssetID() -// // Use the same owner for sending to X-Chain and importing funds to P-Chain -// recipientOwner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// recipientKey.Address(), -// }, -// } -// // Use the same outputs for both C-Chain and P-Chain exports -// exportOutputs := []*avax.TransferableOutput{ -// { -// Asset: avax.Asset{ -// ID: avaxAssetID, -// }, -// Out: &secp256k1fx.TransferOutput{ -// Amt: transferAmount, -// OutputOwners: secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// keychain.Keys[0].Address(), -// }, -// }, -// }, -// }, -// } - -// ginkgo.By("sending funds from one address to another on the X-Chain", func() { -// _, err = xWallet.IssueBaseTx( -// []*avax.TransferableOutput{{ -// Asset: avax.Asset{ -// ID: avaxAssetID, -// }, -// Out: &secp256k1fx.TransferOutput{ -// Amt: transferAmount, -// OutputOwners: recipientOwner, -// }, -// }}, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the X-Chain recipient address has received the sent funds", func() { -// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// ginkgo.By("exporting AVAX from the X-Chain to the C-Chain", func() { -// _, err := xWallet.IssueExportTx( -// cWallet.BlockchainID(), -// exportOutputs, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("initializing a new eth client") -// ethClient := e2e.NewEthClient(nodeURI) - -// ginkgo.By("importing AVAX from the X-Chain to the C-Chain", func() { -// _, err := cWallet.IssueImportTx( -// xWallet.BlockchainID(), -// recipientEthAddress, -// e2e.WithDefaultContext(), -// e2e.WithSuggestedGasPrice(ethClient), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") -// e2e.Eventually(func() bool { -// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) -// require.NoError(err) -// return balance.Cmp(big.NewInt(0)) > 0 -// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see recipient address funded before timeout") - -// ginkgo.By("exporting AVAX from the X-Chain to the P-Chain", func() { -// _, err := xWallet.IssueExportTx( -// constants.PlatformChainID, -// exportOutputs, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("importing AVAX from the X-Chain to the P-Chain", func() { -// _, err := pWallet.IssueImportTx( -// xWallet.BlockchainID(), -// &recipientOwner, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { -// balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) -// }) -// }) +import ( + "math/big" + + ginkgo "github.com/onsi/ginkgo/v2" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/coreth/plugin/evm" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var _ = e2e.DescribeXChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { + require := require.New(ginkgo.GinkgoT()) + + const transferAmount = 10 * units.Avax + + ginkgo.It("should ensure that funds can be transferred from the X-Chain to the C-Chain and the P-Chain", func() { + nodeURI := e2e.Env.GetRandomNodeURI() + + ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") + recipientKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + keychain := e2e.Env.NewKeychain(1) + keychain.Add(recipientKey) + baseWallet := e2e.NewWallet(keychain, nodeURI) + xWallet := baseWallet.X() + cWallet := baseWallet.C() + pWallet := baseWallet.P() + + ginkgo.By("defining common configuration") + recipientEthAddress := evm.GetEthAddress(recipientKey) + avaxAssetID := xWallet.AVAXAssetID() + // Use the same owner for sending to X-Chain and importing funds to P-Chain + recipientOwner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + recipientKey.Address(), + }, + } + // Use the same outputs for both C-Chain and P-Chain exports + exportOutputs := []*avax.TransferableOutput{ + { + Asset: avax.Asset{ + ID: avaxAssetID, + }, + Out: &secp256k1fx.TransferOutput{ + Amt: transferAmount, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + keychain.Keys[0].Address(), + }, + }, + }, + }, + } + + ginkgo.By("sending funds from one address to another on the X-Chain", func() { + _, err = xWallet.IssueBaseTx( + []*avax.TransferableOutput{{ + Asset: avax.Asset{ + ID: avaxAssetID, + }, + Out: &secp256k1fx.TransferOutput{ + Amt: transferAmount, + OutputOwners: recipientOwner, + }, + }}, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the X-Chain recipient address has received the sent funds", func() { + balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + ginkgo.By("exporting AVAX from the X-Chain to the C-Chain", func() { + _, err := xWallet.IssueExportTx( + cWallet.BlockchainID(), + exportOutputs, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("initializing a new eth client") + ethClient := e2e.NewEthClient(nodeURI) + + ginkgo.By("importing AVAX from the X-Chain to the C-Chain", func() { + _, err := cWallet.IssueImportTx( + xWallet.BlockchainID(), + recipientEthAddress, + e2e.WithDefaultContext(), + e2e.WithSuggestedGasPrice(ethClient), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") + e2e.Eventually(func() bool { + balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) + require.NoError(err) + return balance.Cmp(big.NewInt(0)) > 0 + }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see recipient address funded before timeout") + + ginkgo.By("exporting AVAX from the X-Chain to the P-Chain", func() { + _, err := xWallet.IssueExportTx( + constants.PlatformChainID, + exportOutputs, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("importing AVAX from the X-Chain to the P-Chain", func() { + _, err := pWallet.IssueImportTx( + xWallet.BlockchainID(), + &recipientOwner, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { + balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) + }) +}) diff --git a/tests/fixture/e2e/helpers.go b/tests/fixture/e2e/helpers.go index 8e497cf398c0..15da611324e0 100644 --- a/tests/fixture/e2e/helpers.go +++ b/tests/fixture/e2e/helpers.go @@ -5,23 +5,20 @@ package e2e import ( "context" - - // "errors" - // "fmt" - // "math/big" - + "errors" + "fmt" + "math/big" "os" - - // "strings" + "strings" "time" ginkgo "github.com/onsi/ginkgo/v2" "github.com/stretchr/testify/require" - // "github.com/ava-labs/coreth/core/types" - // "github.com/ava-labs/coreth/ethclient" - // "github.com/ava-labs/coreth/interfaces" + "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/coreth/ethclient" + "github.com/ava-labs/coreth/interfaces" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/tests" @@ -70,7 +67,7 @@ func NewWallet(keychain *secp256k1fx.Keychain, nodeURI testnet.NodeURI) primary. baseWallet, err := primary.MakeWallet(DefaultContext(), &primary.WalletConfig{ URI: nodeURI.URI, AVAXKeychain: keychain, - // EthKeychain: keychain, + EthKeychain: keychain, }) require.NoError(ginkgo.GinkgoT(), err) return primary.NewWalletWithOptions( @@ -83,15 +80,15 @@ func NewWallet(keychain *secp256k1fx.Keychain, nodeURI testnet.NodeURI) primary. ) } -// // Create a new eth client targeting the specified node URI. -// func NewEthClient(nodeURI testnet.NodeURI) ethclient.Client { -// tests.Outf("{{blue}} initializing a new eth client for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) -// nodeAddress := strings.Split(nodeURI.URI, "//")[1] -// uri := fmt.Sprintf("ws://%s/ext/bc/C/ws", nodeAddress) -// client, err := ethclient.Dial(uri) -// require.NoError(ginkgo.GinkgoT(), err) -// return client -// } +// Create a new eth client targeting the specified node URI. +func NewEthClient(nodeURI testnet.NodeURI) ethclient.Client { + tests.Outf("{{blue}} initializing a new eth client for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) + nodeAddress := strings.Split(nodeURI.URI, "//")[1] + uri := fmt.Sprintf("ws://%s/ext/bc/C/ws", nodeAddress) + client, err := ethclient.Dial(uri) + require.NoError(ginkgo.GinkgoT(), err) + return client +} // Helper simplifying use of a timed context by canceling the context on ginkgo teardown. func ContextWithTimeout(duration time.Duration) context.Context { @@ -155,49 +152,49 @@ func WaitForHealthy(node testnet.Node) { require.NoError(ginkgo.GinkgoT(), testnet.WaitForHealthy(ctx, node)) } -// // Sends an eth transaction, waits for the transaction receipt to be issued -// // and checks that the receipt indicates success. -// func SendEthTransaction(ethClient ethclient.Client, signedTx *types.Transaction) *types.Receipt { -// require := require.New(ginkgo.GinkgoT()) - -// txID := signedTx.Hash() -// tests.Outf(" sending eth transaction with ID: %s\n", txID) - -// require.NoError(ethClient.SendTransaction(DefaultContext(), signedTx)) - -// // Wait for the receipt -// var receipt *types.Receipt -// Eventually(func() bool { -// var err error -// receipt, err = ethClient.TransactionReceipt(DefaultContext(), txID) -// if errors.Is(err, interfaces.NotFound) { -// return false // Transaction is still pending -// } -// require.NoError(err) -// return true -// }, DefaultTimeout, DefaultPollingInterval, "failed to see transaction acceptance before timeout") - -// require.Equal(receipt.Status, types.ReceiptStatusSuccessful) -// return receipt -// } - -// // Determines the suggested gas price for the configured client that will -// // maximize the chances of transaction acceptance. -// func SuggestGasPrice(ethClient ethclient.Client) *big.Int { -// gasPrice, err := ethClient.SuggestGasPrice(DefaultContext()) -// require.NoError(ginkgo.GinkgoT(), err) -// // Double the suggested gas price to maximize the chances of -// // acceptance. Maybe this can be revisited pending resolution of -// // https://github.com/ava-labs/coreth/issues/314. -// gasPrice.Add(gasPrice, gasPrice) -// return gasPrice -// } - -// // Helper simplifying use via an option of a gas price appropriate for testing. -// func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { -// baseFee := SuggestGasPrice(ethClient) -// return common.WithBaseFee(baseFee) -// } +// Sends an eth transaction, waits for the transaction receipt to be issued +// and checks that the receipt indicates success. +func SendEthTransaction(ethClient ethclient.Client, signedTx *types.Transaction) *types.Receipt { + require := require.New(ginkgo.GinkgoT()) + + txID := signedTx.Hash() + tests.Outf(" sending eth transaction with ID: %s\n", txID) + + require.NoError(ethClient.SendTransaction(DefaultContext(), signedTx)) + + // Wait for the receipt + var receipt *types.Receipt + Eventually(func() bool { + var err error + receipt, err = ethClient.TransactionReceipt(DefaultContext(), txID) + if errors.Is(err, interfaces.NotFound) { + return false // Transaction is still pending + } + require.NoError(err) + return true + }, DefaultTimeout, DefaultPollingInterval, "failed to see transaction acceptance before timeout") + + require.Equal(receipt.Status, types.ReceiptStatusSuccessful) + return receipt +} + +// Determines the suggested gas price for the configured client that will +// maximize the chances of transaction acceptance. +func SuggestGasPrice(ethClient ethclient.Client) *big.Int { + gasPrice, err := ethClient.SuggestGasPrice(DefaultContext()) + require.NoError(ginkgo.GinkgoT(), err) + // Double the suggested gas price to maximize the chances of + // acceptance. Maybe this can be revisited pending resolution of + // https://github.com/ava-labs/coreth/issues/314. + gasPrice.Add(gasPrice, gasPrice) + return gasPrice +} + +// Helper simplifying use via an option of a gas price appropriate for testing. +func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { + baseFee := SuggestGasPrice(ethClient) + return common.WithBaseFee(baseFee) +} // Verify that a new node can bootstrap into the network. func CheckBootstrapIsPossible(network testnet.Network) { diff --git a/tests/fixture/testnet/config.go b/tests/fixture/testnet/config.go index c2e27bbff116..425aa646a690 100644 --- a/tests/fixture/testnet/config.go +++ b/tests/fixture/testnet/config.go @@ -15,9 +15,9 @@ import ( "github.com/spf13/cast" - // "github.com/ava-labs/coreth/core" - // "github.com/ava-labs/coreth/params" - // "github.com/ava-labs/coreth/plugin/evm" + "github.com/ava-labs/coreth/core" + "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm" "github.com/ava-labs/avalanchego/config" "github.com/ava-labs/avalanchego/genesis" @@ -143,15 +143,15 @@ func (c *NetworkConfig) EnsureGenesis(networkID uint32, validatorIDs []ids.NodeI // Ensure pre-funded keys have arbitrary large balances on both chains to support testing xChainBalances := make(XChainBalanceMap, len(c.FundedKeys)) - // cChainBalances := make(core.GenesisAlloc, len(c.FundedKeys)) - // for _, key := range c.FundedKeys { - // xChainBalances[key.Address()] = DefaultFundedKeyXChainAmount - // cChainBalances[evm.GetEthAddress(key)] = core.GenesisAccount{ - // Balance: DefaultFundedKeyCChainAmount, - // } - // } - - genesis, err := NewTestGenesis(networkID, xChainBalances /*, cChainBalances*/, validatorIDs) + cChainBalances := make(core.GenesisAlloc, len(c.FundedKeys)) + for _, key := range c.FundedKeys { + xChainBalances[key.Address()] = DefaultFundedKeyXChainAmount + cChainBalances[evm.GetEthAddress(key)] = core.GenesisAccount{ + Balance: DefaultFundedKeyCChainAmount, + } + } + + genesis, err := NewTestGenesis(networkID, xChainBalances, cChainBalances, validatorIDs) if err != nil { return err } @@ -311,7 +311,7 @@ type XChainBalanceMap map[ids.ShortID]uint64 func NewTestGenesis( networkID uint32, xChainBalances XChainBalanceMap, - // cChainBalances core.GenesisAlloc, + cChainBalances core.GenesisAlloc, validatorIDs []ids.NodeID, ) (*genesis.UnparsedConfig, error) { // Validate inputs @@ -322,7 +322,7 @@ func NewTestGenesis( if len(validatorIDs) == 0 { return nil, errMissingValidatorsForGenesis } - if len(xChainBalances) == 0 /*|| len(cChainBalances) == 0*/ { + if len(xChainBalances) == 0 || len(cChainBalances) == 0 { return nil, errMissingBalancesForGenesis } @@ -394,20 +394,20 @@ func NewTestGenesis( ) } - // // Define C-Chain genesis - // cChainGenesis := &core.Genesis{ - // Config: ¶ms.ChainConfig{ - // ChainID: big.NewInt(43112), // Arbitrary chain ID is arbitrary - // }, - // Difficulty: big.NewInt(0), // Difficulty is a mandatory field - // GasLimit: DefaultGasLimit, - // Alloc: cChainBalances, - // } - // cChainGenesisBytes, err := json.Marshal(cChainGenesis) - // if err != nil { - // return nil, fmt.Errorf("failed to marshal C-Chain genesis: %w", err) - // } - // config.CChainGenesis = string(cChainGenesisBytes) + // Define C-Chain genesis + cChainGenesis := &core.Genesis{ + Config: ¶ms.ChainConfig{ + ChainID: big.NewInt(43112), // Arbitrary chain ID is arbitrary + }, + Difficulty: big.NewInt(0), // Difficulty is a mandatory field + GasLimit: DefaultGasLimit, + Alloc: cChainBalances, + } + cChainGenesisBytes, err := json.Marshal(cChainGenesis) + if err != nil { + return nil, fmt.Errorf("failed to marshal C-Chain genesis: %w", err) + } + config.CChainGenesis = string(cChainGenesisBytes) // Give staking rewards for initial validators to a random address. Any testing of staking rewards // will be easier to perform with nodes other than the initial validators since the timing of diff --git a/vms/example/xsvm/cmd/chain/create/cmd.go b/vms/example/xsvm/cmd/chain/create/cmd.go index 043b4298dcdf..1f00491a4ce6 100644 --- a/vms/example/xsvm/cmd/chain/create/cmd.go +++ b/vms/example/xsvm/cmd/chain/create/cmd.go @@ -42,9 +42,9 @@ func createFunc(c *cobra.Command, args []string) error { // that [uri] is hosting. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: config.URI, - AVAXKeychain: kc, - // EthKeychain: kc, + URI: config.URI, + AVAXKeychain: kc, + EthKeychain: kc, PChainTxsToFetch: set.Of(config.SubnetID), }) if err != nil { diff --git a/wallet/chain/c/backend.go b/wallet/chain/c/backend.go index b88c8c643bc3..0a735116b646 100644 --- a/wallet/chain/c/backend.go +++ b/wallet/chain/c/backend.go @@ -3,153 +3,153 @@ package c -// import ( -// "errors" -// "fmt" -// "math/big" -// "sync" - -// stdcontext "context" - -// "github.com/ava-labs/coreth/plugin/evm" - -// ethcommon "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/avalanchego/database" -// "github.com/ava-labs/avalanchego/utils/math" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var ( -// _ Backend = (*backend)(nil) - -// errUnknownTxType = errors.New("unknown tx type") -// ) - -// // Backend defines the full interface required to support a C-chain wallet. -// type Backend interface { -// common.ChainUTXOs -// BuilderBackend -// SignerBackend - -// AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error -// } - -// type backend struct { -// Context -// common.ChainUTXOs - -// accountsLock sync.RWMutex -// accounts map[ethcommon.Address]*Account -// } - -// type Account struct { -// Balance *big.Int -// Nonce uint64 -// } - -// func NewBackend( -// ctx Context, -// utxos common.ChainUTXOs, -// accounts map[ethcommon.Address]*Account, -// ) Backend { -// return &backend{ -// Context: ctx, -// ChainUTXOs: utxos, -// accounts: accounts, -// } -// } - -// func (b *backend) AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error { -// switch tx := tx.UnsignedAtomicTx.(type) { -// case *evm.UnsignedImportTx: -// for _, input := range tx.ImportedInputs { -// utxoID := input.InputID() -// if err := b.RemoveUTXO(ctx, tx.SourceChain, utxoID); err != nil { -// return err -// } -// } - -// b.accountsLock.Lock() -// defer b.accountsLock.Unlock() - -// for _, output := range tx.Outs { -// account, ok := b.accounts[output.Address] -// if !ok { -// continue -// } - -// balance := new(big.Int).SetUint64(output.Amount) -// balance.Mul(balance, avaxConversionRate) -// account.Balance.Add(account.Balance, balance) -// } -// case *evm.UnsignedExportTx: -// txID := tx.ID() -// for i, out := range tx.ExportedOutputs { -// err := b.AddUTXO( -// ctx, -// tx.DestinationChain, -// &avax.UTXO{ -// UTXOID: avax.UTXOID{ -// TxID: txID, -// OutputIndex: uint32(i), -// }, -// Asset: avax.Asset{ID: out.AssetID()}, -// Out: out.Out, -// }, -// ) -// if err != nil { -// return err -// } -// } - -// b.accountsLock.Lock() -// defer b.accountsLock.Unlock() - -// for _, input := range tx.Ins { -// account, ok := b.accounts[input.Address] -// if !ok { -// continue -// } - -// balance := new(big.Int).SetUint64(input.Amount) -// balance.Mul(balance, avaxConversionRate) -// if account.Balance.Cmp(balance) == -1 { -// return errInsufficientFunds -// } -// account.Balance.Sub(account.Balance, balance) - -// newNonce, err := math.Add64(input.Nonce, 1) -// if err != nil { -// return err -// } -// account.Nonce = newNonce -// } -// default: -// return fmt.Errorf("%w: %T", errUnknownTxType, tx) -// } -// return nil -// } - -// func (b *backend) Balance(_ stdcontext.Context, addr ethcommon.Address) (*big.Int, error) { -// b.accountsLock.RLock() -// defer b.accountsLock.RUnlock() - -// account, exists := b.accounts[addr] -// if !exists { -// return nil, database.ErrNotFound -// } -// return account.Balance, nil -// } - -// func (b *backend) Nonce(_ stdcontext.Context, addr ethcommon.Address) (uint64, error) { -// b.accountsLock.RLock() -// defer b.accountsLock.RUnlock() - -// account, exists := b.accounts[addr] -// if !exists { -// return 0, database.ErrNotFound -// } -// return account.Nonce, nil -// } +import ( + "errors" + "fmt" + "math/big" + "sync" + + stdcontext "context" + + "github.com/ava-labs/coreth/plugin/evm" + + ethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/avalanchego/database" + "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var ( + _ Backend = (*backend)(nil) + + errUnknownTxType = errors.New("unknown tx type") +) + +// Backend defines the full interface required to support a C-chain wallet. +type Backend interface { + common.ChainUTXOs + BuilderBackend + SignerBackend + + AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error +} + +type backend struct { + Context + common.ChainUTXOs + + accountsLock sync.RWMutex + accounts map[ethcommon.Address]*Account +} + +type Account struct { + Balance *big.Int + Nonce uint64 +} + +func NewBackend( + ctx Context, + utxos common.ChainUTXOs, + accounts map[ethcommon.Address]*Account, +) Backend { + return &backend{ + Context: ctx, + ChainUTXOs: utxos, + accounts: accounts, + } +} + +func (b *backend) AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error { + switch tx := tx.UnsignedAtomicTx.(type) { + case *evm.UnsignedImportTx: + for _, input := range tx.ImportedInputs { + utxoID := input.InputID() + if err := b.RemoveUTXO(ctx, tx.SourceChain, utxoID); err != nil { + return err + } + } + + b.accountsLock.Lock() + defer b.accountsLock.Unlock() + + for _, output := range tx.Outs { + account, ok := b.accounts[output.Address] + if !ok { + continue + } + + balance := new(big.Int).SetUint64(output.Amount) + balance.Mul(balance, avaxConversionRate) + account.Balance.Add(account.Balance, balance) + } + case *evm.UnsignedExportTx: + txID := tx.ID() + for i, out := range tx.ExportedOutputs { + err := b.AddUTXO( + ctx, + tx.DestinationChain, + &avax.UTXO{ + UTXOID: avax.UTXOID{ + TxID: txID, + OutputIndex: uint32(i), + }, + Asset: avax.Asset{ID: out.AssetID()}, + Out: out.Out, + }, + ) + if err != nil { + return err + } + } + + b.accountsLock.Lock() + defer b.accountsLock.Unlock() + + for _, input := range tx.Ins { + account, ok := b.accounts[input.Address] + if !ok { + continue + } + + balance := new(big.Int).SetUint64(input.Amount) + balance.Mul(balance, avaxConversionRate) + if account.Balance.Cmp(balance) == -1 { + return errInsufficientFunds + } + account.Balance.Sub(account.Balance, balance) + + newNonce, err := math.Add64(input.Nonce, 1) + if err != nil { + return err + } + account.Nonce = newNonce + } + default: + return fmt.Errorf("%w: %T", errUnknownTxType, tx) + } + return nil +} + +func (b *backend) Balance(_ stdcontext.Context, addr ethcommon.Address) (*big.Int, error) { + b.accountsLock.RLock() + defer b.accountsLock.RUnlock() + + account, exists := b.accounts[addr] + if !exists { + return nil, database.ErrNotFound + } + return account.Balance, nil +} + +func (b *backend) Nonce(_ stdcontext.Context, addr ethcommon.Address) (uint64, error) { + b.accountsLock.RLock() + defer b.accountsLock.RUnlock() + + account, exists := b.accounts[addr] + if !exists { + return 0, database.ErrNotFound + } + return account.Nonce, nil +} diff --git a/wallet/chain/c/builder.go b/wallet/chain/c/builder.go index c51d2647777e..d2d088e88a53 100644 --- a/wallet/chain/c/builder.go +++ b/wallet/chain/c/builder.go @@ -3,399 +3,399 @@ package c -// import ( -// "errors" -// "math/big" - -// stdcontext "context" - -// "github.com/ava-labs/coreth/plugin/evm" - -// ethcommon "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/utils" -// "github.com/ava-labs/avalanchego/utils/math" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// const avaxConversionRateInt = 1_000_000_000 - -// var ( -// _ Builder = (*builder)(nil) - -// errInsufficientFunds = errors.New("insufficient funds") - -// // avaxConversionRate is the conversion rate between the smallest -// // denomination on the X-Chain and P-chain, 1 nAVAX, and the smallest -// // denomination on the C-Chain 1 wei. Where 1 nAVAX = 1 gWei. -// // -// // This is only required for AVAX because the denomination of 1 AVAX is 9 -// // decimal places on the X and P chains, but is 18 decimal places within the -// // EVM. -// avaxConversionRate = big.NewInt(avaxConversionRateInt) -// ) - -// // Builder provides a convenient interface for building unsigned C-chain -// // transactions. -// type Builder interface { -// // GetBalance calculates the amount of AVAX that this builder has control -// // over. -// GetBalance( -// options ...common.Option, -// ) (*big.Int, error) - -// // GetImportableBalance calculates the amount of AVAX that this builder -// // could import from the provided chain. -// // -// // - [chainID] specifies the chain the funds are from. -// GetImportableBalance( -// chainID ids.ID, -// options ...common.Option, -// ) (uint64, error) - -// // NewImportTx creates an import transaction that attempts to consume all -// // the available UTXOs and import the funds to [to]. -// // -// // - [chainID] specifies the chain to be importing funds from. -// // - [to] specifies where to send the imported funds to. -// // - [baseFee] specifies the fee price willing to be paid by this tx. -// NewImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedImportTx, error) - -// // NewExportTx creates an export transaction that attempts to send all the -// // provided [outputs] to the requested [chainID]. -// // -// // - [chainID] specifies the chain to be exporting the funds to. -// // - [outputs] specifies the outputs to send to the [chainID]. -// // - [baseFee] specifies the fee price willing to be paid by this tx. -// NewExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedExportTx, error) -// } - -// // BuilderBackend specifies the required information needed to build unsigned -// // C-chain transactions. -// type BuilderBackend interface { -// Context - -// UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) -// Balance(ctx stdcontext.Context, addr ethcommon.Address) (*big.Int, error) -// Nonce(ctx stdcontext.Context, addr ethcommon.Address) (uint64, error) -// } - -// type builder struct { -// avaxAddrs set.Set[ids.ShortID] -// ethAddrs set.Set[ethcommon.Address] -// backend BuilderBackend -// } - -// // NewBuilder returns a new transaction builder. -// // -// // - [avaxAddrs] is the set of addresses in the AVAX format that the builder -// // assumes can be used when signing the transactions in the future. -// // - [ethAddrs] is the set of addresses in the Eth format that the builder -// // assumes can be used when signing the transactions in the future. -// // - [backend] provides the required access to the chain's context and state -// // to build out the transactions. -// func NewBuilder( -// avaxAddrs set.Set[ids.ShortID], -// ethAddrs set.Set[ethcommon.Address], -// backend BuilderBackend, -// ) Builder { -// return &builder{ -// avaxAddrs: avaxAddrs, -// ethAddrs: ethAddrs, -// backend: backend, -// } -// } - -// func (b *builder) GetBalance( -// options ...common.Option, -// ) (*big.Int, error) { -// var ( -// ops = common.NewOptions(options) -// ctx = ops.Context() -// addrs = ops.EthAddresses(b.ethAddrs) -// totalBalance = new(big.Int) -// ) -// for addr := range addrs { -// balance, err := b.backend.Balance(ctx, addr) -// if err != nil { -// return nil, err -// } -// totalBalance.Add(totalBalance, balance) -// } - -// return totalBalance, nil -// } - -// func (b *builder) GetImportableBalance( -// chainID ids.ID, -// options ...common.Option, -// ) (uint64, error) { -// ops := common.NewOptions(options) -// utxos, err := b.backend.UTXOs(ops.Context(), chainID) -// if err != nil { -// return 0, err -// } - -// var ( -// addrs = ops.Addresses(b.avaxAddrs) -// minIssuanceTime = ops.MinIssuanceTime() -// avaxAssetID = b.backend.AVAXAssetID() -// balance uint64 -// ) -// for _, utxo := range utxos { -// amount, _, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) -// if !ok { -// continue -// } - -// newBalance, err := math.Add64(balance, amount) -// if err != nil { -// return 0, err -// } -// balance = newBalance -// } - -// return balance, nil -// } - -// func (b *builder) NewImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedImportTx, error) { -// ops := common.NewOptions(options) -// utxos, err := b.backend.UTXOs(ops.Context(), chainID) -// if err != nil { -// return nil, err -// } - -// var ( -// addrs = ops.Addresses(b.avaxAddrs) -// minIssuanceTime = ops.MinIssuanceTime() -// avaxAssetID = b.backend.AVAXAssetID() - -// importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) -// importedAmount uint64 -// ) -// for _, utxo := range utxos { -// amount, inputSigIndices, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) -// if !ok { -// continue -// } - -// importedInputs = append(importedInputs, &avax.TransferableInput{ -// UTXOID: utxo.UTXOID, -// Asset: utxo.Asset, -// In: &secp256k1fx.TransferInput{ -// Amt: amount, -// Input: secp256k1fx.Input{ -// SigIndices: inputSigIndices, -// }, -// }, -// }) - -// newImportedAmount, err := math.Add64(importedAmount, amount) -// if err != nil { -// return nil, err -// } -// importedAmount = newImportedAmount -// } - -// utils.Sort(importedInputs) -// tx := &evm.UnsignedImportTx{ -// NetworkID: b.backend.NetworkID(), -// BlockchainID: b.backend.BlockchainID(), -// SourceChain: chainID, -// ImportedInputs: importedInputs, -// } - -// // We must initialize the bytes of the tx to calculate the initial cost -// wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} -// if err := wrappedTx.Sign(evm.Codec, nil); err != nil { -// return nil, err -// } - -// gasUsedWithoutOutput, err := tx.GasUsed(true /*=IsApricotPhase5*/) -// if err != nil { -// return nil, err -// } -// gasUsedWithOutput := gasUsedWithoutOutput + evm.EVMOutputGas - -// txFee, err := evm.CalculateDynamicFee(gasUsedWithOutput, baseFee) -// if err != nil { -// return nil, err -// } - -// if importedAmount <= txFee { -// return nil, errInsufficientFunds -// } - -// tx.Outs = []evm.EVMOutput{{ -// Address: to, -// Amount: importedAmount - txFee, -// AssetID: avaxAssetID, -// }} -// return tx, nil -// } - -// func (b *builder) NewExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedExportTx, error) { -// var ( -// avaxAssetID = b.backend.AVAXAssetID() -// exportedOutputs = make([]*avax.TransferableOutput, len(outputs)) -// exportedAmount uint64 -// ) -// for i, output := range outputs { -// exportedOutputs[i] = &avax.TransferableOutput{ -// Asset: avax.Asset{ID: avaxAssetID}, -// Out: output, -// } - -// newExportedAmount, err := math.Add64(exportedAmount, output.Amt) -// if err != nil { -// return nil, err -// } -// exportedAmount = newExportedAmount -// } - -// avax.SortTransferableOutputs(exportedOutputs, evm.Codec) -// tx := &evm.UnsignedExportTx{ -// NetworkID: b.backend.NetworkID(), -// BlockchainID: b.backend.BlockchainID(), -// DestinationChain: chainID, -// ExportedOutputs: exportedOutputs, -// } - -// // We must initialize the bytes of the tx to calculate the initial cost -// wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} -// if err := wrappedTx.Sign(evm.Codec, nil); err != nil { -// return nil, err -// } - -// cost, err := tx.GasUsed(true /*=IsApricotPhase5*/) -// if err != nil { -// return nil, err -// } - -// initialFee, err := evm.CalculateDynamicFee(cost, baseFee) -// if err != nil { -// return nil, err -// } - -// amountToConsume, err := math.Add64(exportedAmount, initialFee) -// if err != nil { -// return nil, err -// } - -// var ( -// ops = common.NewOptions(options) -// ctx = ops.Context() -// addrs = ops.EthAddresses(b.ethAddrs) -// inputs = make([]evm.EVMInput, 0, addrs.Len()) -// ) -// for addr := range addrs { -// if amountToConsume == 0 { -// break -// } - -// prevFee, err := evm.CalculateDynamicFee(cost, baseFee) -// if err != nil { -// return nil, err -// } - -// newCost := cost + evm.EVMInputGas -// newFee, err := evm.CalculateDynamicFee(newCost, baseFee) -// if err != nil { -// return nil, err -// } - -// additionalFee := newFee - prevFee - -// balance, err := b.backend.Balance(ctx, addr) -// if err != nil { -// return nil, err -// } - -// // Since the asset is AVAX, we divide by the avaxConversionRate to -// // convert back to the correct denomination of AVAX that can be -// // exported. -// avaxBalance := new(big.Int).Div(balance, avaxConversionRate).Uint64() - -// // If the balance for [addr] is insufficient to cover the additional -// // cost of adding an input to the transaction, skip adding the input -// // altogether. -// if avaxBalance <= additionalFee { -// continue -// } - -// // Update the cost for the next iteration -// cost = newCost - -// amountToConsume, err = math.Add64(amountToConsume, additionalFee) -// if err != nil { -// return nil, err -// } - -// nonce, err := b.backend.Nonce(ctx, addr) -// if err != nil { -// return nil, err -// } - -// inputAmount := math.Min(amountToConsume, avaxBalance) -// inputs = append(inputs, evm.EVMInput{ -// Address: addr, -// Amount: inputAmount, -// AssetID: avaxAssetID, -// Nonce: nonce, -// }) -// amountToConsume -= inputAmount -// } - -// if amountToConsume > 0 { -// return nil, errInsufficientFunds -// } - -// utils.Sort(inputs) -// tx.Ins = inputs -// return tx, nil -// } - -// func getSpendableAmount( -// utxo *avax.UTXO, -// addrs set.Set[ids.ShortID], -// minIssuanceTime uint64, -// avaxAssetID ids.ID, -// ) (uint64, []uint32, bool) { -// if utxo.Asset.ID != avaxAssetID { -// // Only AVAX can be imported -// return 0, nil, false -// } - -// out, ok := utxo.Out.(*secp256k1fx.TransferOutput) -// if !ok { -// // Can't import an unknown transfer output type -// return 0, nil, false -// } - -// inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) -// return out.Amt, inputSigIndices, ok -// } +import ( + "errors" + "math/big" + + stdcontext "context" + + "github.com/ava-labs/coreth/plugin/evm" + + ethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils" + "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +const avaxConversionRateInt = 1_000_000_000 + +var ( + _ Builder = (*builder)(nil) + + errInsufficientFunds = errors.New("insufficient funds") + + // avaxConversionRate is the conversion rate between the smallest + // denomination on the X-Chain and P-chain, 1 nAVAX, and the smallest + // denomination on the C-Chain 1 wei. Where 1 nAVAX = 1 gWei. + // + // This is only required for AVAX because the denomination of 1 AVAX is 9 + // decimal places on the X and P chains, but is 18 decimal places within the + // EVM. + avaxConversionRate = big.NewInt(avaxConversionRateInt) +) + +// Builder provides a convenient interface for building unsigned C-chain +// transactions. +type Builder interface { + // GetBalance calculates the amount of AVAX that this builder has control + // over. + GetBalance( + options ...common.Option, + ) (*big.Int, error) + + // GetImportableBalance calculates the amount of AVAX that this builder + // could import from the provided chain. + // + // - [chainID] specifies the chain the funds are from. + GetImportableBalance( + chainID ids.ID, + options ...common.Option, + ) (uint64, error) + + // NewImportTx creates an import transaction that attempts to consume all + // the available UTXOs and import the funds to [to]. + // + // - [chainID] specifies the chain to be importing funds from. + // - [to] specifies where to send the imported funds to. + // - [baseFee] specifies the fee price willing to be paid by this tx. + NewImportTx( + chainID ids.ID, + to ethcommon.Address, + baseFee *big.Int, + options ...common.Option, + ) (*evm.UnsignedImportTx, error) + + // NewExportTx creates an export transaction that attempts to send all the + // provided [outputs] to the requested [chainID]. + // + // - [chainID] specifies the chain to be exporting the funds to. + // - [outputs] specifies the outputs to send to the [chainID]. + // - [baseFee] specifies the fee price willing to be paid by this tx. + NewExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + baseFee *big.Int, + options ...common.Option, + ) (*evm.UnsignedExportTx, error) +} + +// BuilderBackend specifies the required information needed to build unsigned +// C-chain transactions. +type BuilderBackend interface { + Context + + UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) + Balance(ctx stdcontext.Context, addr ethcommon.Address) (*big.Int, error) + Nonce(ctx stdcontext.Context, addr ethcommon.Address) (uint64, error) +} + +type builder struct { + avaxAddrs set.Set[ids.ShortID] + ethAddrs set.Set[ethcommon.Address] + backend BuilderBackend +} + +// NewBuilder returns a new transaction builder. +// +// - [avaxAddrs] is the set of addresses in the AVAX format that the builder +// assumes can be used when signing the transactions in the future. +// - [ethAddrs] is the set of addresses in the Eth format that the builder +// assumes can be used when signing the transactions in the future. +// - [backend] provides the required access to the chain's context and state +// to build out the transactions. +func NewBuilder( + avaxAddrs set.Set[ids.ShortID], + ethAddrs set.Set[ethcommon.Address], + backend BuilderBackend, +) Builder { + return &builder{ + avaxAddrs: avaxAddrs, + ethAddrs: ethAddrs, + backend: backend, + } +} + +func (b *builder) GetBalance( + options ...common.Option, +) (*big.Int, error) { + var ( + ops = common.NewOptions(options) + ctx = ops.Context() + addrs = ops.EthAddresses(b.ethAddrs) + totalBalance = new(big.Int) + ) + for addr := range addrs { + balance, err := b.backend.Balance(ctx, addr) + if err != nil { + return nil, err + } + totalBalance.Add(totalBalance, balance) + } + + return totalBalance, nil +} + +func (b *builder) GetImportableBalance( + chainID ids.ID, + options ...common.Option, +) (uint64, error) { + ops := common.NewOptions(options) + utxos, err := b.backend.UTXOs(ops.Context(), chainID) + if err != nil { + return 0, err + } + + var ( + addrs = ops.Addresses(b.avaxAddrs) + minIssuanceTime = ops.MinIssuanceTime() + avaxAssetID = b.backend.AVAXAssetID() + balance uint64 + ) + for _, utxo := range utxos { + amount, _, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) + if !ok { + continue + } + + newBalance, err := math.Add64(balance, amount) + if err != nil { + return 0, err + } + balance = newBalance + } + + return balance, nil +} + +func (b *builder) NewImportTx( + chainID ids.ID, + to ethcommon.Address, + baseFee *big.Int, + options ...common.Option, +) (*evm.UnsignedImportTx, error) { + ops := common.NewOptions(options) + utxos, err := b.backend.UTXOs(ops.Context(), chainID) + if err != nil { + return nil, err + } + + var ( + addrs = ops.Addresses(b.avaxAddrs) + minIssuanceTime = ops.MinIssuanceTime() + avaxAssetID = b.backend.AVAXAssetID() + + importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) + importedAmount uint64 + ) + for _, utxo := range utxos { + amount, inputSigIndices, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) + if !ok { + continue + } + + importedInputs = append(importedInputs, &avax.TransferableInput{ + UTXOID: utxo.UTXOID, + Asset: utxo.Asset, + In: &secp256k1fx.TransferInput{ + Amt: amount, + Input: secp256k1fx.Input{ + SigIndices: inputSigIndices, + }, + }, + }) + + newImportedAmount, err := math.Add64(importedAmount, amount) + if err != nil { + return nil, err + } + importedAmount = newImportedAmount + } + + utils.Sort(importedInputs) + tx := &evm.UnsignedImportTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: b.backend.BlockchainID(), + SourceChain: chainID, + ImportedInputs: importedInputs, + } + + // We must initialize the bytes of the tx to calculate the initial cost + wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} + if err := wrappedTx.Sign(evm.Codec, nil); err != nil { + return nil, err + } + + gasUsedWithoutOutput, err := tx.GasUsed(true /*=IsApricotPhase5*/) + if err != nil { + return nil, err + } + gasUsedWithOutput := gasUsedWithoutOutput + evm.EVMOutputGas + + txFee, err := evm.CalculateDynamicFee(gasUsedWithOutput, baseFee) + if err != nil { + return nil, err + } + + if importedAmount <= txFee { + return nil, errInsufficientFunds + } + + tx.Outs = []evm.EVMOutput{{ + Address: to, + Amount: importedAmount - txFee, + AssetID: avaxAssetID, + }} + return tx, nil +} + +func (b *builder) NewExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + baseFee *big.Int, + options ...common.Option, +) (*evm.UnsignedExportTx, error) { + var ( + avaxAssetID = b.backend.AVAXAssetID() + exportedOutputs = make([]*avax.TransferableOutput, len(outputs)) + exportedAmount uint64 + ) + for i, output := range outputs { + exportedOutputs[i] = &avax.TransferableOutput{ + Asset: avax.Asset{ID: avaxAssetID}, + Out: output, + } + + newExportedAmount, err := math.Add64(exportedAmount, output.Amt) + if err != nil { + return nil, err + } + exportedAmount = newExportedAmount + } + + avax.SortTransferableOutputs(exportedOutputs, evm.Codec) + tx := &evm.UnsignedExportTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: b.backend.BlockchainID(), + DestinationChain: chainID, + ExportedOutputs: exportedOutputs, + } + + // We must initialize the bytes of the tx to calculate the initial cost + wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} + if err := wrappedTx.Sign(evm.Codec, nil); err != nil { + return nil, err + } + + cost, err := tx.GasUsed(true /*=IsApricotPhase5*/) + if err != nil { + return nil, err + } + + initialFee, err := evm.CalculateDynamicFee(cost, baseFee) + if err != nil { + return nil, err + } + + amountToConsume, err := math.Add64(exportedAmount, initialFee) + if err != nil { + return nil, err + } + + var ( + ops = common.NewOptions(options) + ctx = ops.Context() + addrs = ops.EthAddresses(b.ethAddrs) + inputs = make([]evm.EVMInput, 0, addrs.Len()) + ) + for addr := range addrs { + if amountToConsume == 0 { + break + } + + prevFee, err := evm.CalculateDynamicFee(cost, baseFee) + if err != nil { + return nil, err + } + + newCost := cost + evm.EVMInputGas + newFee, err := evm.CalculateDynamicFee(newCost, baseFee) + if err != nil { + return nil, err + } + + additionalFee := newFee - prevFee + + balance, err := b.backend.Balance(ctx, addr) + if err != nil { + return nil, err + } + + // Since the asset is AVAX, we divide by the avaxConversionRate to + // convert back to the correct denomination of AVAX that can be + // exported. + avaxBalance := new(big.Int).Div(balance, avaxConversionRate).Uint64() + + // If the balance for [addr] is insufficient to cover the additional + // cost of adding an input to the transaction, skip adding the input + // altogether. + if avaxBalance <= additionalFee { + continue + } + + // Update the cost for the next iteration + cost = newCost + + amountToConsume, err = math.Add64(amountToConsume, additionalFee) + if err != nil { + return nil, err + } + + nonce, err := b.backend.Nonce(ctx, addr) + if err != nil { + return nil, err + } + + inputAmount := math.Min(amountToConsume, avaxBalance) + inputs = append(inputs, evm.EVMInput{ + Address: addr, + Amount: inputAmount, + AssetID: avaxAssetID, + Nonce: nonce, + }) + amountToConsume -= inputAmount + } + + if amountToConsume > 0 { + return nil, errInsufficientFunds + } + + utils.Sort(inputs) + tx.Ins = inputs + return tx, nil +} + +func getSpendableAmount( + utxo *avax.UTXO, + addrs set.Set[ids.ShortID], + minIssuanceTime uint64, + avaxAssetID ids.ID, +) (uint64, []uint32, bool) { + if utxo.Asset.ID != avaxAssetID { + // Only AVAX can be imported + return 0, nil, false + } + + out, ok := utxo.Out.(*secp256k1fx.TransferOutput) + if !ok { + // Can't import an unknown transfer output type + return 0, nil, false + } + + inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) + return out.Amt, inputSigIndices, ok +} diff --git a/wallet/chain/c/builder_with_options.go b/wallet/chain/c/builder_with_options.go index 9b7ab8399484..8416dddf9928 100644 --- a/wallet/chain/c/builder_with_options.go +++ b/wallet/chain/c/builder_with_options.go @@ -3,81 +3,81 @@ package c -// import ( -// "math/big" +import ( + "math/big" -// "github.com/ava-labs/coreth/plugin/evm" + "github.com/ava-labs/coreth/plugin/evm" -// ethcommon "github.com/ethereum/go-ethereum/common" + ethcommon "github.com/ethereum/go-ethereum/common" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) -// var _ Builder = (*builderWithOptions)(nil) +var _ Builder = (*builderWithOptions)(nil) -// type builderWithOptions struct { -// Builder -// options []common.Option -// } +type builderWithOptions struct { + Builder + options []common.Option +} -// // NewBuilderWithOptions returns a new transaction builder that will use the -// // given options by default. -// // -// // - [builder] is the builder that will be called to perform the underlying -// // operations. -// // - [options] will be provided to the builder in addition to the options -// // provided in the method calls. -// func NewBuilderWithOptions(builder Builder, options ...common.Option) Builder { -// return &builderWithOptions{ -// Builder: builder, -// options: options, -// } -// } +// NewBuilderWithOptions returns a new transaction builder that will use the +// given options by default. +// +// - [builder] is the builder that will be called to perform the underlying +// operations. +// - [options] will be provided to the builder in addition to the options +// provided in the method calls. +func NewBuilderWithOptions(builder Builder, options ...common.Option) Builder { + return &builderWithOptions{ + Builder: builder, + options: options, + } +} -// func (b *builderWithOptions) GetBalance( -// options ...common.Option, -// ) (*big.Int, error) { -// return b.Builder.GetBalance( -// common.UnionOptions(b.options, options)..., -// ) -// } +func (b *builderWithOptions) GetBalance( + options ...common.Option, +) (*big.Int, error) { + return b.Builder.GetBalance( + common.UnionOptions(b.options, options)..., + ) +} -// func (b *builderWithOptions) GetImportableBalance( -// chainID ids.ID, -// options ...common.Option, -// ) (uint64, error) { -// return b.Builder.GetImportableBalance( -// chainID, -// common.UnionOptions(b.options, options)..., -// ) -// } +func (b *builderWithOptions) GetImportableBalance( + chainID ids.ID, + options ...common.Option, +) (uint64, error) { + return b.Builder.GetImportableBalance( + chainID, + common.UnionOptions(b.options, options)..., + ) +} -// func (b *builderWithOptions) NewImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedImportTx, error) { -// return b.Builder.NewImportTx( -// chainID, -// to, -// baseFee, -// common.UnionOptions(b.options, options)..., -// ) -// } +func (b *builderWithOptions) NewImportTx( + chainID ids.ID, + to ethcommon.Address, + baseFee *big.Int, + options ...common.Option, +) (*evm.UnsignedImportTx, error) { + return b.Builder.NewImportTx( + chainID, + to, + baseFee, + common.UnionOptions(b.options, options)..., + ) +} -// func (b *builderWithOptions) NewExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedExportTx, error) { -// return b.Builder.NewExportTx( -// chainID, -// outputs, -// baseFee, -// common.UnionOptions(b.options, options)..., -// ) -// } +func (b *builderWithOptions) NewExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + baseFee *big.Int, + options ...common.Option, +) (*evm.UnsignedExportTx, error) { + return b.Builder.NewExportTx( + chainID, + outputs, + baseFee, + common.UnionOptions(b.options, options)..., + ) +} diff --git a/wallet/chain/c/context.go b/wallet/chain/c/context.go index 1c01d8fb55c8..d506b42f81fa 100644 --- a/wallet/chain/c/context.go +++ b/wallet/chain/c/context.go @@ -3,81 +3,81 @@ package c -// import ( -// stdcontext "context" +import ( + stdcontext "context" -// "github.com/ava-labs/avalanchego/api/info" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/vms/avm" -// ) + "github.com/ava-labs/avalanchego/api/info" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/avm" +) -// var _ Context = (*context)(nil) +var _ Context = (*context)(nil) -// type Context interface { -// NetworkID() uint32 -// BlockchainID() ids.ID -// AVAXAssetID() ids.ID -// } +type Context interface { + NetworkID() uint32 + BlockchainID() ids.ID + AVAXAssetID() ids.ID +} -// type context struct { -// networkID uint32 -// blockchainID ids.ID -// avaxAssetID ids.ID -// } +type context struct { + networkID uint32 + blockchainID ids.ID + avaxAssetID ids.ID +} -// func NewContextFromURI(ctx stdcontext.Context, uri string) (Context, error) { -// infoClient := info.NewClient(uri) -// xChainClient := avm.NewClient(uri, "X") -// return NewContextFromClients(ctx, infoClient, xChainClient) -// } +func NewContextFromURI(ctx stdcontext.Context, uri string) (Context, error) { + infoClient := info.NewClient(uri) + xChainClient := avm.NewClient(uri, "X") + return NewContextFromClients(ctx, infoClient, xChainClient) +} -// func NewContextFromClients( -// ctx stdcontext.Context, -// infoClient info.Client, -// xChainClient avm.Client, -// ) (Context, error) { -// networkID, err := infoClient.GetNetworkID(ctx) -// if err != nil { -// return nil, err -// } +func NewContextFromClients( + ctx stdcontext.Context, + infoClient info.Client, + xChainClient avm.Client, +) (Context, error) { + networkID, err := infoClient.GetNetworkID(ctx) + if err != nil { + return nil, err + } -// chainID, err := infoClient.GetBlockchainID(ctx, "C") -// if err != nil { -// return nil, err -// } + chainID, err := infoClient.GetBlockchainID(ctx, "C") + if err != nil { + return nil, err + } -// asset, err := xChainClient.GetAssetDescription(ctx, "AVAX") -// if err != nil { -// return nil, err -// } + asset, err := xChainClient.GetAssetDescription(ctx, "AVAX") + if err != nil { + return nil, err + } -// return NewContext( -// networkID, -// chainID, -// asset.AssetID, -// ), nil -// } + return NewContext( + networkID, + chainID, + asset.AssetID, + ), nil +} -// func NewContext( -// networkID uint32, -// blockchainID ids.ID, -// avaxAssetID ids.ID, -// ) Context { -// return &context{ -// networkID: networkID, -// blockchainID: blockchainID, -// avaxAssetID: avaxAssetID, -// } -// } +func NewContext( + networkID uint32, + blockchainID ids.ID, + avaxAssetID ids.ID, +) Context { + return &context{ + networkID: networkID, + blockchainID: blockchainID, + avaxAssetID: avaxAssetID, + } +} -// func (c *context) NetworkID() uint32 { -// return c.networkID -// } +func (c *context) NetworkID() uint32 { + return c.networkID +} -// func (c *context) BlockchainID() ids.ID { -// return c.blockchainID -// } +func (c *context) BlockchainID() ids.ID { + return c.blockchainID +} -// func (c *context) AVAXAssetID() ids.ID { -// return c.avaxAssetID -// } +func (c *context) AVAXAssetID() ids.ID { + return c.avaxAssetID +} diff --git a/wallet/chain/c/signer.go b/wallet/chain/c/signer.go index 4bedc378234b..4fd85ed3b532 100644 --- a/wallet/chain/c/signer.go +++ b/wallet/chain/c/signer.go @@ -3,221 +3,221 @@ package c -// import ( -// "errors" -// "fmt" - -// stdcontext "context" - -// "github.com/ava-labs/coreth/plugin/evm" - -// ethcommon "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/avalanchego/database" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/utils/crypto/keychain" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// "github.com/ava-labs/avalanchego/utils/hashing" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/components/verify" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// ) - -// const version = 0 - -// var ( -// _ Signer = (*txSigner)(nil) - -// errUnknownInputType = errors.New("unknown input type") -// errUnknownCredentialType = errors.New("unknown credential type") -// errUnknownOutputType = errors.New("unknown output type") -// errInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") - -// emptySig [secp256k1.SignatureLen]byte -// ) - -// type Signer interface { -// SignUnsignedAtomic(ctx stdcontext.Context, tx evm.UnsignedAtomicTx) (*evm.Tx, error) -// SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error -// } - -// type EthKeychain interface { -// // The returned Signer can provide a signature for [addr] -// GetEth(addr ethcommon.Address) (keychain.Signer, bool) -// // Returns the set of addresses for which the accessor keeps an associated -// // signer -// EthAddresses() set.Set[ethcommon.Address] -// } - -// type SignerBackend interface { -// GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) -// } - -// type txSigner struct { -// avaxKC keychain.Keychain -// ethKC EthKeychain -// backend SignerBackend -// } - -// func NewSigner(avaxKC keychain.Keychain, ethKC EthKeychain, backend SignerBackend) Signer { -// return &txSigner{ -// avaxKC: avaxKC, -// ethKC: ethKC, -// backend: backend, -// } -// } - -// func (s *txSigner) SignUnsignedAtomic(ctx stdcontext.Context, utx evm.UnsignedAtomicTx) (*evm.Tx, error) { -// tx := &evm.Tx{UnsignedAtomicTx: utx} -// return tx, s.SignAtomic(ctx, tx) -// } - -// func (s *txSigner) SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error { -// switch utx := tx.UnsignedAtomicTx.(type) { -// case *evm.UnsignedImportTx: -// signers, err := s.getImportSigners(ctx, utx.SourceChain, utx.ImportedInputs) -// if err != nil { -// return err -// } -// return sign(tx, true, signers) -// case *evm.UnsignedExportTx: -// signers := s.getExportSigners(utx.Ins) -// return sign(tx, true, signers) -// default: -// return fmt.Errorf("%w: %T", errUnknownTxType, tx) -// } -// } - -// func (s *txSigner) getImportSigners(ctx stdcontext.Context, sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { -// txSigners := make([][]keychain.Signer, len(ins)) -// for credIndex, transferInput := range ins { -// input, ok := transferInput.In.(*secp256k1fx.TransferInput) -// if !ok { -// return nil, errUnknownInputType -// } - -// inputSigners := make([]keychain.Signer, len(input.SigIndices)) -// txSigners[credIndex] = inputSigners - -// utxoID := transferInput.InputID() -// utxo, err := s.backend.GetUTXO(ctx, sourceChainID, utxoID) -// if err == database.ErrNotFound { -// // If we don't have access to the UTXO, then we can't sign this -// // transaction. However, we can attempt to partially sign it. -// continue -// } -// if err != nil { -// return nil, err -// } - -// out, ok := utxo.Out.(*secp256k1fx.TransferOutput) -// if !ok { -// return nil, errUnknownOutputType -// } - -// for sigIndex, addrIndex := range input.SigIndices { -// if addrIndex >= uint32(len(out.Addrs)) { -// return nil, errInvalidUTXOSigIndex -// } - -// addr := out.Addrs[addrIndex] -// key, ok := s.avaxKC.Get(addr) -// if !ok { -// // If we don't have access to the key, then we can't sign this -// // transaction. However, we can attempt to partially sign it. -// continue -// } -// inputSigners[sigIndex] = key -// } -// } -// return txSigners, nil -// } - -// func (s *txSigner) getExportSigners(ins []evm.EVMInput) [][]keychain.Signer { -// txSigners := make([][]keychain.Signer, len(ins)) -// for credIndex, input := range ins { -// inputSigners := make([]keychain.Signer, 1) -// txSigners[credIndex] = inputSigners - -// key, ok := s.ethKC.GetEth(input.Address) -// if !ok { -// // If we don't have access to the key, then we can't sign this -// // transaction. However, we can attempt to partially sign it. -// continue -// } -// inputSigners[0] = key -// } -// return txSigners -// } - -// // TODO: remove [signHash] after the ledger supports signing all transactions. -// func sign(tx *evm.Tx, signHash bool, txSigners [][]keychain.Signer) error { -// unsignedBytes, err := evm.Codec.Marshal(version, &tx.UnsignedAtomicTx) -// if err != nil { -// return fmt.Errorf("couldn't marshal unsigned tx: %w", err) -// } -// unsignedHash := hashing.ComputeHash256(unsignedBytes) - -// if expectedLen := len(txSigners); expectedLen != len(tx.Creds) { -// tx.Creds = make([]verify.Verifiable, expectedLen) -// } - -// sigCache := make(map[ids.ShortID][secp256k1.SignatureLen]byte) -// for credIndex, inputSigners := range txSigners { -// credIntf := tx.Creds[credIndex] -// if credIntf == nil { -// credIntf = &secp256k1fx.Credential{} -// tx.Creds[credIndex] = credIntf -// } - -// cred, ok := credIntf.(*secp256k1fx.Credential) -// if !ok { -// return errUnknownCredentialType -// } -// if expectedLen := len(inputSigners); expectedLen != len(cred.Sigs) { -// cred.Sigs = make([][secp256k1.SignatureLen]byte, expectedLen) -// } - -// for sigIndex, signer := range inputSigners { -// if signer == nil { -// // If we don't have access to the key, then we can't sign this -// // transaction. However, we can attempt to partially sign it. -// continue -// } -// addr := signer.Address() -// if sig := cred.Sigs[sigIndex]; sig != emptySig { -// // If this signature has already been populated, we can just -// // copy the needed signature for the future. -// sigCache[addr] = sig -// continue -// } - -// if sig, exists := sigCache[addr]; exists { -// // If this key has already produced a signature, we can just -// // copy the previous signature. -// cred.Sigs[sigIndex] = sig -// continue -// } - -// var sig []byte -// if signHash { -// sig, err = signer.SignHash(unsignedHash) -// } else { -// sig, err = signer.Sign(unsignedBytes) -// } -// if err != nil { -// return fmt.Errorf("problem signing tx: %w", err) -// } -// copy(cred.Sigs[sigIndex][:], sig) -// sigCache[addr] = cred.Sigs[sigIndex] -// } -// } - -// signedBytes, err := evm.Codec.Marshal(version, tx) -// if err != nil { -// return fmt.Errorf("couldn't marshal tx: %w", err) -// } -// tx.Initialize(unsignedBytes, signedBytes) -// return nil -// } +import ( + "errors" + "fmt" + + stdcontext "context" + + "github.com/ava-labs/coreth/plugin/evm" + + ethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/avalanchego/database" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/crypto/keychain" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/hashing" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/components/verify" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" +) + +const version = 0 + +var ( + _ Signer = (*txSigner)(nil) + + errUnknownInputType = errors.New("unknown input type") + errUnknownCredentialType = errors.New("unknown credential type") + errUnknownOutputType = errors.New("unknown output type") + errInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") + + emptySig [secp256k1.SignatureLen]byte +) + +type Signer interface { + SignUnsignedAtomic(ctx stdcontext.Context, tx evm.UnsignedAtomicTx) (*evm.Tx, error) + SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error +} + +type EthKeychain interface { + // The returned Signer can provide a signature for [addr] + GetEth(addr ethcommon.Address) (keychain.Signer, bool) + // Returns the set of addresses for which the accessor keeps an associated + // signer + EthAddresses() set.Set[ethcommon.Address] +} + +type SignerBackend interface { + GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) +} + +type txSigner struct { + avaxKC keychain.Keychain + ethKC EthKeychain + backend SignerBackend +} + +func NewSigner(avaxKC keychain.Keychain, ethKC EthKeychain, backend SignerBackend) Signer { + return &txSigner{ + avaxKC: avaxKC, + ethKC: ethKC, + backend: backend, + } +} + +func (s *txSigner) SignUnsignedAtomic(ctx stdcontext.Context, utx evm.UnsignedAtomicTx) (*evm.Tx, error) { + tx := &evm.Tx{UnsignedAtomicTx: utx} + return tx, s.SignAtomic(ctx, tx) +} + +func (s *txSigner) SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error { + switch utx := tx.UnsignedAtomicTx.(type) { + case *evm.UnsignedImportTx: + signers, err := s.getImportSigners(ctx, utx.SourceChain, utx.ImportedInputs) + if err != nil { + return err + } + return sign(tx, true, signers) + case *evm.UnsignedExportTx: + signers := s.getExportSigners(utx.Ins) + return sign(tx, true, signers) + default: + return fmt.Errorf("%w: %T", errUnknownTxType, tx) + } +} + +func (s *txSigner) getImportSigners(ctx stdcontext.Context, sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { + txSigners := make([][]keychain.Signer, len(ins)) + for credIndex, transferInput := range ins { + input, ok := transferInput.In.(*secp256k1fx.TransferInput) + if !ok { + return nil, errUnknownInputType + } + + inputSigners := make([]keychain.Signer, len(input.SigIndices)) + txSigners[credIndex] = inputSigners + + utxoID := transferInput.InputID() + utxo, err := s.backend.GetUTXO(ctx, sourceChainID, utxoID) + if err == database.ErrNotFound { + // If we don't have access to the UTXO, then we can't sign this + // transaction. However, we can attempt to partially sign it. + continue + } + if err != nil { + return nil, err + } + + out, ok := utxo.Out.(*secp256k1fx.TransferOutput) + if !ok { + return nil, errUnknownOutputType + } + + for sigIndex, addrIndex := range input.SigIndices { + if addrIndex >= uint32(len(out.Addrs)) { + return nil, errInvalidUTXOSigIndex + } + + addr := out.Addrs[addrIndex] + key, ok := s.avaxKC.Get(addr) + if !ok { + // If we don't have access to the key, then we can't sign this + // transaction. However, we can attempt to partially sign it. + continue + } + inputSigners[sigIndex] = key + } + } + return txSigners, nil +} + +func (s *txSigner) getExportSigners(ins []evm.EVMInput) [][]keychain.Signer { + txSigners := make([][]keychain.Signer, len(ins)) + for credIndex, input := range ins { + inputSigners := make([]keychain.Signer, 1) + txSigners[credIndex] = inputSigners + + key, ok := s.ethKC.GetEth(input.Address) + if !ok { + // If we don't have access to the key, then we can't sign this + // transaction. However, we can attempt to partially sign it. + continue + } + inputSigners[0] = key + } + return txSigners +} + +// TODO: remove [signHash] after the ledger supports signing all transactions. +func sign(tx *evm.Tx, signHash bool, txSigners [][]keychain.Signer) error { + unsignedBytes, err := evm.Codec.Marshal(version, &tx.UnsignedAtomicTx) + if err != nil { + return fmt.Errorf("couldn't marshal unsigned tx: %w", err) + } + unsignedHash := hashing.ComputeHash256(unsignedBytes) + + if expectedLen := len(txSigners); expectedLen != len(tx.Creds) { + tx.Creds = make([]verify.Verifiable, expectedLen) + } + + sigCache := make(map[ids.ShortID][secp256k1.SignatureLen]byte) + for credIndex, inputSigners := range txSigners { + credIntf := tx.Creds[credIndex] + if credIntf == nil { + credIntf = &secp256k1fx.Credential{} + tx.Creds[credIndex] = credIntf + } + + cred, ok := credIntf.(*secp256k1fx.Credential) + if !ok { + return errUnknownCredentialType + } + if expectedLen := len(inputSigners); expectedLen != len(cred.Sigs) { + cred.Sigs = make([][secp256k1.SignatureLen]byte, expectedLen) + } + + for sigIndex, signer := range inputSigners { + if signer == nil { + // If we don't have access to the key, then we can't sign this + // transaction. However, we can attempt to partially sign it. + continue + } + addr := signer.Address() + if sig := cred.Sigs[sigIndex]; sig != emptySig { + // If this signature has already been populated, we can just + // copy the needed signature for the future. + sigCache[addr] = sig + continue + } + + if sig, exists := sigCache[addr]; exists { + // If this key has already produced a signature, we can just + // copy the previous signature. + cred.Sigs[sigIndex] = sig + continue + } + + var sig []byte + if signHash { + sig, err = signer.SignHash(unsignedHash) + } else { + sig, err = signer.Sign(unsignedBytes) + } + if err != nil { + return fmt.Errorf("problem signing tx: %w", err) + } + copy(cred.Sigs[sigIndex][:], sig) + sigCache[addr] = cred.Sigs[sigIndex] + } + } + + signedBytes, err := evm.Codec.Marshal(version, tx) + if err != nil { + return fmt.Errorf("couldn't marshal tx: %w", err) + } + tx.Initialize(unsignedBytes, signedBytes) + return nil +} diff --git a/wallet/chain/c/wallet.go b/wallet/chain/c/wallet.go index ebee50a9a958..fb1a83d53dad 100644 --- a/wallet/chain/c/wallet.go +++ b/wallet/chain/c/wallet.go @@ -3,204 +3,204 @@ package c -// import ( -// "errors" -// "math/big" -// "time" - -// "github.com/ava-labs/coreth/ethclient" -// "github.com/ava-labs/coreth/plugin/evm" - -// ethcommon "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var ( -// _ Wallet = (*wallet)(nil) - -// errNotCommitted = errors.New("not committed") -// ) - -// type Wallet interface { -// Context - -// // Builder returns the builder that will be used to create the transactions. -// Builder() Builder - -// // Signer returns the signer that will be used to sign the transactions. -// Signer() Signer - -// // IssueImportTx creates, signs, and issues an import transaction that -// // attempts to consume all the available UTXOs and import the funds to [to]. -// // -// // - [chainID] specifies the chain to be importing funds from. -// // - [to] specifies where to send the imported funds to. -// IssueImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// options ...common.Option, -// ) (*evm.Tx, error) - -// // IssueExportTx creates, signs, and issues an export transaction that -// // attempts to send all the provided [outputs] to the requested [chainID]. -// // -// // - [chainID] specifies the chain to be exporting the funds to. -// // - [outputs] specifies the outputs to send to the [chainID]. -// IssueExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// options ...common.Option, -// ) (*evm.Tx, error) - -// // IssueUnsignedTx signs and issues the unsigned tx. -// IssueUnsignedAtomicTx( -// utx evm.UnsignedAtomicTx, -// options ...common.Option, -// ) (*evm.Tx, error) - -// // IssueAtomicTx issues the signed tx. -// IssueAtomicTx( -// tx *evm.Tx, -// options ...common.Option, -// ) error -// } - -// func NewWallet( -// builder Builder, -// signer Signer, -// avaxClient evm.Client, -// ethClient ethclient.Client, -// backend Backend, -// ) Wallet { -// return &wallet{ -// Backend: backend, -// builder: builder, -// signer: signer, -// avaxClient: avaxClient, -// ethClient: ethClient, -// } -// } - -// type wallet struct { -// Backend -// builder Builder -// signer Signer -// avaxClient evm.Client -// ethClient ethclient.Client -// } - -// func (w *wallet) Builder() Builder { -// return w.builder -// } - -// func (w *wallet) Signer() Signer { -// return w.signer -// } - -// func (w *wallet) IssueImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// options ...common.Option, -// ) (*evm.Tx, error) { -// baseFee, err := w.baseFee(options) -// if err != nil { -// return nil, err -// } - -// utx, err := w.builder.NewImportTx(chainID, to, baseFee, options...) -// if err != nil { -// return nil, err -// } -// return w.IssueUnsignedAtomicTx(utx, options...) -// } - -// func (w *wallet) IssueExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// options ...common.Option, -// ) (*evm.Tx, error) { -// baseFee, err := w.baseFee(options) -// if err != nil { -// return nil, err -// } - -// utx, err := w.builder.NewExportTx(chainID, outputs, baseFee, options...) -// if err != nil { -// return nil, err -// } -// return w.IssueUnsignedAtomicTx(utx, options...) -// } - -// func (w *wallet) IssueUnsignedAtomicTx( -// utx evm.UnsignedAtomicTx, -// options ...common.Option, -// ) (*evm.Tx, error) { -// ops := common.NewOptions(options) -// ctx := ops.Context() -// tx, err := w.signer.SignUnsignedAtomic(ctx, utx) -// if err != nil { -// return nil, err -// } - -// return tx, w.IssueAtomicTx(tx, options...) -// } - -// func (w *wallet) IssueAtomicTx( -// tx *evm.Tx, -// options ...common.Option, -// ) error { -// ops := common.NewOptions(options) -// ctx := ops.Context() -// txID, err := w.avaxClient.IssueTx(ctx, tx.SignedBytes()) -// if err != nil { -// return err -// } - -// if f := ops.PostIssuanceFunc(); f != nil { -// f(txID) -// } - -// if ops.AssumeDecided() { -// return w.Backend.AcceptAtomicTx(ctx, tx) -// } - -// pollFrequency := ops.PollFrequency() -// ticker := time.NewTicker(pollFrequency) -// defer ticker.Stop() - -// for { -// status, err := w.avaxClient.GetAtomicTxStatus(ctx, txID) -// if err != nil { -// return err -// } - -// switch status { -// case evm.Accepted: -// return w.Backend.AcceptAtomicTx(ctx, tx) -// case evm.Dropped, evm.Unknown: -// return errNotCommitted -// } - -// // The tx is Processing. - -// select { -// case <-ticker.C: -// case <-ctx.Done(): -// return ctx.Err() -// } -// } -// } - -// func (w *wallet) baseFee(options []common.Option) (*big.Int, error) { -// ops := common.NewOptions(options) -// baseFee := ops.BaseFee(nil) -// if baseFee != nil { -// return baseFee, nil -// } - -// ctx := ops.Context() -// return w.ethClient.EstimateBaseFee(ctx) -// } +import ( + "errors" + "math/big" + "time" + + "github.com/ava-labs/coreth/ethclient" + "github.com/ava-labs/coreth/plugin/evm" + + ethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var ( + _ Wallet = (*wallet)(nil) + + errNotCommitted = errors.New("not committed") +) + +type Wallet interface { + Context + + // Builder returns the builder that will be used to create the transactions. + Builder() Builder + + // Signer returns the signer that will be used to sign the transactions. + Signer() Signer + + // IssueImportTx creates, signs, and issues an import transaction that + // attempts to consume all the available UTXOs and import the funds to [to]. + // + // - [chainID] specifies the chain to be importing funds from. + // - [to] specifies where to send the imported funds to. + IssueImportTx( + chainID ids.ID, + to ethcommon.Address, + options ...common.Option, + ) (*evm.Tx, error) + + // IssueExportTx creates, signs, and issues an export transaction that + // attempts to send all the provided [outputs] to the requested [chainID]. + // + // - [chainID] specifies the chain to be exporting the funds to. + // - [outputs] specifies the outputs to send to the [chainID]. + IssueExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + options ...common.Option, + ) (*evm.Tx, error) + + // IssueUnsignedTx signs and issues the unsigned tx. + IssueUnsignedAtomicTx( + utx evm.UnsignedAtomicTx, + options ...common.Option, + ) (*evm.Tx, error) + + // IssueAtomicTx issues the signed tx. + IssueAtomicTx( + tx *evm.Tx, + options ...common.Option, + ) error +} + +func NewWallet( + builder Builder, + signer Signer, + avaxClient evm.Client, + ethClient ethclient.Client, + backend Backend, +) Wallet { + return &wallet{ + Backend: backend, + builder: builder, + signer: signer, + avaxClient: avaxClient, + ethClient: ethClient, + } +} + +type wallet struct { + Backend + builder Builder + signer Signer + avaxClient evm.Client + ethClient ethclient.Client +} + +func (w *wallet) Builder() Builder { + return w.builder +} + +func (w *wallet) Signer() Signer { + return w.signer +} + +func (w *wallet) IssueImportTx( + chainID ids.ID, + to ethcommon.Address, + options ...common.Option, +) (*evm.Tx, error) { + baseFee, err := w.baseFee(options) + if err != nil { + return nil, err + } + + utx, err := w.builder.NewImportTx(chainID, to, baseFee, options...) + if err != nil { + return nil, err + } + return w.IssueUnsignedAtomicTx(utx, options...) +} + +func (w *wallet) IssueExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + options ...common.Option, +) (*evm.Tx, error) { + baseFee, err := w.baseFee(options) + if err != nil { + return nil, err + } + + utx, err := w.builder.NewExportTx(chainID, outputs, baseFee, options...) + if err != nil { + return nil, err + } + return w.IssueUnsignedAtomicTx(utx, options...) +} + +func (w *wallet) IssueUnsignedAtomicTx( + utx evm.UnsignedAtomicTx, + options ...common.Option, +) (*evm.Tx, error) { + ops := common.NewOptions(options) + ctx := ops.Context() + tx, err := w.signer.SignUnsignedAtomic(ctx, utx) + if err != nil { + return nil, err + } + + return tx, w.IssueAtomicTx(tx, options...) +} + +func (w *wallet) IssueAtomicTx( + tx *evm.Tx, + options ...common.Option, +) error { + ops := common.NewOptions(options) + ctx := ops.Context() + txID, err := w.avaxClient.IssueTx(ctx, tx.SignedBytes()) + if err != nil { + return err + } + + if f := ops.PostIssuanceFunc(); f != nil { + f(txID) + } + + if ops.AssumeDecided() { + return w.Backend.AcceptAtomicTx(ctx, tx) + } + + pollFrequency := ops.PollFrequency() + ticker := time.NewTicker(pollFrequency) + defer ticker.Stop() + + for { + status, err := w.avaxClient.GetAtomicTxStatus(ctx, txID) + if err != nil { + return err + } + + switch status { + case evm.Accepted: + return w.Backend.AcceptAtomicTx(ctx, tx) + case evm.Dropped, evm.Unknown: + return errNotCommitted + } + + // The tx is Processing. + + select { + case <-ticker.C: + case <-ctx.Done(): + return ctx.Err() + } + } +} + +func (w *wallet) baseFee(options []common.Option) (*big.Int, error) { + ops := common.NewOptions(options) + baseFee := ops.BaseFee(nil) + if baseFee != nil { + return baseFee, nil + } + + ctx := ops.Context() + return w.ethClient.EstimateBaseFee(ctx) +} diff --git a/wallet/chain/c/wallet_with_options.go b/wallet/chain/c/wallet_with_options.go index fd69a6d4fd02..7d6193683d49 100644 --- a/wallet/chain/c/wallet_with_options.go +++ b/wallet/chain/c/wallet_with_options.go @@ -3,80 +3,80 @@ package c -// import ( -// "github.com/ava-labs/coreth/plugin/evm" +import ( + "github.com/ava-labs/coreth/plugin/evm" -// ethcommon "github.com/ethereum/go-ethereum/common" + ethcommon "github.com/ethereum/go-ethereum/common" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) -// var _ Wallet = (*walletWithOptions)(nil) +var _ Wallet = (*walletWithOptions)(nil) -// func NewWalletWithOptions( -// wallet Wallet, -// options ...common.Option, -// ) Wallet { -// return &walletWithOptions{ -// Wallet: wallet, -// options: options, -// } -// } +func NewWalletWithOptions( + wallet Wallet, + options ...common.Option, +) Wallet { + return &walletWithOptions{ + Wallet: wallet, + options: options, + } +} -// type walletWithOptions struct { -// Wallet -// options []common.Option -// } +type walletWithOptions struct { + Wallet + options []common.Option +} -// func (w *walletWithOptions) Builder() Builder { -// return NewBuilderWithOptions( -// w.Wallet.Builder(), -// w.options..., -// ) -// } +func (w *walletWithOptions) Builder() Builder { + return NewBuilderWithOptions( + w.Wallet.Builder(), + w.options..., + ) +} -// func (w *walletWithOptions) IssueImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// options ...common.Option, -// ) (*evm.Tx, error) { -// return w.Wallet.IssueImportTx( -// chainID, -// to, -// common.UnionOptions(w.options, options)..., -// ) -// } +func (w *walletWithOptions) IssueImportTx( + chainID ids.ID, + to ethcommon.Address, + options ...common.Option, +) (*evm.Tx, error) { + return w.Wallet.IssueImportTx( + chainID, + to, + common.UnionOptions(w.options, options)..., + ) +} -// func (w *walletWithOptions) IssueExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// options ...common.Option, -// ) (*evm.Tx, error) { -// return w.Wallet.IssueExportTx( -// chainID, -// outputs, -// common.UnionOptions(w.options, options)..., -// ) -// } +func (w *walletWithOptions) IssueExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + options ...common.Option, +) (*evm.Tx, error) { + return w.Wallet.IssueExportTx( + chainID, + outputs, + common.UnionOptions(w.options, options)..., + ) +} -// func (w *walletWithOptions) IssueUnsignedAtomicTx( -// utx evm.UnsignedAtomicTx, -// options ...common.Option, -// ) (*evm.Tx, error) { -// return w.Wallet.IssueUnsignedAtomicTx( -// utx, -// common.UnionOptions(w.options, options)..., -// ) -// } +func (w *walletWithOptions) IssueUnsignedAtomicTx( + utx evm.UnsignedAtomicTx, + options ...common.Option, +) (*evm.Tx, error) { + return w.Wallet.IssueUnsignedAtomicTx( + utx, + common.UnionOptions(w.options, options)..., + ) +} -// func (w *walletWithOptions) IssueAtomicTx( -// tx *evm.Tx, -// options ...common.Option, -// ) error { -// return w.Wallet.IssueAtomicTx( -// tx, -// common.UnionOptions(w.options, options)..., -// ) -// } +func (w *walletWithOptions) IssueAtomicTx( + tx *evm.Tx, + options ...common.Option, +) error { + return w.Wallet.IssueAtomicTx( + tx, + common.UnionOptions(w.options, options)..., + ) +} diff --git a/wallet/subnet/primary/api.go b/wallet/subnet/primary/api.go index 00ebea6090fd..3ac72c217884 100644 --- a/wallet/subnet/primary/api.go +++ b/wallet/subnet/primary/api.go @@ -5,11 +5,12 @@ package primary import ( "context" - // "fmt" + "fmt" - // "github.com/ava-labs/coreth/ethclient" + "github.com/ava-labs/coreth/ethclient" + "github.com/ava-labs/coreth/plugin/evm" - // "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common" "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/codec" @@ -21,8 +22,7 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - - // "github.com/ava-labs/avalanchego/wallet/chain/c" + "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/x" ) @@ -59,9 +59,9 @@ type AVAXState struct { PCTX p.Context XClient avm.Client XCTX x.Context - // CClient evm.Client - // CCTX c.Context - UTXOs UTXOs + CClient evm.Client + CCTX c.Context + UTXOs UTXOs } func FetchState( @@ -75,7 +75,7 @@ func FetchState( infoClient := info.NewClient(uri) pClient := platformvm.NewClient(uri) xClient := avm.NewClient(uri, "X") - // cClient := evm.NewCChainClient(uri) + cClient := evm.NewCChainClient(uri) pCTX, err := p.NewContextFromClients(ctx, infoClient, xClient) if err != nil { @@ -87,10 +87,10 @@ func FetchState( return nil, err } - // cCTX, err := c.NewContextFromClients(ctx, infoClient, xClient) - // if err != nil { - // return nil, err - // } + cCTX, err := c.NewContextFromClients(ctx, infoClient, xClient) + if err != nil { + return nil, err + } utxos := NewUTXOs() addrList := addrs.List() @@ -109,11 +109,11 @@ func FetchState( client: xClient, codec: x.Parser.Codec(), }, - // { - // id: cCTX.BlockchainID(), - // client: cClient, - // codec: evm.Codec, - // }, + { + id: cCTX.BlockchainID(), + client: cClient, + codec: evm.Codec, + }, } for _, destinationChain := range chains { for _, sourceChain := range chains { @@ -136,52 +136,52 @@ func FetchState( PCTX: pCTX, XClient: xClient, XCTX: xCTX, - // CClient: cClient, - // CCTX: cCTX, - UTXOs: utxos, + CClient: cClient, + CCTX: cCTX, + UTXOs: utxos, }, nil } -// type EthState struct { -// Client ethclient.Client -// Accounts map[common.Address]*c.Account -// } - -// func FetchEthState( -// ctx context.Context, -// uri string, -// addrs set.Set[common.Address], -// ) (*EthState, error) { -// path := fmt.Sprintf( -// "%s/ext/%s/C/rpc", -// uri, -// constants.ChainAliasPrefix, -// ) -// client, err := ethclient.Dial(path) -// if err != nil { -// return nil, err -// } - -// accounts := make(map[common.Address]*c.Account, addrs.Len()) -// for addr := range addrs { -// balance, err := client.BalanceAt(ctx, addr, nil) -// if err != nil { -// return nil, err -// } -// nonce, err := client.NonceAt(ctx, addr, nil) -// if err != nil { -// return nil, err -// } -// accounts[addr] = &c.Account{ -// Balance: balance, -// Nonce: nonce, -// } -// } -// return &EthState{ -// Client: client, -// Accounts: accounts, -// }, nil -// } +type EthState struct { + Client ethclient.Client + Accounts map[common.Address]*c.Account +} + +func FetchEthState( + ctx context.Context, + uri string, + addrs set.Set[common.Address], +) (*EthState, error) { + path := fmt.Sprintf( + "%s/ext/%s/C/rpc", + uri, + constants.ChainAliasPrefix, + ) + client, err := ethclient.Dial(path) + if err != nil { + return nil, err + } + + accounts := make(map[common.Address]*c.Account, addrs.Len()) + for addr := range addrs { + balance, err := client.BalanceAt(ctx, addr, nil) + if err != nil { + return nil, err + } + nonce, err := client.NonceAt(ctx, addr, nil) + if err != nil { + return nil, err + } + accounts[addr] = &c.Account{ + Balance: balance, + Nonce: nonce, + } + } + return &EthState{ + Client: client, + Accounts: accounts, + }, nil +} // AddAllUTXOs fetches all the UTXOs referenced by [addresses] that were sent // from [sourceChainID] to [destinationChainID] from the [client]. It then uses diff --git a/wallet/subnet/primary/example_test.go b/wallet/subnet/primary/example_test.go index 4a73e8c070b2..483c049d4ac0 100644 --- a/wallet/subnet/primary/example_test.go +++ b/wallet/subnet/primary/example_test.go @@ -30,7 +30,7 @@ func ExampleWallet() { wallet, err := MakeWallet(ctx, &WalletConfig{ URI: LocalAPIURI, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet with: %s\n", err) diff --git a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go index 21c081d2982b..d5e8ce422307 100644 --- a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go +++ b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go @@ -46,9 +46,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - // EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/examples/add-primary-validator/main.go b/wallet/subnet/primary/examples/add-primary-validator/main.go index 13c28f995f63..a56dae23db3a 100644 --- a/wallet/subnet/primary/examples/add-primary-validator/main.go +++ b/wallet/subnet/primary/examples/add-primary-validator/main.go @@ -45,7 +45,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/c-chain-export/main.go b/wallet/subnet/primary/examples/c-chain-export/main.go index a6b9a0c810b8..fec55c899feb 100644 --- a/wallet/subnet/primary/examples/c-chain-export/main.go +++ b/wallet/subnet/primary/examples/c-chain-export/main.go @@ -3,70 +3,70 @@ package main -// import ( -// "context" -// "log" -// "time" +import ( + "context" + "log" + "time" -// "github.com/ava-labs/avalanchego/genesis" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary" -// ) + "github.com/ava-labs/avalanchego/genesis" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary" +) -// func main() { -// key := genesis.EWOQKey -// uri := primary.LocalAPIURI -// kc := secp256k1fx.NewKeychain(key) -// avaxAddr := key.Address() +func main() { + key := genesis.EWOQKey + uri := primary.LocalAPIURI + kc := secp256k1fx.NewKeychain(key) + avaxAddr := key.Address() -// ctx := context.Background() + ctx := context.Background() -// // MakeWallet fetches the available UTXOs owned by [kc] on the network that -// // [uri] is hosting. -// walletSyncStartTime := time.Now() -// wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ -// URI: uri, -// AVAXKeychain: kc, -// EthKeychain: kc, -// }) -// if err != nil { -// log.Fatalf("failed to initialize wallet: %s\n", err) -// } -// log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) + // MakeWallet fetches the available UTXOs owned by [kc] on the network that + // [uri] is hosting. + walletSyncStartTime := time.Now() + wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, + }) + if err != nil { + log.Fatalf("failed to initialize wallet: %s\n", err) + } + log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) -// // Get the P-chain wallet -// pWallet := wallet.P() -// cWallet := wallet.C() + // Get the P-chain wallet + pWallet := wallet.P() + cWallet := wallet.C() -// // Pull out useful constants to use when issuing transactions. -// cChainID := cWallet.BlockchainID() -// owner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// avaxAddr, -// }, -// } + // Pull out useful constants to use when issuing transactions. + cChainID := cWallet.BlockchainID() + owner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + avaxAddr, + }, + } -// exportStartTime := time.Now() -// exportTx, err := cWallet.IssueExportTx( -// constants.PlatformChainID, -// []*secp256k1fx.TransferOutput{{ -// Amt: units.Avax, -// OutputOwners: owner, -// }}, -// ) -// if err != nil { -// log.Fatalf("failed to issue export transaction: %s\n", err) -// } -// log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) + exportStartTime := time.Now() + exportTx, err := cWallet.IssueExportTx( + constants.PlatformChainID, + []*secp256k1fx.TransferOutput{{ + Amt: units.Avax, + OutputOwners: owner, + }}, + ) + if err != nil { + log.Fatalf("failed to issue export transaction: %s\n", err) + } + log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) -// importStartTime := time.Now() -// importTx, err := pWallet.IssueImportTx(cChainID, &owner) -// if err != nil { -// log.Fatalf("failed to issue import transaction: %s\n", err) -// } -// log.Printf("issued import %s in %s\n", importTx.ID(), time.Since(importStartTime)) -// } + importStartTime := time.Now() + importTx, err := pWallet.IssueImportTx(cChainID, &owner) + if err != nil { + log.Fatalf("failed to issue import transaction: %s\n", err) + } + log.Printf("issued import %s in %s\n", importTx.ID(), time.Since(importStartTime)) +} diff --git a/wallet/subnet/primary/examples/c-chain-import/main.go b/wallet/subnet/primary/examples/c-chain-import/main.go index 2d9b8a244cb0..b4dc4e603eb3 100644 --- a/wallet/subnet/primary/examples/c-chain-import/main.go +++ b/wallet/subnet/primary/examples/c-chain-import/main.go @@ -3,75 +3,75 @@ package main -// import ( -// "context" -// "log" -// "time" +import ( + "context" + "log" + "time" -// "github.com/ava-labs/coreth/plugin/evm" + "github.com/ava-labs/coreth/plugin/evm" -// "github.com/ava-labs/avalanchego/genesis" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary" -// ) + "github.com/ava-labs/avalanchego/genesis" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary" +) -// func main() { -// key := genesis.EWOQKey -// uri := primary.LocalAPIURI -// kc := secp256k1fx.NewKeychain(key) -// avaxAddr := key.Address() -// ethAddr := evm.PublicKeyToEthAddress(key.PublicKey()) +func main() { + key := genesis.EWOQKey + uri := primary.LocalAPIURI + kc := secp256k1fx.NewKeychain(key) + avaxAddr := key.Address() + ethAddr := evm.PublicKeyToEthAddress(key.PublicKey()) -// ctx := context.Background() + ctx := context.Background() -// // MakeWallet fetches the available UTXOs owned by [kc] on the network that -// // [uri] is hosting. -// walletSyncStartTime := time.Now() -// wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ -// URI: uri, -// AVAXKeychain: kc, -// EthKeychain: kc, -// }) -// if err != nil { -// log.Fatalf("failed to initialize wallet: %s\n", err) -// } -// log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) + // MakeWallet fetches the available UTXOs owned by [kc] on the network that + // [uri] is hosting. + walletSyncStartTime := time.Now() + wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, + }) + if err != nil { + log.Fatalf("failed to initialize wallet: %s\n", err) + } + log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) -// // Get the P-chain wallet -// pWallet := wallet.P() -// cWallet := wallet.C() + // Get the P-chain wallet + pWallet := wallet.P() + cWallet := wallet.C() -// // Pull out useful constants to use when issuing transactions. -// cChainID := cWallet.BlockchainID() -// avaxAssetID := cWallet.AVAXAssetID() -// owner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// avaxAddr, -// }, -// } + // Pull out useful constants to use when issuing transactions. + cChainID := cWallet.BlockchainID() + avaxAssetID := cWallet.AVAXAssetID() + owner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + avaxAddr, + }, + } -// exportStartTime := time.Now() -// exportTx, err := pWallet.IssueExportTx(cChainID, []*avax.TransferableOutput{{ -// Asset: avax.Asset{ID: avaxAssetID}, -// Out: &secp256k1fx.TransferOutput{ -// Amt: units.Avax, -// OutputOwners: owner, -// }, -// }}) -// if err != nil { -// log.Fatalf("failed to issue export transaction: %s\n", err) -// } -// log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) + exportStartTime := time.Now() + exportTx, err := pWallet.IssueExportTx(cChainID, []*avax.TransferableOutput{{ + Asset: avax.Asset{ID: avaxAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: units.Avax, + OutputOwners: owner, + }, + }}) + if err != nil { + log.Fatalf("failed to issue export transaction: %s\n", err) + } + log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) -// importStartTime := time.Now() -// importTx, err := cWallet.IssueImportTx(constants.PlatformChainID, ethAddr) -// if err != nil { -// log.Fatalf("failed to issue import transaction: %s\n", err) -// } -// log.Printf("issued import %s to %s in %s\n", importTx.ID(), ethAddr.Hex(), time.Since(importStartTime)) -// } + importStartTime := time.Now() + importTx, err := cWallet.IssueImportTx(constants.PlatformChainID, ethAddr) + if err != nil { + log.Fatalf("failed to issue import transaction: %s\n", err) + } + log.Printf("issued import %s to %s in %s\n", importTx.ID(), ethAddr.Hex(), time.Since(importStartTime)) +} diff --git a/wallet/subnet/primary/examples/create-asset/main.go b/wallet/subnet/primary/examples/create-asset/main.go index 0bccfbb5fc52..30804f083df6 100644 --- a/wallet/subnet/primary/examples/create-asset/main.go +++ b/wallet/subnet/primary/examples/create-asset/main.go @@ -30,7 +30,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/create-chain/main.go b/wallet/subnet/primary/examples/create-chain/main.go index 521a3cca53cf..5e6898a1b649 100644 --- a/wallet/subnet/primary/examples/create-chain/main.go +++ b/wallet/subnet/primary/examples/create-chain/main.go @@ -41,9 +41,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - // EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/examples/create-locked-stakeable/main.go b/wallet/subnet/primary/examples/create-locked-stakeable/main.go index 92f1b5cb0e1b..e688968e9e8a 100644 --- a/wallet/subnet/primary/examples/create-locked-stakeable/main.go +++ b/wallet/subnet/primary/examples/create-locked-stakeable/main.go @@ -39,7 +39,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/create-subnet/main.go b/wallet/subnet/primary/examples/create-subnet/main.go index 3e8d69bc016a..add98ea7931c 100644 --- a/wallet/subnet/primary/examples/create-subnet/main.go +++ b/wallet/subnet/primary/examples/create-subnet/main.go @@ -28,7 +28,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/remove-subnet-validator/main.go b/wallet/subnet/primary/examples/remove-subnet-validator/main.go index 46f4b85124db..2842c7c0a790 100644 --- a/wallet/subnet/primary/examples/remove-subnet-validator/main.go +++ b/wallet/subnet/primary/examples/remove-subnet-validator/main.go @@ -38,9 +38,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - // EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/wallet.go b/wallet/subnet/primary/wallet.go index ae5e4202a099..54de390d029c 100644 --- a/wallet/subnet/primary/wallet.go +++ b/wallet/subnet/primary/wallet.go @@ -11,8 +11,7 @@ import ( "github.com/ava-labs/avalanchego/utils/crypto/keychain" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - - // "github.com/ava-labs/avalanchego/wallet/chain/c" + "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/x" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -24,13 +23,13 @@ var _ Wallet = (*wallet)(nil) type Wallet interface { P() p.Wallet X() x.Wallet - // C() c.Wallet + C() c.Wallet } type wallet struct { p p.Wallet x x.Wallet - // c c.Wallet + c c.Wallet } func (w *wallet) P() p.Wallet { @@ -41,16 +40,16 @@ func (w *wallet) X() x.Wallet { return w.x } -// func (w *wallet) C() c.Wallet { -// return w.c -// } +func (w *wallet) C() c.Wallet { + return w.c +} // Creates a new default wallet -func NewWallet(p p.Wallet, x x.Wallet /*, c c.Wallet*/) Wallet { +func NewWallet(p p.Wallet, x x.Wallet, c c.Wallet) Wallet { return &wallet{ p: p, x: x, - // c: c, + c: c, } } @@ -59,7 +58,7 @@ func NewWalletWithOptions(w Wallet, options ...common.Option) Wallet { return NewWallet( p.NewWalletWithOptions(w.P(), options...), x.NewWalletWithOptions(w.X(), options...), - // c.NewWalletWithOptions(w.C(), options...), + c.NewWalletWithOptions(w.C(), options...), ) } @@ -68,7 +67,7 @@ type WalletConfig struct { URI string // required // Keys to use for signing all transactions. AVAXKeychain keychain.Keychain // required - // EthKeychain c.EthKeychain // required + EthKeychain c.EthKeychain // required // Set of P-chain transactions that the wallet should know about to be able // to generate transactions. PChainTxs map[ids.ID]*txs.Tx // optional @@ -94,11 +93,11 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { return nil, err } - // ethAddrs := config.EthKeychain.EthAddresses() - // ethState, err := FetchEthState(ctx, config.URI, ethAddrs) - // if err != nil { - // return nil, err - // } + ethAddrs := config.EthKeychain.EthAddresses() + ethState, err := FetchEthState(ctx, config.URI, ethAddrs) + if err != nil { + return nil, err + } pChainTxs := config.PChainTxs if pChainTxs == nil { @@ -128,15 +127,15 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { xBuilder := x.NewBuilder(avaxAddrs, xBackend) xSigner := x.NewSigner(config.AVAXKeychain, xBackend) - // cChainID := avaxState.CCTX.BlockchainID() - // cUTXOs := NewChainUTXOs(cChainID, avaxState.UTXOs) - // cBackend := c.NewBackend(avaxState.CCTX, cUTXOs, ethState.Accounts) - // cBuilder := c.NewBuilder(avaxAddrs, ethAddrs, cBackend) - // cSigner := c.NewSigner(config.AVAXKeychain, config.EthKeychain, cBackend) + cChainID := avaxState.CCTX.BlockchainID() + cUTXOs := NewChainUTXOs(cChainID, avaxState.UTXOs) + cBackend := c.NewBackend(avaxState.CCTX, cUTXOs, ethState.Accounts) + cBuilder := c.NewBuilder(avaxAddrs, ethAddrs, cBackend) + cSigner := c.NewSigner(config.AVAXKeychain, config.EthKeychain, cBackend) return NewWallet( p.NewWallet(pBuilder, pSigner, avaxState.PClient, pBackend), x.NewWallet(xBuilder, xSigner, avaxState.XClient, xBackend), - // c.NewWallet(cBuilder, cSigner, avaxState.CClient, ethState.Client, cBackend), + c.NewWallet(cBuilder, cSigner, avaxState.CClient, ethState.Client, cBackend), ), nil } From 143934ec169fa68eeca7884248a5c33fe3f55329 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 30 Oct 2023 08:28:32 +0100 Subject: [PATCH 06/13] temporarily cut coreth dependency --- go.mod | 25 - go.sum | 76 -- node/node.go | 4 +- tests/e2e/c/dynamic_fees.go | 326 +++---- tests/e2e/c/interchain_workflow.go | 320 +++---- tests/e2e/p/interchain_workflow.go | 444 +++++----- tests/e2e/x/interchain_workflow.go | 296 +++---- tests/fixture/e2e/helpers.go | 123 +-- tests/fixture/tmpnet/config.go | 56 +- vms/example/xsvm/cmd/chain/create/cmd.go | 6 +- wallet/chain/c/backend.go | 300 +++---- wallet/chain/c/builder.go | 792 +++++++++--------- wallet/chain/c/builder_with_options.go | 136 +-- wallet/chain/c/context.go | 130 +-- wallet/chain/c/signer.go | 436 +++++----- wallet/chain/c/wallet.go | 402 ++++----- wallet/chain/c/wallet_with_options.go | 134 +-- wallet/subnet/primary/api.go | 122 +-- wallet/subnet/primary/example_test.go | 2 +- .../add-permissioned-subnet-validator/main.go | 6 +- .../examples/add-primary-validator/main.go | 2 +- .../primary/examples/c-chain-export/main.go | 118 +-- .../primary/examples/c-chain-import/main.go | 126 +-- .../primary/examples/create-asset/main.go | 2 +- .../primary/examples/create-chain/main.go | 6 +- .../examples/create-locked-stakeable/main.go | 2 +- .../primary/examples/create-subnet/main.go | 2 +- .../examples/remove-subnet-validator/main.go | 6 +- wallet/subnet/primary/wallet.go | 43 +- 29 files changed, 2173 insertions(+), 2270 deletions(-) diff --git a/go.mod b/go.mod index 9a629725cdef..23b752198fdd 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,6 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 - github.com/ava-labs/coreth v0.12.9-rc.7 github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 @@ -75,7 +74,6 @@ require ( github.com/BurntSushi/toml v1.2.1 // indirect github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect - github.com/VictoriaMetrics/fastcache v1.10.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect @@ -83,44 +81,26 @@ require ( github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/redact v1.1.3 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/deckarep/golang-set/v2 v2.1.0 // indirect - github.com/dlclark/regexp2 v1.7.0 // indirect - github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 // indirect - github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect github.com/frankban/quicktest v1.14.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/getsentry/sentry-go v0.18.0 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect - github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect - github.com/go-stack/stack v1.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/go-cmp v0.5.9 // indirect - github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect - github.com/google/uuid v1.3.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 // indirect - github.com/hashicorp/go-bexpr v0.1.10 // indirect - github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e // indirect github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/klauspost/compress v1.15.15 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/magiconair/properties v1.8.6 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect - github.com/mattn/go-runewidth v0.0.9 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/mitchellh/pointerstructure v1.2.0 // indirect - github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -128,17 +108,12 @@ require ( github.com/prometheus/common v0.39.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sanity-io/litter v1.5.1 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/status-im/keycard-go v0.2.0 // indirect github.com/subosito/gotenv v1.3.0 // indirect github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tklauser/numcpus v0.2.2 // indirect - github.com/tyler-smith/go-bip39 v1.1.0 // indirect - github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa // indirect - github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect diff --git a/go.sum b/go.sum index 3478c17b2d6b..2ae152b17faf 100644 --- a/go.sum +++ b/go.sum @@ -56,18 +56,12 @@ github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cq github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= -github.com/VictoriaMetrics/fastcache v1.10.0 h1:5hDJnLsKLpnUEToub7ETuRu8RCkb40woBZAUiKonXzY= -github.com/VictoriaMetrics/fastcache v1.10.0/go.mod h1:tjiYeEfYXCqacuvYw/7UoDIeJaNxq6132xHICNP77w8= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/coreth v0.12.9-rc.7 h1:AlCmXnrJwo0NxlEXQHysQgRQSCA14PZW6iyJmeVYB34= -github.com/ava-labs/coreth v0.12.9-rc.7/go.mod h1:yrf2vEah4Fgj6sJ4UpHewo4DLolwdpf2bJuLRT80PGw= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= @@ -102,18 +96,13 @@ github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46f github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw= github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA= @@ -145,16 +134,12 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= -github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= @@ -165,14 +150,6 @@ github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6ps github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= -github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= -github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 h1:+3HCtB74++ClLy8GgjUQYeC8R4ILzVcIe8+5edAJJnE= -github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= -github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= -github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -189,8 +166,6 @@ github.com/ethereum/go-ethereum v1.12.0 h1:bdnhLPtqETd4m3mS8BGMNvBTf36bO5bx/hxE2 github.com/ethereum/go-ethereum v1.12.0/go.mod h1:/oo2X/dZLJjf2mJ6YT9wcWxa4nNJDBKDBU6sFIpx1Gs= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -199,8 +174,6 @@ github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmV github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= -github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= -github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= @@ -224,11 +197,7 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= -github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= -github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= @@ -313,14 +282,10 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= -github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= @@ -341,17 +306,11 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 h1:kr3j8iIMR4ywO/O0rvksXaJvauGGCMg2zAZIiNZ9uIQ= github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0/go.mod h1:ummNFgdgLhhX7aIiy35vVmQNS0rWXknfPE0qe6fmFXg= -github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= -github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e h1:pIYdhNkDh+YENVNi3gto8n9hAmRxKxoar0iE6BLucjw= -github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e/go.mod h1:j9cQbcqHQujT0oKJ38PylVfqohClLr3CvDC+Qcg+lhU= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c h1:DZfsyhDK1hnSS5lH8l+JggqzEleHteTYfutAiVlSUM8= @@ -363,7 +322,6 @@ github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3 github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -405,7 +363,6 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -413,7 +370,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= @@ -424,17 +380,11 @@ github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPK github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= @@ -443,11 +393,8 @@ github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= -github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -466,8 +413,6 @@ github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= -github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -535,8 +480,6 @@ github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sanity-io/litter v1.5.1 h1:dwnrSypP6q56o3lFxTU+t2fwQ9A+U5qrXVO4Qg9KwVU= github.com/sanity-io/litter v1.5.1/go.mod h1:5Z71SvaYy5kcGtyglXOC9rrUi3c1E8CamFWjQsazTh0= @@ -572,8 +515,6 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= -github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= -github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -605,14 +546,10 @@ github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZF github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE= github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE= -github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= -github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa h1:5SqCsI/2Qya2bCzK15ozrqo2sZxkh0FHynJZOTVoV6Q= -github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= @@ -624,8 +561,6 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= @@ -635,7 +570,6 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= @@ -731,7 +665,6 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -777,7 +710,6 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -801,7 +733,6 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -866,12 +797,8 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -888,7 +815,6 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -952,7 +878,6 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1077,7 +1002,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= diff --git a/node/node.go b/node/node.go index 40eb8dc16bef..d8905719fa6e 100644 --- a/node/node.go +++ b/node/node.go @@ -25,7 +25,7 @@ import ( "go.uber.org/zap" - coreth "github.com/ava-labs/coreth/plugin/evm" + // coreth "github.com/ava-labs/coreth/plugin/evm" "github.com/ava-labs/avalanchego/api/admin" "github.com/ava-labs/avalanchego/api/auth" @@ -1094,7 +1094,7 @@ func (n *Node) initVMs() error { CreateAssetTxFee: n.Config.CreateAssetTxFee, }, }), - vmRegisterer.Register(context.TODO(), constants.EVMID, &coreth.Factory{}), + // vmRegisterer.Register(context.TODO(), constants.EVMID, &coreth.Factory{}), n.VMManager.RegisterFactory(context.TODO(), secp256k1fx.ID, &secp256k1fx.Factory{}), n.VMManager.RegisterFactory(context.TODO(), nftfx.ID, &nftfx.Factory{}), n.VMManager.RegisterFactory(context.TODO(), propertyfx.ID, &propertyfx.Factory{}), diff --git a/tests/e2e/c/dynamic_fees.go b/tests/e2e/c/dynamic_fees.go index 38bbd668079b..8748dda7451d 100644 --- a/tests/e2e/c/dynamic_fees.go +++ b/tests/e2e/c/dynamic_fees.go @@ -3,166 +3,166 @@ package c -import ( - "math/big" - "strings" - - ginkgo "github.com/onsi/ginkgo/v2" - - "github.com/stretchr/testify/require" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/plugin/evm" - - "github.com/ava-labs/avalanchego/tests" - "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -) - -// This test uses the compiled bin for `hashing.sol` as -// well as its ABI contained in `hashing_contract.go`. - -var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { - require := require.New(ginkgo.GinkgoT()) - - // Need a gas limit much larger than the standard 21_000 to enable - // the contract to induce a gas price increase - const largeGasLimit = uint64(8_000_000) - - // TODO(marun) What is the significance of this value? - gasTip := big.NewInt(1000 * params.GWei) - - ginkgo.It("should ensure that the gas price is affected by load", func() { - ginkgo.By("creating a new private network to ensure isolation from other tests") - privateNetwork := e2e.Env.NewPrivateNetwork() - - ginkgo.By("allocating a pre-funded key") - key := privateNetwork.GetConfig().FundedKeys[0] - ethAddress := evm.GetEthAddress(key) - - ginkgo.By("initializing a coreth client") - node := privateNetwork.GetNodes()[0] - nodeURI := tmpnet.NodeURI{ - NodeID: node.GetID(), - URI: node.GetProcessContext().URI, - } - ethClient := e2e.NewEthClient(nodeURI) - - ginkgo.By("initializing a transaction signer") - cChainID, err := ethClient.ChainID(e2e.DefaultContext()) - require.NoError(err) - signer := types.NewEIP155Signer(cChainID) - ecdsaKey := key.ToECDSA() - sign := func(tx *types.Transaction) *types.Transaction { - signedTx, err := types.SignTx(tx, signer, ecdsaKey) - require.NoError(err) - return signedTx - } - - var contractAddress common.Address - ginkgo.By("deploying an expensive contract", func() { - // Create transaction - nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) - require.NoError(err) - compiledContract := common.Hex2Bytes(hashingCompiledContract) - tx := types.NewTx(&types.LegacyTx{ - Nonce: nonce, - GasPrice: gasTip, - Gas: largeGasLimit, - Value: common.Big0, - Data: compiledContract, - }) - - // Send the transaction and wait for acceptance - signedTx := sign(tx) - receipt := e2e.SendEthTransaction(ethClient, signedTx) - - contractAddress = receipt.ContractAddress - }) - - var gasPrice *big.Int - ginkgo.By("calling the expensive contract repeatedly until a gas price increase is detected", func() { - // Evaluate the bytes representation of the contract - hashingABI, err := abi.JSON(strings.NewReader(hashingABIJson)) - require.NoError(err) - contractData, err := hashingABI.Pack("hashIt") - require.NoError(err) - - var initialGasPrice *big.Int - e2e.Eventually(func() bool { - // Check the gas price - var err error - gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) - require.NoError(err) - if initialGasPrice == nil { - initialGasPrice = gasPrice - tests.Outf("{{blue}}initial gas price is %v{{/}}\n", initialGasPrice) - } else if gasPrice.Cmp(initialGasPrice) > 0 { - // Gas price has increased - tests.Outf("{{blue}}gas price has increased to %v{{/}}\n", gasPrice) - return true - } - - // Create the transaction - nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) - require.NoError(err) - tx := types.NewTx(&types.LegacyTx{ - Nonce: nonce, - GasPrice: gasTip, - Gas: largeGasLimit, - To: &contractAddress, - Value: common.Big0, - Data: contractData, - }) - - // Send the transaction and wait for acceptance - signedTx := sign(tx) - _ = e2e.SendEthTransaction(ethClient, signedTx) - - // The gas price will be checked at the start of the next iteration - return false - }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price increase before timeout") - }) - - ginkgo.By("waiting for the gas price to decrease...", func() { - initialGasPrice := gasPrice - e2e.Eventually(func() bool { - var err error - gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) - require.NoError(err) - tests.Outf("{{blue}}.{{/}}") - return initialGasPrice.Cmp(gasPrice) > 0 - }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price decrease before timeout") - tests.Outf("\n{{blue}}gas price has decreased to %v{{/}}\n", gasPrice) - }) - - ginkgo.By("sending funds at the current gas price", func() { - // Create a recipient address - recipientKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - recipientEthAddress := evm.GetEthAddress(recipientKey) - - // Create transaction - nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) - require.NoError(err) - tx := types.NewTx(&types.LegacyTx{ - Nonce: nonce, - GasPrice: gasPrice, - Gas: e2e.DefaultGasLimit, - To: &recipientEthAddress, - Value: common.Big0, - }) - - // Send the transaction and wait for acceptance - signedTx := sign(tx) - _ = e2e.SendEthTransaction(ethClient, signedTx) - }) - - e2e.CheckBootstrapIsPossible(privateNetwork) - }) -}) +// import ( +// "math/big" +// "strings" + +// ginkgo "github.com/onsi/ginkgo/v2" + +// "github.com/stretchr/testify/require" + +// "github.com/ethereum/go-ethereum/accounts/abi" +// "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/coreth/core/types" +// "github.com/ava-labs/coreth/params" +// "github.com/ava-labs/coreth/plugin/evm" + +// "github.com/ava-labs/avalanchego/tests" +// "github.com/ava-labs/avalanchego/tests/e2e" +// "github.com/ava-labs/avalanchego/tests/fixture/testnet" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// ) + +// // This test uses the compiled bin for `hashing.sol` as +// // well as its ABI contained in `hashing_contract.go`. + +// var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { +// require := require.New(ginkgo.GinkgoT()) + +// // Need a gas limit much larger than the standard 21_000 to enable +// // the contract to induce a gas price increase +// const largeGasLimit = uint64(8_000_000) + +// // TODO(marun) What is the significance of this value? +// gasTip := big.NewInt(1000 * params.GWei) + +// ginkgo.It("should ensure that the gas price is affected by load", func() { +// ginkgo.By("creating a new private network to ensure isolation from other tests") +// privateNetwork := e2e.Env.NewPrivateNetwork() + +// ginkgo.By("allocating a pre-funded key") +// key := privateNetwork.GetConfig().FundedKeys[0] +// ethAddress := evm.GetEthAddress(key) + +// ginkgo.By("initializing a coreth client") +// node := privateNetwork.GetNodes()[0] +// nodeURI := testnet.NodeURI{ +// NodeID: node.GetID(), +// URI: node.GetProcessContext().URI, +// } +// ethClient := e2e.NewEthClient(nodeURI) + +// ginkgo.By("initializing a transaction signer") +// cChainID, err := ethClient.ChainID(e2e.DefaultContext()) +// require.NoError(err) +// signer := types.NewEIP155Signer(cChainID) +// ecdsaKey := key.ToECDSA() +// sign := func(tx *types.Transaction) *types.Transaction { +// signedTx, err := types.SignTx(tx, signer, ecdsaKey) +// require.NoError(err) +// return signedTx +// } + +// var contractAddress common.Address +// ginkgo.By("deploying an expensive contract", func() { +// // Create transaction +// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) +// require.NoError(err) +// compiledContract := common.Hex2Bytes(hashingCompiledContract) +// tx := types.NewTx(&types.LegacyTx{ +// Nonce: nonce, +// GasPrice: gasTip, +// Gas: largeGasLimit, +// Value: common.Big0, +// Data: compiledContract, +// }) + +// // Send the transaction and wait for acceptance +// signedTx := sign(tx) +// receipt := e2e.SendEthTransaction(ethClient, signedTx) + +// contractAddress = receipt.ContractAddress +// }) + +// var gasPrice *big.Int +// ginkgo.By("calling the expensive contract repeatedly until a gas price increase is detected", func() { +// // Evaluate the bytes representation of the contract +// hashingABI, err := abi.JSON(strings.NewReader(hashingABIJson)) +// require.NoError(err) +// contractData, err := hashingABI.Pack("hashIt") +// require.NoError(err) + +// var initialGasPrice *big.Int +// e2e.Eventually(func() bool { +// // Check the gas price +// var err error +// gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) +// require.NoError(err) +// if initialGasPrice == nil { +// initialGasPrice = gasPrice +// tests.Outf("{{blue}}initial gas price is %v{{/}}\n", initialGasPrice) +// } else if gasPrice.Cmp(initialGasPrice) > 0 { +// // Gas price has increased +// tests.Outf("{{blue}}gas price has increased to %v{{/}}\n", gasPrice) +// return true +// } + +// // Create the transaction +// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) +// require.NoError(err) +// tx := types.NewTx(&types.LegacyTx{ +// Nonce: nonce, +// GasPrice: gasTip, +// Gas: largeGasLimit, +// To: &contractAddress, +// Value: common.Big0, +// Data: contractData, +// }) + +// // Send the transaction and wait for acceptance +// signedTx := sign(tx) +// _ = e2e.SendEthTransaction(ethClient, signedTx) + +// // The gas price will be checked at the start of the next iteration +// return false +// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price increase before timeout") +// }) + +// ginkgo.By("waiting for the gas price to decrease...", func() { +// initialGasPrice := gasPrice +// e2e.Eventually(func() bool { +// var err error +// gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) +// require.NoError(err) +// tests.Outf("{{blue}}.{{/}}") +// return initialGasPrice.Cmp(gasPrice) > 0 +// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price decrease before timeout") +// tests.Outf("\n{{blue}}gas price has decreased to %v{{/}}\n", gasPrice) +// }) + +// ginkgo.By("sending funds at the current gas price", func() { +// // Create a recipient address +// recipientKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) +// recipientEthAddress := evm.GetEthAddress(recipientKey) + +// // Create transaction +// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) +// require.NoError(err) +// tx := types.NewTx(&types.LegacyTx{ +// Nonce: nonce, +// GasPrice: gasPrice, +// Gas: e2e.DefaultGasLimit, +// To: &recipientEthAddress, +// Value: common.Big0, +// }) + +// // Send the transaction and wait for acceptance +// signedTx := sign(tx) +// _ = e2e.SendEthTransaction(ethClient, signedTx) +// }) + +// e2e.CheckBootstrapIsPossible(privateNetwork) +// }) +// }) diff --git a/tests/e2e/c/interchain_workflow.go b/tests/e2e/c/interchain_workflow.go index 2c9bd198ec39..c5af17c750bf 100644 --- a/tests/e2e/c/interchain_workflow.go +++ b/tests/e2e/c/interchain_workflow.go @@ -3,163 +3,163 @@ package c -import ( - "math/big" - - ginkgo "github.com/onsi/ginkgo/v2" - - "github.com/stretchr/testify/require" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/plugin/evm" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var _ = e2e.DescribeCChain("[Interchain Workflow]", func() { - require := require.New(ginkgo.GinkgoT()) - - const txAmount = 10 * units.Avax // Arbitrary amount to send and transfer - - ginkgo.It("should ensure that funds can be transferred from the C-Chain to the X-Chain and the P-Chain", func() { - ginkgo.By("initializing a new eth client") - // Select a random node URI to use for both the eth client and - // the wallet to avoid having to verify that all nodes are at - // the same height before initializing the wallet. - nodeURI := e2e.Env.GetRandomNodeURI() - ethClient := e2e.NewEthClient(nodeURI) - - ginkgo.By("allocating a pre-funded key to send from and a recipient key to deliver to") - senderKey := e2e.Env.AllocateFundedKey() - senderEthAddress := evm.GetEthAddress(senderKey) - recipientKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - recipientEthAddress := evm.GetEthAddress(recipientKey) - - ginkgo.By("sending funds from one address to another on the C-Chain", func() { - // Create transaction - acceptedNonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), senderEthAddress) - require.NoError(err) - gasPrice := e2e.SuggestGasPrice(ethClient) - tx := types.NewTransaction( - acceptedNonce, - recipientEthAddress, - big.NewInt(int64(txAmount)), - e2e.DefaultGasLimit, - gasPrice, - nil, - ) - - // Sign transaction - cChainID, err := ethClient.ChainID(e2e.DefaultContext()) - require.NoError(err) - signer := types.NewEIP155Signer(cChainID) - signedTx, err := types.SignTx(tx, signer, senderKey.ToECDSA()) - require.NoError(err) - - _ = e2e.SendEthTransaction(ethClient, signedTx) - - ginkgo.By("waiting for the C-Chain recipient address to have received the sent funds") - e2e.Eventually(func() bool { - balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) - require.NoError(err) - return balance.Cmp(big.NewInt(0)) > 0 - }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see funds delivered before timeout") - }) - - // Wallet must be initialized after sending funds on the - // C-Chain with the same node URI to ensure wallet state - // matches on-chain state. - ginkgo.By("initializing a keychain and associated wallet") - keychain := secp256k1fx.NewKeychain(senderKey, recipientKey) - baseWallet := e2e.NewWallet(keychain, nodeURI) - xWallet := baseWallet.X() - cWallet := baseWallet.C() - pWallet := baseWallet.P() - - ginkgo.By("defining common configuration") - avaxAssetID := xWallet.AVAXAssetID() - // Use the same owner for import funds to X-Chain and P-Chain - recipientOwner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - recipientKey.Address(), - }, - } - // Use the same outputs for both X-Chain and P-Chain exports - exportOutputs := []*secp256k1fx.TransferOutput{ - { - Amt: txAmount, - OutputOwners: secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - keychain.Keys[0].Address(), - }, - }, - }, - } - - ginkgo.By("exporting AVAX from the C-Chain to the X-Chain", func() { - _, err := cWallet.IssueExportTx( - xWallet.BlockchainID(), - exportOutputs, - e2e.WithDefaultContext(), - e2e.WithSuggestedGasPrice(ethClient), - ) - require.NoError(err) - }) - - ginkgo.By("importing AVAX from the C-Chain to the X-Chain", func() { - _, err := xWallet.IssueImportTx( - cWallet.BlockchainID(), - &recipientOwner, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { - balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - ginkgo.By("exporting AVAX from the C-Chain to the P-Chain", func() { - _, err := cWallet.IssueExportTx( - constants.PlatformChainID, - exportOutputs, - e2e.WithDefaultContext(), - e2e.WithSuggestedGasPrice(ethClient), - ) - require.NoError(err) - }) - - ginkgo.By("importing AVAX from the C-Chain to the P-Chain", func() { - _, err = pWallet.IssueImportTx( - cWallet.BlockchainID(), - &recipientOwner, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { - balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) - }) -}) +// import ( +// "math/big" + +// ginkgo "github.com/onsi/ginkgo/v2" + +// "github.com/stretchr/testify/require" + +// "github.com/ava-labs/coreth/core/types" +// "github.com/ava-labs/coreth/plugin/evm" + +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/tests/e2e" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var _ = e2e.DescribeCChain("[Interchain Workflow]", func() { +// require := require.New(ginkgo.GinkgoT()) + +// const txAmount = 10 * units.Avax // Arbitrary amount to send and transfer + +// ginkgo.It("should ensure that funds can be transferred from the C-Chain to the X-Chain and the P-Chain", func() { +// ginkgo.By("initializing a new eth client") +// // Select a random node URI to use for both the eth client and +// // the wallet to avoid having to verify that all nodes are at +// // the same height before initializing the wallet. +// nodeURI := e2e.Env.GetRandomNodeURI() +// ethClient := e2e.NewEthClient(nodeURI) + +// ginkgo.By("allocating a pre-funded key to send from and a recipient key to deliver to") +// senderKey := e2e.Env.AllocateFundedKey() +// senderEthAddress := evm.GetEthAddress(senderKey) +// recipientKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) +// recipientEthAddress := evm.GetEthAddress(recipientKey) + +// ginkgo.By("sending funds from one address to another on the C-Chain", func() { +// // Create transaction +// acceptedNonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), senderEthAddress) +// require.NoError(err) +// gasPrice := e2e.SuggestGasPrice(ethClient) +// tx := types.NewTransaction( +// acceptedNonce, +// recipientEthAddress, +// big.NewInt(int64(txAmount)), +// e2e.DefaultGasLimit, +// gasPrice, +// nil, +// ) + +// // Sign transaction +// cChainID, err := ethClient.ChainID(e2e.DefaultContext()) +// require.NoError(err) +// signer := types.NewEIP155Signer(cChainID) +// signedTx, err := types.SignTx(tx, signer, senderKey.ToECDSA()) +// require.NoError(err) + +// _ = e2e.SendEthTransaction(ethClient, signedTx) + +// ginkgo.By("waiting for the C-Chain recipient address to have received the sent funds") +// e2e.Eventually(func() bool { +// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) +// require.NoError(err) +// return balance.Cmp(big.NewInt(0)) > 0 +// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see funds delivered before timeout") +// }) + +// // Wallet must be initialized after sending funds on the +// // C-Chain with the same node URI to ensure wallet state +// // matches on-chain state. +// ginkgo.By("initializing a keychain and associated wallet") +// keychain := secp256k1fx.NewKeychain(senderKey, recipientKey) +// baseWallet := e2e.NewWallet(keychain, nodeURI) +// xWallet := baseWallet.X() +// cWallet := baseWallet.C() +// pWallet := baseWallet.P() + +// ginkgo.By("defining common configuration") +// avaxAssetID := xWallet.AVAXAssetID() +// // Use the same owner for import funds to X-Chain and P-Chain +// recipientOwner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// recipientKey.Address(), +// }, +// } +// // Use the same outputs for both X-Chain and P-Chain exports +// exportOutputs := []*secp256k1fx.TransferOutput{ +// { +// Amt: txAmount, +// OutputOwners: secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// keychain.Keys[0].Address(), +// }, +// }, +// }, +// } + +// ginkgo.By("exporting AVAX from the C-Chain to the X-Chain", func() { +// _, err := cWallet.IssueExportTx( +// xWallet.BlockchainID(), +// exportOutputs, +// e2e.WithDefaultContext(), +// e2e.WithSuggestedGasPrice(ethClient), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("importing AVAX from the C-Chain to the X-Chain", func() { +// _, err := xWallet.IssueImportTx( +// cWallet.BlockchainID(), +// &recipientOwner, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { +// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// ginkgo.By("exporting AVAX from the C-Chain to the P-Chain", func() { +// _, err := cWallet.IssueExportTx( +// constants.PlatformChainID, +// exportOutputs, +// e2e.WithDefaultContext(), +// e2e.WithSuggestedGasPrice(ethClient), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("importing AVAX from the C-Chain to the P-Chain", func() { +// _, err = pWallet.IssueImportTx( +// cWallet.BlockchainID(), +// &recipientOwner, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { +// balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) +// }) +// }) diff --git a/tests/e2e/p/interchain_workflow.go b/tests/e2e/p/interchain_workflow.go index 678f9b5cc204..e90e0382e286 100644 --- a/tests/e2e/p/interchain_workflow.go +++ b/tests/e2e/p/interchain_workflow.go @@ -3,225 +3,225 @@ package p -import ( - "math/big" - "time" - - ginkgo "github.com/onsi/ginkgo/v2" - - "github.com/spf13/cast" - - "github.com/stretchr/testify/require" - - "github.com/ava-labs/coreth/plugin/evm" - - "github.com/ava-labs/avalanchego/api/info" - "github.com/ava-labs/avalanchego/config" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/platformvm/reward" - "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { - require := require.New(ginkgo.GinkgoT()) - - const ( - transferAmount = 10 * units.Avax - weight = 2_000 * units.Avax // Used for both validation and delegation - ) - - ginkgo.It("should ensure that funds can be transferred from the P-Chain to the X-Chain and the C-Chain", func() { - network := e2e.Env.GetNetwork() - - ginkgo.By("checking that the network has a compatible minimum stake duration", func() { - minStakeDuration := cast.ToDuration(network.GetConfig().DefaultFlags[config.MinStakeDurationKey]) - require.Equal(tmpnet.DefaultMinStakeDuration, minStakeDuration) - }) - - ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") - recipientKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - keychain := e2e.Env.NewKeychain(1) - keychain.Add(recipientKey) - nodeURI := e2e.Env.GetRandomNodeURI() - baseWallet := e2e.NewWallet(keychain, nodeURI) - xWallet := baseWallet.X() - cWallet := baseWallet.C() - pWallet := baseWallet.P() - - ginkgo.By("defining common configuration") - recipientEthAddress := evm.GetEthAddress(recipientKey) - avaxAssetID := xWallet.AVAXAssetID() - // Use the same owner for sending to X-Chain and importing funds to P-Chain - recipientOwner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - recipientKey.Address(), - }, - } - // Use the same outputs for both X-Chain and C-Chain exports - exportOutputs := []*avax.TransferableOutput{ - { - Asset: avax.Asset{ - ID: avaxAssetID, - }, - Out: &secp256k1fx.TransferOutput{ - Amt: transferAmount, - OutputOwners: secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - keychain.Keys[0].Address(), - }, - }, - }, - }, - } - - ginkgo.By("adding new node and waiting for it to report healthy") - node := e2e.AddEphemeralNode(network, tmpnet.FlagsMap{}) - e2e.WaitForHealthy(node) - - ginkgo.By("retrieving new node's id and pop") - infoClient := info.NewClient(node.GetProcessContext().URI) - nodeID, nodePOP, err := infoClient.GetNodeID(e2e.DefaultContext()) - require.NoError(err) - - ginkgo.By("adding the new node as a validator", func() { - startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) - // Validation duration doesn't actually matter to this - // test - it is only ensuring that adding a validator - // doesn't break interchain transfer. - endTime := startTime.Add(30 * time.Second) - - rewardKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - - const ( - delegationPercent = 0.10 // 10% - delegationShare = reward.PercentDenominator * delegationPercent - ) - - _, err = pWallet.IssueAddPermissionlessValidatorTx( - &txs.SubnetValidator{ - Validator: txs.Validator{ - NodeID: nodeID, - Start: uint64(startTime.Unix()), - End: uint64(endTime.Unix()), - Wght: weight, - }, - Subnet: constants.PrimaryNetworkID, - }, - nodePOP, - pWallet.AVAXAssetID(), - &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{rewardKey.Address()}, - }, - &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{rewardKey.Address()}, - }, - delegationShare, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("adding a delegator to the new node", func() { - startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) - // Delegation duration doesn't actually matter to this - // test - it is only ensuring that adding a delegator - // doesn't break interchain transfer. - endTime := startTime.Add(15 * time.Second) - - rewardKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - - _, err = pWallet.IssueAddPermissionlessDelegatorTx( - &txs.SubnetValidator{ - Validator: txs.Validator{ - NodeID: nodeID, - Start: uint64(startTime.Unix()), - End: uint64(endTime.Unix()), - Wght: weight, - }, - Subnet: constants.PrimaryNetworkID, - }, - pWallet.AVAXAssetID(), - &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{rewardKey.Address()}, - }, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("exporting AVAX from the P-Chain to the X-Chain", func() { - _, err := pWallet.IssueExportTx( - xWallet.BlockchainID(), - exportOutputs, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("importing AVAX from the P-Chain to the X-Chain", func() { - _, err := xWallet.IssueImportTx( - constants.PlatformChainID, - &recipientOwner, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { - balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - ginkgo.By("exporting AVAX from the P-Chain to the C-Chain", func() { - _, err := pWallet.IssueExportTx( - cWallet.BlockchainID(), - exportOutputs, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("initializing a new eth client") - ethClient := e2e.NewEthClient(nodeURI) - - ginkgo.By("importing AVAX from the P-Chain to the C-Chain", func() { - _, err := cWallet.IssueImportTx( - constants.PlatformChainID, - recipientEthAddress, - e2e.WithDefaultContext(), - e2e.WithSuggestedGasPrice(ethClient), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") - balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) - require.NoError(err) - require.Positive(balance.Cmp(big.NewInt(0))) - - ginkgo.By("stopping validator node to free up resources for a bootstrap check") - require.NoError(node.Stop()) - - e2e.CheckBootstrapIsPossible(network) - }) -}) +// import ( +// "math/big" +// "time" + +// ginkgo "github.com/onsi/ginkgo/v2" + +// "github.com/spf13/cast" + +// "github.com/stretchr/testify/require" + +// "github.com/ava-labs/coreth/plugin/evm" + +// "github.com/ava-labs/avalanchego/api/info" +// "github.com/ava-labs/avalanchego/config" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/tests/e2e" +// "github.com/ava-labs/avalanchego/tests/fixture/testnet" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/platformvm/reward" +// "github.com/ava-labs/avalanchego/vms/platformvm/txs" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { +// require := require.New(ginkgo.GinkgoT()) + +// const ( +// transferAmount = 10 * units.Avax +// weight = 2_000 * units.Avax // Used for both validation and delegation +// ) + +// ginkgo.It("should ensure that funds can be transferred from the P-Chain to the X-Chain and the C-Chain", func() { +// network := e2e.Env.GetNetwork() + +// ginkgo.By("checking that the network has a compatible minimum stake duration", func() { +// minStakeDuration := cast.ToDuration(network.GetConfig().DefaultFlags[config.MinStakeDurationKey]) +// require.Equal(testnet.DefaultMinStakeDuration, minStakeDuration) +// }) + +// ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") +// recipientKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) +// keychain := e2e.Env.NewKeychain(1) +// keychain.Add(recipientKey) +// nodeURI := e2e.Env.GetRandomNodeURI() +// baseWallet := e2e.Env.NewWallet(keychain, nodeURI) +// xWallet := baseWallet.X() +// cWallet := baseWallet.C() +// pWallet := baseWallet.P() + +// ginkgo.By("defining common configuration") +// recipientEthAddress := evm.GetEthAddress(recipientKey) +// avaxAssetID := xWallet.AVAXAssetID() +// // Use the same owner for sending to X-Chain and importing funds to P-Chain +// recipientOwner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// recipientKey.Address(), +// }, +// } +// // Use the same outputs for both X-Chain and C-Chain exports +// exportOutputs := []*avax.TransferableOutput{ +// { +// Asset: avax.Asset{ +// ID: avaxAssetID, +// }, +// Out: &secp256k1fx.TransferOutput{ +// Amt: transferAmount, +// OutputOwners: secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// keychain.Keys[0].Address(), +// }, +// }, +// }, +// }, +// } + +// ginkgo.By("adding new node and waiting for it to report healthy") +// node := e2e.AddEphemeralNode(network, testnet.FlagsMap{}) +// e2e.WaitForHealthy(node) + +// ginkgo.By("retrieving new node's id and pop") +// infoClient := info.NewClient(node.GetProcessContext().URI) +// nodeID, nodePOP, err := infoClient.GetNodeID(e2e.DefaultContext()) +// require.NoError(err) + +// ginkgo.By("adding the new node as a validator", func() { +// startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) +// // Validation duration doesn't actually matter to this +// // test - it is only ensuring that adding a validator +// // doesn't break interchain transfer. +// endTime := startTime.Add(30 * time.Second) + +// rewardKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) + +// const ( +// delegationPercent = 0.10 // 10% +// delegationShare = reward.PercentDenominator * delegationPercent +// ) + +// _, err = pWallet.IssueAddPermissionlessValidatorTx( +// &txs.SubnetValidator{ +// Validator: txs.Validator{ +// NodeID: nodeID, +// Start: uint64(startTime.Unix()), +// End: uint64(endTime.Unix()), +// Wght: weight, +// }, +// Subnet: constants.PrimaryNetworkID, +// }, +// nodePOP, +// pWallet.AVAXAssetID(), +// &secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{rewardKey.Address()}, +// }, +// &secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{rewardKey.Address()}, +// }, +// delegationShare, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("adding a delegator to the new node", func() { +// startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) +// // Delegation duration doesn't actually matter to this +// // test - it is only ensuring that adding a delegator +// // doesn't break interchain transfer. +// endTime := startTime.Add(15 * time.Second) + +// rewardKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) + +// _, err = pWallet.IssueAddPermissionlessDelegatorTx( +// &txs.SubnetValidator{ +// Validator: txs.Validator{ +// NodeID: nodeID, +// Start: uint64(startTime.Unix()), +// End: uint64(endTime.Unix()), +// Wght: weight, +// }, +// Subnet: constants.PrimaryNetworkID, +// }, +// pWallet.AVAXAssetID(), +// &secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{rewardKey.Address()}, +// }, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("exporting AVAX from the P-Chain to the X-Chain", func() { +// _, err := pWallet.IssueExportTx( +// xWallet.BlockchainID(), +// exportOutputs, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("importing AVAX from the P-Chain to the X-Chain", func() { +// _, err := xWallet.IssueImportTx( +// constants.PlatformChainID, +// &recipientOwner, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { +// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// ginkgo.By("exporting AVAX from the P-Chain to the C-Chain", func() { +// _, err := pWallet.IssueExportTx( +// cWallet.BlockchainID(), +// exportOutputs, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("initializing a new eth client") +// ethClient := e2e.NewEthClient(nodeURI) + +// ginkgo.By("importing AVAX from the P-Chain to the C-Chain", func() { +// _, err := cWallet.IssueImportTx( +// constants.PlatformChainID, +// recipientEthAddress, +// e2e.WithDefaultContext(), +// e2e.WithSuggestedGasPrice(ethClient), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") +// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) +// require.NoError(err) +// require.Positive(balance.Cmp(big.NewInt(0))) + +// ginkgo.By("stopping validator node to free up resources for a bootstrap check") +// require.NoError(node.Stop()) + +// e2e.CheckBootstrapIsPossible(network) +// }) +// }) diff --git a/tests/e2e/x/interchain_workflow.go b/tests/e2e/x/interchain_workflow.go index f0c2951feb84..d738e55a7f7a 100644 --- a/tests/e2e/x/interchain_workflow.go +++ b/tests/e2e/x/interchain_workflow.go @@ -3,151 +3,151 @@ package x -import ( - "math/big" - - ginkgo "github.com/onsi/ginkgo/v2" - - "github.com/stretchr/testify/require" - - "github.com/ava-labs/coreth/plugin/evm" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var _ = e2e.DescribeXChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { - require := require.New(ginkgo.GinkgoT()) - - const transferAmount = 10 * units.Avax - - ginkgo.It("should ensure that funds can be transferred from the X-Chain to the C-Chain and the P-Chain", func() { - nodeURI := e2e.Env.GetRandomNodeURI() - - ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") - recipientKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - keychain := e2e.Env.NewKeychain(1) - keychain.Add(recipientKey) - baseWallet := e2e.NewWallet(keychain, nodeURI) - xWallet := baseWallet.X() - cWallet := baseWallet.C() - pWallet := baseWallet.P() - - ginkgo.By("defining common configuration") - recipientEthAddress := evm.GetEthAddress(recipientKey) - avaxAssetID := xWallet.AVAXAssetID() - // Use the same owner for sending to X-Chain and importing funds to P-Chain - recipientOwner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - recipientKey.Address(), - }, - } - // Use the same outputs for both C-Chain and P-Chain exports - exportOutputs := []*avax.TransferableOutput{ - { - Asset: avax.Asset{ - ID: avaxAssetID, - }, - Out: &secp256k1fx.TransferOutput{ - Amt: transferAmount, - OutputOwners: secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - keychain.Keys[0].Address(), - }, - }, - }, - }, - } - - ginkgo.By("sending funds from one address to another on the X-Chain", func() { - _, err = xWallet.IssueBaseTx( - []*avax.TransferableOutput{{ - Asset: avax.Asset{ - ID: avaxAssetID, - }, - Out: &secp256k1fx.TransferOutput{ - Amt: transferAmount, - OutputOwners: recipientOwner, - }, - }}, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the X-Chain recipient address has received the sent funds", func() { - balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - ginkgo.By("exporting AVAX from the X-Chain to the C-Chain", func() { - _, err := xWallet.IssueExportTx( - cWallet.BlockchainID(), - exportOutputs, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("initializing a new eth client") - ethClient := e2e.NewEthClient(nodeURI) - - ginkgo.By("importing AVAX from the X-Chain to the C-Chain", func() { - _, err := cWallet.IssueImportTx( - xWallet.BlockchainID(), - recipientEthAddress, - e2e.WithDefaultContext(), - e2e.WithSuggestedGasPrice(ethClient), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") - e2e.Eventually(func() bool { - balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) - require.NoError(err) - return balance.Cmp(big.NewInt(0)) > 0 - }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see recipient address funded before timeout") - - ginkgo.By("exporting AVAX from the X-Chain to the P-Chain", func() { - _, err := xWallet.IssueExportTx( - constants.PlatformChainID, - exportOutputs, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("importing AVAX from the X-Chain to the P-Chain", func() { - _, err := pWallet.IssueImportTx( - xWallet.BlockchainID(), - &recipientOwner, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { - balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) - }) -}) +// import ( +// "math/big" + +// ginkgo "github.com/onsi/ginkgo/v2" + +// "github.com/stretchr/testify/require" + +// "github.com/ava-labs/coreth/plugin/evm" + +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/tests/e2e" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var _ = e2e.DescribeXChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { +// require := require.New(ginkgo.GinkgoT()) + +// const transferAmount = 10 * units.Avax + +// ginkgo.It("should ensure that funds can be transferred from the X-Chain to the C-Chain and the P-Chain", func() { +// nodeURI := e2e.Env.GetRandomNodeURI() + +// ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") +// recipientKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) +// keychain := e2e.Env.NewKeychain(1) +// keychain.Add(recipientKey) +// baseWallet := e2e.Env.NewWallet(keychain, nodeURI) +// xWallet := baseWallet.X() +// cWallet := baseWallet.C() +// pWallet := baseWallet.P() + +// ginkgo.By("defining common configuration") +// recipientEthAddress := evm.GetEthAddress(recipientKey) +// avaxAssetID := xWallet.AVAXAssetID() +// // Use the same owner for sending to X-Chain and importing funds to P-Chain +// recipientOwner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// recipientKey.Address(), +// }, +// } +// // Use the same outputs for both C-Chain and P-Chain exports +// exportOutputs := []*avax.TransferableOutput{ +// { +// Asset: avax.Asset{ +// ID: avaxAssetID, +// }, +// Out: &secp256k1fx.TransferOutput{ +// Amt: transferAmount, +// OutputOwners: secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// keychain.Keys[0].Address(), +// }, +// }, +// }, +// }, +// } + +// ginkgo.By("sending funds from one address to another on the X-Chain", func() { +// _, err = xWallet.IssueBaseTx( +// []*avax.TransferableOutput{{ +// Asset: avax.Asset{ +// ID: avaxAssetID, +// }, +// Out: &secp256k1fx.TransferOutput{ +// Amt: transferAmount, +// OutputOwners: recipientOwner, +// }, +// }}, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the X-Chain recipient address has received the sent funds", func() { +// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// ginkgo.By("exporting AVAX from the X-Chain to the C-Chain", func() { +// _, err := xWallet.IssueExportTx( +// cWallet.BlockchainID(), +// exportOutputs, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("initializing a new eth client") +// ethClient := e2e.NewEthClient(nodeURI) + +// ginkgo.By("importing AVAX from the X-Chain to the C-Chain", func() { +// _, err := cWallet.IssueImportTx( +// xWallet.BlockchainID(), +// recipientEthAddress, +// e2e.WithDefaultContext(), +// e2e.WithSuggestedGasPrice(ethClient), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") +// e2e.Eventually(func() bool { +// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) +// require.NoError(err) +// return balance.Cmp(big.NewInt(0)) > 0 +// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see recipient address funded before timeout") + +// ginkgo.By("exporting AVAX from the X-Chain to the P-Chain", func() { +// _, err := xWallet.IssueExportTx( +// constants.PlatformChainID, +// exportOutputs, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("importing AVAX from the X-Chain to the P-Chain", func() { +// _, err := pWallet.IssueImportTx( +// xWallet.BlockchainID(), +// &recipientOwner, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { +// balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) +// }) +// }) diff --git a/tests/fixture/e2e/helpers.go b/tests/fixture/e2e/helpers.go index 8b7eb5260b8c..4cf6d32bdfc2 100644 --- a/tests/fixture/e2e/helpers.go +++ b/tests/fixture/e2e/helpers.go @@ -5,20 +5,23 @@ package e2e import ( "context" - "errors" - "fmt" - "math/big" + + // "errors" + // "fmt" + // "math/big" + "os" - "strings" + + // "strings" "time" ginkgo "github.com/onsi/ginkgo/v2" "github.com/stretchr/testify/require" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/ethclient" - "github.com/ava-labs/coreth/interfaces" + // "github.com/ava-labs/coreth/core/types" + // "github.com/ava-labs/coreth/ethclient" + // "github.com/ava-labs/coreth/interfaces" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/tests" @@ -67,7 +70,7 @@ func NewWallet(keychain *secp256k1fx.Keychain, nodeURI tmpnet.NodeURI) primary.W baseWallet, err := primary.MakeWallet(DefaultContext(), &primary.WalletConfig{ URI: nodeURI.URI, AVAXKeychain: keychain, - EthKeychain: keychain, + // EthKeychain: keychain, }) require.NoError(ginkgo.GinkgoT(), err) return primary.NewWalletWithOptions( @@ -80,15 +83,15 @@ func NewWallet(keychain *secp256k1fx.Keychain, nodeURI tmpnet.NodeURI) primary.W ) } -// Create a new eth client targeting the specified node URI. -func NewEthClient(nodeURI tmpnet.NodeURI) ethclient.Client { - tests.Outf("{{blue}} initializing a new eth client for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) - nodeAddress := strings.Split(nodeURI.URI, "//")[1] - uri := fmt.Sprintf("ws://%s/ext/bc/C/ws", nodeAddress) - client, err := ethclient.Dial(uri) - require.NoError(ginkgo.GinkgoT(), err) - return client -} +// // Create a new eth client targeting the specified node URI. +// func NewEthClient(nodeURI testnet.NodeURI) ethclient.Client { +// tests.Outf("{{blue}} initializing a new eth client for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) +// nodeAddress := strings.Split(nodeURI.URI, "//")[1] +// uri := fmt.Sprintf("ws://%s/ext/bc/C/ws", nodeAddress) +// client, err := ethclient.Dial(uri) +// require.NoError(ginkgo.GinkgoT(), err) +// return client +// } // Helper simplifying use of a timed context by canceling the context on ginkgo teardown. func ContextWithTimeout(duration time.Duration) context.Context { @@ -152,49 +155,49 @@ func WaitForHealthy(node tmpnet.Node) { require.NoError(ginkgo.GinkgoT(), tmpnet.WaitForHealthy(ctx, node)) } -// Sends an eth transaction, waits for the transaction receipt to be issued -// and checks that the receipt indicates success. -func SendEthTransaction(ethClient ethclient.Client, signedTx *types.Transaction) *types.Receipt { - require := require.New(ginkgo.GinkgoT()) - - txID := signedTx.Hash() - tests.Outf(" sending eth transaction with ID: %s\n", txID) - - require.NoError(ethClient.SendTransaction(DefaultContext(), signedTx)) - - // Wait for the receipt - var receipt *types.Receipt - Eventually(func() bool { - var err error - receipt, err = ethClient.TransactionReceipt(DefaultContext(), txID) - if errors.Is(err, interfaces.NotFound) { - return false // Transaction is still pending - } - require.NoError(err) - return true - }, DefaultTimeout, DefaultPollingInterval, "failed to see transaction acceptance before timeout") - - require.Equal(receipt.Status, types.ReceiptStatusSuccessful) - return receipt -} - -// Determines the suggested gas price for the configured client that will -// maximize the chances of transaction acceptance. -func SuggestGasPrice(ethClient ethclient.Client) *big.Int { - gasPrice, err := ethClient.SuggestGasPrice(DefaultContext()) - require.NoError(ginkgo.GinkgoT(), err) - // Double the suggested gas price to maximize the chances of - // acceptance. Maybe this can be revisited pending resolution of - // https://github.com/ava-labs/coreth/issues/314. - gasPrice.Add(gasPrice, gasPrice) - return gasPrice -} - -// Helper simplifying use via an option of a gas price appropriate for testing. -func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { - baseFee := SuggestGasPrice(ethClient) - return common.WithBaseFee(baseFee) -} +// // Sends an eth transaction, waits for the transaction receipt to be issued +// // and checks that the receipt indicates success. +// func SendEthTransaction(ethClient ethclient.Client, signedTx *types.Transaction) *types.Receipt { +// require := require.New(ginkgo.GinkgoT()) + +// txID := signedTx.Hash() +// tests.Outf(" sending eth transaction with ID: %s\n", txID) + +// require.NoError(ethClient.SendTransaction(DefaultContext(), signedTx)) + +// // Wait for the receipt +// var receipt *types.Receipt +// Eventually(func() bool { +// var err error +// receipt, err = ethClient.TransactionReceipt(DefaultContext(), txID) +// if errors.Is(err, interfaces.NotFound) { +// return false // Transaction is still pending +// } +// require.NoError(err) +// return true +// }, DefaultTimeout, DefaultPollingInterval, "failed to see transaction acceptance before timeout") + +// require.Equal(receipt.Status, types.ReceiptStatusSuccessful) +// return receipt +// } + +// // Determines the suggested gas price for the configured client that will +// // maximize the chances of transaction acceptance. +// func SuggestGasPrice(ethClient ethclient.Client) *big.Int { +// gasPrice, err := ethClient.SuggestGasPrice(DefaultContext()) +// require.NoError(ginkgo.GinkgoT(), err) +// // Double the suggested gas price to maximize the chances of +// // acceptance. Maybe this can be revisited pending resolution of +// // https://github.com/ava-labs/coreth/issues/314. +// gasPrice.Add(gasPrice, gasPrice) +// return gasPrice +// } + +// // Helper simplifying use via an option of a gas price appropriate for testing. +// func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { +// baseFee := SuggestGasPrice(ethClient) +// return common.WithBaseFee(baseFee) +// } // Verify that a new node can bootstrap into the network. func CheckBootstrapIsPossible(network tmpnet.Network) { diff --git a/tests/fixture/tmpnet/config.go b/tests/fixture/tmpnet/config.go index f504eb84d20d..bc22df0df115 100644 --- a/tests/fixture/tmpnet/config.go +++ b/tests/fixture/tmpnet/config.go @@ -15,9 +15,9 @@ import ( "github.com/spf13/cast" - "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/plugin/evm" + // "github.com/ava-labs/coreth/core" + // "github.com/ava-labs/coreth/params" + // "github.com/ava-labs/coreth/plugin/evm" "github.com/ava-labs/avalanchego/config" "github.com/ava-labs/avalanchego/genesis" @@ -143,15 +143,15 @@ func (c *NetworkConfig) EnsureGenesis(networkID uint32, validatorIDs []ids.NodeI // Ensure pre-funded keys have arbitrary large balances on both chains to support testing xChainBalances := make(XChainBalanceMap, len(c.FundedKeys)) - cChainBalances := make(core.GenesisAlloc, len(c.FundedKeys)) - for _, key := range c.FundedKeys { - xChainBalances[key.Address()] = DefaultFundedKeyXChainAmount - cChainBalances[evm.GetEthAddress(key)] = core.GenesisAccount{ - Balance: DefaultFundedKeyCChainAmount, - } - } - - genesis, err := NewTestGenesis(networkID, xChainBalances, cChainBalances, validatorIDs) + // cChainBalances := make(core.GenesisAlloc, len(c.FundedKeys)) + // for _, key := range c.FundedKeys { + // xChainBalances[key.Address()] = DefaultFundedKeyXChainAmount + // cChainBalances[evm.GetEthAddress(key)] = core.GenesisAccount{ + // Balance: DefaultFundedKeyCChainAmount, + // } + // } + + genesis, err := NewTestGenesis(networkID, xChainBalances /*, cChainBalances*/, validatorIDs) if err != nil { return err } @@ -311,7 +311,7 @@ type XChainBalanceMap map[ids.ShortID]uint64 func NewTestGenesis( networkID uint32, xChainBalances XChainBalanceMap, - cChainBalances core.GenesisAlloc, + // cChainBalances core.GenesisAlloc, validatorIDs []ids.NodeID, ) (*genesis.UnparsedConfig, error) { // Validate inputs @@ -322,7 +322,7 @@ func NewTestGenesis( if len(validatorIDs) == 0 { return nil, errMissingValidatorsForGenesis } - if len(xChainBalances) == 0 || len(cChainBalances) == 0 { + if len(xChainBalances) == 0 /*|| len(cChainBalances) == 0*/ { return nil, errMissingBalancesForGenesis } @@ -394,20 +394,20 @@ func NewTestGenesis( ) } - // Define C-Chain genesis - cChainGenesis := &core.Genesis{ - Config: ¶ms.ChainConfig{ - ChainID: big.NewInt(43112), // Arbitrary chain ID is arbitrary - }, - Difficulty: big.NewInt(0), // Difficulty is a mandatory field - GasLimit: DefaultGasLimit, - Alloc: cChainBalances, - } - cChainGenesisBytes, err := json.Marshal(cChainGenesis) - if err != nil { - return nil, fmt.Errorf("failed to marshal C-Chain genesis: %w", err) - } - config.CChainGenesis = string(cChainGenesisBytes) + // // Define C-Chain genesis + // cChainGenesis := &core.Genesis{ + // Config: ¶ms.ChainConfig{ + // ChainID: big.NewInt(43112), // Arbitrary chain ID is arbitrary + // }, + // Difficulty: big.NewInt(0), // Difficulty is a mandatory field + // GasLimit: DefaultGasLimit, + // Alloc: cChainBalances, + // } + // cChainGenesisBytes, err := json.Marshal(cChainGenesis) + // if err != nil { + // return nil, fmt.Errorf("failed to marshal C-Chain genesis: %w", err) + // } + // config.CChainGenesis = string(cChainGenesisBytes) // Give staking rewards for initial validators to a random address. Any testing of staking rewards // will be easier to perform with nodes other than the initial validators since the timing of diff --git a/vms/example/xsvm/cmd/chain/create/cmd.go b/vms/example/xsvm/cmd/chain/create/cmd.go index 1f00491a4ce6..043b4298dcdf 100644 --- a/vms/example/xsvm/cmd/chain/create/cmd.go +++ b/vms/example/xsvm/cmd/chain/create/cmd.go @@ -42,9 +42,9 @@ func createFunc(c *cobra.Command, args []string) error { // that [uri] is hosting. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: config.URI, - AVAXKeychain: kc, - EthKeychain: kc, + URI: config.URI, + AVAXKeychain: kc, + // EthKeychain: kc, PChainTxsToFetch: set.Of(config.SubnetID), }) if err != nil { diff --git a/wallet/chain/c/backend.go b/wallet/chain/c/backend.go index 0a735116b646..b88c8c643bc3 100644 --- a/wallet/chain/c/backend.go +++ b/wallet/chain/c/backend.go @@ -3,153 +3,153 @@ package c -import ( - "errors" - "fmt" - "math/big" - "sync" - - stdcontext "context" - - "github.com/ava-labs/coreth/plugin/evm" - - ethcommon "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/avalanchego/database" - "github.com/ava-labs/avalanchego/utils/math" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var ( - _ Backend = (*backend)(nil) - - errUnknownTxType = errors.New("unknown tx type") -) - -// Backend defines the full interface required to support a C-chain wallet. -type Backend interface { - common.ChainUTXOs - BuilderBackend - SignerBackend - - AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error -} - -type backend struct { - Context - common.ChainUTXOs - - accountsLock sync.RWMutex - accounts map[ethcommon.Address]*Account -} - -type Account struct { - Balance *big.Int - Nonce uint64 -} - -func NewBackend( - ctx Context, - utxos common.ChainUTXOs, - accounts map[ethcommon.Address]*Account, -) Backend { - return &backend{ - Context: ctx, - ChainUTXOs: utxos, - accounts: accounts, - } -} - -func (b *backend) AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error { - switch tx := tx.UnsignedAtomicTx.(type) { - case *evm.UnsignedImportTx: - for _, input := range tx.ImportedInputs { - utxoID := input.InputID() - if err := b.RemoveUTXO(ctx, tx.SourceChain, utxoID); err != nil { - return err - } - } - - b.accountsLock.Lock() - defer b.accountsLock.Unlock() - - for _, output := range tx.Outs { - account, ok := b.accounts[output.Address] - if !ok { - continue - } - - balance := new(big.Int).SetUint64(output.Amount) - balance.Mul(balance, avaxConversionRate) - account.Balance.Add(account.Balance, balance) - } - case *evm.UnsignedExportTx: - txID := tx.ID() - for i, out := range tx.ExportedOutputs { - err := b.AddUTXO( - ctx, - tx.DestinationChain, - &avax.UTXO{ - UTXOID: avax.UTXOID{ - TxID: txID, - OutputIndex: uint32(i), - }, - Asset: avax.Asset{ID: out.AssetID()}, - Out: out.Out, - }, - ) - if err != nil { - return err - } - } - - b.accountsLock.Lock() - defer b.accountsLock.Unlock() - - for _, input := range tx.Ins { - account, ok := b.accounts[input.Address] - if !ok { - continue - } - - balance := new(big.Int).SetUint64(input.Amount) - balance.Mul(balance, avaxConversionRate) - if account.Balance.Cmp(balance) == -1 { - return errInsufficientFunds - } - account.Balance.Sub(account.Balance, balance) - - newNonce, err := math.Add64(input.Nonce, 1) - if err != nil { - return err - } - account.Nonce = newNonce - } - default: - return fmt.Errorf("%w: %T", errUnknownTxType, tx) - } - return nil -} - -func (b *backend) Balance(_ stdcontext.Context, addr ethcommon.Address) (*big.Int, error) { - b.accountsLock.RLock() - defer b.accountsLock.RUnlock() - - account, exists := b.accounts[addr] - if !exists { - return nil, database.ErrNotFound - } - return account.Balance, nil -} - -func (b *backend) Nonce(_ stdcontext.Context, addr ethcommon.Address) (uint64, error) { - b.accountsLock.RLock() - defer b.accountsLock.RUnlock() - - account, exists := b.accounts[addr] - if !exists { - return 0, database.ErrNotFound - } - return account.Nonce, nil -} +// import ( +// "errors" +// "fmt" +// "math/big" +// "sync" + +// stdcontext "context" + +// "github.com/ava-labs/coreth/plugin/evm" + +// ethcommon "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/avalanchego/database" +// "github.com/ava-labs/avalanchego/utils/math" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var ( +// _ Backend = (*backend)(nil) + +// errUnknownTxType = errors.New("unknown tx type") +// ) + +// // Backend defines the full interface required to support a C-chain wallet. +// type Backend interface { +// common.ChainUTXOs +// BuilderBackend +// SignerBackend + +// AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error +// } + +// type backend struct { +// Context +// common.ChainUTXOs + +// accountsLock sync.RWMutex +// accounts map[ethcommon.Address]*Account +// } + +// type Account struct { +// Balance *big.Int +// Nonce uint64 +// } + +// func NewBackend( +// ctx Context, +// utxos common.ChainUTXOs, +// accounts map[ethcommon.Address]*Account, +// ) Backend { +// return &backend{ +// Context: ctx, +// ChainUTXOs: utxos, +// accounts: accounts, +// } +// } + +// func (b *backend) AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error { +// switch tx := tx.UnsignedAtomicTx.(type) { +// case *evm.UnsignedImportTx: +// for _, input := range tx.ImportedInputs { +// utxoID := input.InputID() +// if err := b.RemoveUTXO(ctx, tx.SourceChain, utxoID); err != nil { +// return err +// } +// } + +// b.accountsLock.Lock() +// defer b.accountsLock.Unlock() + +// for _, output := range tx.Outs { +// account, ok := b.accounts[output.Address] +// if !ok { +// continue +// } + +// balance := new(big.Int).SetUint64(output.Amount) +// balance.Mul(balance, avaxConversionRate) +// account.Balance.Add(account.Balance, balance) +// } +// case *evm.UnsignedExportTx: +// txID := tx.ID() +// for i, out := range tx.ExportedOutputs { +// err := b.AddUTXO( +// ctx, +// tx.DestinationChain, +// &avax.UTXO{ +// UTXOID: avax.UTXOID{ +// TxID: txID, +// OutputIndex: uint32(i), +// }, +// Asset: avax.Asset{ID: out.AssetID()}, +// Out: out.Out, +// }, +// ) +// if err != nil { +// return err +// } +// } + +// b.accountsLock.Lock() +// defer b.accountsLock.Unlock() + +// for _, input := range tx.Ins { +// account, ok := b.accounts[input.Address] +// if !ok { +// continue +// } + +// balance := new(big.Int).SetUint64(input.Amount) +// balance.Mul(balance, avaxConversionRate) +// if account.Balance.Cmp(balance) == -1 { +// return errInsufficientFunds +// } +// account.Balance.Sub(account.Balance, balance) + +// newNonce, err := math.Add64(input.Nonce, 1) +// if err != nil { +// return err +// } +// account.Nonce = newNonce +// } +// default: +// return fmt.Errorf("%w: %T", errUnknownTxType, tx) +// } +// return nil +// } + +// func (b *backend) Balance(_ stdcontext.Context, addr ethcommon.Address) (*big.Int, error) { +// b.accountsLock.RLock() +// defer b.accountsLock.RUnlock() + +// account, exists := b.accounts[addr] +// if !exists { +// return nil, database.ErrNotFound +// } +// return account.Balance, nil +// } + +// func (b *backend) Nonce(_ stdcontext.Context, addr ethcommon.Address) (uint64, error) { +// b.accountsLock.RLock() +// defer b.accountsLock.RUnlock() + +// account, exists := b.accounts[addr] +// if !exists { +// return 0, database.ErrNotFound +// } +// return account.Nonce, nil +// } diff --git a/wallet/chain/c/builder.go b/wallet/chain/c/builder.go index d2d088e88a53..c51d2647777e 100644 --- a/wallet/chain/c/builder.go +++ b/wallet/chain/c/builder.go @@ -3,399 +3,399 @@ package c -import ( - "errors" - "math/big" - - stdcontext "context" - - "github.com/ava-labs/coreth/plugin/evm" - - ethcommon "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils" - "github.com/ava-labs/avalanchego/utils/math" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -const avaxConversionRateInt = 1_000_000_000 - -var ( - _ Builder = (*builder)(nil) - - errInsufficientFunds = errors.New("insufficient funds") - - // avaxConversionRate is the conversion rate between the smallest - // denomination on the X-Chain and P-chain, 1 nAVAX, and the smallest - // denomination on the C-Chain 1 wei. Where 1 nAVAX = 1 gWei. - // - // This is only required for AVAX because the denomination of 1 AVAX is 9 - // decimal places on the X and P chains, but is 18 decimal places within the - // EVM. - avaxConversionRate = big.NewInt(avaxConversionRateInt) -) - -// Builder provides a convenient interface for building unsigned C-chain -// transactions. -type Builder interface { - // GetBalance calculates the amount of AVAX that this builder has control - // over. - GetBalance( - options ...common.Option, - ) (*big.Int, error) - - // GetImportableBalance calculates the amount of AVAX that this builder - // could import from the provided chain. - // - // - [chainID] specifies the chain the funds are from. - GetImportableBalance( - chainID ids.ID, - options ...common.Option, - ) (uint64, error) - - // NewImportTx creates an import transaction that attempts to consume all - // the available UTXOs and import the funds to [to]. - // - // - [chainID] specifies the chain to be importing funds from. - // - [to] specifies where to send the imported funds to. - // - [baseFee] specifies the fee price willing to be paid by this tx. - NewImportTx( - chainID ids.ID, - to ethcommon.Address, - baseFee *big.Int, - options ...common.Option, - ) (*evm.UnsignedImportTx, error) - - // NewExportTx creates an export transaction that attempts to send all the - // provided [outputs] to the requested [chainID]. - // - // - [chainID] specifies the chain to be exporting the funds to. - // - [outputs] specifies the outputs to send to the [chainID]. - // - [baseFee] specifies the fee price willing to be paid by this tx. - NewExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - baseFee *big.Int, - options ...common.Option, - ) (*evm.UnsignedExportTx, error) -} - -// BuilderBackend specifies the required information needed to build unsigned -// C-chain transactions. -type BuilderBackend interface { - Context - - UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) - Balance(ctx stdcontext.Context, addr ethcommon.Address) (*big.Int, error) - Nonce(ctx stdcontext.Context, addr ethcommon.Address) (uint64, error) -} - -type builder struct { - avaxAddrs set.Set[ids.ShortID] - ethAddrs set.Set[ethcommon.Address] - backend BuilderBackend -} - -// NewBuilder returns a new transaction builder. -// -// - [avaxAddrs] is the set of addresses in the AVAX format that the builder -// assumes can be used when signing the transactions in the future. -// - [ethAddrs] is the set of addresses in the Eth format that the builder -// assumes can be used when signing the transactions in the future. -// - [backend] provides the required access to the chain's context and state -// to build out the transactions. -func NewBuilder( - avaxAddrs set.Set[ids.ShortID], - ethAddrs set.Set[ethcommon.Address], - backend BuilderBackend, -) Builder { - return &builder{ - avaxAddrs: avaxAddrs, - ethAddrs: ethAddrs, - backend: backend, - } -} - -func (b *builder) GetBalance( - options ...common.Option, -) (*big.Int, error) { - var ( - ops = common.NewOptions(options) - ctx = ops.Context() - addrs = ops.EthAddresses(b.ethAddrs) - totalBalance = new(big.Int) - ) - for addr := range addrs { - balance, err := b.backend.Balance(ctx, addr) - if err != nil { - return nil, err - } - totalBalance.Add(totalBalance, balance) - } - - return totalBalance, nil -} - -func (b *builder) GetImportableBalance( - chainID ids.ID, - options ...common.Option, -) (uint64, error) { - ops := common.NewOptions(options) - utxos, err := b.backend.UTXOs(ops.Context(), chainID) - if err != nil { - return 0, err - } - - var ( - addrs = ops.Addresses(b.avaxAddrs) - minIssuanceTime = ops.MinIssuanceTime() - avaxAssetID = b.backend.AVAXAssetID() - balance uint64 - ) - for _, utxo := range utxos { - amount, _, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) - if !ok { - continue - } - - newBalance, err := math.Add64(balance, amount) - if err != nil { - return 0, err - } - balance = newBalance - } - - return balance, nil -} - -func (b *builder) NewImportTx( - chainID ids.ID, - to ethcommon.Address, - baseFee *big.Int, - options ...common.Option, -) (*evm.UnsignedImportTx, error) { - ops := common.NewOptions(options) - utxos, err := b.backend.UTXOs(ops.Context(), chainID) - if err != nil { - return nil, err - } - - var ( - addrs = ops.Addresses(b.avaxAddrs) - minIssuanceTime = ops.MinIssuanceTime() - avaxAssetID = b.backend.AVAXAssetID() - - importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) - importedAmount uint64 - ) - for _, utxo := range utxos { - amount, inputSigIndices, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) - if !ok { - continue - } - - importedInputs = append(importedInputs, &avax.TransferableInput{ - UTXOID: utxo.UTXOID, - Asset: utxo.Asset, - In: &secp256k1fx.TransferInput{ - Amt: amount, - Input: secp256k1fx.Input{ - SigIndices: inputSigIndices, - }, - }, - }) - - newImportedAmount, err := math.Add64(importedAmount, amount) - if err != nil { - return nil, err - } - importedAmount = newImportedAmount - } - - utils.Sort(importedInputs) - tx := &evm.UnsignedImportTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: b.backend.BlockchainID(), - SourceChain: chainID, - ImportedInputs: importedInputs, - } - - // We must initialize the bytes of the tx to calculate the initial cost - wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} - if err := wrappedTx.Sign(evm.Codec, nil); err != nil { - return nil, err - } - - gasUsedWithoutOutput, err := tx.GasUsed(true /*=IsApricotPhase5*/) - if err != nil { - return nil, err - } - gasUsedWithOutput := gasUsedWithoutOutput + evm.EVMOutputGas - - txFee, err := evm.CalculateDynamicFee(gasUsedWithOutput, baseFee) - if err != nil { - return nil, err - } - - if importedAmount <= txFee { - return nil, errInsufficientFunds - } - - tx.Outs = []evm.EVMOutput{{ - Address: to, - Amount: importedAmount - txFee, - AssetID: avaxAssetID, - }} - return tx, nil -} - -func (b *builder) NewExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - baseFee *big.Int, - options ...common.Option, -) (*evm.UnsignedExportTx, error) { - var ( - avaxAssetID = b.backend.AVAXAssetID() - exportedOutputs = make([]*avax.TransferableOutput, len(outputs)) - exportedAmount uint64 - ) - for i, output := range outputs { - exportedOutputs[i] = &avax.TransferableOutput{ - Asset: avax.Asset{ID: avaxAssetID}, - Out: output, - } - - newExportedAmount, err := math.Add64(exportedAmount, output.Amt) - if err != nil { - return nil, err - } - exportedAmount = newExportedAmount - } - - avax.SortTransferableOutputs(exportedOutputs, evm.Codec) - tx := &evm.UnsignedExportTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: b.backend.BlockchainID(), - DestinationChain: chainID, - ExportedOutputs: exportedOutputs, - } - - // We must initialize the bytes of the tx to calculate the initial cost - wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} - if err := wrappedTx.Sign(evm.Codec, nil); err != nil { - return nil, err - } - - cost, err := tx.GasUsed(true /*=IsApricotPhase5*/) - if err != nil { - return nil, err - } - - initialFee, err := evm.CalculateDynamicFee(cost, baseFee) - if err != nil { - return nil, err - } - - amountToConsume, err := math.Add64(exportedAmount, initialFee) - if err != nil { - return nil, err - } - - var ( - ops = common.NewOptions(options) - ctx = ops.Context() - addrs = ops.EthAddresses(b.ethAddrs) - inputs = make([]evm.EVMInput, 0, addrs.Len()) - ) - for addr := range addrs { - if amountToConsume == 0 { - break - } - - prevFee, err := evm.CalculateDynamicFee(cost, baseFee) - if err != nil { - return nil, err - } - - newCost := cost + evm.EVMInputGas - newFee, err := evm.CalculateDynamicFee(newCost, baseFee) - if err != nil { - return nil, err - } - - additionalFee := newFee - prevFee - - balance, err := b.backend.Balance(ctx, addr) - if err != nil { - return nil, err - } - - // Since the asset is AVAX, we divide by the avaxConversionRate to - // convert back to the correct denomination of AVAX that can be - // exported. - avaxBalance := new(big.Int).Div(balance, avaxConversionRate).Uint64() - - // If the balance for [addr] is insufficient to cover the additional - // cost of adding an input to the transaction, skip adding the input - // altogether. - if avaxBalance <= additionalFee { - continue - } - - // Update the cost for the next iteration - cost = newCost - - amountToConsume, err = math.Add64(amountToConsume, additionalFee) - if err != nil { - return nil, err - } - - nonce, err := b.backend.Nonce(ctx, addr) - if err != nil { - return nil, err - } - - inputAmount := math.Min(amountToConsume, avaxBalance) - inputs = append(inputs, evm.EVMInput{ - Address: addr, - Amount: inputAmount, - AssetID: avaxAssetID, - Nonce: nonce, - }) - amountToConsume -= inputAmount - } - - if amountToConsume > 0 { - return nil, errInsufficientFunds - } - - utils.Sort(inputs) - tx.Ins = inputs - return tx, nil -} - -func getSpendableAmount( - utxo *avax.UTXO, - addrs set.Set[ids.ShortID], - minIssuanceTime uint64, - avaxAssetID ids.ID, -) (uint64, []uint32, bool) { - if utxo.Asset.ID != avaxAssetID { - // Only AVAX can be imported - return 0, nil, false - } - - out, ok := utxo.Out.(*secp256k1fx.TransferOutput) - if !ok { - // Can't import an unknown transfer output type - return 0, nil, false - } - - inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) - return out.Amt, inputSigIndices, ok -} +// import ( +// "errors" +// "math/big" + +// stdcontext "context" + +// "github.com/ava-labs/coreth/plugin/evm" + +// ethcommon "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/utils" +// "github.com/ava-labs/avalanchego/utils/math" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// const avaxConversionRateInt = 1_000_000_000 + +// var ( +// _ Builder = (*builder)(nil) + +// errInsufficientFunds = errors.New("insufficient funds") + +// // avaxConversionRate is the conversion rate between the smallest +// // denomination on the X-Chain and P-chain, 1 nAVAX, and the smallest +// // denomination on the C-Chain 1 wei. Where 1 nAVAX = 1 gWei. +// // +// // This is only required for AVAX because the denomination of 1 AVAX is 9 +// // decimal places on the X and P chains, but is 18 decimal places within the +// // EVM. +// avaxConversionRate = big.NewInt(avaxConversionRateInt) +// ) + +// // Builder provides a convenient interface for building unsigned C-chain +// // transactions. +// type Builder interface { +// // GetBalance calculates the amount of AVAX that this builder has control +// // over. +// GetBalance( +// options ...common.Option, +// ) (*big.Int, error) + +// // GetImportableBalance calculates the amount of AVAX that this builder +// // could import from the provided chain. +// // +// // - [chainID] specifies the chain the funds are from. +// GetImportableBalance( +// chainID ids.ID, +// options ...common.Option, +// ) (uint64, error) + +// // NewImportTx creates an import transaction that attempts to consume all +// // the available UTXOs and import the funds to [to]. +// // +// // - [chainID] specifies the chain to be importing funds from. +// // - [to] specifies where to send the imported funds to. +// // - [baseFee] specifies the fee price willing to be paid by this tx. +// NewImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedImportTx, error) + +// // NewExportTx creates an export transaction that attempts to send all the +// // provided [outputs] to the requested [chainID]. +// // +// // - [chainID] specifies the chain to be exporting the funds to. +// // - [outputs] specifies the outputs to send to the [chainID]. +// // - [baseFee] specifies the fee price willing to be paid by this tx. +// NewExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedExportTx, error) +// } + +// // BuilderBackend specifies the required information needed to build unsigned +// // C-chain transactions. +// type BuilderBackend interface { +// Context + +// UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) +// Balance(ctx stdcontext.Context, addr ethcommon.Address) (*big.Int, error) +// Nonce(ctx stdcontext.Context, addr ethcommon.Address) (uint64, error) +// } + +// type builder struct { +// avaxAddrs set.Set[ids.ShortID] +// ethAddrs set.Set[ethcommon.Address] +// backend BuilderBackend +// } + +// // NewBuilder returns a new transaction builder. +// // +// // - [avaxAddrs] is the set of addresses in the AVAX format that the builder +// // assumes can be used when signing the transactions in the future. +// // - [ethAddrs] is the set of addresses in the Eth format that the builder +// // assumes can be used when signing the transactions in the future. +// // - [backend] provides the required access to the chain's context and state +// // to build out the transactions. +// func NewBuilder( +// avaxAddrs set.Set[ids.ShortID], +// ethAddrs set.Set[ethcommon.Address], +// backend BuilderBackend, +// ) Builder { +// return &builder{ +// avaxAddrs: avaxAddrs, +// ethAddrs: ethAddrs, +// backend: backend, +// } +// } + +// func (b *builder) GetBalance( +// options ...common.Option, +// ) (*big.Int, error) { +// var ( +// ops = common.NewOptions(options) +// ctx = ops.Context() +// addrs = ops.EthAddresses(b.ethAddrs) +// totalBalance = new(big.Int) +// ) +// for addr := range addrs { +// balance, err := b.backend.Balance(ctx, addr) +// if err != nil { +// return nil, err +// } +// totalBalance.Add(totalBalance, balance) +// } + +// return totalBalance, nil +// } + +// func (b *builder) GetImportableBalance( +// chainID ids.ID, +// options ...common.Option, +// ) (uint64, error) { +// ops := common.NewOptions(options) +// utxos, err := b.backend.UTXOs(ops.Context(), chainID) +// if err != nil { +// return 0, err +// } + +// var ( +// addrs = ops.Addresses(b.avaxAddrs) +// minIssuanceTime = ops.MinIssuanceTime() +// avaxAssetID = b.backend.AVAXAssetID() +// balance uint64 +// ) +// for _, utxo := range utxos { +// amount, _, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) +// if !ok { +// continue +// } + +// newBalance, err := math.Add64(balance, amount) +// if err != nil { +// return 0, err +// } +// balance = newBalance +// } + +// return balance, nil +// } + +// func (b *builder) NewImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedImportTx, error) { +// ops := common.NewOptions(options) +// utxos, err := b.backend.UTXOs(ops.Context(), chainID) +// if err != nil { +// return nil, err +// } + +// var ( +// addrs = ops.Addresses(b.avaxAddrs) +// minIssuanceTime = ops.MinIssuanceTime() +// avaxAssetID = b.backend.AVAXAssetID() + +// importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) +// importedAmount uint64 +// ) +// for _, utxo := range utxos { +// amount, inputSigIndices, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) +// if !ok { +// continue +// } + +// importedInputs = append(importedInputs, &avax.TransferableInput{ +// UTXOID: utxo.UTXOID, +// Asset: utxo.Asset, +// In: &secp256k1fx.TransferInput{ +// Amt: amount, +// Input: secp256k1fx.Input{ +// SigIndices: inputSigIndices, +// }, +// }, +// }) + +// newImportedAmount, err := math.Add64(importedAmount, amount) +// if err != nil { +// return nil, err +// } +// importedAmount = newImportedAmount +// } + +// utils.Sort(importedInputs) +// tx := &evm.UnsignedImportTx{ +// NetworkID: b.backend.NetworkID(), +// BlockchainID: b.backend.BlockchainID(), +// SourceChain: chainID, +// ImportedInputs: importedInputs, +// } + +// // We must initialize the bytes of the tx to calculate the initial cost +// wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} +// if err := wrappedTx.Sign(evm.Codec, nil); err != nil { +// return nil, err +// } + +// gasUsedWithoutOutput, err := tx.GasUsed(true /*=IsApricotPhase5*/) +// if err != nil { +// return nil, err +// } +// gasUsedWithOutput := gasUsedWithoutOutput + evm.EVMOutputGas + +// txFee, err := evm.CalculateDynamicFee(gasUsedWithOutput, baseFee) +// if err != nil { +// return nil, err +// } + +// if importedAmount <= txFee { +// return nil, errInsufficientFunds +// } + +// tx.Outs = []evm.EVMOutput{{ +// Address: to, +// Amount: importedAmount - txFee, +// AssetID: avaxAssetID, +// }} +// return tx, nil +// } + +// func (b *builder) NewExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedExportTx, error) { +// var ( +// avaxAssetID = b.backend.AVAXAssetID() +// exportedOutputs = make([]*avax.TransferableOutput, len(outputs)) +// exportedAmount uint64 +// ) +// for i, output := range outputs { +// exportedOutputs[i] = &avax.TransferableOutput{ +// Asset: avax.Asset{ID: avaxAssetID}, +// Out: output, +// } + +// newExportedAmount, err := math.Add64(exportedAmount, output.Amt) +// if err != nil { +// return nil, err +// } +// exportedAmount = newExportedAmount +// } + +// avax.SortTransferableOutputs(exportedOutputs, evm.Codec) +// tx := &evm.UnsignedExportTx{ +// NetworkID: b.backend.NetworkID(), +// BlockchainID: b.backend.BlockchainID(), +// DestinationChain: chainID, +// ExportedOutputs: exportedOutputs, +// } + +// // We must initialize the bytes of the tx to calculate the initial cost +// wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} +// if err := wrappedTx.Sign(evm.Codec, nil); err != nil { +// return nil, err +// } + +// cost, err := tx.GasUsed(true /*=IsApricotPhase5*/) +// if err != nil { +// return nil, err +// } + +// initialFee, err := evm.CalculateDynamicFee(cost, baseFee) +// if err != nil { +// return nil, err +// } + +// amountToConsume, err := math.Add64(exportedAmount, initialFee) +// if err != nil { +// return nil, err +// } + +// var ( +// ops = common.NewOptions(options) +// ctx = ops.Context() +// addrs = ops.EthAddresses(b.ethAddrs) +// inputs = make([]evm.EVMInput, 0, addrs.Len()) +// ) +// for addr := range addrs { +// if amountToConsume == 0 { +// break +// } + +// prevFee, err := evm.CalculateDynamicFee(cost, baseFee) +// if err != nil { +// return nil, err +// } + +// newCost := cost + evm.EVMInputGas +// newFee, err := evm.CalculateDynamicFee(newCost, baseFee) +// if err != nil { +// return nil, err +// } + +// additionalFee := newFee - prevFee + +// balance, err := b.backend.Balance(ctx, addr) +// if err != nil { +// return nil, err +// } + +// // Since the asset is AVAX, we divide by the avaxConversionRate to +// // convert back to the correct denomination of AVAX that can be +// // exported. +// avaxBalance := new(big.Int).Div(balance, avaxConversionRate).Uint64() + +// // If the balance for [addr] is insufficient to cover the additional +// // cost of adding an input to the transaction, skip adding the input +// // altogether. +// if avaxBalance <= additionalFee { +// continue +// } + +// // Update the cost for the next iteration +// cost = newCost + +// amountToConsume, err = math.Add64(amountToConsume, additionalFee) +// if err != nil { +// return nil, err +// } + +// nonce, err := b.backend.Nonce(ctx, addr) +// if err != nil { +// return nil, err +// } + +// inputAmount := math.Min(amountToConsume, avaxBalance) +// inputs = append(inputs, evm.EVMInput{ +// Address: addr, +// Amount: inputAmount, +// AssetID: avaxAssetID, +// Nonce: nonce, +// }) +// amountToConsume -= inputAmount +// } + +// if amountToConsume > 0 { +// return nil, errInsufficientFunds +// } + +// utils.Sort(inputs) +// tx.Ins = inputs +// return tx, nil +// } + +// func getSpendableAmount( +// utxo *avax.UTXO, +// addrs set.Set[ids.ShortID], +// minIssuanceTime uint64, +// avaxAssetID ids.ID, +// ) (uint64, []uint32, bool) { +// if utxo.Asset.ID != avaxAssetID { +// // Only AVAX can be imported +// return 0, nil, false +// } + +// out, ok := utxo.Out.(*secp256k1fx.TransferOutput) +// if !ok { +// // Can't import an unknown transfer output type +// return 0, nil, false +// } + +// inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) +// return out.Amt, inputSigIndices, ok +// } diff --git a/wallet/chain/c/builder_with_options.go b/wallet/chain/c/builder_with_options.go index 8416dddf9928..9b7ab8399484 100644 --- a/wallet/chain/c/builder_with_options.go +++ b/wallet/chain/c/builder_with_options.go @@ -3,81 +3,81 @@ package c -import ( - "math/big" +// import ( +// "math/big" - "github.com/ava-labs/coreth/plugin/evm" +// "github.com/ava-labs/coreth/plugin/evm" - ethcommon "github.com/ethereum/go-ethereum/common" +// ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) -var _ Builder = (*builderWithOptions)(nil) +// var _ Builder = (*builderWithOptions)(nil) -type builderWithOptions struct { - Builder - options []common.Option -} +// type builderWithOptions struct { +// Builder +// options []common.Option +// } -// NewBuilderWithOptions returns a new transaction builder that will use the -// given options by default. -// -// - [builder] is the builder that will be called to perform the underlying -// operations. -// - [options] will be provided to the builder in addition to the options -// provided in the method calls. -func NewBuilderWithOptions(builder Builder, options ...common.Option) Builder { - return &builderWithOptions{ - Builder: builder, - options: options, - } -} +// // NewBuilderWithOptions returns a new transaction builder that will use the +// // given options by default. +// // +// // - [builder] is the builder that will be called to perform the underlying +// // operations. +// // - [options] will be provided to the builder in addition to the options +// // provided in the method calls. +// func NewBuilderWithOptions(builder Builder, options ...common.Option) Builder { +// return &builderWithOptions{ +// Builder: builder, +// options: options, +// } +// } -func (b *builderWithOptions) GetBalance( - options ...common.Option, -) (*big.Int, error) { - return b.Builder.GetBalance( - common.UnionOptions(b.options, options)..., - ) -} +// func (b *builderWithOptions) GetBalance( +// options ...common.Option, +// ) (*big.Int, error) { +// return b.Builder.GetBalance( +// common.UnionOptions(b.options, options)..., +// ) +// } -func (b *builderWithOptions) GetImportableBalance( - chainID ids.ID, - options ...common.Option, -) (uint64, error) { - return b.Builder.GetImportableBalance( - chainID, - common.UnionOptions(b.options, options)..., - ) -} +// func (b *builderWithOptions) GetImportableBalance( +// chainID ids.ID, +// options ...common.Option, +// ) (uint64, error) { +// return b.Builder.GetImportableBalance( +// chainID, +// common.UnionOptions(b.options, options)..., +// ) +// } -func (b *builderWithOptions) NewImportTx( - chainID ids.ID, - to ethcommon.Address, - baseFee *big.Int, - options ...common.Option, -) (*evm.UnsignedImportTx, error) { - return b.Builder.NewImportTx( - chainID, - to, - baseFee, - common.UnionOptions(b.options, options)..., - ) -} +// func (b *builderWithOptions) NewImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedImportTx, error) { +// return b.Builder.NewImportTx( +// chainID, +// to, +// baseFee, +// common.UnionOptions(b.options, options)..., +// ) +// } -func (b *builderWithOptions) NewExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - baseFee *big.Int, - options ...common.Option, -) (*evm.UnsignedExportTx, error) { - return b.Builder.NewExportTx( - chainID, - outputs, - baseFee, - common.UnionOptions(b.options, options)..., - ) -} +// func (b *builderWithOptions) NewExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedExportTx, error) { +// return b.Builder.NewExportTx( +// chainID, +// outputs, +// baseFee, +// common.UnionOptions(b.options, options)..., +// ) +// } diff --git a/wallet/chain/c/context.go b/wallet/chain/c/context.go index d506b42f81fa..1c01d8fb55c8 100644 --- a/wallet/chain/c/context.go +++ b/wallet/chain/c/context.go @@ -3,81 +3,81 @@ package c -import ( - stdcontext "context" +// import ( +// stdcontext "context" - "github.com/ava-labs/avalanchego/api/info" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/avm" -) +// "github.com/ava-labs/avalanchego/api/info" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/vms/avm" +// ) -var _ Context = (*context)(nil) +// var _ Context = (*context)(nil) -type Context interface { - NetworkID() uint32 - BlockchainID() ids.ID - AVAXAssetID() ids.ID -} +// type Context interface { +// NetworkID() uint32 +// BlockchainID() ids.ID +// AVAXAssetID() ids.ID +// } -type context struct { - networkID uint32 - blockchainID ids.ID - avaxAssetID ids.ID -} +// type context struct { +// networkID uint32 +// blockchainID ids.ID +// avaxAssetID ids.ID +// } -func NewContextFromURI(ctx stdcontext.Context, uri string) (Context, error) { - infoClient := info.NewClient(uri) - xChainClient := avm.NewClient(uri, "X") - return NewContextFromClients(ctx, infoClient, xChainClient) -} +// func NewContextFromURI(ctx stdcontext.Context, uri string) (Context, error) { +// infoClient := info.NewClient(uri) +// xChainClient := avm.NewClient(uri, "X") +// return NewContextFromClients(ctx, infoClient, xChainClient) +// } -func NewContextFromClients( - ctx stdcontext.Context, - infoClient info.Client, - xChainClient avm.Client, -) (Context, error) { - networkID, err := infoClient.GetNetworkID(ctx) - if err != nil { - return nil, err - } +// func NewContextFromClients( +// ctx stdcontext.Context, +// infoClient info.Client, +// xChainClient avm.Client, +// ) (Context, error) { +// networkID, err := infoClient.GetNetworkID(ctx) +// if err != nil { +// return nil, err +// } - chainID, err := infoClient.GetBlockchainID(ctx, "C") - if err != nil { - return nil, err - } +// chainID, err := infoClient.GetBlockchainID(ctx, "C") +// if err != nil { +// return nil, err +// } - asset, err := xChainClient.GetAssetDescription(ctx, "AVAX") - if err != nil { - return nil, err - } +// asset, err := xChainClient.GetAssetDescription(ctx, "AVAX") +// if err != nil { +// return nil, err +// } - return NewContext( - networkID, - chainID, - asset.AssetID, - ), nil -} +// return NewContext( +// networkID, +// chainID, +// asset.AssetID, +// ), nil +// } -func NewContext( - networkID uint32, - blockchainID ids.ID, - avaxAssetID ids.ID, -) Context { - return &context{ - networkID: networkID, - blockchainID: blockchainID, - avaxAssetID: avaxAssetID, - } -} +// func NewContext( +// networkID uint32, +// blockchainID ids.ID, +// avaxAssetID ids.ID, +// ) Context { +// return &context{ +// networkID: networkID, +// blockchainID: blockchainID, +// avaxAssetID: avaxAssetID, +// } +// } -func (c *context) NetworkID() uint32 { - return c.networkID -} +// func (c *context) NetworkID() uint32 { +// return c.networkID +// } -func (c *context) BlockchainID() ids.ID { - return c.blockchainID -} +// func (c *context) BlockchainID() ids.ID { +// return c.blockchainID +// } -func (c *context) AVAXAssetID() ids.ID { - return c.avaxAssetID -} +// func (c *context) AVAXAssetID() ids.ID { +// return c.avaxAssetID +// } diff --git a/wallet/chain/c/signer.go b/wallet/chain/c/signer.go index 4fd85ed3b532..4bedc378234b 100644 --- a/wallet/chain/c/signer.go +++ b/wallet/chain/c/signer.go @@ -3,221 +3,221 @@ package c -import ( - "errors" - "fmt" - - stdcontext "context" - - "github.com/ava-labs/coreth/plugin/evm" - - ethcommon "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/avalanchego/database" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/crypto/keychain" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/hashing" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/components/verify" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" -) - -const version = 0 - -var ( - _ Signer = (*txSigner)(nil) - - errUnknownInputType = errors.New("unknown input type") - errUnknownCredentialType = errors.New("unknown credential type") - errUnknownOutputType = errors.New("unknown output type") - errInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") - - emptySig [secp256k1.SignatureLen]byte -) - -type Signer interface { - SignUnsignedAtomic(ctx stdcontext.Context, tx evm.UnsignedAtomicTx) (*evm.Tx, error) - SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error -} - -type EthKeychain interface { - // The returned Signer can provide a signature for [addr] - GetEth(addr ethcommon.Address) (keychain.Signer, bool) - // Returns the set of addresses for which the accessor keeps an associated - // signer - EthAddresses() set.Set[ethcommon.Address] -} - -type SignerBackend interface { - GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) -} - -type txSigner struct { - avaxKC keychain.Keychain - ethKC EthKeychain - backend SignerBackend -} - -func NewSigner(avaxKC keychain.Keychain, ethKC EthKeychain, backend SignerBackend) Signer { - return &txSigner{ - avaxKC: avaxKC, - ethKC: ethKC, - backend: backend, - } -} - -func (s *txSigner) SignUnsignedAtomic(ctx stdcontext.Context, utx evm.UnsignedAtomicTx) (*evm.Tx, error) { - tx := &evm.Tx{UnsignedAtomicTx: utx} - return tx, s.SignAtomic(ctx, tx) -} - -func (s *txSigner) SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error { - switch utx := tx.UnsignedAtomicTx.(type) { - case *evm.UnsignedImportTx: - signers, err := s.getImportSigners(ctx, utx.SourceChain, utx.ImportedInputs) - if err != nil { - return err - } - return sign(tx, true, signers) - case *evm.UnsignedExportTx: - signers := s.getExportSigners(utx.Ins) - return sign(tx, true, signers) - default: - return fmt.Errorf("%w: %T", errUnknownTxType, tx) - } -} - -func (s *txSigner) getImportSigners(ctx stdcontext.Context, sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { - txSigners := make([][]keychain.Signer, len(ins)) - for credIndex, transferInput := range ins { - input, ok := transferInput.In.(*secp256k1fx.TransferInput) - if !ok { - return nil, errUnknownInputType - } - - inputSigners := make([]keychain.Signer, len(input.SigIndices)) - txSigners[credIndex] = inputSigners - - utxoID := transferInput.InputID() - utxo, err := s.backend.GetUTXO(ctx, sourceChainID, utxoID) - if err == database.ErrNotFound { - // If we don't have access to the UTXO, then we can't sign this - // transaction. However, we can attempt to partially sign it. - continue - } - if err != nil { - return nil, err - } - - out, ok := utxo.Out.(*secp256k1fx.TransferOutput) - if !ok { - return nil, errUnknownOutputType - } - - for sigIndex, addrIndex := range input.SigIndices { - if addrIndex >= uint32(len(out.Addrs)) { - return nil, errInvalidUTXOSigIndex - } - - addr := out.Addrs[addrIndex] - key, ok := s.avaxKC.Get(addr) - if !ok { - // If we don't have access to the key, then we can't sign this - // transaction. However, we can attempt to partially sign it. - continue - } - inputSigners[sigIndex] = key - } - } - return txSigners, nil -} - -func (s *txSigner) getExportSigners(ins []evm.EVMInput) [][]keychain.Signer { - txSigners := make([][]keychain.Signer, len(ins)) - for credIndex, input := range ins { - inputSigners := make([]keychain.Signer, 1) - txSigners[credIndex] = inputSigners - - key, ok := s.ethKC.GetEth(input.Address) - if !ok { - // If we don't have access to the key, then we can't sign this - // transaction. However, we can attempt to partially sign it. - continue - } - inputSigners[0] = key - } - return txSigners -} - -// TODO: remove [signHash] after the ledger supports signing all transactions. -func sign(tx *evm.Tx, signHash bool, txSigners [][]keychain.Signer) error { - unsignedBytes, err := evm.Codec.Marshal(version, &tx.UnsignedAtomicTx) - if err != nil { - return fmt.Errorf("couldn't marshal unsigned tx: %w", err) - } - unsignedHash := hashing.ComputeHash256(unsignedBytes) - - if expectedLen := len(txSigners); expectedLen != len(tx.Creds) { - tx.Creds = make([]verify.Verifiable, expectedLen) - } - - sigCache := make(map[ids.ShortID][secp256k1.SignatureLen]byte) - for credIndex, inputSigners := range txSigners { - credIntf := tx.Creds[credIndex] - if credIntf == nil { - credIntf = &secp256k1fx.Credential{} - tx.Creds[credIndex] = credIntf - } - - cred, ok := credIntf.(*secp256k1fx.Credential) - if !ok { - return errUnknownCredentialType - } - if expectedLen := len(inputSigners); expectedLen != len(cred.Sigs) { - cred.Sigs = make([][secp256k1.SignatureLen]byte, expectedLen) - } - - for sigIndex, signer := range inputSigners { - if signer == nil { - // If we don't have access to the key, then we can't sign this - // transaction. However, we can attempt to partially sign it. - continue - } - addr := signer.Address() - if sig := cred.Sigs[sigIndex]; sig != emptySig { - // If this signature has already been populated, we can just - // copy the needed signature for the future. - sigCache[addr] = sig - continue - } - - if sig, exists := sigCache[addr]; exists { - // If this key has already produced a signature, we can just - // copy the previous signature. - cred.Sigs[sigIndex] = sig - continue - } - - var sig []byte - if signHash { - sig, err = signer.SignHash(unsignedHash) - } else { - sig, err = signer.Sign(unsignedBytes) - } - if err != nil { - return fmt.Errorf("problem signing tx: %w", err) - } - copy(cred.Sigs[sigIndex][:], sig) - sigCache[addr] = cred.Sigs[sigIndex] - } - } - - signedBytes, err := evm.Codec.Marshal(version, tx) - if err != nil { - return fmt.Errorf("couldn't marshal tx: %w", err) - } - tx.Initialize(unsignedBytes, signedBytes) - return nil -} +// import ( +// "errors" +// "fmt" + +// stdcontext "context" + +// "github.com/ava-labs/coreth/plugin/evm" + +// ethcommon "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/avalanchego/database" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/utils/crypto/keychain" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// "github.com/ava-labs/avalanchego/utils/hashing" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/components/verify" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// ) + +// const version = 0 + +// var ( +// _ Signer = (*txSigner)(nil) + +// errUnknownInputType = errors.New("unknown input type") +// errUnknownCredentialType = errors.New("unknown credential type") +// errUnknownOutputType = errors.New("unknown output type") +// errInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") + +// emptySig [secp256k1.SignatureLen]byte +// ) + +// type Signer interface { +// SignUnsignedAtomic(ctx stdcontext.Context, tx evm.UnsignedAtomicTx) (*evm.Tx, error) +// SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error +// } + +// type EthKeychain interface { +// // The returned Signer can provide a signature for [addr] +// GetEth(addr ethcommon.Address) (keychain.Signer, bool) +// // Returns the set of addresses for which the accessor keeps an associated +// // signer +// EthAddresses() set.Set[ethcommon.Address] +// } + +// type SignerBackend interface { +// GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) +// } + +// type txSigner struct { +// avaxKC keychain.Keychain +// ethKC EthKeychain +// backend SignerBackend +// } + +// func NewSigner(avaxKC keychain.Keychain, ethKC EthKeychain, backend SignerBackend) Signer { +// return &txSigner{ +// avaxKC: avaxKC, +// ethKC: ethKC, +// backend: backend, +// } +// } + +// func (s *txSigner) SignUnsignedAtomic(ctx stdcontext.Context, utx evm.UnsignedAtomicTx) (*evm.Tx, error) { +// tx := &evm.Tx{UnsignedAtomicTx: utx} +// return tx, s.SignAtomic(ctx, tx) +// } + +// func (s *txSigner) SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error { +// switch utx := tx.UnsignedAtomicTx.(type) { +// case *evm.UnsignedImportTx: +// signers, err := s.getImportSigners(ctx, utx.SourceChain, utx.ImportedInputs) +// if err != nil { +// return err +// } +// return sign(tx, true, signers) +// case *evm.UnsignedExportTx: +// signers := s.getExportSigners(utx.Ins) +// return sign(tx, true, signers) +// default: +// return fmt.Errorf("%w: %T", errUnknownTxType, tx) +// } +// } + +// func (s *txSigner) getImportSigners(ctx stdcontext.Context, sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { +// txSigners := make([][]keychain.Signer, len(ins)) +// for credIndex, transferInput := range ins { +// input, ok := transferInput.In.(*secp256k1fx.TransferInput) +// if !ok { +// return nil, errUnknownInputType +// } + +// inputSigners := make([]keychain.Signer, len(input.SigIndices)) +// txSigners[credIndex] = inputSigners + +// utxoID := transferInput.InputID() +// utxo, err := s.backend.GetUTXO(ctx, sourceChainID, utxoID) +// if err == database.ErrNotFound { +// // If we don't have access to the UTXO, then we can't sign this +// // transaction. However, we can attempt to partially sign it. +// continue +// } +// if err != nil { +// return nil, err +// } + +// out, ok := utxo.Out.(*secp256k1fx.TransferOutput) +// if !ok { +// return nil, errUnknownOutputType +// } + +// for sigIndex, addrIndex := range input.SigIndices { +// if addrIndex >= uint32(len(out.Addrs)) { +// return nil, errInvalidUTXOSigIndex +// } + +// addr := out.Addrs[addrIndex] +// key, ok := s.avaxKC.Get(addr) +// if !ok { +// // If we don't have access to the key, then we can't sign this +// // transaction. However, we can attempt to partially sign it. +// continue +// } +// inputSigners[sigIndex] = key +// } +// } +// return txSigners, nil +// } + +// func (s *txSigner) getExportSigners(ins []evm.EVMInput) [][]keychain.Signer { +// txSigners := make([][]keychain.Signer, len(ins)) +// for credIndex, input := range ins { +// inputSigners := make([]keychain.Signer, 1) +// txSigners[credIndex] = inputSigners + +// key, ok := s.ethKC.GetEth(input.Address) +// if !ok { +// // If we don't have access to the key, then we can't sign this +// // transaction. However, we can attempt to partially sign it. +// continue +// } +// inputSigners[0] = key +// } +// return txSigners +// } + +// // TODO: remove [signHash] after the ledger supports signing all transactions. +// func sign(tx *evm.Tx, signHash bool, txSigners [][]keychain.Signer) error { +// unsignedBytes, err := evm.Codec.Marshal(version, &tx.UnsignedAtomicTx) +// if err != nil { +// return fmt.Errorf("couldn't marshal unsigned tx: %w", err) +// } +// unsignedHash := hashing.ComputeHash256(unsignedBytes) + +// if expectedLen := len(txSigners); expectedLen != len(tx.Creds) { +// tx.Creds = make([]verify.Verifiable, expectedLen) +// } + +// sigCache := make(map[ids.ShortID][secp256k1.SignatureLen]byte) +// for credIndex, inputSigners := range txSigners { +// credIntf := tx.Creds[credIndex] +// if credIntf == nil { +// credIntf = &secp256k1fx.Credential{} +// tx.Creds[credIndex] = credIntf +// } + +// cred, ok := credIntf.(*secp256k1fx.Credential) +// if !ok { +// return errUnknownCredentialType +// } +// if expectedLen := len(inputSigners); expectedLen != len(cred.Sigs) { +// cred.Sigs = make([][secp256k1.SignatureLen]byte, expectedLen) +// } + +// for sigIndex, signer := range inputSigners { +// if signer == nil { +// // If we don't have access to the key, then we can't sign this +// // transaction. However, we can attempt to partially sign it. +// continue +// } +// addr := signer.Address() +// if sig := cred.Sigs[sigIndex]; sig != emptySig { +// // If this signature has already been populated, we can just +// // copy the needed signature for the future. +// sigCache[addr] = sig +// continue +// } + +// if sig, exists := sigCache[addr]; exists { +// // If this key has already produced a signature, we can just +// // copy the previous signature. +// cred.Sigs[sigIndex] = sig +// continue +// } + +// var sig []byte +// if signHash { +// sig, err = signer.SignHash(unsignedHash) +// } else { +// sig, err = signer.Sign(unsignedBytes) +// } +// if err != nil { +// return fmt.Errorf("problem signing tx: %w", err) +// } +// copy(cred.Sigs[sigIndex][:], sig) +// sigCache[addr] = cred.Sigs[sigIndex] +// } +// } + +// signedBytes, err := evm.Codec.Marshal(version, tx) +// if err != nil { +// return fmt.Errorf("couldn't marshal tx: %w", err) +// } +// tx.Initialize(unsignedBytes, signedBytes) +// return nil +// } diff --git a/wallet/chain/c/wallet.go b/wallet/chain/c/wallet.go index fb1a83d53dad..ebee50a9a958 100644 --- a/wallet/chain/c/wallet.go +++ b/wallet/chain/c/wallet.go @@ -3,204 +3,204 @@ package c -import ( - "errors" - "math/big" - "time" - - "github.com/ava-labs/coreth/ethclient" - "github.com/ava-labs/coreth/plugin/evm" - - ethcommon "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var ( - _ Wallet = (*wallet)(nil) - - errNotCommitted = errors.New("not committed") -) - -type Wallet interface { - Context - - // Builder returns the builder that will be used to create the transactions. - Builder() Builder - - // Signer returns the signer that will be used to sign the transactions. - Signer() Signer - - // IssueImportTx creates, signs, and issues an import transaction that - // attempts to consume all the available UTXOs and import the funds to [to]. - // - // - [chainID] specifies the chain to be importing funds from. - // - [to] specifies where to send the imported funds to. - IssueImportTx( - chainID ids.ID, - to ethcommon.Address, - options ...common.Option, - ) (*evm.Tx, error) - - // IssueExportTx creates, signs, and issues an export transaction that - // attempts to send all the provided [outputs] to the requested [chainID]. - // - // - [chainID] specifies the chain to be exporting the funds to. - // - [outputs] specifies the outputs to send to the [chainID]. - IssueExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - options ...common.Option, - ) (*evm.Tx, error) - - // IssueUnsignedTx signs and issues the unsigned tx. - IssueUnsignedAtomicTx( - utx evm.UnsignedAtomicTx, - options ...common.Option, - ) (*evm.Tx, error) - - // IssueAtomicTx issues the signed tx. - IssueAtomicTx( - tx *evm.Tx, - options ...common.Option, - ) error -} - -func NewWallet( - builder Builder, - signer Signer, - avaxClient evm.Client, - ethClient ethclient.Client, - backend Backend, -) Wallet { - return &wallet{ - Backend: backend, - builder: builder, - signer: signer, - avaxClient: avaxClient, - ethClient: ethClient, - } -} - -type wallet struct { - Backend - builder Builder - signer Signer - avaxClient evm.Client - ethClient ethclient.Client -} - -func (w *wallet) Builder() Builder { - return w.builder -} - -func (w *wallet) Signer() Signer { - return w.signer -} - -func (w *wallet) IssueImportTx( - chainID ids.ID, - to ethcommon.Address, - options ...common.Option, -) (*evm.Tx, error) { - baseFee, err := w.baseFee(options) - if err != nil { - return nil, err - } - - utx, err := w.builder.NewImportTx(chainID, to, baseFee, options...) - if err != nil { - return nil, err - } - return w.IssueUnsignedAtomicTx(utx, options...) -} - -func (w *wallet) IssueExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - options ...common.Option, -) (*evm.Tx, error) { - baseFee, err := w.baseFee(options) - if err != nil { - return nil, err - } - - utx, err := w.builder.NewExportTx(chainID, outputs, baseFee, options...) - if err != nil { - return nil, err - } - return w.IssueUnsignedAtomicTx(utx, options...) -} - -func (w *wallet) IssueUnsignedAtomicTx( - utx evm.UnsignedAtomicTx, - options ...common.Option, -) (*evm.Tx, error) { - ops := common.NewOptions(options) - ctx := ops.Context() - tx, err := w.signer.SignUnsignedAtomic(ctx, utx) - if err != nil { - return nil, err - } - - return tx, w.IssueAtomicTx(tx, options...) -} - -func (w *wallet) IssueAtomicTx( - tx *evm.Tx, - options ...common.Option, -) error { - ops := common.NewOptions(options) - ctx := ops.Context() - txID, err := w.avaxClient.IssueTx(ctx, tx.SignedBytes()) - if err != nil { - return err - } - - if f := ops.PostIssuanceFunc(); f != nil { - f(txID) - } - - if ops.AssumeDecided() { - return w.Backend.AcceptAtomicTx(ctx, tx) - } - - pollFrequency := ops.PollFrequency() - ticker := time.NewTicker(pollFrequency) - defer ticker.Stop() - - for { - status, err := w.avaxClient.GetAtomicTxStatus(ctx, txID) - if err != nil { - return err - } - - switch status { - case evm.Accepted: - return w.Backend.AcceptAtomicTx(ctx, tx) - case evm.Dropped, evm.Unknown: - return errNotCommitted - } - - // The tx is Processing. - - select { - case <-ticker.C: - case <-ctx.Done(): - return ctx.Err() - } - } -} - -func (w *wallet) baseFee(options []common.Option) (*big.Int, error) { - ops := common.NewOptions(options) - baseFee := ops.BaseFee(nil) - if baseFee != nil { - return baseFee, nil - } - - ctx := ops.Context() - return w.ethClient.EstimateBaseFee(ctx) -} +// import ( +// "errors" +// "math/big" +// "time" + +// "github.com/ava-labs/coreth/ethclient" +// "github.com/ava-labs/coreth/plugin/evm" + +// ethcommon "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var ( +// _ Wallet = (*wallet)(nil) + +// errNotCommitted = errors.New("not committed") +// ) + +// type Wallet interface { +// Context + +// // Builder returns the builder that will be used to create the transactions. +// Builder() Builder + +// // Signer returns the signer that will be used to sign the transactions. +// Signer() Signer + +// // IssueImportTx creates, signs, and issues an import transaction that +// // attempts to consume all the available UTXOs and import the funds to [to]. +// // +// // - [chainID] specifies the chain to be importing funds from. +// // - [to] specifies where to send the imported funds to. +// IssueImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// options ...common.Option, +// ) (*evm.Tx, error) + +// // IssueExportTx creates, signs, and issues an export transaction that +// // attempts to send all the provided [outputs] to the requested [chainID]. +// // +// // - [chainID] specifies the chain to be exporting the funds to. +// // - [outputs] specifies the outputs to send to the [chainID]. +// IssueExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// options ...common.Option, +// ) (*evm.Tx, error) + +// // IssueUnsignedTx signs and issues the unsigned tx. +// IssueUnsignedAtomicTx( +// utx evm.UnsignedAtomicTx, +// options ...common.Option, +// ) (*evm.Tx, error) + +// // IssueAtomicTx issues the signed tx. +// IssueAtomicTx( +// tx *evm.Tx, +// options ...common.Option, +// ) error +// } + +// func NewWallet( +// builder Builder, +// signer Signer, +// avaxClient evm.Client, +// ethClient ethclient.Client, +// backend Backend, +// ) Wallet { +// return &wallet{ +// Backend: backend, +// builder: builder, +// signer: signer, +// avaxClient: avaxClient, +// ethClient: ethClient, +// } +// } + +// type wallet struct { +// Backend +// builder Builder +// signer Signer +// avaxClient evm.Client +// ethClient ethclient.Client +// } + +// func (w *wallet) Builder() Builder { +// return w.builder +// } + +// func (w *wallet) Signer() Signer { +// return w.signer +// } + +// func (w *wallet) IssueImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// options ...common.Option, +// ) (*evm.Tx, error) { +// baseFee, err := w.baseFee(options) +// if err != nil { +// return nil, err +// } + +// utx, err := w.builder.NewImportTx(chainID, to, baseFee, options...) +// if err != nil { +// return nil, err +// } +// return w.IssueUnsignedAtomicTx(utx, options...) +// } + +// func (w *wallet) IssueExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// options ...common.Option, +// ) (*evm.Tx, error) { +// baseFee, err := w.baseFee(options) +// if err != nil { +// return nil, err +// } + +// utx, err := w.builder.NewExportTx(chainID, outputs, baseFee, options...) +// if err != nil { +// return nil, err +// } +// return w.IssueUnsignedAtomicTx(utx, options...) +// } + +// func (w *wallet) IssueUnsignedAtomicTx( +// utx evm.UnsignedAtomicTx, +// options ...common.Option, +// ) (*evm.Tx, error) { +// ops := common.NewOptions(options) +// ctx := ops.Context() +// tx, err := w.signer.SignUnsignedAtomic(ctx, utx) +// if err != nil { +// return nil, err +// } + +// return tx, w.IssueAtomicTx(tx, options...) +// } + +// func (w *wallet) IssueAtomicTx( +// tx *evm.Tx, +// options ...common.Option, +// ) error { +// ops := common.NewOptions(options) +// ctx := ops.Context() +// txID, err := w.avaxClient.IssueTx(ctx, tx.SignedBytes()) +// if err != nil { +// return err +// } + +// if f := ops.PostIssuanceFunc(); f != nil { +// f(txID) +// } + +// if ops.AssumeDecided() { +// return w.Backend.AcceptAtomicTx(ctx, tx) +// } + +// pollFrequency := ops.PollFrequency() +// ticker := time.NewTicker(pollFrequency) +// defer ticker.Stop() + +// for { +// status, err := w.avaxClient.GetAtomicTxStatus(ctx, txID) +// if err != nil { +// return err +// } + +// switch status { +// case evm.Accepted: +// return w.Backend.AcceptAtomicTx(ctx, tx) +// case evm.Dropped, evm.Unknown: +// return errNotCommitted +// } + +// // The tx is Processing. + +// select { +// case <-ticker.C: +// case <-ctx.Done(): +// return ctx.Err() +// } +// } +// } + +// func (w *wallet) baseFee(options []common.Option) (*big.Int, error) { +// ops := common.NewOptions(options) +// baseFee := ops.BaseFee(nil) +// if baseFee != nil { +// return baseFee, nil +// } + +// ctx := ops.Context() +// return w.ethClient.EstimateBaseFee(ctx) +// } diff --git a/wallet/chain/c/wallet_with_options.go b/wallet/chain/c/wallet_with_options.go index 7d6193683d49..fd69a6d4fd02 100644 --- a/wallet/chain/c/wallet_with_options.go +++ b/wallet/chain/c/wallet_with_options.go @@ -3,80 +3,80 @@ package c -import ( - "github.com/ava-labs/coreth/plugin/evm" +// import ( +// "github.com/ava-labs/coreth/plugin/evm" - ethcommon "github.com/ethereum/go-ethereum/common" +// ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) -var _ Wallet = (*walletWithOptions)(nil) +// var _ Wallet = (*walletWithOptions)(nil) -func NewWalletWithOptions( - wallet Wallet, - options ...common.Option, -) Wallet { - return &walletWithOptions{ - Wallet: wallet, - options: options, - } -} +// func NewWalletWithOptions( +// wallet Wallet, +// options ...common.Option, +// ) Wallet { +// return &walletWithOptions{ +// Wallet: wallet, +// options: options, +// } +// } -type walletWithOptions struct { - Wallet - options []common.Option -} +// type walletWithOptions struct { +// Wallet +// options []common.Option +// } -func (w *walletWithOptions) Builder() Builder { - return NewBuilderWithOptions( - w.Wallet.Builder(), - w.options..., - ) -} +// func (w *walletWithOptions) Builder() Builder { +// return NewBuilderWithOptions( +// w.Wallet.Builder(), +// w.options..., +// ) +// } -func (w *walletWithOptions) IssueImportTx( - chainID ids.ID, - to ethcommon.Address, - options ...common.Option, -) (*evm.Tx, error) { - return w.Wallet.IssueImportTx( - chainID, - to, - common.UnionOptions(w.options, options)..., - ) -} +// func (w *walletWithOptions) IssueImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// options ...common.Option, +// ) (*evm.Tx, error) { +// return w.Wallet.IssueImportTx( +// chainID, +// to, +// common.UnionOptions(w.options, options)..., +// ) +// } -func (w *walletWithOptions) IssueExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - options ...common.Option, -) (*evm.Tx, error) { - return w.Wallet.IssueExportTx( - chainID, - outputs, - common.UnionOptions(w.options, options)..., - ) -} +// func (w *walletWithOptions) IssueExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// options ...common.Option, +// ) (*evm.Tx, error) { +// return w.Wallet.IssueExportTx( +// chainID, +// outputs, +// common.UnionOptions(w.options, options)..., +// ) +// } -func (w *walletWithOptions) IssueUnsignedAtomicTx( - utx evm.UnsignedAtomicTx, - options ...common.Option, -) (*evm.Tx, error) { - return w.Wallet.IssueUnsignedAtomicTx( - utx, - common.UnionOptions(w.options, options)..., - ) -} +// func (w *walletWithOptions) IssueUnsignedAtomicTx( +// utx evm.UnsignedAtomicTx, +// options ...common.Option, +// ) (*evm.Tx, error) { +// return w.Wallet.IssueUnsignedAtomicTx( +// utx, +// common.UnionOptions(w.options, options)..., +// ) +// } -func (w *walletWithOptions) IssueAtomicTx( - tx *evm.Tx, - options ...common.Option, -) error { - return w.Wallet.IssueAtomicTx( - tx, - common.UnionOptions(w.options, options)..., - ) -} +// func (w *walletWithOptions) IssueAtomicTx( +// tx *evm.Tx, +// options ...common.Option, +// ) error { +// return w.Wallet.IssueAtomicTx( +// tx, +// common.UnionOptions(w.options, options)..., +// ) +// } diff --git a/wallet/subnet/primary/api.go b/wallet/subnet/primary/api.go index 3ac72c217884..00ebea6090fd 100644 --- a/wallet/subnet/primary/api.go +++ b/wallet/subnet/primary/api.go @@ -5,12 +5,11 @@ package primary import ( "context" - "fmt" + // "fmt" - "github.com/ava-labs/coreth/ethclient" - "github.com/ava-labs/coreth/plugin/evm" + // "github.com/ava-labs/coreth/ethclient" - "github.com/ethereum/go-ethereum/common" + // "github.com/ethereum/go-ethereum/common" "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/codec" @@ -22,7 +21,8 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/wallet/chain/c" + + // "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/x" ) @@ -59,9 +59,9 @@ type AVAXState struct { PCTX p.Context XClient avm.Client XCTX x.Context - CClient evm.Client - CCTX c.Context - UTXOs UTXOs + // CClient evm.Client + // CCTX c.Context + UTXOs UTXOs } func FetchState( @@ -75,7 +75,7 @@ func FetchState( infoClient := info.NewClient(uri) pClient := platformvm.NewClient(uri) xClient := avm.NewClient(uri, "X") - cClient := evm.NewCChainClient(uri) + // cClient := evm.NewCChainClient(uri) pCTX, err := p.NewContextFromClients(ctx, infoClient, xClient) if err != nil { @@ -87,10 +87,10 @@ func FetchState( return nil, err } - cCTX, err := c.NewContextFromClients(ctx, infoClient, xClient) - if err != nil { - return nil, err - } + // cCTX, err := c.NewContextFromClients(ctx, infoClient, xClient) + // if err != nil { + // return nil, err + // } utxos := NewUTXOs() addrList := addrs.List() @@ -109,11 +109,11 @@ func FetchState( client: xClient, codec: x.Parser.Codec(), }, - { - id: cCTX.BlockchainID(), - client: cClient, - codec: evm.Codec, - }, + // { + // id: cCTX.BlockchainID(), + // client: cClient, + // codec: evm.Codec, + // }, } for _, destinationChain := range chains { for _, sourceChain := range chains { @@ -136,52 +136,52 @@ func FetchState( PCTX: pCTX, XClient: xClient, XCTX: xCTX, - CClient: cClient, - CCTX: cCTX, - UTXOs: utxos, + // CClient: cClient, + // CCTX: cCTX, + UTXOs: utxos, }, nil } -type EthState struct { - Client ethclient.Client - Accounts map[common.Address]*c.Account -} - -func FetchEthState( - ctx context.Context, - uri string, - addrs set.Set[common.Address], -) (*EthState, error) { - path := fmt.Sprintf( - "%s/ext/%s/C/rpc", - uri, - constants.ChainAliasPrefix, - ) - client, err := ethclient.Dial(path) - if err != nil { - return nil, err - } - - accounts := make(map[common.Address]*c.Account, addrs.Len()) - for addr := range addrs { - balance, err := client.BalanceAt(ctx, addr, nil) - if err != nil { - return nil, err - } - nonce, err := client.NonceAt(ctx, addr, nil) - if err != nil { - return nil, err - } - accounts[addr] = &c.Account{ - Balance: balance, - Nonce: nonce, - } - } - return &EthState{ - Client: client, - Accounts: accounts, - }, nil -} +// type EthState struct { +// Client ethclient.Client +// Accounts map[common.Address]*c.Account +// } + +// func FetchEthState( +// ctx context.Context, +// uri string, +// addrs set.Set[common.Address], +// ) (*EthState, error) { +// path := fmt.Sprintf( +// "%s/ext/%s/C/rpc", +// uri, +// constants.ChainAliasPrefix, +// ) +// client, err := ethclient.Dial(path) +// if err != nil { +// return nil, err +// } + +// accounts := make(map[common.Address]*c.Account, addrs.Len()) +// for addr := range addrs { +// balance, err := client.BalanceAt(ctx, addr, nil) +// if err != nil { +// return nil, err +// } +// nonce, err := client.NonceAt(ctx, addr, nil) +// if err != nil { +// return nil, err +// } +// accounts[addr] = &c.Account{ +// Balance: balance, +// Nonce: nonce, +// } +// } +// return &EthState{ +// Client: client, +// Accounts: accounts, +// }, nil +// } // AddAllUTXOs fetches all the UTXOs referenced by [addresses] that were sent // from [sourceChainID] to [destinationChainID] from the [client]. It then uses diff --git a/wallet/subnet/primary/example_test.go b/wallet/subnet/primary/example_test.go index 483c049d4ac0..4a73e8c070b2 100644 --- a/wallet/subnet/primary/example_test.go +++ b/wallet/subnet/primary/example_test.go @@ -30,7 +30,7 @@ func ExampleWallet() { wallet, err := MakeWallet(ctx, &WalletConfig{ URI: LocalAPIURI, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet with: %s\n", err) diff --git a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go index d5e8ce422307..21c081d2982b 100644 --- a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go +++ b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go @@ -46,9 +46,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + // EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/examples/add-primary-validator/main.go b/wallet/subnet/primary/examples/add-primary-validator/main.go index a56dae23db3a..13c28f995f63 100644 --- a/wallet/subnet/primary/examples/add-primary-validator/main.go +++ b/wallet/subnet/primary/examples/add-primary-validator/main.go @@ -45,7 +45,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/c-chain-export/main.go b/wallet/subnet/primary/examples/c-chain-export/main.go index fec55c899feb..a6b9a0c810b8 100644 --- a/wallet/subnet/primary/examples/c-chain-export/main.go +++ b/wallet/subnet/primary/examples/c-chain-export/main.go @@ -3,70 +3,70 @@ package main -import ( - "context" - "log" - "time" +// import ( +// "context" +// "log" +// "time" - "github.com/ava-labs/avalanchego/genesis" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary" -) +// "github.com/ava-labs/avalanchego/genesis" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary" +// ) -func main() { - key := genesis.EWOQKey - uri := primary.LocalAPIURI - kc := secp256k1fx.NewKeychain(key) - avaxAddr := key.Address() +// func main() { +// key := genesis.EWOQKey +// uri := primary.LocalAPIURI +// kc := secp256k1fx.NewKeychain(key) +// avaxAddr := key.Address() - ctx := context.Background() +// ctx := context.Background() - // MakeWallet fetches the available UTXOs owned by [kc] on the network that - // [uri] is hosting. - walletSyncStartTime := time.Now() - wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, - }) - if err != nil { - log.Fatalf("failed to initialize wallet: %s\n", err) - } - log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) +// // MakeWallet fetches the available UTXOs owned by [kc] on the network that +// // [uri] is hosting. +// walletSyncStartTime := time.Now() +// wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ +// URI: uri, +// AVAXKeychain: kc, +// EthKeychain: kc, +// }) +// if err != nil { +// log.Fatalf("failed to initialize wallet: %s\n", err) +// } +// log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) - // Get the P-chain wallet - pWallet := wallet.P() - cWallet := wallet.C() +// // Get the P-chain wallet +// pWallet := wallet.P() +// cWallet := wallet.C() - // Pull out useful constants to use when issuing transactions. - cChainID := cWallet.BlockchainID() - owner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - avaxAddr, - }, - } +// // Pull out useful constants to use when issuing transactions. +// cChainID := cWallet.BlockchainID() +// owner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// avaxAddr, +// }, +// } - exportStartTime := time.Now() - exportTx, err := cWallet.IssueExportTx( - constants.PlatformChainID, - []*secp256k1fx.TransferOutput{{ - Amt: units.Avax, - OutputOwners: owner, - }}, - ) - if err != nil { - log.Fatalf("failed to issue export transaction: %s\n", err) - } - log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) +// exportStartTime := time.Now() +// exportTx, err := cWallet.IssueExportTx( +// constants.PlatformChainID, +// []*secp256k1fx.TransferOutput{{ +// Amt: units.Avax, +// OutputOwners: owner, +// }}, +// ) +// if err != nil { +// log.Fatalf("failed to issue export transaction: %s\n", err) +// } +// log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) - importStartTime := time.Now() - importTx, err := pWallet.IssueImportTx(cChainID, &owner) - if err != nil { - log.Fatalf("failed to issue import transaction: %s\n", err) - } - log.Printf("issued import %s in %s\n", importTx.ID(), time.Since(importStartTime)) -} +// importStartTime := time.Now() +// importTx, err := pWallet.IssueImportTx(cChainID, &owner) +// if err != nil { +// log.Fatalf("failed to issue import transaction: %s\n", err) +// } +// log.Printf("issued import %s in %s\n", importTx.ID(), time.Since(importStartTime)) +// } diff --git a/wallet/subnet/primary/examples/c-chain-import/main.go b/wallet/subnet/primary/examples/c-chain-import/main.go index b4dc4e603eb3..2d9b8a244cb0 100644 --- a/wallet/subnet/primary/examples/c-chain-import/main.go +++ b/wallet/subnet/primary/examples/c-chain-import/main.go @@ -3,75 +3,75 @@ package main -import ( - "context" - "log" - "time" +// import ( +// "context" +// "log" +// "time" - "github.com/ava-labs/coreth/plugin/evm" +// "github.com/ava-labs/coreth/plugin/evm" - "github.com/ava-labs/avalanchego/genesis" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary" -) +// "github.com/ava-labs/avalanchego/genesis" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary" +// ) -func main() { - key := genesis.EWOQKey - uri := primary.LocalAPIURI - kc := secp256k1fx.NewKeychain(key) - avaxAddr := key.Address() - ethAddr := evm.PublicKeyToEthAddress(key.PublicKey()) +// func main() { +// key := genesis.EWOQKey +// uri := primary.LocalAPIURI +// kc := secp256k1fx.NewKeychain(key) +// avaxAddr := key.Address() +// ethAddr := evm.PublicKeyToEthAddress(key.PublicKey()) - ctx := context.Background() +// ctx := context.Background() - // MakeWallet fetches the available UTXOs owned by [kc] on the network that - // [uri] is hosting. - walletSyncStartTime := time.Now() - wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, - }) - if err != nil { - log.Fatalf("failed to initialize wallet: %s\n", err) - } - log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) +// // MakeWallet fetches the available UTXOs owned by [kc] on the network that +// // [uri] is hosting. +// walletSyncStartTime := time.Now() +// wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ +// URI: uri, +// AVAXKeychain: kc, +// EthKeychain: kc, +// }) +// if err != nil { +// log.Fatalf("failed to initialize wallet: %s\n", err) +// } +// log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) - // Get the P-chain wallet - pWallet := wallet.P() - cWallet := wallet.C() +// // Get the P-chain wallet +// pWallet := wallet.P() +// cWallet := wallet.C() - // Pull out useful constants to use when issuing transactions. - cChainID := cWallet.BlockchainID() - avaxAssetID := cWallet.AVAXAssetID() - owner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - avaxAddr, - }, - } +// // Pull out useful constants to use when issuing transactions. +// cChainID := cWallet.BlockchainID() +// avaxAssetID := cWallet.AVAXAssetID() +// owner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// avaxAddr, +// }, +// } - exportStartTime := time.Now() - exportTx, err := pWallet.IssueExportTx(cChainID, []*avax.TransferableOutput{{ - Asset: avax.Asset{ID: avaxAssetID}, - Out: &secp256k1fx.TransferOutput{ - Amt: units.Avax, - OutputOwners: owner, - }, - }}) - if err != nil { - log.Fatalf("failed to issue export transaction: %s\n", err) - } - log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) +// exportStartTime := time.Now() +// exportTx, err := pWallet.IssueExportTx(cChainID, []*avax.TransferableOutput{{ +// Asset: avax.Asset{ID: avaxAssetID}, +// Out: &secp256k1fx.TransferOutput{ +// Amt: units.Avax, +// OutputOwners: owner, +// }, +// }}) +// if err != nil { +// log.Fatalf("failed to issue export transaction: %s\n", err) +// } +// log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) - importStartTime := time.Now() - importTx, err := cWallet.IssueImportTx(constants.PlatformChainID, ethAddr) - if err != nil { - log.Fatalf("failed to issue import transaction: %s\n", err) - } - log.Printf("issued import %s to %s in %s\n", importTx.ID(), ethAddr.Hex(), time.Since(importStartTime)) -} +// importStartTime := time.Now() +// importTx, err := cWallet.IssueImportTx(constants.PlatformChainID, ethAddr) +// if err != nil { +// log.Fatalf("failed to issue import transaction: %s\n", err) +// } +// log.Printf("issued import %s to %s in %s\n", importTx.ID(), ethAddr.Hex(), time.Since(importStartTime)) +// } diff --git a/wallet/subnet/primary/examples/create-asset/main.go b/wallet/subnet/primary/examples/create-asset/main.go index 30804f083df6..0bccfbb5fc52 100644 --- a/wallet/subnet/primary/examples/create-asset/main.go +++ b/wallet/subnet/primary/examples/create-asset/main.go @@ -30,7 +30,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/create-chain/main.go b/wallet/subnet/primary/examples/create-chain/main.go index 5e6898a1b649..521a3cca53cf 100644 --- a/wallet/subnet/primary/examples/create-chain/main.go +++ b/wallet/subnet/primary/examples/create-chain/main.go @@ -41,9 +41,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + // EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/examples/create-locked-stakeable/main.go b/wallet/subnet/primary/examples/create-locked-stakeable/main.go index e688968e9e8a..92f1b5cb0e1b 100644 --- a/wallet/subnet/primary/examples/create-locked-stakeable/main.go +++ b/wallet/subnet/primary/examples/create-locked-stakeable/main.go @@ -39,7 +39,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/create-subnet/main.go b/wallet/subnet/primary/examples/create-subnet/main.go index add98ea7931c..3e8d69bc016a 100644 --- a/wallet/subnet/primary/examples/create-subnet/main.go +++ b/wallet/subnet/primary/examples/create-subnet/main.go @@ -28,7 +28,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/remove-subnet-validator/main.go b/wallet/subnet/primary/examples/remove-subnet-validator/main.go index 2842c7c0a790..46f4b85124db 100644 --- a/wallet/subnet/primary/examples/remove-subnet-validator/main.go +++ b/wallet/subnet/primary/examples/remove-subnet-validator/main.go @@ -38,9 +38,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + // EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/wallet.go b/wallet/subnet/primary/wallet.go index 54de390d029c..ae5e4202a099 100644 --- a/wallet/subnet/primary/wallet.go +++ b/wallet/subnet/primary/wallet.go @@ -11,7 +11,8 @@ import ( "github.com/ava-labs/avalanchego/utils/crypto/keychain" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/wallet/chain/c" + + // "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/x" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -23,13 +24,13 @@ var _ Wallet = (*wallet)(nil) type Wallet interface { P() p.Wallet X() x.Wallet - C() c.Wallet + // C() c.Wallet } type wallet struct { p p.Wallet x x.Wallet - c c.Wallet + // c c.Wallet } func (w *wallet) P() p.Wallet { @@ -40,16 +41,16 @@ func (w *wallet) X() x.Wallet { return w.x } -func (w *wallet) C() c.Wallet { - return w.c -} +// func (w *wallet) C() c.Wallet { +// return w.c +// } // Creates a new default wallet -func NewWallet(p p.Wallet, x x.Wallet, c c.Wallet) Wallet { +func NewWallet(p p.Wallet, x x.Wallet /*, c c.Wallet*/) Wallet { return &wallet{ p: p, x: x, - c: c, + // c: c, } } @@ -58,7 +59,7 @@ func NewWalletWithOptions(w Wallet, options ...common.Option) Wallet { return NewWallet( p.NewWalletWithOptions(w.P(), options...), x.NewWalletWithOptions(w.X(), options...), - c.NewWalletWithOptions(w.C(), options...), + // c.NewWalletWithOptions(w.C(), options...), ) } @@ -67,7 +68,7 @@ type WalletConfig struct { URI string // required // Keys to use for signing all transactions. AVAXKeychain keychain.Keychain // required - EthKeychain c.EthKeychain // required + // EthKeychain c.EthKeychain // required // Set of P-chain transactions that the wallet should know about to be able // to generate transactions. PChainTxs map[ids.ID]*txs.Tx // optional @@ -93,11 +94,11 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { return nil, err } - ethAddrs := config.EthKeychain.EthAddresses() - ethState, err := FetchEthState(ctx, config.URI, ethAddrs) - if err != nil { - return nil, err - } + // ethAddrs := config.EthKeychain.EthAddresses() + // ethState, err := FetchEthState(ctx, config.URI, ethAddrs) + // if err != nil { + // return nil, err + // } pChainTxs := config.PChainTxs if pChainTxs == nil { @@ -127,15 +128,15 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { xBuilder := x.NewBuilder(avaxAddrs, xBackend) xSigner := x.NewSigner(config.AVAXKeychain, xBackend) - cChainID := avaxState.CCTX.BlockchainID() - cUTXOs := NewChainUTXOs(cChainID, avaxState.UTXOs) - cBackend := c.NewBackend(avaxState.CCTX, cUTXOs, ethState.Accounts) - cBuilder := c.NewBuilder(avaxAddrs, ethAddrs, cBackend) - cSigner := c.NewSigner(config.AVAXKeychain, config.EthKeychain, cBackend) + // cChainID := avaxState.CCTX.BlockchainID() + // cUTXOs := NewChainUTXOs(cChainID, avaxState.UTXOs) + // cBackend := c.NewBackend(avaxState.CCTX, cUTXOs, ethState.Accounts) + // cBuilder := c.NewBuilder(avaxAddrs, ethAddrs, cBackend) + // cSigner := c.NewSigner(config.AVAXKeychain, config.EthKeychain, cBackend) return NewWallet( p.NewWallet(pBuilder, pSigner, avaxState.PClient, pBackend), x.NewWallet(xBuilder, xSigner, avaxState.XClient, xBackend), - c.NewWallet(cBuilder, cSigner, avaxState.CClient, ethState.Client, cBackend), + // c.NewWallet(cBuilder, cSigner, avaxState.CClient, ethState.Client, cBackend), ), nil } From 78cc14b422c84d27ee3887d1e661a47ced3351f4 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Sun, 3 Dec 2023 16:16:48 +0100 Subject: [PATCH 07/13] bumped coreth version --- go.mod | 25 + go.sum | 76 ++ node/node.go | 4 +- tests/e2e/c/dynamic_fees.go | 326 +++---- tests/e2e/c/interchain_workflow.go | 320 +++---- tests/e2e/p/interchain_workflow.go | 444 +++++----- tests/e2e/x/interchain_workflow.go | 296 +++---- tests/fixture/e2e/helpers.go | 123 ++- tests/fixture/tmpnet/config.go | 56 +- vms/example/xsvm/cmd/chain/create/cmd.go | 6 +- wallet/chain/c/backend.go | 300 +++---- wallet/chain/c/builder.go | 792 +++++++++--------- wallet/chain/c/builder_with_options.go | 136 +-- wallet/chain/c/context.go | 130 +-- wallet/chain/c/signer.go | 436 +++++----- wallet/chain/c/wallet.go | 402 ++++----- wallet/chain/c/wallet_with_options.go | 134 +-- wallet/subnet/primary/api.go | 122 +-- wallet/subnet/primary/example_test.go | 2 +- .../add-permissioned-subnet-validator/main.go | 6 +- .../examples/add-primary-validator/main.go | 2 +- .../primary/examples/c-chain-export/main.go | 118 +-- .../primary/examples/c-chain-import/main.go | 126 +-- .../primary/examples/create-asset/main.go | 2 +- .../primary/examples/create-chain/main.go | 6 +- .../examples/create-locked-stakeable/main.go | 2 +- .../primary/examples/create-subnet/main.go | 2 +- .../examples/remove-subnet-validator/main.go | 6 +- wallet/subnet/primary/wallet.go | 43 +- 29 files changed, 2270 insertions(+), 2173 deletions(-) diff --git a/go.mod b/go.mod index 23b752198fdd..8b6595134563 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 + github.com/ava-labs/coreth v0.12.9-rc.9.0.20231203150607-6b4bc85e7fd3 github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 @@ -74,6 +75,7 @@ require ( github.com/BurntSushi/toml v1.2.1 // indirect github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect + github.com/VictoriaMetrics/fastcache v1.10.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect @@ -81,26 +83,44 @@ require ( github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/redact v1.1.3 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/deckarep/golang-set/v2 v2.1.0 // indirect + github.com/dlclark/regexp2 v1.7.0 // indirect + github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 // indirect + github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect github.com/frankban/quicktest v1.14.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/getsentry/sentry-go v0.18.0 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect + github.com/go-stack/stack v1.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/go-cmp v0.5.9 // indirect + github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect + github.com/google/uuid v1.3.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 // indirect + github.com/hashicorp/go-bexpr v0.1.10 // indirect + github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e // indirect github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/klauspost/compress v1.15.15 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/magiconair/properties v1.8.6 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mitchellh/pointerstructure v1.2.0 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -108,12 +128,17 @@ require ( github.com/prometheus/common v0.39.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sanity-io/litter v1.5.1 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/status-im/keycard-go v0.2.0 // indirect github.com/subosito/gotenv v1.3.0 // indirect github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tklauser/numcpus v0.2.2 // indirect + github.com/tyler-smith/go-bip39 v1.1.0 // indirect + github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect diff --git a/go.sum b/go.sum index 2ae152b17faf..33be6882fdfc 100644 --- a/go.sum +++ b/go.sum @@ -56,12 +56,18 @@ github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cq github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= +github.com/VictoriaMetrics/fastcache v1.10.0 h1:5hDJnLsKLpnUEToub7ETuRu8RCkb40woBZAUiKonXzY= +github.com/VictoriaMetrics/fastcache v1.10.0/go.mod h1:tjiYeEfYXCqacuvYw/7UoDIeJaNxq6132xHICNP77w8= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/ava-labs/coreth v0.12.9-rc.9.0.20231203150607-6b4bc85e7fd3 h1:8rhv9HbAVk6HA47BxMp9G1TKqzjR7SU9KdKBWLgzAYQ= +github.com/ava-labs/coreth v0.12.9-rc.9.0.20231203150607-6b4bc85e7fd3/go.mod h1:andnP2rPsMwF6eyeUmYto5B3z6PjemJXZwroqS5yGMs= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= @@ -96,13 +102,18 @@ github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46f github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw= github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA= @@ -134,12 +145,16 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= +github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= @@ -150,6 +165,14 @@ github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6ps github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= +github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 h1:+3HCtB74++ClLy8GgjUQYeC8R4ILzVcIe8+5edAJJnE= +github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= +github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= +github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -166,6 +189,8 @@ github.com/ethereum/go-ethereum v1.12.0 h1:bdnhLPtqETd4m3mS8BGMNvBTf36bO5bx/hxE2 github.com/ethereum/go-ethereum v1.12.0/go.mod h1:/oo2X/dZLJjf2mJ6YT9wcWxa4nNJDBKDBU6sFIpx1Gs= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -174,6 +199,8 @@ github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmV github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= @@ -197,7 +224,11 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= +github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= @@ -282,10 +313,14 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= @@ -306,11 +341,17 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 h1:kr3j8iIMR4ywO/O0rvksXaJvauGGCMg2zAZIiNZ9uIQ= github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0/go.mod h1:ummNFgdgLhhX7aIiy35vVmQNS0rWXknfPE0qe6fmFXg= +github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e h1:pIYdhNkDh+YENVNi3gto8n9hAmRxKxoar0iE6BLucjw= +github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e/go.mod h1:j9cQbcqHQujT0oKJ38PylVfqohClLr3CvDC+Qcg+lhU= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c h1:DZfsyhDK1hnSS5lH8l+JggqzEleHteTYfutAiVlSUM8= @@ -322,6 +363,7 @@ github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3 github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -363,6 +405,7 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -370,6 +413,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= @@ -380,11 +424,17 @@ github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPK github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= @@ -393,8 +443,11 @@ github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -413,6 +466,8 @@ github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -480,6 +535,8 @@ github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sanity-io/litter v1.5.1 h1:dwnrSypP6q56o3lFxTU+t2fwQ9A+U5qrXVO4Qg9KwVU= github.com/sanity-io/litter v1.5.1/go.mod h1:5Z71SvaYy5kcGtyglXOC9rrUi3c1E8CamFWjQsazTh0= @@ -515,6 +572,8 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= +github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= +github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -546,10 +605,14 @@ github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZF github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE= github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa h1:5SqCsI/2Qya2bCzK15ozrqo2sZxkh0FHynJZOTVoV6Q= +github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= @@ -561,6 +624,8 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= @@ -570,6 +635,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= @@ -665,6 +731,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -710,6 +777,7 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -733,6 +801,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -797,8 +866,12 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -815,6 +888,7 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -878,6 +952,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1002,6 +1077,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= diff --git a/node/node.go b/node/node.go index d8905719fa6e..40eb8dc16bef 100644 --- a/node/node.go +++ b/node/node.go @@ -25,7 +25,7 @@ import ( "go.uber.org/zap" - // coreth "github.com/ava-labs/coreth/plugin/evm" + coreth "github.com/ava-labs/coreth/plugin/evm" "github.com/ava-labs/avalanchego/api/admin" "github.com/ava-labs/avalanchego/api/auth" @@ -1094,7 +1094,7 @@ func (n *Node) initVMs() error { CreateAssetTxFee: n.Config.CreateAssetTxFee, }, }), - // vmRegisterer.Register(context.TODO(), constants.EVMID, &coreth.Factory{}), + vmRegisterer.Register(context.TODO(), constants.EVMID, &coreth.Factory{}), n.VMManager.RegisterFactory(context.TODO(), secp256k1fx.ID, &secp256k1fx.Factory{}), n.VMManager.RegisterFactory(context.TODO(), nftfx.ID, &nftfx.Factory{}), n.VMManager.RegisterFactory(context.TODO(), propertyfx.ID, &propertyfx.Factory{}), diff --git a/tests/e2e/c/dynamic_fees.go b/tests/e2e/c/dynamic_fees.go index 8748dda7451d..38bbd668079b 100644 --- a/tests/e2e/c/dynamic_fees.go +++ b/tests/e2e/c/dynamic_fees.go @@ -3,166 +3,166 @@ package c -// import ( -// "math/big" -// "strings" - -// ginkgo "github.com/onsi/ginkgo/v2" - -// "github.com/stretchr/testify/require" - -// "github.com/ethereum/go-ethereum/accounts/abi" -// "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/coreth/core/types" -// "github.com/ava-labs/coreth/params" -// "github.com/ava-labs/coreth/plugin/evm" - -// "github.com/ava-labs/avalanchego/tests" -// "github.com/ava-labs/avalanchego/tests/e2e" -// "github.com/ava-labs/avalanchego/tests/fixture/testnet" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// ) - -// // This test uses the compiled bin for `hashing.sol` as -// // well as its ABI contained in `hashing_contract.go`. - -// var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { -// require := require.New(ginkgo.GinkgoT()) - -// // Need a gas limit much larger than the standard 21_000 to enable -// // the contract to induce a gas price increase -// const largeGasLimit = uint64(8_000_000) - -// // TODO(marun) What is the significance of this value? -// gasTip := big.NewInt(1000 * params.GWei) - -// ginkgo.It("should ensure that the gas price is affected by load", func() { -// ginkgo.By("creating a new private network to ensure isolation from other tests") -// privateNetwork := e2e.Env.NewPrivateNetwork() - -// ginkgo.By("allocating a pre-funded key") -// key := privateNetwork.GetConfig().FundedKeys[0] -// ethAddress := evm.GetEthAddress(key) - -// ginkgo.By("initializing a coreth client") -// node := privateNetwork.GetNodes()[0] -// nodeURI := testnet.NodeURI{ -// NodeID: node.GetID(), -// URI: node.GetProcessContext().URI, -// } -// ethClient := e2e.NewEthClient(nodeURI) - -// ginkgo.By("initializing a transaction signer") -// cChainID, err := ethClient.ChainID(e2e.DefaultContext()) -// require.NoError(err) -// signer := types.NewEIP155Signer(cChainID) -// ecdsaKey := key.ToECDSA() -// sign := func(tx *types.Transaction) *types.Transaction { -// signedTx, err := types.SignTx(tx, signer, ecdsaKey) -// require.NoError(err) -// return signedTx -// } - -// var contractAddress common.Address -// ginkgo.By("deploying an expensive contract", func() { -// // Create transaction -// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) -// require.NoError(err) -// compiledContract := common.Hex2Bytes(hashingCompiledContract) -// tx := types.NewTx(&types.LegacyTx{ -// Nonce: nonce, -// GasPrice: gasTip, -// Gas: largeGasLimit, -// Value: common.Big0, -// Data: compiledContract, -// }) - -// // Send the transaction and wait for acceptance -// signedTx := sign(tx) -// receipt := e2e.SendEthTransaction(ethClient, signedTx) - -// contractAddress = receipt.ContractAddress -// }) - -// var gasPrice *big.Int -// ginkgo.By("calling the expensive contract repeatedly until a gas price increase is detected", func() { -// // Evaluate the bytes representation of the contract -// hashingABI, err := abi.JSON(strings.NewReader(hashingABIJson)) -// require.NoError(err) -// contractData, err := hashingABI.Pack("hashIt") -// require.NoError(err) - -// var initialGasPrice *big.Int -// e2e.Eventually(func() bool { -// // Check the gas price -// var err error -// gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) -// require.NoError(err) -// if initialGasPrice == nil { -// initialGasPrice = gasPrice -// tests.Outf("{{blue}}initial gas price is %v{{/}}\n", initialGasPrice) -// } else if gasPrice.Cmp(initialGasPrice) > 0 { -// // Gas price has increased -// tests.Outf("{{blue}}gas price has increased to %v{{/}}\n", gasPrice) -// return true -// } - -// // Create the transaction -// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) -// require.NoError(err) -// tx := types.NewTx(&types.LegacyTx{ -// Nonce: nonce, -// GasPrice: gasTip, -// Gas: largeGasLimit, -// To: &contractAddress, -// Value: common.Big0, -// Data: contractData, -// }) - -// // Send the transaction and wait for acceptance -// signedTx := sign(tx) -// _ = e2e.SendEthTransaction(ethClient, signedTx) - -// // The gas price will be checked at the start of the next iteration -// return false -// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price increase before timeout") -// }) - -// ginkgo.By("waiting for the gas price to decrease...", func() { -// initialGasPrice := gasPrice -// e2e.Eventually(func() bool { -// var err error -// gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) -// require.NoError(err) -// tests.Outf("{{blue}}.{{/}}") -// return initialGasPrice.Cmp(gasPrice) > 0 -// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price decrease before timeout") -// tests.Outf("\n{{blue}}gas price has decreased to %v{{/}}\n", gasPrice) -// }) - -// ginkgo.By("sending funds at the current gas price", func() { -// // Create a recipient address -// recipientKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) -// recipientEthAddress := evm.GetEthAddress(recipientKey) - -// // Create transaction -// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) -// require.NoError(err) -// tx := types.NewTx(&types.LegacyTx{ -// Nonce: nonce, -// GasPrice: gasPrice, -// Gas: e2e.DefaultGasLimit, -// To: &recipientEthAddress, -// Value: common.Big0, -// }) - -// // Send the transaction and wait for acceptance -// signedTx := sign(tx) -// _ = e2e.SendEthTransaction(ethClient, signedTx) -// }) - -// e2e.CheckBootstrapIsPossible(privateNetwork) -// }) -// }) +import ( + "math/big" + "strings" + + ginkgo "github.com/onsi/ginkgo/v2" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm" + + "github.com/ava-labs/avalanchego/tests" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +) + +// This test uses the compiled bin for `hashing.sol` as +// well as its ABI contained in `hashing_contract.go`. + +var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { + require := require.New(ginkgo.GinkgoT()) + + // Need a gas limit much larger than the standard 21_000 to enable + // the contract to induce a gas price increase + const largeGasLimit = uint64(8_000_000) + + // TODO(marun) What is the significance of this value? + gasTip := big.NewInt(1000 * params.GWei) + + ginkgo.It("should ensure that the gas price is affected by load", func() { + ginkgo.By("creating a new private network to ensure isolation from other tests") + privateNetwork := e2e.Env.NewPrivateNetwork() + + ginkgo.By("allocating a pre-funded key") + key := privateNetwork.GetConfig().FundedKeys[0] + ethAddress := evm.GetEthAddress(key) + + ginkgo.By("initializing a coreth client") + node := privateNetwork.GetNodes()[0] + nodeURI := tmpnet.NodeURI{ + NodeID: node.GetID(), + URI: node.GetProcessContext().URI, + } + ethClient := e2e.NewEthClient(nodeURI) + + ginkgo.By("initializing a transaction signer") + cChainID, err := ethClient.ChainID(e2e.DefaultContext()) + require.NoError(err) + signer := types.NewEIP155Signer(cChainID) + ecdsaKey := key.ToECDSA() + sign := func(tx *types.Transaction) *types.Transaction { + signedTx, err := types.SignTx(tx, signer, ecdsaKey) + require.NoError(err) + return signedTx + } + + var contractAddress common.Address + ginkgo.By("deploying an expensive contract", func() { + // Create transaction + nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) + require.NoError(err) + compiledContract := common.Hex2Bytes(hashingCompiledContract) + tx := types.NewTx(&types.LegacyTx{ + Nonce: nonce, + GasPrice: gasTip, + Gas: largeGasLimit, + Value: common.Big0, + Data: compiledContract, + }) + + // Send the transaction and wait for acceptance + signedTx := sign(tx) + receipt := e2e.SendEthTransaction(ethClient, signedTx) + + contractAddress = receipt.ContractAddress + }) + + var gasPrice *big.Int + ginkgo.By("calling the expensive contract repeatedly until a gas price increase is detected", func() { + // Evaluate the bytes representation of the contract + hashingABI, err := abi.JSON(strings.NewReader(hashingABIJson)) + require.NoError(err) + contractData, err := hashingABI.Pack("hashIt") + require.NoError(err) + + var initialGasPrice *big.Int + e2e.Eventually(func() bool { + // Check the gas price + var err error + gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) + require.NoError(err) + if initialGasPrice == nil { + initialGasPrice = gasPrice + tests.Outf("{{blue}}initial gas price is %v{{/}}\n", initialGasPrice) + } else if gasPrice.Cmp(initialGasPrice) > 0 { + // Gas price has increased + tests.Outf("{{blue}}gas price has increased to %v{{/}}\n", gasPrice) + return true + } + + // Create the transaction + nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) + require.NoError(err) + tx := types.NewTx(&types.LegacyTx{ + Nonce: nonce, + GasPrice: gasTip, + Gas: largeGasLimit, + To: &contractAddress, + Value: common.Big0, + Data: contractData, + }) + + // Send the transaction and wait for acceptance + signedTx := sign(tx) + _ = e2e.SendEthTransaction(ethClient, signedTx) + + // The gas price will be checked at the start of the next iteration + return false + }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price increase before timeout") + }) + + ginkgo.By("waiting for the gas price to decrease...", func() { + initialGasPrice := gasPrice + e2e.Eventually(func() bool { + var err error + gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) + require.NoError(err) + tests.Outf("{{blue}}.{{/}}") + return initialGasPrice.Cmp(gasPrice) > 0 + }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price decrease before timeout") + tests.Outf("\n{{blue}}gas price has decreased to %v{{/}}\n", gasPrice) + }) + + ginkgo.By("sending funds at the current gas price", func() { + // Create a recipient address + recipientKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + recipientEthAddress := evm.GetEthAddress(recipientKey) + + // Create transaction + nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) + require.NoError(err) + tx := types.NewTx(&types.LegacyTx{ + Nonce: nonce, + GasPrice: gasPrice, + Gas: e2e.DefaultGasLimit, + To: &recipientEthAddress, + Value: common.Big0, + }) + + // Send the transaction and wait for acceptance + signedTx := sign(tx) + _ = e2e.SendEthTransaction(ethClient, signedTx) + }) + + e2e.CheckBootstrapIsPossible(privateNetwork) + }) +}) diff --git a/tests/e2e/c/interchain_workflow.go b/tests/e2e/c/interchain_workflow.go index c5af17c750bf..2c9bd198ec39 100644 --- a/tests/e2e/c/interchain_workflow.go +++ b/tests/e2e/c/interchain_workflow.go @@ -3,163 +3,163 @@ package c -// import ( -// "math/big" - -// ginkgo "github.com/onsi/ginkgo/v2" - -// "github.com/stretchr/testify/require" - -// "github.com/ava-labs/coreth/core/types" -// "github.com/ava-labs/coreth/plugin/evm" - -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/tests/e2e" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var _ = e2e.DescribeCChain("[Interchain Workflow]", func() { -// require := require.New(ginkgo.GinkgoT()) - -// const txAmount = 10 * units.Avax // Arbitrary amount to send and transfer - -// ginkgo.It("should ensure that funds can be transferred from the C-Chain to the X-Chain and the P-Chain", func() { -// ginkgo.By("initializing a new eth client") -// // Select a random node URI to use for both the eth client and -// // the wallet to avoid having to verify that all nodes are at -// // the same height before initializing the wallet. -// nodeURI := e2e.Env.GetRandomNodeURI() -// ethClient := e2e.NewEthClient(nodeURI) - -// ginkgo.By("allocating a pre-funded key to send from and a recipient key to deliver to") -// senderKey := e2e.Env.AllocateFundedKey() -// senderEthAddress := evm.GetEthAddress(senderKey) -// recipientKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) -// recipientEthAddress := evm.GetEthAddress(recipientKey) - -// ginkgo.By("sending funds from one address to another on the C-Chain", func() { -// // Create transaction -// acceptedNonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), senderEthAddress) -// require.NoError(err) -// gasPrice := e2e.SuggestGasPrice(ethClient) -// tx := types.NewTransaction( -// acceptedNonce, -// recipientEthAddress, -// big.NewInt(int64(txAmount)), -// e2e.DefaultGasLimit, -// gasPrice, -// nil, -// ) - -// // Sign transaction -// cChainID, err := ethClient.ChainID(e2e.DefaultContext()) -// require.NoError(err) -// signer := types.NewEIP155Signer(cChainID) -// signedTx, err := types.SignTx(tx, signer, senderKey.ToECDSA()) -// require.NoError(err) - -// _ = e2e.SendEthTransaction(ethClient, signedTx) - -// ginkgo.By("waiting for the C-Chain recipient address to have received the sent funds") -// e2e.Eventually(func() bool { -// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) -// require.NoError(err) -// return balance.Cmp(big.NewInt(0)) > 0 -// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see funds delivered before timeout") -// }) - -// // Wallet must be initialized after sending funds on the -// // C-Chain with the same node URI to ensure wallet state -// // matches on-chain state. -// ginkgo.By("initializing a keychain and associated wallet") -// keychain := secp256k1fx.NewKeychain(senderKey, recipientKey) -// baseWallet := e2e.NewWallet(keychain, nodeURI) -// xWallet := baseWallet.X() -// cWallet := baseWallet.C() -// pWallet := baseWallet.P() - -// ginkgo.By("defining common configuration") -// avaxAssetID := xWallet.AVAXAssetID() -// // Use the same owner for import funds to X-Chain and P-Chain -// recipientOwner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// recipientKey.Address(), -// }, -// } -// // Use the same outputs for both X-Chain and P-Chain exports -// exportOutputs := []*secp256k1fx.TransferOutput{ -// { -// Amt: txAmount, -// OutputOwners: secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// keychain.Keys[0].Address(), -// }, -// }, -// }, -// } - -// ginkgo.By("exporting AVAX from the C-Chain to the X-Chain", func() { -// _, err := cWallet.IssueExportTx( -// xWallet.BlockchainID(), -// exportOutputs, -// e2e.WithDefaultContext(), -// e2e.WithSuggestedGasPrice(ethClient), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("importing AVAX from the C-Chain to the X-Chain", func() { -// _, err := xWallet.IssueImportTx( -// cWallet.BlockchainID(), -// &recipientOwner, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { -// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// ginkgo.By("exporting AVAX from the C-Chain to the P-Chain", func() { -// _, err := cWallet.IssueExportTx( -// constants.PlatformChainID, -// exportOutputs, -// e2e.WithDefaultContext(), -// e2e.WithSuggestedGasPrice(ethClient), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("importing AVAX from the C-Chain to the P-Chain", func() { -// _, err = pWallet.IssueImportTx( -// cWallet.BlockchainID(), -// &recipientOwner, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { -// balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) -// }) -// }) +import ( + "math/big" + + ginkgo "github.com/onsi/ginkgo/v2" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/coreth/plugin/evm" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var _ = e2e.DescribeCChain("[Interchain Workflow]", func() { + require := require.New(ginkgo.GinkgoT()) + + const txAmount = 10 * units.Avax // Arbitrary amount to send and transfer + + ginkgo.It("should ensure that funds can be transferred from the C-Chain to the X-Chain and the P-Chain", func() { + ginkgo.By("initializing a new eth client") + // Select a random node URI to use for both the eth client and + // the wallet to avoid having to verify that all nodes are at + // the same height before initializing the wallet. + nodeURI := e2e.Env.GetRandomNodeURI() + ethClient := e2e.NewEthClient(nodeURI) + + ginkgo.By("allocating a pre-funded key to send from and a recipient key to deliver to") + senderKey := e2e.Env.AllocateFundedKey() + senderEthAddress := evm.GetEthAddress(senderKey) + recipientKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + recipientEthAddress := evm.GetEthAddress(recipientKey) + + ginkgo.By("sending funds from one address to another on the C-Chain", func() { + // Create transaction + acceptedNonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), senderEthAddress) + require.NoError(err) + gasPrice := e2e.SuggestGasPrice(ethClient) + tx := types.NewTransaction( + acceptedNonce, + recipientEthAddress, + big.NewInt(int64(txAmount)), + e2e.DefaultGasLimit, + gasPrice, + nil, + ) + + // Sign transaction + cChainID, err := ethClient.ChainID(e2e.DefaultContext()) + require.NoError(err) + signer := types.NewEIP155Signer(cChainID) + signedTx, err := types.SignTx(tx, signer, senderKey.ToECDSA()) + require.NoError(err) + + _ = e2e.SendEthTransaction(ethClient, signedTx) + + ginkgo.By("waiting for the C-Chain recipient address to have received the sent funds") + e2e.Eventually(func() bool { + balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) + require.NoError(err) + return balance.Cmp(big.NewInt(0)) > 0 + }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see funds delivered before timeout") + }) + + // Wallet must be initialized after sending funds on the + // C-Chain with the same node URI to ensure wallet state + // matches on-chain state. + ginkgo.By("initializing a keychain and associated wallet") + keychain := secp256k1fx.NewKeychain(senderKey, recipientKey) + baseWallet := e2e.NewWallet(keychain, nodeURI) + xWallet := baseWallet.X() + cWallet := baseWallet.C() + pWallet := baseWallet.P() + + ginkgo.By("defining common configuration") + avaxAssetID := xWallet.AVAXAssetID() + // Use the same owner for import funds to X-Chain and P-Chain + recipientOwner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + recipientKey.Address(), + }, + } + // Use the same outputs for both X-Chain and P-Chain exports + exportOutputs := []*secp256k1fx.TransferOutput{ + { + Amt: txAmount, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + keychain.Keys[0].Address(), + }, + }, + }, + } + + ginkgo.By("exporting AVAX from the C-Chain to the X-Chain", func() { + _, err := cWallet.IssueExportTx( + xWallet.BlockchainID(), + exportOutputs, + e2e.WithDefaultContext(), + e2e.WithSuggestedGasPrice(ethClient), + ) + require.NoError(err) + }) + + ginkgo.By("importing AVAX from the C-Chain to the X-Chain", func() { + _, err := xWallet.IssueImportTx( + cWallet.BlockchainID(), + &recipientOwner, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { + balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + ginkgo.By("exporting AVAX from the C-Chain to the P-Chain", func() { + _, err := cWallet.IssueExportTx( + constants.PlatformChainID, + exportOutputs, + e2e.WithDefaultContext(), + e2e.WithSuggestedGasPrice(ethClient), + ) + require.NoError(err) + }) + + ginkgo.By("importing AVAX from the C-Chain to the P-Chain", func() { + _, err = pWallet.IssueImportTx( + cWallet.BlockchainID(), + &recipientOwner, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { + balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) + }) +}) diff --git a/tests/e2e/p/interchain_workflow.go b/tests/e2e/p/interchain_workflow.go index e90e0382e286..678f9b5cc204 100644 --- a/tests/e2e/p/interchain_workflow.go +++ b/tests/e2e/p/interchain_workflow.go @@ -3,225 +3,225 @@ package p -// import ( -// "math/big" -// "time" - -// ginkgo "github.com/onsi/ginkgo/v2" - -// "github.com/spf13/cast" - -// "github.com/stretchr/testify/require" - -// "github.com/ava-labs/coreth/plugin/evm" - -// "github.com/ava-labs/avalanchego/api/info" -// "github.com/ava-labs/avalanchego/config" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/tests/e2e" -// "github.com/ava-labs/avalanchego/tests/fixture/testnet" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/platformvm/reward" -// "github.com/ava-labs/avalanchego/vms/platformvm/txs" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { -// require := require.New(ginkgo.GinkgoT()) - -// const ( -// transferAmount = 10 * units.Avax -// weight = 2_000 * units.Avax // Used for both validation and delegation -// ) - -// ginkgo.It("should ensure that funds can be transferred from the P-Chain to the X-Chain and the C-Chain", func() { -// network := e2e.Env.GetNetwork() - -// ginkgo.By("checking that the network has a compatible minimum stake duration", func() { -// minStakeDuration := cast.ToDuration(network.GetConfig().DefaultFlags[config.MinStakeDurationKey]) -// require.Equal(testnet.DefaultMinStakeDuration, minStakeDuration) -// }) - -// ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") -// recipientKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) -// keychain := e2e.Env.NewKeychain(1) -// keychain.Add(recipientKey) -// nodeURI := e2e.Env.GetRandomNodeURI() -// baseWallet := e2e.Env.NewWallet(keychain, nodeURI) -// xWallet := baseWallet.X() -// cWallet := baseWallet.C() -// pWallet := baseWallet.P() - -// ginkgo.By("defining common configuration") -// recipientEthAddress := evm.GetEthAddress(recipientKey) -// avaxAssetID := xWallet.AVAXAssetID() -// // Use the same owner for sending to X-Chain and importing funds to P-Chain -// recipientOwner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// recipientKey.Address(), -// }, -// } -// // Use the same outputs for both X-Chain and C-Chain exports -// exportOutputs := []*avax.TransferableOutput{ -// { -// Asset: avax.Asset{ -// ID: avaxAssetID, -// }, -// Out: &secp256k1fx.TransferOutput{ -// Amt: transferAmount, -// OutputOwners: secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// keychain.Keys[0].Address(), -// }, -// }, -// }, -// }, -// } - -// ginkgo.By("adding new node and waiting for it to report healthy") -// node := e2e.AddEphemeralNode(network, testnet.FlagsMap{}) -// e2e.WaitForHealthy(node) - -// ginkgo.By("retrieving new node's id and pop") -// infoClient := info.NewClient(node.GetProcessContext().URI) -// nodeID, nodePOP, err := infoClient.GetNodeID(e2e.DefaultContext()) -// require.NoError(err) - -// ginkgo.By("adding the new node as a validator", func() { -// startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) -// // Validation duration doesn't actually matter to this -// // test - it is only ensuring that adding a validator -// // doesn't break interchain transfer. -// endTime := startTime.Add(30 * time.Second) - -// rewardKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) - -// const ( -// delegationPercent = 0.10 // 10% -// delegationShare = reward.PercentDenominator * delegationPercent -// ) - -// _, err = pWallet.IssueAddPermissionlessValidatorTx( -// &txs.SubnetValidator{ -// Validator: txs.Validator{ -// NodeID: nodeID, -// Start: uint64(startTime.Unix()), -// End: uint64(endTime.Unix()), -// Wght: weight, -// }, -// Subnet: constants.PrimaryNetworkID, -// }, -// nodePOP, -// pWallet.AVAXAssetID(), -// &secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{rewardKey.Address()}, -// }, -// &secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{rewardKey.Address()}, -// }, -// delegationShare, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("adding a delegator to the new node", func() { -// startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) -// // Delegation duration doesn't actually matter to this -// // test - it is only ensuring that adding a delegator -// // doesn't break interchain transfer. -// endTime := startTime.Add(15 * time.Second) - -// rewardKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) - -// _, err = pWallet.IssueAddPermissionlessDelegatorTx( -// &txs.SubnetValidator{ -// Validator: txs.Validator{ -// NodeID: nodeID, -// Start: uint64(startTime.Unix()), -// End: uint64(endTime.Unix()), -// Wght: weight, -// }, -// Subnet: constants.PrimaryNetworkID, -// }, -// pWallet.AVAXAssetID(), -// &secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{rewardKey.Address()}, -// }, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("exporting AVAX from the P-Chain to the X-Chain", func() { -// _, err := pWallet.IssueExportTx( -// xWallet.BlockchainID(), -// exportOutputs, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("importing AVAX from the P-Chain to the X-Chain", func() { -// _, err := xWallet.IssueImportTx( -// constants.PlatformChainID, -// &recipientOwner, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { -// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// ginkgo.By("exporting AVAX from the P-Chain to the C-Chain", func() { -// _, err := pWallet.IssueExportTx( -// cWallet.BlockchainID(), -// exportOutputs, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("initializing a new eth client") -// ethClient := e2e.NewEthClient(nodeURI) - -// ginkgo.By("importing AVAX from the P-Chain to the C-Chain", func() { -// _, err := cWallet.IssueImportTx( -// constants.PlatformChainID, -// recipientEthAddress, -// e2e.WithDefaultContext(), -// e2e.WithSuggestedGasPrice(ethClient), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") -// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) -// require.NoError(err) -// require.Positive(balance.Cmp(big.NewInt(0))) - -// ginkgo.By("stopping validator node to free up resources for a bootstrap check") -// require.NoError(node.Stop()) - -// e2e.CheckBootstrapIsPossible(network) -// }) -// }) +import ( + "math/big" + "time" + + ginkgo "github.com/onsi/ginkgo/v2" + + "github.com/spf13/cast" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/coreth/plugin/evm" + + "github.com/ava-labs/avalanchego/api/info" + "github.com/ava-labs/avalanchego/config" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/platformvm/reward" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { + require := require.New(ginkgo.GinkgoT()) + + const ( + transferAmount = 10 * units.Avax + weight = 2_000 * units.Avax // Used for both validation and delegation + ) + + ginkgo.It("should ensure that funds can be transferred from the P-Chain to the X-Chain and the C-Chain", func() { + network := e2e.Env.GetNetwork() + + ginkgo.By("checking that the network has a compatible minimum stake duration", func() { + minStakeDuration := cast.ToDuration(network.GetConfig().DefaultFlags[config.MinStakeDurationKey]) + require.Equal(tmpnet.DefaultMinStakeDuration, minStakeDuration) + }) + + ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") + recipientKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + keychain := e2e.Env.NewKeychain(1) + keychain.Add(recipientKey) + nodeURI := e2e.Env.GetRandomNodeURI() + baseWallet := e2e.NewWallet(keychain, nodeURI) + xWallet := baseWallet.X() + cWallet := baseWallet.C() + pWallet := baseWallet.P() + + ginkgo.By("defining common configuration") + recipientEthAddress := evm.GetEthAddress(recipientKey) + avaxAssetID := xWallet.AVAXAssetID() + // Use the same owner for sending to X-Chain and importing funds to P-Chain + recipientOwner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + recipientKey.Address(), + }, + } + // Use the same outputs for both X-Chain and C-Chain exports + exportOutputs := []*avax.TransferableOutput{ + { + Asset: avax.Asset{ + ID: avaxAssetID, + }, + Out: &secp256k1fx.TransferOutput{ + Amt: transferAmount, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + keychain.Keys[0].Address(), + }, + }, + }, + }, + } + + ginkgo.By("adding new node and waiting for it to report healthy") + node := e2e.AddEphemeralNode(network, tmpnet.FlagsMap{}) + e2e.WaitForHealthy(node) + + ginkgo.By("retrieving new node's id and pop") + infoClient := info.NewClient(node.GetProcessContext().URI) + nodeID, nodePOP, err := infoClient.GetNodeID(e2e.DefaultContext()) + require.NoError(err) + + ginkgo.By("adding the new node as a validator", func() { + startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) + // Validation duration doesn't actually matter to this + // test - it is only ensuring that adding a validator + // doesn't break interchain transfer. + endTime := startTime.Add(30 * time.Second) + + rewardKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + + const ( + delegationPercent = 0.10 // 10% + delegationShare = reward.PercentDenominator * delegationPercent + ) + + _, err = pWallet.IssueAddPermissionlessValidatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(endTime.Unix()), + Wght: weight, + }, + Subnet: constants.PrimaryNetworkID, + }, + nodePOP, + pWallet.AVAXAssetID(), + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardKey.Address()}, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardKey.Address()}, + }, + delegationShare, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("adding a delegator to the new node", func() { + startTime := time.Now().Add(e2e.DefaultValidatorStartTimeDiff) + // Delegation duration doesn't actually matter to this + // test - it is only ensuring that adding a delegator + // doesn't break interchain transfer. + endTime := startTime.Add(15 * time.Second) + + rewardKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + + _, err = pWallet.IssueAddPermissionlessDelegatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(endTime.Unix()), + Wght: weight, + }, + Subnet: constants.PrimaryNetworkID, + }, + pWallet.AVAXAssetID(), + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardKey.Address()}, + }, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("exporting AVAX from the P-Chain to the X-Chain", func() { + _, err := pWallet.IssueExportTx( + xWallet.BlockchainID(), + exportOutputs, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("importing AVAX from the P-Chain to the X-Chain", func() { + _, err := xWallet.IssueImportTx( + constants.PlatformChainID, + &recipientOwner, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { + balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + ginkgo.By("exporting AVAX from the P-Chain to the C-Chain", func() { + _, err := pWallet.IssueExportTx( + cWallet.BlockchainID(), + exportOutputs, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("initializing a new eth client") + ethClient := e2e.NewEthClient(nodeURI) + + ginkgo.By("importing AVAX from the P-Chain to the C-Chain", func() { + _, err := cWallet.IssueImportTx( + constants.PlatformChainID, + recipientEthAddress, + e2e.WithDefaultContext(), + e2e.WithSuggestedGasPrice(ethClient), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") + balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) + require.NoError(err) + require.Positive(balance.Cmp(big.NewInt(0))) + + ginkgo.By("stopping validator node to free up resources for a bootstrap check") + require.NoError(node.Stop()) + + e2e.CheckBootstrapIsPossible(network) + }) +}) diff --git a/tests/e2e/x/interchain_workflow.go b/tests/e2e/x/interchain_workflow.go index d738e55a7f7a..f0c2951feb84 100644 --- a/tests/e2e/x/interchain_workflow.go +++ b/tests/e2e/x/interchain_workflow.go @@ -3,151 +3,151 @@ package x -// import ( -// "math/big" - -// ginkgo "github.com/onsi/ginkgo/v2" - -// "github.com/stretchr/testify/require" - -// "github.com/ava-labs/coreth/plugin/evm" - -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/tests/e2e" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var _ = e2e.DescribeXChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { -// require := require.New(ginkgo.GinkgoT()) - -// const transferAmount = 10 * units.Avax - -// ginkgo.It("should ensure that funds can be transferred from the X-Chain to the C-Chain and the P-Chain", func() { -// nodeURI := e2e.Env.GetRandomNodeURI() - -// ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") -// recipientKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) -// keychain := e2e.Env.NewKeychain(1) -// keychain.Add(recipientKey) -// baseWallet := e2e.Env.NewWallet(keychain, nodeURI) -// xWallet := baseWallet.X() -// cWallet := baseWallet.C() -// pWallet := baseWallet.P() - -// ginkgo.By("defining common configuration") -// recipientEthAddress := evm.GetEthAddress(recipientKey) -// avaxAssetID := xWallet.AVAXAssetID() -// // Use the same owner for sending to X-Chain and importing funds to P-Chain -// recipientOwner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// recipientKey.Address(), -// }, -// } -// // Use the same outputs for both C-Chain and P-Chain exports -// exportOutputs := []*avax.TransferableOutput{ -// { -// Asset: avax.Asset{ -// ID: avaxAssetID, -// }, -// Out: &secp256k1fx.TransferOutput{ -// Amt: transferAmount, -// OutputOwners: secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// keychain.Keys[0].Address(), -// }, -// }, -// }, -// }, -// } - -// ginkgo.By("sending funds from one address to another on the X-Chain", func() { -// _, err = xWallet.IssueBaseTx( -// []*avax.TransferableOutput{{ -// Asset: avax.Asset{ -// ID: avaxAssetID, -// }, -// Out: &secp256k1fx.TransferOutput{ -// Amt: transferAmount, -// OutputOwners: recipientOwner, -// }, -// }}, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the X-Chain recipient address has received the sent funds", func() { -// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// ginkgo.By("exporting AVAX from the X-Chain to the C-Chain", func() { -// _, err := xWallet.IssueExportTx( -// cWallet.BlockchainID(), -// exportOutputs, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("initializing a new eth client") -// ethClient := e2e.NewEthClient(nodeURI) - -// ginkgo.By("importing AVAX from the X-Chain to the C-Chain", func() { -// _, err := cWallet.IssueImportTx( -// xWallet.BlockchainID(), -// recipientEthAddress, -// e2e.WithDefaultContext(), -// e2e.WithSuggestedGasPrice(ethClient), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") -// e2e.Eventually(func() bool { -// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) -// require.NoError(err) -// return balance.Cmp(big.NewInt(0)) > 0 -// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see recipient address funded before timeout") - -// ginkgo.By("exporting AVAX from the X-Chain to the P-Chain", func() { -// _, err := xWallet.IssueExportTx( -// constants.PlatformChainID, -// exportOutputs, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("importing AVAX from the X-Chain to the P-Chain", func() { -// _, err := pWallet.IssueImportTx( -// xWallet.BlockchainID(), -// &recipientOwner, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { -// balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) -// }) -// }) +import ( + "math/big" + + ginkgo "github.com/onsi/ginkgo/v2" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/coreth/plugin/evm" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var _ = e2e.DescribeXChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { + require := require.New(ginkgo.GinkgoT()) + + const transferAmount = 10 * units.Avax + + ginkgo.It("should ensure that funds can be transferred from the X-Chain to the C-Chain and the P-Chain", func() { + nodeURI := e2e.Env.GetRandomNodeURI() + + ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") + recipientKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + keychain := e2e.Env.NewKeychain(1) + keychain.Add(recipientKey) + baseWallet := e2e.NewWallet(keychain, nodeURI) + xWallet := baseWallet.X() + cWallet := baseWallet.C() + pWallet := baseWallet.P() + + ginkgo.By("defining common configuration") + recipientEthAddress := evm.GetEthAddress(recipientKey) + avaxAssetID := xWallet.AVAXAssetID() + // Use the same owner for sending to X-Chain and importing funds to P-Chain + recipientOwner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + recipientKey.Address(), + }, + } + // Use the same outputs for both C-Chain and P-Chain exports + exportOutputs := []*avax.TransferableOutput{ + { + Asset: avax.Asset{ + ID: avaxAssetID, + }, + Out: &secp256k1fx.TransferOutput{ + Amt: transferAmount, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + keychain.Keys[0].Address(), + }, + }, + }, + }, + } + + ginkgo.By("sending funds from one address to another on the X-Chain", func() { + _, err = xWallet.IssueBaseTx( + []*avax.TransferableOutput{{ + Asset: avax.Asset{ + ID: avaxAssetID, + }, + Out: &secp256k1fx.TransferOutput{ + Amt: transferAmount, + OutputOwners: recipientOwner, + }, + }}, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the X-Chain recipient address has received the sent funds", func() { + balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + ginkgo.By("exporting AVAX from the X-Chain to the C-Chain", func() { + _, err := xWallet.IssueExportTx( + cWallet.BlockchainID(), + exportOutputs, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("initializing a new eth client") + ethClient := e2e.NewEthClient(nodeURI) + + ginkgo.By("importing AVAX from the X-Chain to the C-Chain", func() { + _, err := cWallet.IssueImportTx( + xWallet.BlockchainID(), + recipientEthAddress, + e2e.WithDefaultContext(), + e2e.WithSuggestedGasPrice(ethClient), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") + e2e.Eventually(func() bool { + balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) + require.NoError(err) + return balance.Cmp(big.NewInt(0)) > 0 + }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see recipient address funded before timeout") + + ginkgo.By("exporting AVAX from the X-Chain to the P-Chain", func() { + _, err := xWallet.IssueExportTx( + constants.PlatformChainID, + exportOutputs, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("importing AVAX from the X-Chain to the P-Chain", func() { + _, err := pWallet.IssueImportTx( + xWallet.BlockchainID(), + &recipientOwner, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { + balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) + }) +}) diff --git a/tests/fixture/e2e/helpers.go b/tests/fixture/e2e/helpers.go index 4cf6d32bdfc2..8b7eb5260b8c 100644 --- a/tests/fixture/e2e/helpers.go +++ b/tests/fixture/e2e/helpers.go @@ -5,23 +5,20 @@ package e2e import ( "context" - - // "errors" - // "fmt" - // "math/big" - + "errors" + "fmt" + "math/big" "os" - - // "strings" + "strings" "time" ginkgo "github.com/onsi/ginkgo/v2" "github.com/stretchr/testify/require" - // "github.com/ava-labs/coreth/core/types" - // "github.com/ava-labs/coreth/ethclient" - // "github.com/ava-labs/coreth/interfaces" + "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/coreth/ethclient" + "github.com/ava-labs/coreth/interfaces" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/tests" @@ -70,7 +67,7 @@ func NewWallet(keychain *secp256k1fx.Keychain, nodeURI tmpnet.NodeURI) primary.W baseWallet, err := primary.MakeWallet(DefaultContext(), &primary.WalletConfig{ URI: nodeURI.URI, AVAXKeychain: keychain, - // EthKeychain: keychain, + EthKeychain: keychain, }) require.NoError(ginkgo.GinkgoT(), err) return primary.NewWalletWithOptions( @@ -83,15 +80,15 @@ func NewWallet(keychain *secp256k1fx.Keychain, nodeURI tmpnet.NodeURI) primary.W ) } -// // Create a new eth client targeting the specified node URI. -// func NewEthClient(nodeURI testnet.NodeURI) ethclient.Client { -// tests.Outf("{{blue}} initializing a new eth client for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) -// nodeAddress := strings.Split(nodeURI.URI, "//")[1] -// uri := fmt.Sprintf("ws://%s/ext/bc/C/ws", nodeAddress) -// client, err := ethclient.Dial(uri) -// require.NoError(ginkgo.GinkgoT(), err) -// return client -// } +// Create a new eth client targeting the specified node URI. +func NewEthClient(nodeURI tmpnet.NodeURI) ethclient.Client { + tests.Outf("{{blue}} initializing a new eth client for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) + nodeAddress := strings.Split(nodeURI.URI, "//")[1] + uri := fmt.Sprintf("ws://%s/ext/bc/C/ws", nodeAddress) + client, err := ethclient.Dial(uri) + require.NoError(ginkgo.GinkgoT(), err) + return client +} // Helper simplifying use of a timed context by canceling the context on ginkgo teardown. func ContextWithTimeout(duration time.Duration) context.Context { @@ -155,49 +152,49 @@ func WaitForHealthy(node tmpnet.Node) { require.NoError(ginkgo.GinkgoT(), tmpnet.WaitForHealthy(ctx, node)) } -// // Sends an eth transaction, waits for the transaction receipt to be issued -// // and checks that the receipt indicates success. -// func SendEthTransaction(ethClient ethclient.Client, signedTx *types.Transaction) *types.Receipt { -// require := require.New(ginkgo.GinkgoT()) - -// txID := signedTx.Hash() -// tests.Outf(" sending eth transaction with ID: %s\n", txID) - -// require.NoError(ethClient.SendTransaction(DefaultContext(), signedTx)) - -// // Wait for the receipt -// var receipt *types.Receipt -// Eventually(func() bool { -// var err error -// receipt, err = ethClient.TransactionReceipt(DefaultContext(), txID) -// if errors.Is(err, interfaces.NotFound) { -// return false // Transaction is still pending -// } -// require.NoError(err) -// return true -// }, DefaultTimeout, DefaultPollingInterval, "failed to see transaction acceptance before timeout") - -// require.Equal(receipt.Status, types.ReceiptStatusSuccessful) -// return receipt -// } - -// // Determines the suggested gas price for the configured client that will -// // maximize the chances of transaction acceptance. -// func SuggestGasPrice(ethClient ethclient.Client) *big.Int { -// gasPrice, err := ethClient.SuggestGasPrice(DefaultContext()) -// require.NoError(ginkgo.GinkgoT(), err) -// // Double the suggested gas price to maximize the chances of -// // acceptance. Maybe this can be revisited pending resolution of -// // https://github.com/ava-labs/coreth/issues/314. -// gasPrice.Add(gasPrice, gasPrice) -// return gasPrice -// } - -// // Helper simplifying use via an option of a gas price appropriate for testing. -// func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { -// baseFee := SuggestGasPrice(ethClient) -// return common.WithBaseFee(baseFee) -// } +// Sends an eth transaction, waits for the transaction receipt to be issued +// and checks that the receipt indicates success. +func SendEthTransaction(ethClient ethclient.Client, signedTx *types.Transaction) *types.Receipt { + require := require.New(ginkgo.GinkgoT()) + + txID := signedTx.Hash() + tests.Outf(" sending eth transaction with ID: %s\n", txID) + + require.NoError(ethClient.SendTransaction(DefaultContext(), signedTx)) + + // Wait for the receipt + var receipt *types.Receipt + Eventually(func() bool { + var err error + receipt, err = ethClient.TransactionReceipt(DefaultContext(), txID) + if errors.Is(err, interfaces.NotFound) { + return false // Transaction is still pending + } + require.NoError(err) + return true + }, DefaultTimeout, DefaultPollingInterval, "failed to see transaction acceptance before timeout") + + require.Equal(receipt.Status, types.ReceiptStatusSuccessful) + return receipt +} + +// Determines the suggested gas price for the configured client that will +// maximize the chances of transaction acceptance. +func SuggestGasPrice(ethClient ethclient.Client) *big.Int { + gasPrice, err := ethClient.SuggestGasPrice(DefaultContext()) + require.NoError(ginkgo.GinkgoT(), err) + // Double the suggested gas price to maximize the chances of + // acceptance. Maybe this can be revisited pending resolution of + // https://github.com/ava-labs/coreth/issues/314. + gasPrice.Add(gasPrice, gasPrice) + return gasPrice +} + +// Helper simplifying use via an option of a gas price appropriate for testing. +func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { + baseFee := SuggestGasPrice(ethClient) + return common.WithBaseFee(baseFee) +} // Verify that a new node can bootstrap into the network. func CheckBootstrapIsPossible(network tmpnet.Network) { diff --git a/tests/fixture/tmpnet/config.go b/tests/fixture/tmpnet/config.go index bc22df0df115..f504eb84d20d 100644 --- a/tests/fixture/tmpnet/config.go +++ b/tests/fixture/tmpnet/config.go @@ -15,9 +15,9 @@ import ( "github.com/spf13/cast" - // "github.com/ava-labs/coreth/core" - // "github.com/ava-labs/coreth/params" - // "github.com/ava-labs/coreth/plugin/evm" + "github.com/ava-labs/coreth/core" + "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm" "github.com/ava-labs/avalanchego/config" "github.com/ava-labs/avalanchego/genesis" @@ -143,15 +143,15 @@ func (c *NetworkConfig) EnsureGenesis(networkID uint32, validatorIDs []ids.NodeI // Ensure pre-funded keys have arbitrary large balances on both chains to support testing xChainBalances := make(XChainBalanceMap, len(c.FundedKeys)) - // cChainBalances := make(core.GenesisAlloc, len(c.FundedKeys)) - // for _, key := range c.FundedKeys { - // xChainBalances[key.Address()] = DefaultFundedKeyXChainAmount - // cChainBalances[evm.GetEthAddress(key)] = core.GenesisAccount{ - // Balance: DefaultFundedKeyCChainAmount, - // } - // } - - genesis, err := NewTestGenesis(networkID, xChainBalances /*, cChainBalances*/, validatorIDs) + cChainBalances := make(core.GenesisAlloc, len(c.FundedKeys)) + for _, key := range c.FundedKeys { + xChainBalances[key.Address()] = DefaultFundedKeyXChainAmount + cChainBalances[evm.GetEthAddress(key)] = core.GenesisAccount{ + Balance: DefaultFundedKeyCChainAmount, + } + } + + genesis, err := NewTestGenesis(networkID, xChainBalances, cChainBalances, validatorIDs) if err != nil { return err } @@ -311,7 +311,7 @@ type XChainBalanceMap map[ids.ShortID]uint64 func NewTestGenesis( networkID uint32, xChainBalances XChainBalanceMap, - // cChainBalances core.GenesisAlloc, + cChainBalances core.GenesisAlloc, validatorIDs []ids.NodeID, ) (*genesis.UnparsedConfig, error) { // Validate inputs @@ -322,7 +322,7 @@ func NewTestGenesis( if len(validatorIDs) == 0 { return nil, errMissingValidatorsForGenesis } - if len(xChainBalances) == 0 /*|| len(cChainBalances) == 0*/ { + if len(xChainBalances) == 0 || len(cChainBalances) == 0 { return nil, errMissingBalancesForGenesis } @@ -394,20 +394,20 @@ func NewTestGenesis( ) } - // // Define C-Chain genesis - // cChainGenesis := &core.Genesis{ - // Config: ¶ms.ChainConfig{ - // ChainID: big.NewInt(43112), // Arbitrary chain ID is arbitrary - // }, - // Difficulty: big.NewInt(0), // Difficulty is a mandatory field - // GasLimit: DefaultGasLimit, - // Alloc: cChainBalances, - // } - // cChainGenesisBytes, err := json.Marshal(cChainGenesis) - // if err != nil { - // return nil, fmt.Errorf("failed to marshal C-Chain genesis: %w", err) - // } - // config.CChainGenesis = string(cChainGenesisBytes) + // Define C-Chain genesis + cChainGenesis := &core.Genesis{ + Config: ¶ms.ChainConfig{ + ChainID: big.NewInt(43112), // Arbitrary chain ID is arbitrary + }, + Difficulty: big.NewInt(0), // Difficulty is a mandatory field + GasLimit: DefaultGasLimit, + Alloc: cChainBalances, + } + cChainGenesisBytes, err := json.Marshal(cChainGenesis) + if err != nil { + return nil, fmt.Errorf("failed to marshal C-Chain genesis: %w", err) + } + config.CChainGenesis = string(cChainGenesisBytes) // Give staking rewards for initial validators to a random address. Any testing of staking rewards // will be easier to perform with nodes other than the initial validators since the timing of diff --git a/vms/example/xsvm/cmd/chain/create/cmd.go b/vms/example/xsvm/cmd/chain/create/cmd.go index 043b4298dcdf..1f00491a4ce6 100644 --- a/vms/example/xsvm/cmd/chain/create/cmd.go +++ b/vms/example/xsvm/cmd/chain/create/cmd.go @@ -42,9 +42,9 @@ func createFunc(c *cobra.Command, args []string) error { // that [uri] is hosting. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: config.URI, - AVAXKeychain: kc, - // EthKeychain: kc, + URI: config.URI, + AVAXKeychain: kc, + EthKeychain: kc, PChainTxsToFetch: set.Of(config.SubnetID), }) if err != nil { diff --git a/wallet/chain/c/backend.go b/wallet/chain/c/backend.go index b88c8c643bc3..0a735116b646 100644 --- a/wallet/chain/c/backend.go +++ b/wallet/chain/c/backend.go @@ -3,153 +3,153 @@ package c -// import ( -// "errors" -// "fmt" -// "math/big" -// "sync" - -// stdcontext "context" - -// "github.com/ava-labs/coreth/plugin/evm" - -// ethcommon "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/avalanchego/database" -// "github.com/ava-labs/avalanchego/utils/math" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var ( -// _ Backend = (*backend)(nil) - -// errUnknownTxType = errors.New("unknown tx type") -// ) - -// // Backend defines the full interface required to support a C-chain wallet. -// type Backend interface { -// common.ChainUTXOs -// BuilderBackend -// SignerBackend - -// AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error -// } - -// type backend struct { -// Context -// common.ChainUTXOs - -// accountsLock sync.RWMutex -// accounts map[ethcommon.Address]*Account -// } - -// type Account struct { -// Balance *big.Int -// Nonce uint64 -// } - -// func NewBackend( -// ctx Context, -// utxos common.ChainUTXOs, -// accounts map[ethcommon.Address]*Account, -// ) Backend { -// return &backend{ -// Context: ctx, -// ChainUTXOs: utxos, -// accounts: accounts, -// } -// } - -// func (b *backend) AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error { -// switch tx := tx.UnsignedAtomicTx.(type) { -// case *evm.UnsignedImportTx: -// for _, input := range tx.ImportedInputs { -// utxoID := input.InputID() -// if err := b.RemoveUTXO(ctx, tx.SourceChain, utxoID); err != nil { -// return err -// } -// } - -// b.accountsLock.Lock() -// defer b.accountsLock.Unlock() - -// for _, output := range tx.Outs { -// account, ok := b.accounts[output.Address] -// if !ok { -// continue -// } - -// balance := new(big.Int).SetUint64(output.Amount) -// balance.Mul(balance, avaxConversionRate) -// account.Balance.Add(account.Balance, balance) -// } -// case *evm.UnsignedExportTx: -// txID := tx.ID() -// for i, out := range tx.ExportedOutputs { -// err := b.AddUTXO( -// ctx, -// tx.DestinationChain, -// &avax.UTXO{ -// UTXOID: avax.UTXOID{ -// TxID: txID, -// OutputIndex: uint32(i), -// }, -// Asset: avax.Asset{ID: out.AssetID()}, -// Out: out.Out, -// }, -// ) -// if err != nil { -// return err -// } -// } - -// b.accountsLock.Lock() -// defer b.accountsLock.Unlock() - -// for _, input := range tx.Ins { -// account, ok := b.accounts[input.Address] -// if !ok { -// continue -// } - -// balance := new(big.Int).SetUint64(input.Amount) -// balance.Mul(balance, avaxConversionRate) -// if account.Balance.Cmp(balance) == -1 { -// return errInsufficientFunds -// } -// account.Balance.Sub(account.Balance, balance) - -// newNonce, err := math.Add64(input.Nonce, 1) -// if err != nil { -// return err -// } -// account.Nonce = newNonce -// } -// default: -// return fmt.Errorf("%w: %T", errUnknownTxType, tx) -// } -// return nil -// } - -// func (b *backend) Balance(_ stdcontext.Context, addr ethcommon.Address) (*big.Int, error) { -// b.accountsLock.RLock() -// defer b.accountsLock.RUnlock() - -// account, exists := b.accounts[addr] -// if !exists { -// return nil, database.ErrNotFound -// } -// return account.Balance, nil -// } - -// func (b *backend) Nonce(_ stdcontext.Context, addr ethcommon.Address) (uint64, error) { -// b.accountsLock.RLock() -// defer b.accountsLock.RUnlock() - -// account, exists := b.accounts[addr] -// if !exists { -// return 0, database.ErrNotFound -// } -// return account.Nonce, nil -// } +import ( + "errors" + "fmt" + "math/big" + "sync" + + stdcontext "context" + + "github.com/ava-labs/coreth/plugin/evm" + + ethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/avalanchego/database" + "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var ( + _ Backend = (*backend)(nil) + + errUnknownTxType = errors.New("unknown tx type") +) + +// Backend defines the full interface required to support a C-chain wallet. +type Backend interface { + common.ChainUTXOs + BuilderBackend + SignerBackend + + AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error +} + +type backend struct { + Context + common.ChainUTXOs + + accountsLock sync.RWMutex + accounts map[ethcommon.Address]*Account +} + +type Account struct { + Balance *big.Int + Nonce uint64 +} + +func NewBackend( + ctx Context, + utxos common.ChainUTXOs, + accounts map[ethcommon.Address]*Account, +) Backend { + return &backend{ + Context: ctx, + ChainUTXOs: utxos, + accounts: accounts, + } +} + +func (b *backend) AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error { + switch tx := tx.UnsignedAtomicTx.(type) { + case *evm.UnsignedImportTx: + for _, input := range tx.ImportedInputs { + utxoID := input.InputID() + if err := b.RemoveUTXO(ctx, tx.SourceChain, utxoID); err != nil { + return err + } + } + + b.accountsLock.Lock() + defer b.accountsLock.Unlock() + + for _, output := range tx.Outs { + account, ok := b.accounts[output.Address] + if !ok { + continue + } + + balance := new(big.Int).SetUint64(output.Amount) + balance.Mul(balance, avaxConversionRate) + account.Balance.Add(account.Balance, balance) + } + case *evm.UnsignedExportTx: + txID := tx.ID() + for i, out := range tx.ExportedOutputs { + err := b.AddUTXO( + ctx, + tx.DestinationChain, + &avax.UTXO{ + UTXOID: avax.UTXOID{ + TxID: txID, + OutputIndex: uint32(i), + }, + Asset: avax.Asset{ID: out.AssetID()}, + Out: out.Out, + }, + ) + if err != nil { + return err + } + } + + b.accountsLock.Lock() + defer b.accountsLock.Unlock() + + for _, input := range tx.Ins { + account, ok := b.accounts[input.Address] + if !ok { + continue + } + + balance := new(big.Int).SetUint64(input.Amount) + balance.Mul(balance, avaxConversionRate) + if account.Balance.Cmp(balance) == -1 { + return errInsufficientFunds + } + account.Balance.Sub(account.Balance, balance) + + newNonce, err := math.Add64(input.Nonce, 1) + if err != nil { + return err + } + account.Nonce = newNonce + } + default: + return fmt.Errorf("%w: %T", errUnknownTxType, tx) + } + return nil +} + +func (b *backend) Balance(_ stdcontext.Context, addr ethcommon.Address) (*big.Int, error) { + b.accountsLock.RLock() + defer b.accountsLock.RUnlock() + + account, exists := b.accounts[addr] + if !exists { + return nil, database.ErrNotFound + } + return account.Balance, nil +} + +func (b *backend) Nonce(_ stdcontext.Context, addr ethcommon.Address) (uint64, error) { + b.accountsLock.RLock() + defer b.accountsLock.RUnlock() + + account, exists := b.accounts[addr] + if !exists { + return 0, database.ErrNotFound + } + return account.Nonce, nil +} diff --git a/wallet/chain/c/builder.go b/wallet/chain/c/builder.go index c51d2647777e..d2d088e88a53 100644 --- a/wallet/chain/c/builder.go +++ b/wallet/chain/c/builder.go @@ -3,399 +3,399 @@ package c -// import ( -// "errors" -// "math/big" - -// stdcontext "context" - -// "github.com/ava-labs/coreth/plugin/evm" - -// ethcommon "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/utils" -// "github.com/ava-labs/avalanchego/utils/math" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// const avaxConversionRateInt = 1_000_000_000 - -// var ( -// _ Builder = (*builder)(nil) - -// errInsufficientFunds = errors.New("insufficient funds") - -// // avaxConversionRate is the conversion rate between the smallest -// // denomination on the X-Chain and P-chain, 1 nAVAX, and the smallest -// // denomination on the C-Chain 1 wei. Where 1 nAVAX = 1 gWei. -// // -// // This is only required for AVAX because the denomination of 1 AVAX is 9 -// // decimal places on the X and P chains, but is 18 decimal places within the -// // EVM. -// avaxConversionRate = big.NewInt(avaxConversionRateInt) -// ) - -// // Builder provides a convenient interface for building unsigned C-chain -// // transactions. -// type Builder interface { -// // GetBalance calculates the amount of AVAX that this builder has control -// // over. -// GetBalance( -// options ...common.Option, -// ) (*big.Int, error) - -// // GetImportableBalance calculates the amount of AVAX that this builder -// // could import from the provided chain. -// // -// // - [chainID] specifies the chain the funds are from. -// GetImportableBalance( -// chainID ids.ID, -// options ...common.Option, -// ) (uint64, error) - -// // NewImportTx creates an import transaction that attempts to consume all -// // the available UTXOs and import the funds to [to]. -// // -// // - [chainID] specifies the chain to be importing funds from. -// // - [to] specifies where to send the imported funds to. -// // - [baseFee] specifies the fee price willing to be paid by this tx. -// NewImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedImportTx, error) - -// // NewExportTx creates an export transaction that attempts to send all the -// // provided [outputs] to the requested [chainID]. -// // -// // - [chainID] specifies the chain to be exporting the funds to. -// // - [outputs] specifies the outputs to send to the [chainID]. -// // - [baseFee] specifies the fee price willing to be paid by this tx. -// NewExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedExportTx, error) -// } - -// // BuilderBackend specifies the required information needed to build unsigned -// // C-chain transactions. -// type BuilderBackend interface { -// Context - -// UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) -// Balance(ctx stdcontext.Context, addr ethcommon.Address) (*big.Int, error) -// Nonce(ctx stdcontext.Context, addr ethcommon.Address) (uint64, error) -// } - -// type builder struct { -// avaxAddrs set.Set[ids.ShortID] -// ethAddrs set.Set[ethcommon.Address] -// backend BuilderBackend -// } - -// // NewBuilder returns a new transaction builder. -// // -// // - [avaxAddrs] is the set of addresses in the AVAX format that the builder -// // assumes can be used when signing the transactions in the future. -// // - [ethAddrs] is the set of addresses in the Eth format that the builder -// // assumes can be used when signing the transactions in the future. -// // - [backend] provides the required access to the chain's context and state -// // to build out the transactions. -// func NewBuilder( -// avaxAddrs set.Set[ids.ShortID], -// ethAddrs set.Set[ethcommon.Address], -// backend BuilderBackend, -// ) Builder { -// return &builder{ -// avaxAddrs: avaxAddrs, -// ethAddrs: ethAddrs, -// backend: backend, -// } -// } - -// func (b *builder) GetBalance( -// options ...common.Option, -// ) (*big.Int, error) { -// var ( -// ops = common.NewOptions(options) -// ctx = ops.Context() -// addrs = ops.EthAddresses(b.ethAddrs) -// totalBalance = new(big.Int) -// ) -// for addr := range addrs { -// balance, err := b.backend.Balance(ctx, addr) -// if err != nil { -// return nil, err -// } -// totalBalance.Add(totalBalance, balance) -// } - -// return totalBalance, nil -// } - -// func (b *builder) GetImportableBalance( -// chainID ids.ID, -// options ...common.Option, -// ) (uint64, error) { -// ops := common.NewOptions(options) -// utxos, err := b.backend.UTXOs(ops.Context(), chainID) -// if err != nil { -// return 0, err -// } - -// var ( -// addrs = ops.Addresses(b.avaxAddrs) -// minIssuanceTime = ops.MinIssuanceTime() -// avaxAssetID = b.backend.AVAXAssetID() -// balance uint64 -// ) -// for _, utxo := range utxos { -// amount, _, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) -// if !ok { -// continue -// } - -// newBalance, err := math.Add64(balance, amount) -// if err != nil { -// return 0, err -// } -// balance = newBalance -// } - -// return balance, nil -// } - -// func (b *builder) NewImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedImportTx, error) { -// ops := common.NewOptions(options) -// utxos, err := b.backend.UTXOs(ops.Context(), chainID) -// if err != nil { -// return nil, err -// } - -// var ( -// addrs = ops.Addresses(b.avaxAddrs) -// minIssuanceTime = ops.MinIssuanceTime() -// avaxAssetID = b.backend.AVAXAssetID() - -// importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) -// importedAmount uint64 -// ) -// for _, utxo := range utxos { -// amount, inputSigIndices, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) -// if !ok { -// continue -// } - -// importedInputs = append(importedInputs, &avax.TransferableInput{ -// UTXOID: utxo.UTXOID, -// Asset: utxo.Asset, -// In: &secp256k1fx.TransferInput{ -// Amt: amount, -// Input: secp256k1fx.Input{ -// SigIndices: inputSigIndices, -// }, -// }, -// }) - -// newImportedAmount, err := math.Add64(importedAmount, amount) -// if err != nil { -// return nil, err -// } -// importedAmount = newImportedAmount -// } - -// utils.Sort(importedInputs) -// tx := &evm.UnsignedImportTx{ -// NetworkID: b.backend.NetworkID(), -// BlockchainID: b.backend.BlockchainID(), -// SourceChain: chainID, -// ImportedInputs: importedInputs, -// } - -// // We must initialize the bytes of the tx to calculate the initial cost -// wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} -// if err := wrappedTx.Sign(evm.Codec, nil); err != nil { -// return nil, err -// } - -// gasUsedWithoutOutput, err := tx.GasUsed(true /*=IsApricotPhase5*/) -// if err != nil { -// return nil, err -// } -// gasUsedWithOutput := gasUsedWithoutOutput + evm.EVMOutputGas - -// txFee, err := evm.CalculateDynamicFee(gasUsedWithOutput, baseFee) -// if err != nil { -// return nil, err -// } - -// if importedAmount <= txFee { -// return nil, errInsufficientFunds -// } - -// tx.Outs = []evm.EVMOutput{{ -// Address: to, -// Amount: importedAmount - txFee, -// AssetID: avaxAssetID, -// }} -// return tx, nil -// } - -// func (b *builder) NewExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedExportTx, error) { -// var ( -// avaxAssetID = b.backend.AVAXAssetID() -// exportedOutputs = make([]*avax.TransferableOutput, len(outputs)) -// exportedAmount uint64 -// ) -// for i, output := range outputs { -// exportedOutputs[i] = &avax.TransferableOutput{ -// Asset: avax.Asset{ID: avaxAssetID}, -// Out: output, -// } - -// newExportedAmount, err := math.Add64(exportedAmount, output.Amt) -// if err != nil { -// return nil, err -// } -// exportedAmount = newExportedAmount -// } - -// avax.SortTransferableOutputs(exportedOutputs, evm.Codec) -// tx := &evm.UnsignedExportTx{ -// NetworkID: b.backend.NetworkID(), -// BlockchainID: b.backend.BlockchainID(), -// DestinationChain: chainID, -// ExportedOutputs: exportedOutputs, -// } - -// // We must initialize the bytes of the tx to calculate the initial cost -// wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} -// if err := wrappedTx.Sign(evm.Codec, nil); err != nil { -// return nil, err -// } - -// cost, err := tx.GasUsed(true /*=IsApricotPhase5*/) -// if err != nil { -// return nil, err -// } - -// initialFee, err := evm.CalculateDynamicFee(cost, baseFee) -// if err != nil { -// return nil, err -// } - -// amountToConsume, err := math.Add64(exportedAmount, initialFee) -// if err != nil { -// return nil, err -// } - -// var ( -// ops = common.NewOptions(options) -// ctx = ops.Context() -// addrs = ops.EthAddresses(b.ethAddrs) -// inputs = make([]evm.EVMInput, 0, addrs.Len()) -// ) -// for addr := range addrs { -// if amountToConsume == 0 { -// break -// } - -// prevFee, err := evm.CalculateDynamicFee(cost, baseFee) -// if err != nil { -// return nil, err -// } - -// newCost := cost + evm.EVMInputGas -// newFee, err := evm.CalculateDynamicFee(newCost, baseFee) -// if err != nil { -// return nil, err -// } - -// additionalFee := newFee - prevFee - -// balance, err := b.backend.Balance(ctx, addr) -// if err != nil { -// return nil, err -// } - -// // Since the asset is AVAX, we divide by the avaxConversionRate to -// // convert back to the correct denomination of AVAX that can be -// // exported. -// avaxBalance := new(big.Int).Div(balance, avaxConversionRate).Uint64() - -// // If the balance for [addr] is insufficient to cover the additional -// // cost of adding an input to the transaction, skip adding the input -// // altogether. -// if avaxBalance <= additionalFee { -// continue -// } - -// // Update the cost for the next iteration -// cost = newCost - -// amountToConsume, err = math.Add64(amountToConsume, additionalFee) -// if err != nil { -// return nil, err -// } - -// nonce, err := b.backend.Nonce(ctx, addr) -// if err != nil { -// return nil, err -// } - -// inputAmount := math.Min(amountToConsume, avaxBalance) -// inputs = append(inputs, evm.EVMInput{ -// Address: addr, -// Amount: inputAmount, -// AssetID: avaxAssetID, -// Nonce: nonce, -// }) -// amountToConsume -= inputAmount -// } - -// if amountToConsume > 0 { -// return nil, errInsufficientFunds -// } - -// utils.Sort(inputs) -// tx.Ins = inputs -// return tx, nil -// } - -// func getSpendableAmount( -// utxo *avax.UTXO, -// addrs set.Set[ids.ShortID], -// minIssuanceTime uint64, -// avaxAssetID ids.ID, -// ) (uint64, []uint32, bool) { -// if utxo.Asset.ID != avaxAssetID { -// // Only AVAX can be imported -// return 0, nil, false -// } - -// out, ok := utxo.Out.(*secp256k1fx.TransferOutput) -// if !ok { -// // Can't import an unknown transfer output type -// return 0, nil, false -// } - -// inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) -// return out.Amt, inputSigIndices, ok -// } +import ( + "errors" + "math/big" + + stdcontext "context" + + "github.com/ava-labs/coreth/plugin/evm" + + ethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils" + "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +const avaxConversionRateInt = 1_000_000_000 + +var ( + _ Builder = (*builder)(nil) + + errInsufficientFunds = errors.New("insufficient funds") + + // avaxConversionRate is the conversion rate between the smallest + // denomination on the X-Chain and P-chain, 1 nAVAX, and the smallest + // denomination on the C-Chain 1 wei. Where 1 nAVAX = 1 gWei. + // + // This is only required for AVAX because the denomination of 1 AVAX is 9 + // decimal places on the X and P chains, but is 18 decimal places within the + // EVM. + avaxConversionRate = big.NewInt(avaxConversionRateInt) +) + +// Builder provides a convenient interface for building unsigned C-chain +// transactions. +type Builder interface { + // GetBalance calculates the amount of AVAX that this builder has control + // over. + GetBalance( + options ...common.Option, + ) (*big.Int, error) + + // GetImportableBalance calculates the amount of AVAX that this builder + // could import from the provided chain. + // + // - [chainID] specifies the chain the funds are from. + GetImportableBalance( + chainID ids.ID, + options ...common.Option, + ) (uint64, error) + + // NewImportTx creates an import transaction that attempts to consume all + // the available UTXOs and import the funds to [to]. + // + // - [chainID] specifies the chain to be importing funds from. + // - [to] specifies where to send the imported funds to. + // - [baseFee] specifies the fee price willing to be paid by this tx. + NewImportTx( + chainID ids.ID, + to ethcommon.Address, + baseFee *big.Int, + options ...common.Option, + ) (*evm.UnsignedImportTx, error) + + // NewExportTx creates an export transaction that attempts to send all the + // provided [outputs] to the requested [chainID]. + // + // - [chainID] specifies the chain to be exporting the funds to. + // - [outputs] specifies the outputs to send to the [chainID]. + // - [baseFee] specifies the fee price willing to be paid by this tx. + NewExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + baseFee *big.Int, + options ...common.Option, + ) (*evm.UnsignedExportTx, error) +} + +// BuilderBackend specifies the required information needed to build unsigned +// C-chain transactions. +type BuilderBackend interface { + Context + + UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) + Balance(ctx stdcontext.Context, addr ethcommon.Address) (*big.Int, error) + Nonce(ctx stdcontext.Context, addr ethcommon.Address) (uint64, error) +} + +type builder struct { + avaxAddrs set.Set[ids.ShortID] + ethAddrs set.Set[ethcommon.Address] + backend BuilderBackend +} + +// NewBuilder returns a new transaction builder. +// +// - [avaxAddrs] is the set of addresses in the AVAX format that the builder +// assumes can be used when signing the transactions in the future. +// - [ethAddrs] is the set of addresses in the Eth format that the builder +// assumes can be used when signing the transactions in the future. +// - [backend] provides the required access to the chain's context and state +// to build out the transactions. +func NewBuilder( + avaxAddrs set.Set[ids.ShortID], + ethAddrs set.Set[ethcommon.Address], + backend BuilderBackend, +) Builder { + return &builder{ + avaxAddrs: avaxAddrs, + ethAddrs: ethAddrs, + backend: backend, + } +} + +func (b *builder) GetBalance( + options ...common.Option, +) (*big.Int, error) { + var ( + ops = common.NewOptions(options) + ctx = ops.Context() + addrs = ops.EthAddresses(b.ethAddrs) + totalBalance = new(big.Int) + ) + for addr := range addrs { + balance, err := b.backend.Balance(ctx, addr) + if err != nil { + return nil, err + } + totalBalance.Add(totalBalance, balance) + } + + return totalBalance, nil +} + +func (b *builder) GetImportableBalance( + chainID ids.ID, + options ...common.Option, +) (uint64, error) { + ops := common.NewOptions(options) + utxos, err := b.backend.UTXOs(ops.Context(), chainID) + if err != nil { + return 0, err + } + + var ( + addrs = ops.Addresses(b.avaxAddrs) + minIssuanceTime = ops.MinIssuanceTime() + avaxAssetID = b.backend.AVAXAssetID() + balance uint64 + ) + for _, utxo := range utxos { + amount, _, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) + if !ok { + continue + } + + newBalance, err := math.Add64(balance, amount) + if err != nil { + return 0, err + } + balance = newBalance + } + + return balance, nil +} + +func (b *builder) NewImportTx( + chainID ids.ID, + to ethcommon.Address, + baseFee *big.Int, + options ...common.Option, +) (*evm.UnsignedImportTx, error) { + ops := common.NewOptions(options) + utxos, err := b.backend.UTXOs(ops.Context(), chainID) + if err != nil { + return nil, err + } + + var ( + addrs = ops.Addresses(b.avaxAddrs) + minIssuanceTime = ops.MinIssuanceTime() + avaxAssetID = b.backend.AVAXAssetID() + + importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) + importedAmount uint64 + ) + for _, utxo := range utxos { + amount, inputSigIndices, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) + if !ok { + continue + } + + importedInputs = append(importedInputs, &avax.TransferableInput{ + UTXOID: utxo.UTXOID, + Asset: utxo.Asset, + In: &secp256k1fx.TransferInput{ + Amt: amount, + Input: secp256k1fx.Input{ + SigIndices: inputSigIndices, + }, + }, + }) + + newImportedAmount, err := math.Add64(importedAmount, amount) + if err != nil { + return nil, err + } + importedAmount = newImportedAmount + } + + utils.Sort(importedInputs) + tx := &evm.UnsignedImportTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: b.backend.BlockchainID(), + SourceChain: chainID, + ImportedInputs: importedInputs, + } + + // We must initialize the bytes of the tx to calculate the initial cost + wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} + if err := wrappedTx.Sign(evm.Codec, nil); err != nil { + return nil, err + } + + gasUsedWithoutOutput, err := tx.GasUsed(true /*=IsApricotPhase5*/) + if err != nil { + return nil, err + } + gasUsedWithOutput := gasUsedWithoutOutput + evm.EVMOutputGas + + txFee, err := evm.CalculateDynamicFee(gasUsedWithOutput, baseFee) + if err != nil { + return nil, err + } + + if importedAmount <= txFee { + return nil, errInsufficientFunds + } + + tx.Outs = []evm.EVMOutput{{ + Address: to, + Amount: importedAmount - txFee, + AssetID: avaxAssetID, + }} + return tx, nil +} + +func (b *builder) NewExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + baseFee *big.Int, + options ...common.Option, +) (*evm.UnsignedExportTx, error) { + var ( + avaxAssetID = b.backend.AVAXAssetID() + exportedOutputs = make([]*avax.TransferableOutput, len(outputs)) + exportedAmount uint64 + ) + for i, output := range outputs { + exportedOutputs[i] = &avax.TransferableOutput{ + Asset: avax.Asset{ID: avaxAssetID}, + Out: output, + } + + newExportedAmount, err := math.Add64(exportedAmount, output.Amt) + if err != nil { + return nil, err + } + exportedAmount = newExportedAmount + } + + avax.SortTransferableOutputs(exportedOutputs, evm.Codec) + tx := &evm.UnsignedExportTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: b.backend.BlockchainID(), + DestinationChain: chainID, + ExportedOutputs: exportedOutputs, + } + + // We must initialize the bytes of the tx to calculate the initial cost + wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} + if err := wrappedTx.Sign(evm.Codec, nil); err != nil { + return nil, err + } + + cost, err := tx.GasUsed(true /*=IsApricotPhase5*/) + if err != nil { + return nil, err + } + + initialFee, err := evm.CalculateDynamicFee(cost, baseFee) + if err != nil { + return nil, err + } + + amountToConsume, err := math.Add64(exportedAmount, initialFee) + if err != nil { + return nil, err + } + + var ( + ops = common.NewOptions(options) + ctx = ops.Context() + addrs = ops.EthAddresses(b.ethAddrs) + inputs = make([]evm.EVMInput, 0, addrs.Len()) + ) + for addr := range addrs { + if amountToConsume == 0 { + break + } + + prevFee, err := evm.CalculateDynamicFee(cost, baseFee) + if err != nil { + return nil, err + } + + newCost := cost + evm.EVMInputGas + newFee, err := evm.CalculateDynamicFee(newCost, baseFee) + if err != nil { + return nil, err + } + + additionalFee := newFee - prevFee + + balance, err := b.backend.Balance(ctx, addr) + if err != nil { + return nil, err + } + + // Since the asset is AVAX, we divide by the avaxConversionRate to + // convert back to the correct denomination of AVAX that can be + // exported. + avaxBalance := new(big.Int).Div(balance, avaxConversionRate).Uint64() + + // If the balance for [addr] is insufficient to cover the additional + // cost of adding an input to the transaction, skip adding the input + // altogether. + if avaxBalance <= additionalFee { + continue + } + + // Update the cost for the next iteration + cost = newCost + + amountToConsume, err = math.Add64(amountToConsume, additionalFee) + if err != nil { + return nil, err + } + + nonce, err := b.backend.Nonce(ctx, addr) + if err != nil { + return nil, err + } + + inputAmount := math.Min(amountToConsume, avaxBalance) + inputs = append(inputs, evm.EVMInput{ + Address: addr, + Amount: inputAmount, + AssetID: avaxAssetID, + Nonce: nonce, + }) + amountToConsume -= inputAmount + } + + if amountToConsume > 0 { + return nil, errInsufficientFunds + } + + utils.Sort(inputs) + tx.Ins = inputs + return tx, nil +} + +func getSpendableAmount( + utxo *avax.UTXO, + addrs set.Set[ids.ShortID], + minIssuanceTime uint64, + avaxAssetID ids.ID, +) (uint64, []uint32, bool) { + if utxo.Asset.ID != avaxAssetID { + // Only AVAX can be imported + return 0, nil, false + } + + out, ok := utxo.Out.(*secp256k1fx.TransferOutput) + if !ok { + // Can't import an unknown transfer output type + return 0, nil, false + } + + inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) + return out.Amt, inputSigIndices, ok +} diff --git a/wallet/chain/c/builder_with_options.go b/wallet/chain/c/builder_with_options.go index 9b7ab8399484..8416dddf9928 100644 --- a/wallet/chain/c/builder_with_options.go +++ b/wallet/chain/c/builder_with_options.go @@ -3,81 +3,81 @@ package c -// import ( -// "math/big" +import ( + "math/big" -// "github.com/ava-labs/coreth/plugin/evm" + "github.com/ava-labs/coreth/plugin/evm" -// ethcommon "github.com/ethereum/go-ethereum/common" + ethcommon "github.com/ethereum/go-ethereum/common" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) -// var _ Builder = (*builderWithOptions)(nil) +var _ Builder = (*builderWithOptions)(nil) -// type builderWithOptions struct { -// Builder -// options []common.Option -// } +type builderWithOptions struct { + Builder + options []common.Option +} -// // NewBuilderWithOptions returns a new transaction builder that will use the -// // given options by default. -// // -// // - [builder] is the builder that will be called to perform the underlying -// // operations. -// // - [options] will be provided to the builder in addition to the options -// // provided in the method calls. -// func NewBuilderWithOptions(builder Builder, options ...common.Option) Builder { -// return &builderWithOptions{ -// Builder: builder, -// options: options, -// } -// } +// NewBuilderWithOptions returns a new transaction builder that will use the +// given options by default. +// +// - [builder] is the builder that will be called to perform the underlying +// operations. +// - [options] will be provided to the builder in addition to the options +// provided in the method calls. +func NewBuilderWithOptions(builder Builder, options ...common.Option) Builder { + return &builderWithOptions{ + Builder: builder, + options: options, + } +} -// func (b *builderWithOptions) GetBalance( -// options ...common.Option, -// ) (*big.Int, error) { -// return b.Builder.GetBalance( -// common.UnionOptions(b.options, options)..., -// ) -// } +func (b *builderWithOptions) GetBalance( + options ...common.Option, +) (*big.Int, error) { + return b.Builder.GetBalance( + common.UnionOptions(b.options, options)..., + ) +} -// func (b *builderWithOptions) GetImportableBalance( -// chainID ids.ID, -// options ...common.Option, -// ) (uint64, error) { -// return b.Builder.GetImportableBalance( -// chainID, -// common.UnionOptions(b.options, options)..., -// ) -// } +func (b *builderWithOptions) GetImportableBalance( + chainID ids.ID, + options ...common.Option, +) (uint64, error) { + return b.Builder.GetImportableBalance( + chainID, + common.UnionOptions(b.options, options)..., + ) +} -// func (b *builderWithOptions) NewImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedImportTx, error) { -// return b.Builder.NewImportTx( -// chainID, -// to, -// baseFee, -// common.UnionOptions(b.options, options)..., -// ) -// } +func (b *builderWithOptions) NewImportTx( + chainID ids.ID, + to ethcommon.Address, + baseFee *big.Int, + options ...common.Option, +) (*evm.UnsignedImportTx, error) { + return b.Builder.NewImportTx( + chainID, + to, + baseFee, + common.UnionOptions(b.options, options)..., + ) +} -// func (b *builderWithOptions) NewExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedExportTx, error) { -// return b.Builder.NewExportTx( -// chainID, -// outputs, -// baseFee, -// common.UnionOptions(b.options, options)..., -// ) -// } +func (b *builderWithOptions) NewExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + baseFee *big.Int, + options ...common.Option, +) (*evm.UnsignedExportTx, error) { + return b.Builder.NewExportTx( + chainID, + outputs, + baseFee, + common.UnionOptions(b.options, options)..., + ) +} diff --git a/wallet/chain/c/context.go b/wallet/chain/c/context.go index 1c01d8fb55c8..d506b42f81fa 100644 --- a/wallet/chain/c/context.go +++ b/wallet/chain/c/context.go @@ -3,81 +3,81 @@ package c -// import ( -// stdcontext "context" +import ( + stdcontext "context" -// "github.com/ava-labs/avalanchego/api/info" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/vms/avm" -// ) + "github.com/ava-labs/avalanchego/api/info" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/avm" +) -// var _ Context = (*context)(nil) +var _ Context = (*context)(nil) -// type Context interface { -// NetworkID() uint32 -// BlockchainID() ids.ID -// AVAXAssetID() ids.ID -// } +type Context interface { + NetworkID() uint32 + BlockchainID() ids.ID + AVAXAssetID() ids.ID +} -// type context struct { -// networkID uint32 -// blockchainID ids.ID -// avaxAssetID ids.ID -// } +type context struct { + networkID uint32 + blockchainID ids.ID + avaxAssetID ids.ID +} -// func NewContextFromURI(ctx stdcontext.Context, uri string) (Context, error) { -// infoClient := info.NewClient(uri) -// xChainClient := avm.NewClient(uri, "X") -// return NewContextFromClients(ctx, infoClient, xChainClient) -// } +func NewContextFromURI(ctx stdcontext.Context, uri string) (Context, error) { + infoClient := info.NewClient(uri) + xChainClient := avm.NewClient(uri, "X") + return NewContextFromClients(ctx, infoClient, xChainClient) +} -// func NewContextFromClients( -// ctx stdcontext.Context, -// infoClient info.Client, -// xChainClient avm.Client, -// ) (Context, error) { -// networkID, err := infoClient.GetNetworkID(ctx) -// if err != nil { -// return nil, err -// } +func NewContextFromClients( + ctx stdcontext.Context, + infoClient info.Client, + xChainClient avm.Client, +) (Context, error) { + networkID, err := infoClient.GetNetworkID(ctx) + if err != nil { + return nil, err + } -// chainID, err := infoClient.GetBlockchainID(ctx, "C") -// if err != nil { -// return nil, err -// } + chainID, err := infoClient.GetBlockchainID(ctx, "C") + if err != nil { + return nil, err + } -// asset, err := xChainClient.GetAssetDescription(ctx, "AVAX") -// if err != nil { -// return nil, err -// } + asset, err := xChainClient.GetAssetDescription(ctx, "AVAX") + if err != nil { + return nil, err + } -// return NewContext( -// networkID, -// chainID, -// asset.AssetID, -// ), nil -// } + return NewContext( + networkID, + chainID, + asset.AssetID, + ), nil +} -// func NewContext( -// networkID uint32, -// blockchainID ids.ID, -// avaxAssetID ids.ID, -// ) Context { -// return &context{ -// networkID: networkID, -// blockchainID: blockchainID, -// avaxAssetID: avaxAssetID, -// } -// } +func NewContext( + networkID uint32, + blockchainID ids.ID, + avaxAssetID ids.ID, +) Context { + return &context{ + networkID: networkID, + blockchainID: blockchainID, + avaxAssetID: avaxAssetID, + } +} -// func (c *context) NetworkID() uint32 { -// return c.networkID -// } +func (c *context) NetworkID() uint32 { + return c.networkID +} -// func (c *context) BlockchainID() ids.ID { -// return c.blockchainID -// } +func (c *context) BlockchainID() ids.ID { + return c.blockchainID +} -// func (c *context) AVAXAssetID() ids.ID { -// return c.avaxAssetID -// } +func (c *context) AVAXAssetID() ids.ID { + return c.avaxAssetID +} diff --git a/wallet/chain/c/signer.go b/wallet/chain/c/signer.go index 4bedc378234b..4fd85ed3b532 100644 --- a/wallet/chain/c/signer.go +++ b/wallet/chain/c/signer.go @@ -3,221 +3,221 @@ package c -// import ( -// "errors" -// "fmt" - -// stdcontext "context" - -// "github.com/ava-labs/coreth/plugin/evm" - -// ethcommon "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/avalanchego/database" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/utils/crypto/keychain" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// "github.com/ava-labs/avalanchego/utils/hashing" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/components/verify" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// ) - -// const version = 0 - -// var ( -// _ Signer = (*txSigner)(nil) - -// errUnknownInputType = errors.New("unknown input type") -// errUnknownCredentialType = errors.New("unknown credential type") -// errUnknownOutputType = errors.New("unknown output type") -// errInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") - -// emptySig [secp256k1.SignatureLen]byte -// ) - -// type Signer interface { -// SignUnsignedAtomic(ctx stdcontext.Context, tx evm.UnsignedAtomicTx) (*evm.Tx, error) -// SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error -// } - -// type EthKeychain interface { -// // The returned Signer can provide a signature for [addr] -// GetEth(addr ethcommon.Address) (keychain.Signer, bool) -// // Returns the set of addresses for which the accessor keeps an associated -// // signer -// EthAddresses() set.Set[ethcommon.Address] -// } - -// type SignerBackend interface { -// GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) -// } - -// type txSigner struct { -// avaxKC keychain.Keychain -// ethKC EthKeychain -// backend SignerBackend -// } - -// func NewSigner(avaxKC keychain.Keychain, ethKC EthKeychain, backend SignerBackend) Signer { -// return &txSigner{ -// avaxKC: avaxKC, -// ethKC: ethKC, -// backend: backend, -// } -// } - -// func (s *txSigner) SignUnsignedAtomic(ctx stdcontext.Context, utx evm.UnsignedAtomicTx) (*evm.Tx, error) { -// tx := &evm.Tx{UnsignedAtomicTx: utx} -// return tx, s.SignAtomic(ctx, tx) -// } - -// func (s *txSigner) SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error { -// switch utx := tx.UnsignedAtomicTx.(type) { -// case *evm.UnsignedImportTx: -// signers, err := s.getImportSigners(ctx, utx.SourceChain, utx.ImportedInputs) -// if err != nil { -// return err -// } -// return sign(tx, true, signers) -// case *evm.UnsignedExportTx: -// signers := s.getExportSigners(utx.Ins) -// return sign(tx, true, signers) -// default: -// return fmt.Errorf("%w: %T", errUnknownTxType, tx) -// } -// } - -// func (s *txSigner) getImportSigners(ctx stdcontext.Context, sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { -// txSigners := make([][]keychain.Signer, len(ins)) -// for credIndex, transferInput := range ins { -// input, ok := transferInput.In.(*secp256k1fx.TransferInput) -// if !ok { -// return nil, errUnknownInputType -// } - -// inputSigners := make([]keychain.Signer, len(input.SigIndices)) -// txSigners[credIndex] = inputSigners - -// utxoID := transferInput.InputID() -// utxo, err := s.backend.GetUTXO(ctx, sourceChainID, utxoID) -// if err == database.ErrNotFound { -// // If we don't have access to the UTXO, then we can't sign this -// // transaction. However, we can attempt to partially sign it. -// continue -// } -// if err != nil { -// return nil, err -// } - -// out, ok := utxo.Out.(*secp256k1fx.TransferOutput) -// if !ok { -// return nil, errUnknownOutputType -// } - -// for sigIndex, addrIndex := range input.SigIndices { -// if addrIndex >= uint32(len(out.Addrs)) { -// return nil, errInvalidUTXOSigIndex -// } - -// addr := out.Addrs[addrIndex] -// key, ok := s.avaxKC.Get(addr) -// if !ok { -// // If we don't have access to the key, then we can't sign this -// // transaction. However, we can attempt to partially sign it. -// continue -// } -// inputSigners[sigIndex] = key -// } -// } -// return txSigners, nil -// } - -// func (s *txSigner) getExportSigners(ins []evm.EVMInput) [][]keychain.Signer { -// txSigners := make([][]keychain.Signer, len(ins)) -// for credIndex, input := range ins { -// inputSigners := make([]keychain.Signer, 1) -// txSigners[credIndex] = inputSigners - -// key, ok := s.ethKC.GetEth(input.Address) -// if !ok { -// // If we don't have access to the key, then we can't sign this -// // transaction. However, we can attempt to partially sign it. -// continue -// } -// inputSigners[0] = key -// } -// return txSigners -// } - -// // TODO: remove [signHash] after the ledger supports signing all transactions. -// func sign(tx *evm.Tx, signHash bool, txSigners [][]keychain.Signer) error { -// unsignedBytes, err := evm.Codec.Marshal(version, &tx.UnsignedAtomicTx) -// if err != nil { -// return fmt.Errorf("couldn't marshal unsigned tx: %w", err) -// } -// unsignedHash := hashing.ComputeHash256(unsignedBytes) - -// if expectedLen := len(txSigners); expectedLen != len(tx.Creds) { -// tx.Creds = make([]verify.Verifiable, expectedLen) -// } - -// sigCache := make(map[ids.ShortID][secp256k1.SignatureLen]byte) -// for credIndex, inputSigners := range txSigners { -// credIntf := tx.Creds[credIndex] -// if credIntf == nil { -// credIntf = &secp256k1fx.Credential{} -// tx.Creds[credIndex] = credIntf -// } - -// cred, ok := credIntf.(*secp256k1fx.Credential) -// if !ok { -// return errUnknownCredentialType -// } -// if expectedLen := len(inputSigners); expectedLen != len(cred.Sigs) { -// cred.Sigs = make([][secp256k1.SignatureLen]byte, expectedLen) -// } - -// for sigIndex, signer := range inputSigners { -// if signer == nil { -// // If we don't have access to the key, then we can't sign this -// // transaction. However, we can attempt to partially sign it. -// continue -// } -// addr := signer.Address() -// if sig := cred.Sigs[sigIndex]; sig != emptySig { -// // If this signature has already been populated, we can just -// // copy the needed signature for the future. -// sigCache[addr] = sig -// continue -// } - -// if sig, exists := sigCache[addr]; exists { -// // If this key has already produced a signature, we can just -// // copy the previous signature. -// cred.Sigs[sigIndex] = sig -// continue -// } - -// var sig []byte -// if signHash { -// sig, err = signer.SignHash(unsignedHash) -// } else { -// sig, err = signer.Sign(unsignedBytes) -// } -// if err != nil { -// return fmt.Errorf("problem signing tx: %w", err) -// } -// copy(cred.Sigs[sigIndex][:], sig) -// sigCache[addr] = cred.Sigs[sigIndex] -// } -// } - -// signedBytes, err := evm.Codec.Marshal(version, tx) -// if err != nil { -// return fmt.Errorf("couldn't marshal tx: %w", err) -// } -// tx.Initialize(unsignedBytes, signedBytes) -// return nil -// } +import ( + "errors" + "fmt" + + stdcontext "context" + + "github.com/ava-labs/coreth/plugin/evm" + + ethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/avalanchego/database" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/crypto/keychain" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/hashing" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/components/verify" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" +) + +const version = 0 + +var ( + _ Signer = (*txSigner)(nil) + + errUnknownInputType = errors.New("unknown input type") + errUnknownCredentialType = errors.New("unknown credential type") + errUnknownOutputType = errors.New("unknown output type") + errInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") + + emptySig [secp256k1.SignatureLen]byte +) + +type Signer interface { + SignUnsignedAtomic(ctx stdcontext.Context, tx evm.UnsignedAtomicTx) (*evm.Tx, error) + SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error +} + +type EthKeychain interface { + // The returned Signer can provide a signature for [addr] + GetEth(addr ethcommon.Address) (keychain.Signer, bool) + // Returns the set of addresses for which the accessor keeps an associated + // signer + EthAddresses() set.Set[ethcommon.Address] +} + +type SignerBackend interface { + GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) +} + +type txSigner struct { + avaxKC keychain.Keychain + ethKC EthKeychain + backend SignerBackend +} + +func NewSigner(avaxKC keychain.Keychain, ethKC EthKeychain, backend SignerBackend) Signer { + return &txSigner{ + avaxKC: avaxKC, + ethKC: ethKC, + backend: backend, + } +} + +func (s *txSigner) SignUnsignedAtomic(ctx stdcontext.Context, utx evm.UnsignedAtomicTx) (*evm.Tx, error) { + tx := &evm.Tx{UnsignedAtomicTx: utx} + return tx, s.SignAtomic(ctx, tx) +} + +func (s *txSigner) SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error { + switch utx := tx.UnsignedAtomicTx.(type) { + case *evm.UnsignedImportTx: + signers, err := s.getImportSigners(ctx, utx.SourceChain, utx.ImportedInputs) + if err != nil { + return err + } + return sign(tx, true, signers) + case *evm.UnsignedExportTx: + signers := s.getExportSigners(utx.Ins) + return sign(tx, true, signers) + default: + return fmt.Errorf("%w: %T", errUnknownTxType, tx) + } +} + +func (s *txSigner) getImportSigners(ctx stdcontext.Context, sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { + txSigners := make([][]keychain.Signer, len(ins)) + for credIndex, transferInput := range ins { + input, ok := transferInput.In.(*secp256k1fx.TransferInput) + if !ok { + return nil, errUnknownInputType + } + + inputSigners := make([]keychain.Signer, len(input.SigIndices)) + txSigners[credIndex] = inputSigners + + utxoID := transferInput.InputID() + utxo, err := s.backend.GetUTXO(ctx, sourceChainID, utxoID) + if err == database.ErrNotFound { + // If we don't have access to the UTXO, then we can't sign this + // transaction. However, we can attempt to partially sign it. + continue + } + if err != nil { + return nil, err + } + + out, ok := utxo.Out.(*secp256k1fx.TransferOutput) + if !ok { + return nil, errUnknownOutputType + } + + for sigIndex, addrIndex := range input.SigIndices { + if addrIndex >= uint32(len(out.Addrs)) { + return nil, errInvalidUTXOSigIndex + } + + addr := out.Addrs[addrIndex] + key, ok := s.avaxKC.Get(addr) + if !ok { + // If we don't have access to the key, then we can't sign this + // transaction. However, we can attempt to partially sign it. + continue + } + inputSigners[sigIndex] = key + } + } + return txSigners, nil +} + +func (s *txSigner) getExportSigners(ins []evm.EVMInput) [][]keychain.Signer { + txSigners := make([][]keychain.Signer, len(ins)) + for credIndex, input := range ins { + inputSigners := make([]keychain.Signer, 1) + txSigners[credIndex] = inputSigners + + key, ok := s.ethKC.GetEth(input.Address) + if !ok { + // If we don't have access to the key, then we can't sign this + // transaction. However, we can attempt to partially sign it. + continue + } + inputSigners[0] = key + } + return txSigners +} + +// TODO: remove [signHash] after the ledger supports signing all transactions. +func sign(tx *evm.Tx, signHash bool, txSigners [][]keychain.Signer) error { + unsignedBytes, err := evm.Codec.Marshal(version, &tx.UnsignedAtomicTx) + if err != nil { + return fmt.Errorf("couldn't marshal unsigned tx: %w", err) + } + unsignedHash := hashing.ComputeHash256(unsignedBytes) + + if expectedLen := len(txSigners); expectedLen != len(tx.Creds) { + tx.Creds = make([]verify.Verifiable, expectedLen) + } + + sigCache := make(map[ids.ShortID][secp256k1.SignatureLen]byte) + for credIndex, inputSigners := range txSigners { + credIntf := tx.Creds[credIndex] + if credIntf == nil { + credIntf = &secp256k1fx.Credential{} + tx.Creds[credIndex] = credIntf + } + + cred, ok := credIntf.(*secp256k1fx.Credential) + if !ok { + return errUnknownCredentialType + } + if expectedLen := len(inputSigners); expectedLen != len(cred.Sigs) { + cred.Sigs = make([][secp256k1.SignatureLen]byte, expectedLen) + } + + for sigIndex, signer := range inputSigners { + if signer == nil { + // If we don't have access to the key, then we can't sign this + // transaction. However, we can attempt to partially sign it. + continue + } + addr := signer.Address() + if sig := cred.Sigs[sigIndex]; sig != emptySig { + // If this signature has already been populated, we can just + // copy the needed signature for the future. + sigCache[addr] = sig + continue + } + + if sig, exists := sigCache[addr]; exists { + // If this key has already produced a signature, we can just + // copy the previous signature. + cred.Sigs[sigIndex] = sig + continue + } + + var sig []byte + if signHash { + sig, err = signer.SignHash(unsignedHash) + } else { + sig, err = signer.Sign(unsignedBytes) + } + if err != nil { + return fmt.Errorf("problem signing tx: %w", err) + } + copy(cred.Sigs[sigIndex][:], sig) + sigCache[addr] = cred.Sigs[sigIndex] + } + } + + signedBytes, err := evm.Codec.Marshal(version, tx) + if err != nil { + return fmt.Errorf("couldn't marshal tx: %w", err) + } + tx.Initialize(unsignedBytes, signedBytes) + return nil +} diff --git a/wallet/chain/c/wallet.go b/wallet/chain/c/wallet.go index ebee50a9a958..fb1a83d53dad 100644 --- a/wallet/chain/c/wallet.go +++ b/wallet/chain/c/wallet.go @@ -3,204 +3,204 @@ package c -// import ( -// "errors" -// "math/big" -// "time" - -// "github.com/ava-labs/coreth/ethclient" -// "github.com/ava-labs/coreth/plugin/evm" - -// ethcommon "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var ( -// _ Wallet = (*wallet)(nil) - -// errNotCommitted = errors.New("not committed") -// ) - -// type Wallet interface { -// Context - -// // Builder returns the builder that will be used to create the transactions. -// Builder() Builder - -// // Signer returns the signer that will be used to sign the transactions. -// Signer() Signer - -// // IssueImportTx creates, signs, and issues an import transaction that -// // attempts to consume all the available UTXOs and import the funds to [to]. -// // -// // - [chainID] specifies the chain to be importing funds from. -// // - [to] specifies where to send the imported funds to. -// IssueImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// options ...common.Option, -// ) (*evm.Tx, error) - -// // IssueExportTx creates, signs, and issues an export transaction that -// // attempts to send all the provided [outputs] to the requested [chainID]. -// // -// // - [chainID] specifies the chain to be exporting the funds to. -// // - [outputs] specifies the outputs to send to the [chainID]. -// IssueExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// options ...common.Option, -// ) (*evm.Tx, error) - -// // IssueUnsignedTx signs and issues the unsigned tx. -// IssueUnsignedAtomicTx( -// utx evm.UnsignedAtomicTx, -// options ...common.Option, -// ) (*evm.Tx, error) - -// // IssueAtomicTx issues the signed tx. -// IssueAtomicTx( -// tx *evm.Tx, -// options ...common.Option, -// ) error -// } - -// func NewWallet( -// builder Builder, -// signer Signer, -// avaxClient evm.Client, -// ethClient ethclient.Client, -// backend Backend, -// ) Wallet { -// return &wallet{ -// Backend: backend, -// builder: builder, -// signer: signer, -// avaxClient: avaxClient, -// ethClient: ethClient, -// } -// } - -// type wallet struct { -// Backend -// builder Builder -// signer Signer -// avaxClient evm.Client -// ethClient ethclient.Client -// } - -// func (w *wallet) Builder() Builder { -// return w.builder -// } - -// func (w *wallet) Signer() Signer { -// return w.signer -// } - -// func (w *wallet) IssueImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// options ...common.Option, -// ) (*evm.Tx, error) { -// baseFee, err := w.baseFee(options) -// if err != nil { -// return nil, err -// } - -// utx, err := w.builder.NewImportTx(chainID, to, baseFee, options...) -// if err != nil { -// return nil, err -// } -// return w.IssueUnsignedAtomicTx(utx, options...) -// } - -// func (w *wallet) IssueExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// options ...common.Option, -// ) (*evm.Tx, error) { -// baseFee, err := w.baseFee(options) -// if err != nil { -// return nil, err -// } - -// utx, err := w.builder.NewExportTx(chainID, outputs, baseFee, options...) -// if err != nil { -// return nil, err -// } -// return w.IssueUnsignedAtomicTx(utx, options...) -// } - -// func (w *wallet) IssueUnsignedAtomicTx( -// utx evm.UnsignedAtomicTx, -// options ...common.Option, -// ) (*evm.Tx, error) { -// ops := common.NewOptions(options) -// ctx := ops.Context() -// tx, err := w.signer.SignUnsignedAtomic(ctx, utx) -// if err != nil { -// return nil, err -// } - -// return tx, w.IssueAtomicTx(tx, options...) -// } - -// func (w *wallet) IssueAtomicTx( -// tx *evm.Tx, -// options ...common.Option, -// ) error { -// ops := common.NewOptions(options) -// ctx := ops.Context() -// txID, err := w.avaxClient.IssueTx(ctx, tx.SignedBytes()) -// if err != nil { -// return err -// } - -// if f := ops.PostIssuanceFunc(); f != nil { -// f(txID) -// } - -// if ops.AssumeDecided() { -// return w.Backend.AcceptAtomicTx(ctx, tx) -// } - -// pollFrequency := ops.PollFrequency() -// ticker := time.NewTicker(pollFrequency) -// defer ticker.Stop() - -// for { -// status, err := w.avaxClient.GetAtomicTxStatus(ctx, txID) -// if err != nil { -// return err -// } - -// switch status { -// case evm.Accepted: -// return w.Backend.AcceptAtomicTx(ctx, tx) -// case evm.Dropped, evm.Unknown: -// return errNotCommitted -// } - -// // The tx is Processing. - -// select { -// case <-ticker.C: -// case <-ctx.Done(): -// return ctx.Err() -// } -// } -// } - -// func (w *wallet) baseFee(options []common.Option) (*big.Int, error) { -// ops := common.NewOptions(options) -// baseFee := ops.BaseFee(nil) -// if baseFee != nil { -// return baseFee, nil -// } - -// ctx := ops.Context() -// return w.ethClient.EstimateBaseFee(ctx) -// } +import ( + "errors" + "math/big" + "time" + + "github.com/ava-labs/coreth/ethclient" + "github.com/ava-labs/coreth/plugin/evm" + + ethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var ( + _ Wallet = (*wallet)(nil) + + errNotCommitted = errors.New("not committed") +) + +type Wallet interface { + Context + + // Builder returns the builder that will be used to create the transactions. + Builder() Builder + + // Signer returns the signer that will be used to sign the transactions. + Signer() Signer + + // IssueImportTx creates, signs, and issues an import transaction that + // attempts to consume all the available UTXOs and import the funds to [to]. + // + // - [chainID] specifies the chain to be importing funds from. + // - [to] specifies where to send the imported funds to. + IssueImportTx( + chainID ids.ID, + to ethcommon.Address, + options ...common.Option, + ) (*evm.Tx, error) + + // IssueExportTx creates, signs, and issues an export transaction that + // attempts to send all the provided [outputs] to the requested [chainID]. + // + // - [chainID] specifies the chain to be exporting the funds to. + // - [outputs] specifies the outputs to send to the [chainID]. + IssueExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + options ...common.Option, + ) (*evm.Tx, error) + + // IssueUnsignedTx signs and issues the unsigned tx. + IssueUnsignedAtomicTx( + utx evm.UnsignedAtomicTx, + options ...common.Option, + ) (*evm.Tx, error) + + // IssueAtomicTx issues the signed tx. + IssueAtomicTx( + tx *evm.Tx, + options ...common.Option, + ) error +} + +func NewWallet( + builder Builder, + signer Signer, + avaxClient evm.Client, + ethClient ethclient.Client, + backend Backend, +) Wallet { + return &wallet{ + Backend: backend, + builder: builder, + signer: signer, + avaxClient: avaxClient, + ethClient: ethClient, + } +} + +type wallet struct { + Backend + builder Builder + signer Signer + avaxClient evm.Client + ethClient ethclient.Client +} + +func (w *wallet) Builder() Builder { + return w.builder +} + +func (w *wallet) Signer() Signer { + return w.signer +} + +func (w *wallet) IssueImportTx( + chainID ids.ID, + to ethcommon.Address, + options ...common.Option, +) (*evm.Tx, error) { + baseFee, err := w.baseFee(options) + if err != nil { + return nil, err + } + + utx, err := w.builder.NewImportTx(chainID, to, baseFee, options...) + if err != nil { + return nil, err + } + return w.IssueUnsignedAtomicTx(utx, options...) +} + +func (w *wallet) IssueExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + options ...common.Option, +) (*evm.Tx, error) { + baseFee, err := w.baseFee(options) + if err != nil { + return nil, err + } + + utx, err := w.builder.NewExportTx(chainID, outputs, baseFee, options...) + if err != nil { + return nil, err + } + return w.IssueUnsignedAtomicTx(utx, options...) +} + +func (w *wallet) IssueUnsignedAtomicTx( + utx evm.UnsignedAtomicTx, + options ...common.Option, +) (*evm.Tx, error) { + ops := common.NewOptions(options) + ctx := ops.Context() + tx, err := w.signer.SignUnsignedAtomic(ctx, utx) + if err != nil { + return nil, err + } + + return tx, w.IssueAtomicTx(tx, options...) +} + +func (w *wallet) IssueAtomicTx( + tx *evm.Tx, + options ...common.Option, +) error { + ops := common.NewOptions(options) + ctx := ops.Context() + txID, err := w.avaxClient.IssueTx(ctx, tx.SignedBytes()) + if err != nil { + return err + } + + if f := ops.PostIssuanceFunc(); f != nil { + f(txID) + } + + if ops.AssumeDecided() { + return w.Backend.AcceptAtomicTx(ctx, tx) + } + + pollFrequency := ops.PollFrequency() + ticker := time.NewTicker(pollFrequency) + defer ticker.Stop() + + for { + status, err := w.avaxClient.GetAtomicTxStatus(ctx, txID) + if err != nil { + return err + } + + switch status { + case evm.Accepted: + return w.Backend.AcceptAtomicTx(ctx, tx) + case evm.Dropped, evm.Unknown: + return errNotCommitted + } + + // The tx is Processing. + + select { + case <-ticker.C: + case <-ctx.Done(): + return ctx.Err() + } + } +} + +func (w *wallet) baseFee(options []common.Option) (*big.Int, error) { + ops := common.NewOptions(options) + baseFee := ops.BaseFee(nil) + if baseFee != nil { + return baseFee, nil + } + + ctx := ops.Context() + return w.ethClient.EstimateBaseFee(ctx) +} diff --git a/wallet/chain/c/wallet_with_options.go b/wallet/chain/c/wallet_with_options.go index fd69a6d4fd02..7d6193683d49 100644 --- a/wallet/chain/c/wallet_with_options.go +++ b/wallet/chain/c/wallet_with_options.go @@ -3,80 +3,80 @@ package c -// import ( -// "github.com/ava-labs/coreth/plugin/evm" +import ( + "github.com/ava-labs/coreth/plugin/evm" -// ethcommon "github.com/ethereum/go-ethereum/common" + ethcommon "github.com/ethereum/go-ethereum/common" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) -// var _ Wallet = (*walletWithOptions)(nil) +var _ Wallet = (*walletWithOptions)(nil) -// func NewWalletWithOptions( -// wallet Wallet, -// options ...common.Option, -// ) Wallet { -// return &walletWithOptions{ -// Wallet: wallet, -// options: options, -// } -// } +func NewWalletWithOptions( + wallet Wallet, + options ...common.Option, +) Wallet { + return &walletWithOptions{ + Wallet: wallet, + options: options, + } +} -// type walletWithOptions struct { -// Wallet -// options []common.Option -// } +type walletWithOptions struct { + Wallet + options []common.Option +} -// func (w *walletWithOptions) Builder() Builder { -// return NewBuilderWithOptions( -// w.Wallet.Builder(), -// w.options..., -// ) -// } +func (w *walletWithOptions) Builder() Builder { + return NewBuilderWithOptions( + w.Wallet.Builder(), + w.options..., + ) +} -// func (w *walletWithOptions) IssueImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// options ...common.Option, -// ) (*evm.Tx, error) { -// return w.Wallet.IssueImportTx( -// chainID, -// to, -// common.UnionOptions(w.options, options)..., -// ) -// } +func (w *walletWithOptions) IssueImportTx( + chainID ids.ID, + to ethcommon.Address, + options ...common.Option, +) (*evm.Tx, error) { + return w.Wallet.IssueImportTx( + chainID, + to, + common.UnionOptions(w.options, options)..., + ) +} -// func (w *walletWithOptions) IssueExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// options ...common.Option, -// ) (*evm.Tx, error) { -// return w.Wallet.IssueExportTx( -// chainID, -// outputs, -// common.UnionOptions(w.options, options)..., -// ) -// } +func (w *walletWithOptions) IssueExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + options ...common.Option, +) (*evm.Tx, error) { + return w.Wallet.IssueExportTx( + chainID, + outputs, + common.UnionOptions(w.options, options)..., + ) +} -// func (w *walletWithOptions) IssueUnsignedAtomicTx( -// utx evm.UnsignedAtomicTx, -// options ...common.Option, -// ) (*evm.Tx, error) { -// return w.Wallet.IssueUnsignedAtomicTx( -// utx, -// common.UnionOptions(w.options, options)..., -// ) -// } +func (w *walletWithOptions) IssueUnsignedAtomicTx( + utx evm.UnsignedAtomicTx, + options ...common.Option, +) (*evm.Tx, error) { + return w.Wallet.IssueUnsignedAtomicTx( + utx, + common.UnionOptions(w.options, options)..., + ) +} -// func (w *walletWithOptions) IssueAtomicTx( -// tx *evm.Tx, -// options ...common.Option, -// ) error { -// return w.Wallet.IssueAtomicTx( -// tx, -// common.UnionOptions(w.options, options)..., -// ) -// } +func (w *walletWithOptions) IssueAtomicTx( + tx *evm.Tx, + options ...common.Option, +) error { + return w.Wallet.IssueAtomicTx( + tx, + common.UnionOptions(w.options, options)..., + ) +} diff --git a/wallet/subnet/primary/api.go b/wallet/subnet/primary/api.go index 00ebea6090fd..3ac72c217884 100644 --- a/wallet/subnet/primary/api.go +++ b/wallet/subnet/primary/api.go @@ -5,11 +5,12 @@ package primary import ( "context" - // "fmt" + "fmt" - // "github.com/ava-labs/coreth/ethclient" + "github.com/ava-labs/coreth/ethclient" + "github.com/ava-labs/coreth/plugin/evm" - // "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common" "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/codec" @@ -21,8 +22,7 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - - // "github.com/ava-labs/avalanchego/wallet/chain/c" + "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/x" ) @@ -59,9 +59,9 @@ type AVAXState struct { PCTX p.Context XClient avm.Client XCTX x.Context - // CClient evm.Client - // CCTX c.Context - UTXOs UTXOs + CClient evm.Client + CCTX c.Context + UTXOs UTXOs } func FetchState( @@ -75,7 +75,7 @@ func FetchState( infoClient := info.NewClient(uri) pClient := platformvm.NewClient(uri) xClient := avm.NewClient(uri, "X") - // cClient := evm.NewCChainClient(uri) + cClient := evm.NewCChainClient(uri) pCTX, err := p.NewContextFromClients(ctx, infoClient, xClient) if err != nil { @@ -87,10 +87,10 @@ func FetchState( return nil, err } - // cCTX, err := c.NewContextFromClients(ctx, infoClient, xClient) - // if err != nil { - // return nil, err - // } + cCTX, err := c.NewContextFromClients(ctx, infoClient, xClient) + if err != nil { + return nil, err + } utxos := NewUTXOs() addrList := addrs.List() @@ -109,11 +109,11 @@ func FetchState( client: xClient, codec: x.Parser.Codec(), }, - // { - // id: cCTX.BlockchainID(), - // client: cClient, - // codec: evm.Codec, - // }, + { + id: cCTX.BlockchainID(), + client: cClient, + codec: evm.Codec, + }, } for _, destinationChain := range chains { for _, sourceChain := range chains { @@ -136,52 +136,52 @@ func FetchState( PCTX: pCTX, XClient: xClient, XCTX: xCTX, - // CClient: cClient, - // CCTX: cCTX, - UTXOs: utxos, + CClient: cClient, + CCTX: cCTX, + UTXOs: utxos, }, nil } -// type EthState struct { -// Client ethclient.Client -// Accounts map[common.Address]*c.Account -// } - -// func FetchEthState( -// ctx context.Context, -// uri string, -// addrs set.Set[common.Address], -// ) (*EthState, error) { -// path := fmt.Sprintf( -// "%s/ext/%s/C/rpc", -// uri, -// constants.ChainAliasPrefix, -// ) -// client, err := ethclient.Dial(path) -// if err != nil { -// return nil, err -// } - -// accounts := make(map[common.Address]*c.Account, addrs.Len()) -// for addr := range addrs { -// balance, err := client.BalanceAt(ctx, addr, nil) -// if err != nil { -// return nil, err -// } -// nonce, err := client.NonceAt(ctx, addr, nil) -// if err != nil { -// return nil, err -// } -// accounts[addr] = &c.Account{ -// Balance: balance, -// Nonce: nonce, -// } -// } -// return &EthState{ -// Client: client, -// Accounts: accounts, -// }, nil -// } +type EthState struct { + Client ethclient.Client + Accounts map[common.Address]*c.Account +} + +func FetchEthState( + ctx context.Context, + uri string, + addrs set.Set[common.Address], +) (*EthState, error) { + path := fmt.Sprintf( + "%s/ext/%s/C/rpc", + uri, + constants.ChainAliasPrefix, + ) + client, err := ethclient.Dial(path) + if err != nil { + return nil, err + } + + accounts := make(map[common.Address]*c.Account, addrs.Len()) + for addr := range addrs { + balance, err := client.BalanceAt(ctx, addr, nil) + if err != nil { + return nil, err + } + nonce, err := client.NonceAt(ctx, addr, nil) + if err != nil { + return nil, err + } + accounts[addr] = &c.Account{ + Balance: balance, + Nonce: nonce, + } + } + return &EthState{ + Client: client, + Accounts: accounts, + }, nil +} // AddAllUTXOs fetches all the UTXOs referenced by [addresses] that were sent // from [sourceChainID] to [destinationChainID] from the [client]. It then uses diff --git a/wallet/subnet/primary/example_test.go b/wallet/subnet/primary/example_test.go index 4a73e8c070b2..483c049d4ac0 100644 --- a/wallet/subnet/primary/example_test.go +++ b/wallet/subnet/primary/example_test.go @@ -30,7 +30,7 @@ func ExampleWallet() { wallet, err := MakeWallet(ctx, &WalletConfig{ URI: LocalAPIURI, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet with: %s\n", err) diff --git a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go index 21c081d2982b..d5e8ce422307 100644 --- a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go +++ b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go @@ -46,9 +46,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - // EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/examples/add-primary-validator/main.go b/wallet/subnet/primary/examples/add-primary-validator/main.go index 13c28f995f63..a56dae23db3a 100644 --- a/wallet/subnet/primary/examples/add-primary-validator/main.go +++ b/wallet/subnet/primary/examples/add-primary-validator/main.go @@ -45,7 +45,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/c-chain-export/main.go b/wallet/subnet/primary/examples/c-chain-export/main.go index a6b9a0c810b8..fec55c899feb 100644 --- a/wallet/subnet/primary/examples/c-chain-export/main.go +++ b/wallet/subnet/primary/examples/c-chain-export/main.go @@ -3,70 +3,70 @@ package main -// import ( -// "context" -// "log" -// "time" +import ( + "context" + "log" + "time" -// "github.com/ava-labs/avalanchego/genesis" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary" -// ) + "github.com/ava-labs/avalanchego/genesis" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary" +) -// func main() { -// key := genesis.EWOQKey -// uri := primary.LocalAPIURI -// kc := secp256k1fx.NewKeychain(key) -// avaxAddr := key.Address() +func main() { + key := genesis.EWOQKey + uri := primary.LocalAPIURI + kc := secp256k1fx.NewKeychain(key) + avaxAddr := key.Address() -// ctx := context.Background() + ctx := context.Background() -// // MakeWallet fetches the available UTXOs owned by [kc] on the network that -// // [uri] is hosting. -// walletSyncStartTime := time.Now() -// wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ -// URI: uri, -// AVAXKeychain: kc, -// EthKeychain: kc, -// }) -// if err != nil { -// log.Fatalf("failed to initialize wallet: %s\n", err) -// } -// log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) + // MakeWallet fetches the available UTXOs owned by [kc] on the network that + // [uri] is hosting. + walletSyncStartTime := time.Now() + wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, + }) + if err != nil { + log.Fatalf("failed to initialize wallet: %s\n", err) + } + log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) -// // Get the P-chain wallet -// pWallet := wallet.P() -// cWallet := wallet.C() + // Get the P-chain wallet + pWallet := wallet.P() + cWallet := wallet.C() -// // Pull out useful constants to use when issuing transactions. -// cChainID := cWallet.BlockchainID() -// owner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// avaxAddr, -// }, -// } + // Pull out useful constants to use when issuing transactions. + cChainID := cWallet.BlockchainID() + owner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + avaxAddr, + }, + } -// exportStartTime := time.Now() -// exportTx, err := cWallet.IssueExportTx( -// constants.PlatformChainID, -// []*secp256k1fx.TransferOutput{{ -// Amt: units.Avax, -// OutputOwners: owner, -// }}, -// ) -// if err != nil { -// log.Fatalf("failed to issue export transaction: %s\n", err) -// } -// log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) + exportStartTime := time.Now() + exportTx, err := cWallet.IssueExportTx( + constants.PlatformChainID, + []*secp256k1fx.TransferOutput{{ + Amt: units.Avax, + OutputOwners: owner, + }}, + ) + if err != nil { + log.Fatalf("failed to issue export transaction: %s\n", err) + } + log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) -// importStartTime := time.Now() -// importTx, err := pWallet.IssueImportTx(cChainID, &owner) -// if err != nil { -// log.Fatalf("failed to issue import transaction: %s\n", err) -// } -// log.Printf("issued import %s in %s\n", importTx.ID(), time.Since(importStartTime)) -// } + importStartTime := time.Now() + importTx, err := pWallet.IssueImportTx(cChainID, &owner) + if err != nil { + log.Fatalf("failed to issue import transaction: %s\n", err) + } + log.Printf("issued import %s in %s\n", importTx.ID(), time.Since(importStartTime)) +} diff --git a/wallet/subnet/primary/examples/c-chain-import/main.go b/wallet/subnet/primary/examples/c-chain-import/main.go index 2d9b8a244cb0..b4dc4e603eb3 100644 --- a/wallet/subnet/primary/examples/c-chain-import/main.go +++ b/wallet/subnet/primary/examples/c-chain-import/main.go @@ -3,75 +3,75 @@ package main -// import ( -// "context" -// "log" -// "time" +import ( + "context" + "log" + "time" -// "github.com/ava-labs/coreth/plugin/evm" + "github.com/ava-labs/coreth/plugin/evm" -// "github.com/ava-labs/avalanchego/genesis" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary" -// ) + "github.com/ava-labs/avalanchego/genesis" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary" +) -// func main() { -// key := genesis.EWOQKey -// uri := primary.LocalAPIURI -// kc := secp256k1fx.NewKeychain(key) -// avaxAddr := key.Address() -// ethAddr := evm.PublicKeyToEthAddress(key.PublicKey()) +func main() { + key := genesis.EWOQKey + uri := primary.LocalAPIURI + kc := secp256k1fx.NewKeychain(key) + avaxAddr := key.Address() + ethAddr := evm.PublicKeyToEthAddress(key.PublicKey()) -// ctx := context.Background() + ctx := context.Background() -// // MakeWallet fetches the available UTXOs owned by [kc] on the network that -// // [uri] is hosting. -// walletSyncStartTime := time.Now() -// wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ -// URI: uri, -// AVAXKeychain: kc, -// EthKeychain: kc, -// }) -// if err != nil { -// log.Fatalf("failed to initialize wallet: %s\n", err) -// } -// log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) + // MakeWallet fetches the available UTXOs owned by [kc] on the network that + // [uri] is hosting. + walletSyncStartTime := time.Now() + wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, + }) + if err != nil { + log.Fatalf("failed to initialize wallet: %s\n", err) + } + log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) -// // Get the P-chain wallet -// pWallet := wallet.P() -// cWallet := wallet.C() + // Get the P-chain wallet + pWallet := wallet.P() + cWallet := wallet.C() -// // Pull out useful constants to use when issuing transactions. -// cChainID := cWallet.BlockchainID() -// avaxAssetID := cWallet.AVAXAssetID() -// owner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// avaxAddr, -// }, -// } + // Pull out useful constants to use when issuing transactions. + cChainID := cWallet.BlockchainID() + avaxAssetID := cWallet.AVAXAssetID() + owner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + avaxAddr, + }, + } -// exportStartTime := time.Now() -// exportTx, err := pWallet.IssueExportTx(cChainID, []*avax.TransferableOutput{{ -// Asset: avax.Asset{ID: avaxAssetID}, -// Out: &secp256k1fx.TransferOutput{ -// Amt: units.Avax, -// OutputOwners: owner, -// }, -// }}) -// if err != nil { -// log.Fatalf("failed to issue export transaction: %s\n", err) -// } -// log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) + exportStartTime := time.Now() + exportTx, err := pWallet.IssueExportTx(cChainID, []*avax.TransferableOutput{{ + Asset: avax.Asset{ID: avaxAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: units.Avax, + OutputOwners: owner, + }, + }}) + if err != nil { + log.Fatalf("failed to issue export transaction: %s\n", err) + } + log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) -// importStartTime := time.Now() -// importTx, err := cWallet.IssueImportTx(constants.PlatformChainID, ethAddr) -// if err != nil { -// log.Fatalf("failed to issue import transaction: %s\n", err) -// } -// log.Printf("issued import %s to %s in %s\n", importTx.ID(), ethAddr.Hex(), time.Since(importStartTime)) -// } + importStartTime := time.Now() + importTx, err := cWallet.IssueImportTx(constants.PlatformChainID, ethAddr) + if err != nil { + log.Fatalf("failed to issue import transaction: %s\n", err) + } + log.Printf("issued import %s to %s in %s\n", importTx.ID(), ethAddr.Hex(), time.Since(importStartTime)) +} diff --git a/wallet/subnet/primary/examples/create-asset/main.go b/wallet/subnet/primary/examples/create-asset/main.go index 0bccfbb5fc52..30804f083df6 100644 --- a/wallet/subnet/primary/examples/create-asset/main.go +++ b/wallet/subnet/primary/examples/create-asset/main.go @@ -30,7 +30,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/create-chain/main.go b/wallet/subnet/primary/examples/create-chain/main.go index 521a3cca53cf..5e6898a1b649 100644 --- a/wallet/subnet/primary/examples/create-chain/main.go +++ b/wallet/subnet/primary/examples/create-chain/main.go @@ -41,9 +41,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - // EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/examples/create-locked-stakeable/main.go b/wallet/subnet/primary/examples/create-locked-stakeable/main.go index 92f1b5cb0e1b..e688968e9e8a 100644 --- a/wallet/subnet/primary/examples/create-locked-stakeable/main.go +++ b/wallet/subnet/primary/examples/create-locked-stakeable/main.go @@ -39,7 +39,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/create-subnet/main.go b/wallet/subnet/primary/examples/create-subnet/main.go index 3e8d69bc016a..add98ea7931c 100644 --- a/wallet/subnet/primary/examples/create-subnet/main.go +++ b/wallet/subnet/primary/examples/create-subnet/main.go @@ -28,7 +28,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/remove-subnet-validator/main.go b/wallet/subnet/primary/examples/remove-subnet-validator/main.go index 46f4b85124db..2842c7c0a790 100644 --- a/wallet/subnet/primary/examples/remove-subnet-validator/main.go +++ b/wallet/subnet/primary/examples/remove-subnet-validator/main.go @@ -38,9 +38,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - // EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/wallet.go b/wallet/subnet/primary/wallet.go index ae5e4202a099..54de390d029c 100644 --- a/wallet/subnet/primary/wallet.go +++ b/wallet/subnet/primary/wallet.go @@ -11,8 +11,7 @@ import ( "github.com/ava-labs/avalanchego/utils/crypto/keychain" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - - // "github.com/ava-labs/avalanchego/wallet/chain/c" + "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/x" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -24,13 +23,13 @@ var _ Wallet = (*wallet)(nil) type Wallet interface { P() p.Wallet X() x.Wallet - // C() c.Wallet + C() c.Wallet } type wallet struct { p p.Wallet x x.Wallet - // c c.Wallet + c c.Wallet } func (w *wallet) P() p.Wallet { @@ -41,16 +40,16 @@ func (w *wallet) X() x.Wallet { return w.x } -// func (w *wallet) C() c.Wallet { -// return w.c -// } +func (w *wallet) C() c.Wallet { + return w.c +} // Creates a new default wallet -func NewWallet(p p.Wallet, x x.Wallet /*, c c.Wallet*/) Wallet { +func NewWallet(p p.Wallet, x x.Wallet, c c.Wallet) Wallet { return &wallet{ p: p, x: x, - // c: c, + c: c, } } @@ -59,7 +58,7 @@ func NewWalletWithOptions(w Wallet, options ...common.Option) Wallet { return NewWallet( p.NewWalletWithOptions(w.P(), options...), x.NewWalletWithOptions(w.X(), options...), - // c.NewWalletWithOptions(w.C(), options...), + c.NewWalletWithOptions(w.C(), options...), ) } @@ -68,7 +67,7 @@ type WalletConfig struct { URI string // required // Keys to use for signing all transactions. AVAXKeychain keychain.Keychain // required - // EthKeychain c.EthKeychain // required + EthKeychain c.EthKeychain // required // Set of P-chain transactions that the wallet should know about to be able // to generate transactions. PChainTxs map[ids.ID]*txs.Tx // optional @@ -94,11 +93,11 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { return nil, err } - // ethAddrs := config.EthKeychain.EthAddresses() - // ethState, err := FetchEthState(ctx, config.URI, ethAddrs) - // if err != nil { - // return nil, err - // } + ethAddrs := config.EthKeychain.EthAddresses() + ethState, err := FetchEthState(ctx, config.URI, ethAddrs) + if err != nil { + return nil, err + } pChainTxs := config.PChainTxs if pChainTxs == nil { @@ -128,15 +127,15 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { xBuilder := x.NewBuilder(avaxAddrs, xBackend) xSigner := x.NewSigner(config.AVAXKeychain, xBackend) - // cChainID := avaxState.CCTX.BlockchainID() - // cUTXOs := NewChainUTXOs(cChainID, avaxState.UTXOs) - // cBackend := c.NewBackend(avaxState.CCTX, cUTXOs, ethState.Accounts) - // cBuilder := c.NewBuilder(avaxAddrs, ethAddrs, cBackend) - // cSigner := c.NewSigner(config.AVAXKeychain, config.EthKeychain, cBackend) + cChainID := avaxState.CCTX.BlockchainID() + cUTXOs := NewChainUTXOs(cChainID, avaxState.UTXOs) + cBackend := c.NewBackend(avaxState.CCTX, cUTXOs, ethState.Accounts) + cBuilder := c.NewBuilder(avaxAddrs, ethAddrs, cBackend) + cSigner := c.NewSigner(config.AVAXKeychain, config.EthKeychain, cBackend) return NewWallet( p.NewWallet(pBuilder, pSigner, avaxState.PClient, pBackend), x.NewWallet(xBuilder, xSigner, avaxState.XClient, xBackend), - // c.NewWallet(cBuilder, cSigner, avaxState.CClient, ethState.Client, cBackend), + c.NewWallet(cBuilder, cSigner, avaxState.CClient, ethState.Client, cBackend), ), nil } From fa7f02daf6de2bb7f99079f17bd5eb14fe1505b1 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Sat, 9 Dec 2023 21:17:31 +0100 Subject: [PATCH 08/13] bumped coreth version --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b793394d8d24..df00284cf522 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 - github.com/ava-labs/coreth v0.12.10-rc.0 + github.com/ava-labs/coreth v0.12.9-rc.9.0.20231209201450-b2b381262a3a github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 diff --git a/go.sum b/go.sum index 7b9a76de9663..ab1e22673b30 100644 --- a/go.sum +++ b/go.sum @@ -66,8 +66,8 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/coreth v0.12.10-rc.0 h1:qmuom7rtH5hc1E3lnqrMFNLFL1TMnEVa/2O8poB1YLU= -github.com/ava-labs/coreth v0.12.10-rc.0/go.mod h1:plFm/xzvWmx1+qJ3JQSTzF8+FdaA2xu7GgY/AdaZDfk= +github.com/ava-labs/coreth v0.12.9-rc.9.0.20231209201450-b2b381262a3a h1:7l9M7Ej2Zu5hBQhNsitUDS2rofVeHmLOCTWUqygIWho= +github.com/ava-labs/coreth v0.12.9-rc.9.0.20231209201450-b2b381262a3a/go.mod h1:XGVU/xdpxYhCHSHqafqv7nz34bh3GcZcZFneBQyguOw= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= From 5b058f77894478bf6db50f9838afb03024d50df0 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 30 Oct 2023 08:28:32 +0100 Subject: [PATCH 09/13] temporarily cut coreth dependency --- go.mod | 26 +- go.sum | 77 +- node/node.go | 4 +- tests/e2e/c/dynamic_fees.go | 326 +++---- tests/e2e/c/interchain_workflow.go | 320 +++---- tests/e2e/p/interchain_workflow.go | 422 ++++----- tests/e2e/x/interchain_workflow.go | 296 +++---- tests/fixture/e2e/helpers.go | 123 +-- tests/fixture/tmpnet/genesis.go | 50 +- vms/example/xsvm/cmd/chain/create/cmd.go | 6 +- wallet/chain/c/backend.go | 300 +++---- wallet/chain/c/builder.go | 812 +++++++++--------- wallet/chain/c/builder_with_options.go | 136 +-- wallet/chain/c/context.go | 194 ++--- wallet/chain/c/signer.go | 436 +++++----- wallet/chain/c/wallet.go | 402 ++++----- wallet/chain/c/wallet_with_options.go | 134 +-- wallet/subnet/primary/api.go | 122 +-- wallet/subnet/primary/example_test.go | 2 +- .../add-permissioned-subnet-validator/main.go | 6 +- .../examples/add-primary-validator/main.go | 2 +- .../primary/examples/c-chain-export/main.go | 118 +-- .../primary/examples/c-chain-import/main.go | 126 +-- .../primary/examples/create-asset/main.go | 2 +- .../primary/examples/create-chain/main.go | 6 +- .../examples/create-locked-stakeable/main.go | 2 +- .../primary/examples/create-subnet/main.go | 2 +- .../examples/remove-subnet-validator/main.go | 6 +- wallet/subnet/primary/wallet.go | 43 +- 29 files changed, 2200 insertions(+), 2301 deletions(-) diff --git a/go.mod b/go.mod index c1b6367a5223..cd9743e7bdfb 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,6 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 - github.com/ava-labs/coreth v0.12.10-rc.2 github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 @@ -75,7 +74,6 @@ require ( github.com/BurntSushi/toml v1.2.1 // indirect github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect - github.com/VictoriaMetrics/fastcache v1.10.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect @@ -83,45 +81,28 @@ require ( github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/redact v1.1.3 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/deckarep/golang-set/v2 v2.1.0 // indirect - github.com/dlclark/regexp2 v1.7.0 // indirect - github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 // indirect - github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect github.com/frankban/quicktest v1.14.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/getsentry/sentry-go v0.18.0 // indirect github.com/go-logr/logr v1.3.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect - github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect - github.com/go-stack/stack v1.8.1 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/go-cmp v0.6.0 // indirect - github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect - github.com/google/uuid v1.3.0 // indirect + github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 // indirect - github.com/hashicorp/go-bexpr v0.1.10 // indirect - github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e // indirect github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/klauspost/compress v1.15.15 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/magiconair/properties v1.8.6 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect - github.com/mattn/go-runewidth v0.0.9 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/mitchellh/pointerstructure v1.2.0 // indirect - github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -129,17 +110,12 @@ require ( github.com/prometheus/common v0.39.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sanity-io/litter v1.5.1 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/status-im/keycard-go v0.2.0 // indirect github.com/subosito/gotenv v1.3.0 // indirect github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tklauser/numcpus v0.2.2 // indirect - github.com/tyler-smith/go-bip39 v1.1.0 // indirect - github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa // indirect - github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect diff --git a/go.sum b/go.sum index d83821fc4ceb..3ef5760fbfd8 100644 --- a/go.sum +++ b/go.sum @@ -56,18 +56,12 @@ github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cq github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= -github.com/VictoriaMetrics/fastcache v1.10.0 h1:5hDJnLsKLpnUEToub7ETuRu8RCkb40woBZAUiKonXzY= -github.com/VictoriaMetrics/fastcache v1.10.0/go.mod h1:tjiYeEfYXCqacuvYw/7UoDIeJaNxq6132xHICNP77w8= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/coreth v0.12.10-rc.2 h1:+2YK7PzStcLCHtsBb1VQjw6DyMl1sMZatReZAyIy7w8= -github.com/ava-labs/coreth v0.12.10-rc.2/go.mod h1:RIbv14KMyWSj4hB1danS+vEPCUsgArZUEo99SaP5nW8= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= @@ -102,18 +96,13 @@ github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46f github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw= github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA= @@ -145,16 +134,12 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= -github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= @@ -165,14 +150,6 @@ github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6ps github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= -github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= -github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 h1:+3HCtB74++ClLy8GgjUQYeC8R4ILzVcIe8+5edAJJnE= -github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= -github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= -github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -189,8 +166,6 @@ github.com/ethereum/go-ethereum v1.12.0 h1:bdnhLPtqETd4m3mS8BGMNvBTf36bO5bx/hxE2 github.com/ethereum/go-ethereum v1.12.0/go.mod h1:/oo2X/dZLJjf2mJ6YT9wcWxa4nNJDBKDBU6sFIpx1Gs= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -199,8 +174,6 @@ github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmV github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= -github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= -github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= @@ -224,11 +197,7 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= -github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= -github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= @@ -315,15 +284,12 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= -github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= @@ -344,17 +310,11 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 h1:kr3j8iIMR4ywO/O0rvksXaJvauGGCMg2zAZIiNZ9uIQ= github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0/go.mod h1:ummNFgdgLhhX7aIiy35vVmQNS0rWXknfPE0qe6fmFXg= -github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= -github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e h1:pIYdhNkDh+YENVNi3gto8n9hAmRxKxoar0iE6BLucjw= -github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e/go.mod h1:j9cQbcqHQujT0oKJ38PylVfqohClLr3CvDC+Qcg+lhU= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c h1:DZfsyhDK1hnSS5lH8l+JggqzEleHteTYfutAiVlSUM8= @@ -366,7 +326,6 @@ github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3 github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -408,7 +367,6 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -416,7 +374,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= @@ -427,17 +384,11 @@ github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPK github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= @@ -446,11 +397,8 @@ github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= -github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -469,8 +417,6 @@ github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= -github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -538,8 +484,6 @@ github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sanity-io/litter v1.5.1 h1:dwnrSypP6q56o3lFxTU+t2fwQ9A+U5qrXVO4Qg9KwVU= github.com/sanity-io/litter v1.5.1/go.mod h1:5Z71SvaYy5kcGtyglXOC9rrUi3c1E8CamFWjQsazTh0= @@ -575,8 +519,6 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= -github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= -github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -609,14 +551,10 @@ github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZF github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE= github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE= -github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= -github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa h1:5SqCsI/2Qya2bCzK15ozrqo2sZxkh0FHynJZOTVoV6Q= -github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= @@ -628,8 +566,6 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= @@ -639,7 +575,6 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= @@ -735,7 +670,6 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -782,7 +716,6 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -806,7 +739,6 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -871,12 +803,8 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= @@ -893,7 +821,6 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -957,7 +884,6 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1084,7 +1010,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= diff --git a/node/node.go b/node/node.go index 22be7d5436eb..151f878ee6d7 100644 --- a/node/node.go +++ b/node/node.go @@ -25,7 +25,7 @@ import ( "go.uber.org/zap" - coreth "github.com/ava-labs/coreth/plugin/evm" + // coreth "github.com/ava-labs/coreth/plugin/evm" "github.com/ava-labs/avalanchego/api/admin" "github.com/ava-labs/avalanchego/api/auth" @@ -1116,7 +1116,7 @@ func (n *Node) initVMs() error { CreateAssetTxFee: n.Config.CreateAssetTxFee, }, }), - vmRegisterer.Register(context.TODO(), constants.EVMID, &coreth.Factory{}), + // vmRegisterer.Register(context.TODO(), constants.EVMID, &coreth.Factory{}), n.VMManager.RegisterFactory(context.TODO(), secp256k1fx.ID, &secp256k1fx.Factory{}), n.VMManager.RegisterFactory(context.TODO(), nftfx.ID, &nftfx.Factory{}), n.VMManager.RegisterFactory(context.TODO(), propertyfx.ID, &propertyfx.Factory{}), diff --git a/tests/e2e/c/dynamic_fees.go b/tests/e2e/c/dynamic_fees.go index 5e80573542b4..7cd53f52baaf 100644 --- a/tests/e2e/c/dynamic_fees.go +++ b/tests/e2e/c/dynamic_fees.go @@ -3,166 +3,166 @@ package c -import ( - "math/big" - "strings" - - ginkgo "github.com/onsi/ginkgo/v2" - - "github.com/stretchr/testify/require" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/plugin/evm" - - "github.com/ava-labs/avalanchego/tests" - "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -) - -// This test uses the compiled bin for `hashing.sol` as -// well as its ABI contained in `hashing_contract.go`. - -var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { - require := require.New(ginkgo.GinkgoT()) - - // Need a gas limit much larger than the standard 21_000 to enable - // the contract to induce a gas price increase - const largeGasLimit = uint64(8_000_000) - - // TODO(marun) What is the significance of this value? - gasTip := big.NewInt(1000 * params.GWei) - - ginkgo.It("should ensure that the gas price is affected by load", func() { - ginkgo.By("creating a new private network to ensure isolation from other tests") - privateNetwork := e2e.Env.NewPrivateNetwork() - - ginkgo.By("allocating a pre-funded key") - key := privateNetwork.PreFundedKeys[0] - ethAddress := evm.GetEthAddress(key) - - ginkgo.By("initializing a coreth client") - node := privateNetwork.Nodes[0] - nodeURI := tmpnet.NodeURI{ - NodeID: node.NodeID, - URI: node.URI, - } - ethClient := e2e.NewEthClient(nodeURI) - - ginkgo.By("initializing a transaction signer") - cChainID, err := ethClient.ChainID(e2e.DefaultContext()) - require.NoError(err) - signer := types.NewEIP155Signer(cChainID) - ecdsaKey := key.ToECDSA() - sign := func(tx *types.Transaction) *types.Transaction { - signedTx, err := types.SignTx(tx, signer, ecdsaKey) - require.NoError(err) - return signedTx - } - - var contractAddress common.Address - ginkgo.By("deploying an expensive contract", func() { - // Create transaction - nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) - require.NoError(err) - compiledContract := common.Hex2Bytes(hashingCompiledContract) - tx := types.NewTx(&types.LegacyTx{ - Nonce: nonce, - GasPrice: gasTip, - Gas: largeGasLimit, - Value: common.Big0, - Data: compiledContract, - }) - - // Send the transaction and wait for acceptance - signedTx := sign(tx) - receipt := e2e.SendEthTransaction(ethClient, signedTx) - - contractAddress = receipt.ContractAddress - }) - - var gasPrice *big.Int - ginkgo.By("calling the expensive contract repeatedly until a gas price increase is detected", func() { - // Evaluate the bytes representation of the contract - hashingABI, err := abi.JSON(strings.NewReader(hashingABIJson)) - require.NoError(err) - contractData, err := hashingABI.Pack("hashIt") - require.NoError(err) - - var initialGasPrice *big.Int - e2e.Eventually(func() bool { - // Check the gas price - var err error - gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) - require.NoError(err) - if initialGasPrice == nil { - initialGasPrice = gasPrice - tests.Outf("{{blue}}initial gas price is %v{{/}}\n", initialGasPrice) - } else if gasPrice.Cmp(initialGasPrice) > 0 { - // Gas price has increased - tests.Outf("{{blue}}gas price has increased to %v{{/}}\n", gasPrice) - return true - } - - // Create the transaction - nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) - require.NoError(err) - tx := types.NewTx(&types.LegacyTx{ - Nonce: nonce, - GasPrice: gasTip, - Gas: largeGasLimit, - To: &contractAddress, - Value: common.Big0, - Data: contractData, - }) - - // Send the transaction and wait for acceptance - signedTx := sign(tx) - _ = e2e.SendEthTransaction(ethClient, signedTx) - - // The gas price will be checked at the start of the next iteration - return false - }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price increase before timeout") - }) - - ginkgo.By("waiting for the gas price to decrease...", func() { - initialGasPrice := gasPrice - e2e.Eventually(func() bool { - var err error - gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) - require.NoError(err) - tests.Outf("{{blue}}.{{/}}") - return initialGasPrice.Cmp(gasPrice) > 0 - }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price decrease before timeout") - tests.Outf("\n{{blue}}gas price has decreased to %v{{/}}\n", gasPrice) - }) - - ginkgo.By("sending funds at the current gas price", func() { - // Create a recipient address - recipientKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - recipientEthAddress := evm.GetEthAddress(recipientKey) - - // Create transaction - nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) - require.NoError(err) - tx := types.NewTx(&types.LegacyTx{ - Nonce: nonce, - GasPrice: gasPrice, - Gas: e2e.DefaultGasLimit, - To: &recipientEthAddress, - Value: common.Big0, - }) - - // Send the transaction and wait for acceptance - signedTx := sign(tx) - _ = e2e.SendEthTransaction(ethClient, signedTx) - }) - - e2e.CheckBootstrapIsPossible(privateNetwork) - }) -}) +// import ( +// "math/big" +// "strings" + +// ginkgo "github.com/onsi/ginkgo/v2" + +// "github.com/stretchr/testify/require" + +// "github.com/ethereum/go-ethereum/accounts/abi" +// "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/coreth/core/types" +// "github.com/ava-labs/coreth/params" +// "github.com/ava-labs/coreth/plugin/evm" + +// "github.com/ava-labs/avalanchego/tests" +// "github.com/ava-labs/avalanchego/tests/e2e" +// "github.com/ava-labs/avalanchego/tests/fixture/testnet" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// ) + +// // This test uses the compiled bin for `hashing.sol` as +// // well as its ABI contained in `hashing_contract.go`. + +// var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { +// require := require.New(ginkgo.GinkgoT()) + +// // Need a gas limit much larger than the standard 21_000 to enable +// // the contract to induce a gas price increase +// const largeGasLimit = uint64(8_000_000) + +// // TODO(marun) What is the significance of this value? +// gasTip := big.NewInt(1000 * params.GWei) + +// ginkgo.It("should ensure that the gas price is affected by load", func() { +// ginkgo.By("creating a new private network to ensure isolation from other tests") +// privateNetwork := e2e.Env.NewPrivateNetwork() + +// ginkgo.By("allocating a pre-funded key") +// key := privateNetwork.PreFundedKeys[0] +// ethAddress := evm.GetEthAddress(key) + +// ginkgo.By("initializing a coreth client") +// node := privateNetwork.Nodes[0] +// nodeURI := tmpnet.NodeURI{ +// NodeID: node.NodeID, +// URI: node.URI, +// } +// ethClient := e2e.NewEthClient(nodeURI) + +// ginkgo.By("initializing a transaction signer") +// cChainID, err := ethClient.ChainID(e2e.DefaultContext()) +// require.NoError(err) +// signer := types.NewEIP155Signer(cChainID) +// ecdsaKey := key.ToECDSA() +// sign := func(tx *types.Transaction) *types.Transaction { +// signedTx, err := types.SignTx(tx, signer, ecdsaKey) +// require.NoError(err) +// return signedTx +// } + +// var contractAddress common.Address +// ginkgo.By("deploying an expensive contract", func() { +// // Create transaction +// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) +// require.NoError(err) +// compiledContract := common.Hex2Bytes(hashingCompiledContract) +// tx := types.NewTx(&types.LegacyTx{ +// Nonce: nonce, +// GasPrice: gasTip, +// Gas: largeGasLimit, +// Value: common.Big0, +// Data: compiledContract, +// }) + +// // Send the transaction and wait for acceptance +// signedTx := sign(tx) +// receipt := e2e.SendEthTransaction(ethClient, signedTx) + +// contractAddress = receipt.ContractAddress +// }) + +// var gasPrice *big.Int +// ginkgo.By("calling the expensive contract repeatedly until a gas price increase is detected", func() { +// // Evaluate the bytes representation of the contract +// hashingABI, err := abi.JSON(strings.NewReader(hashingABIJson)) +// require.NoError(err) +// contractData, err := hashingABI.Pack("hashIt") +// require.NoError(err) + +// var initialGasPrice *big.Int +// e2e.Eventually(func() bool { +// // Check the gas price +// var err error +// gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) +// require.NoError(err) +// if initialGasPrice == nil { +// initialGasPrice = gasPrice +// tests.Outf("{{blue}}initial gas price is %v{{/}}\n", initialGasPrice) +// } else if gasPrice.Cmp(initialGasPrice) > 0 { +// // Gas price has increased +// tests.Outf("{{blue}}gas price has increased to %v{{/}}\n", gasPrice) +// return true +// } + +// // Create the transaction +// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) +// require.NoError(err) +// tx := types.NewTx(&types.LegacyTx{ +// Nonce: nonce, +// GasPrice: gasTip, +// Gas: largeGasLimit, +// To: &contractAddress, +// Value: common.Big0, +// Data: contractData, +// }) + +// // Send the transaction and wait for acceptance +// signedTx := sign(tx) +// _ = e2e.SendEthTransaction(ethClient, signedTx) + +// // The gas price will be checked at the start of the next iteration +// return false +// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price increase before timeout") +// }) + +// ginkgo.By("waiting for the gas price to decrease...", func() { +// initialGasPrice := gasPrice +// e2e.Eventually(func() bool { +// var err error +// gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) +// require.NoError(err) +// tests.Outf("{{blue}}.{{/}}") +// return initialGasPrice.Cmp(gasPrice) > 0 +// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price decrease before timeout") +// tests.Outf("\n{{blue}}gas price has decreased to %v{{/}}\n", gasPrice) +// }) + +// ginkgo.By("sending funds at the current gas price", func() { +// // Create a recipient address +// recipientKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) +// recipientEthAddress := evm.GetEthAddress(recipientKey) + +// // Create transaction +// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) +// require.NoError(err) +// tx := types.NewTx(&types.LegacyTx{ +// Nonce: nonce, +// GasPrice: gasPrice, +// Gas: e2e.DefaultGasLimit, +// To: &recipientEthAddress, +// Value: common.Big0, +// }) + +// // Send the transaction and wait for acceptance +// signedTx := sign(tx) +// _ = e2e.SendEthTransaction(ethClient, signedTx) +// }) + +// e2e.CheckBootstrapIsPossible(privateNetwork) +// }) +// }) diff --git a/tests/e2e/c/interchain_workflow.go b/tests/e2e/c/interchain_workflow.go index e959418e878a..a111029b543a 100644 --- a/tests/e2e/c/interchain_workflow.go +++ b/tests/e2e/c/interchain_workflow.go @@ -3,163 +3,163 @@ package c -import ( - "math/big" - - ginkgo "github.com/onsi/ginkgo/v2" - - "github.com/stretchr/testify/require" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/plugin/evm" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var _ = e2e.DescribeCChain("[Interchain Workflow]", func() { - require := require.New(ginkgo.GinkgoT()) - - const txAmount = 10 * units.Avax // Arbitrary amount to send and transfer - - ginkgo.It("should ensure that funds can be transferred from the C-Chain to the X-Chain and the P-Chain", func() { - ginkgo.By("initializing a new eth client") - // Select a random node URI to use for both the eth client and - // the wallet to avoid having to verify that all nodes are at - // the same height before initializing the wallet. - nodeURI := e2e.Env.GetRandomNodeURI() - ethClient := e2e.NewEthClient(nodeURI) - - ginkgo.By("allocating a pre-funded key to send from and a recipient key to deliver to") - senderKey := e2e.Env.AllocatePreFundedKey() - senderEthAddress := evm.GetEthAddress(senderKey) - recipientKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - recipientEthAddress := evm.GetEthAddress(recipientKey) - - ginkgo.By("sending funds from one address to another on the C-Chain", func() { - // Create transaction - acceptedNonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), senderEthAddress) - require.NoError(err) - gasPrice := e2e.SuggestGasPrice(ethClient) - tx := types.NewTransaction( - acceptedNonce, - recipientEthAddress, - big.NewInt(int64(txAmount)), - e2e.DefaultGasLimit, - gasPrice, - nil, - ) - - // Sign transaction - cChainID, err := ethClient.ChainID(e2e.DefaultContext()) - require.NoError(err) - signer := types.NewEIP155Signer(cChainID) - signedTx, err := types.SignTx(tx, signer, senderKey.ToECDSA()) - require.NoError(err) - - _ = e2e.SendEthTransaction(ethClient, signedTx) - - ginkgo.By("waiting for the C-Chain recipient address to have received the sent funds") - e2e.Eventually(func() bool { - balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) - require.NoError(err) - return balance.Cmp(big.NewInt(0)) > 0 - }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see funds delivered before timeout") - }) - - // Wallet must be initialized after sending funds on the - // C-Chain with the same node URI to ensure wallet state - // matches on-chain state. - ginkgo.By("initializing a keychain and associated wallet") - keychain := secp256k1fx.NewKeychain(senderKey, recipientKey) - baseWallet := e2e.NewWallet(keychain, nodeURI) - xWallet := baseWallet.X() - cWallet := baseWallet.C() - pWallet := baseWallet.P() - - ginkgo.By("defining common configuration") - avaxAssetID := xWallet.AVAXAssetID() - // Use the same owner for import funds to X-Chain and P-Chain - recipientOwner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - recipientKey.Address(), - }, - } - // Use the same outputs for both X-Chain and P-Chain exports - exportOutputs := []*secp256k1fx.TransferOutput{ - { - Amt: txAmount, - OutputOwners: secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - keychain.Keys[0].Address(), - }, - }, - }, - } - - ginkgo.By("exporting AVAX from the C-Chain to the X-Chain", func() { - _, err := cWallet.IssueExportTx( - xWallet.BlockchainID(), - exportOutputs, - e2e.WithDefaultContext(), - e2e.WithSuggestedGasPrice(ethClient), - ) - require.NoError(err) - }) - - ginkgo.By("importing AVAX from the C-Chain to the X-Chain", func() { - _, err := xWallet.IssueImportTx( - cWallet.BlockchainID(), - &recipientOwner, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { - balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - ginkgo.By("exporting AVAX from the C-Chain to the P-Chain", func() { - _, err := cWallet.IssueExportTx( - constants.PlatformChainID, - exportOutputs, - e2e.WithDefaultContext(), - e2e.WithSuggestedGasPrice(ethClient), - ) - require.NoError(err) - }) - - ginkgo.By("importing AVAX from the C-Chain to the P-Chain", func() { - _, err = pWallet.IssueImportTx( - cWallet.BlockchainID(), - &recipientOwner, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { - balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) - }) -}) +// import ( +// "math/big" + +// ginkgo "github.com/onsi/ginkgo/v2" + +// "github.com/stretchr/testify/require" + +// "github.com/ava-labs/coreth/core/types" +// "github.com/ava-labs/coreth/plugin/evm" + +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/tests/e2e" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var _ = e2e.DescribeCChain("[Interchain Workflow]", func() { +// require := require.New(ginkgo.GinkgoT()) + +// const txAmount = 10 * units.Avax // Arbitrary amount to send and transfer + +// ginkgo.It("should ensure that funds can be transferred from the C-Chain to the X-Chain and the P-Chain", func() { +// ginkgo.By("initializing a new eth client") +// // Select a random node URI to use for both the eth client and +// // the wallet to avoid having to verify that all nodes are at +// // the same height before initializing the wallet. +// nodeURI := e2e.Env.GetRandomNodeURI() +// ethClient := e2e.NewEthClient(nodeURI) + +// ginkgo.By("allocating a pre-funded key to send from and a recipient key to deliver to") +// senderKey := e2e.Env.AllocatePreFundedKey() +// senderEthAddress := evm.GetEthAddress(senderKey) +// recipientKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) +// recipientEthAddress := evm.GetEthAddress(recipientKey) + +// ginkgo.By("sending funds from one address to another on the C-Chain", func() { +// // Create transaction +// acceptedNonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), senderEthAddress) +// require.NoError(err) +// gasPrice := e2e.SuggestGasPrice(ethClient) +// tx := types.NewTransaction( +// acceptedNonce, +// recipientEthAddress, +// big.NewInt(int64(txAmount)), +// e2e.DefaultGasLimit, +// gasPrice, +// nil, +// ) + +// // Sign transaction +// cChainID, err := ethClient.ChainID(e2e.DefaultContext()) +// require.NoError(err) +// signer := types.NewEIP155Signer(cChainID) +// signedTx, err := types.SignTx(tx, signer, senderKey.ToECDSA()) +// require.NoError(err) + +// _ = e2e.SendEthTransaction(ethClient, signedTx) + +// ginkgo.By("waiting for the C-Chain recipient address to have received the sent funds") +// e2e.Eventually(func() bool { +// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) +// require.NoError(err) +// return balance.Cmp(big.NewInt(0)) > 0 +// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see funds delivered before timeout") +// }) + +// // Wallet must be initialized after sending funds on the +// // C-Chain with the same node URI to ensure wallet state +// // matches on-chain state. +// ginkgo.By("initializing a keychain and associated wallet") +// keychain := secp256k1fx.NewKeychain(senderKey, recipientKey) +// baseWallet := e2e.NewWallet(keychain, nodeURI) +// xWallet := baseWallet.X() +// cWallet := baseWallet.C() +// pWallet := baseWallet.P() + +// ginkgo.By("defining common configuration") +// avaxAssetID := xWallet.AVAXAssetID() +// // Use the same owner for import funds to X-Chain and P-Chain +// recipientOwner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// recipientKey.Address(), +// }, +// } +// // Use the same outputs for both X-Chain and P-Chain exports +// exportOutputs := []*secp256k1fx.TransferOutput{ +// { +// Amt: txAmount, +// OutputOwners: secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// keychain.Keys[0].Address(), +// }, +// }, +// }, +// } + +// ginkgo.By("exporting AVAX from the C-Chain to the X-Chain", func() { +// _, err := cWallet.IssueExportTx( +// xWallet.BlockchainID(), +// exportOutputs, +// e2e.WithDefaultContext(), +// e2e.WithSuggestedGasPrice(ethClient), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("importing AVAX from the C-Chain to the X-Chain", func() { +// _, err := xWallet.IssueImportTx( +// cWallet.BlockchainID(), +// &recipientOwner, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { +// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// ginkgo.By("exporting AVAX from the C-Chain to the P-Chain", func() { +// _, err := cWallet.IssueExportTx( +// constants.PlatformChainID, +// exportOutputs, +// e2e.WithDefaultContext(), +// e2e.WithSuggestedGasPrice(ethClient), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("importing AVAX from the C-Chain to the P-Chain", func() { +// _, err = pWallet.IssueImportTx( +// cWallet.BlockchainID(), +// &recipientOwner, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { +// balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) +// }) +// }) diff --git a/tests/e2e/p/interchain_workflow.go b/tests/e2e/p/interchain_workflow.go index 59e90198bed0..b300ba4b2bd3 100644 --- a/tests/e2e/p/interchain_workflow.go +++ b/tests/e2e/p/interchain_workflow.go @@ -3,214 +3,214 @@ package p -import ( - "math/big" - "time" - - ginkgo "github.com/onsi/ginkgo/v2" - - "github.com/spf13/cast" - - "github.com/stretchr/testify/require" - - "github.com/ava-labs/coreth/plugin/evm" - - "github.com/ava-labs/avalanchego/api/info" - "github.com/ava-labs/avalanchego/config" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/platformvm/reward" - "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { - require := require.New(ginkgo.GinkgoT()) - - const ( - transferAmount = 10 * units.Avax - weight = 2_000 * units.Avax // Used for both validation and delegation - ) - - ginkgo.It("should ensure that funds can be transferred from the P-Chain to the X-Chain and the C-Chain", func() { - network := e2e.Env.GetNetwork() - - ginkgo.By("checking that the network has a compatible minimum stake duration", func() { - minStakeDuration := cast.ToDuration(network.DefaultFlags[config.MinStakeDurationKey]) - require.Equal(tmpnet.DefaultMinStakeDuration, minStakeDuration) - }) - - ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") - recipientKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - keychain := e2e.Env.NewKeychain(1) - keychain.Add(recipientKey) - nodeURI := e2e.Env.GetRandomNodeURI() - baseWallet := e2e.NewWallet(keychain, nodeURI) - xWallet := baseWallet.X() - cWallet := baseWallet.C() - pWallet := baseWallet.P() - - ginkgo.By("defining common configuration") - recipientEthAddress := evm.GetEthAddress(recipientKey) - avaxAssetID := xWallet.AVAXAssetID() - // Use the same owner for sending to X-Chain and importing funds to P-Chain - recipientOwner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - recipientKey.Address(), - }, - } - // Use the same outputs for both X-Chain and C-Chain exports - exportOutputs := []*avax.TransferableOutput{ - { - Asset: avax.Asset{ - ID: avaxAssetID, - }, - Out: &secp256k1fx.TransferOutput{ - Amt: transferAmount, - OutputOwners: secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - keychain.Keys[0].Address(), - }, - }, - }, - }, - } - - ginkgo.By("adding new node and waiting for it to report healthy") - node := e2e.AddEphemeralNode(network, tmpnet.FlagsMap{}) - e2e.WaitForHealthy(node) - - ginkgo.By("retrieving new node's id and pop") - infoClient := info.NewClient(node.URI) - nodeID, nodePOP, err := infoClient.GetNodeID(e2e.DefaultContext()) - require.NoError(err) - - // Adding a validator should not break interchain transfer. - endTime := time.Now().Add(30 * time.Second) - ginkgo.By("adding the new node as a validator", func() { - rewardKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - - const ( - delegationPercent = 0.10 // 10% - delegationShare = reward.PercentDenominator * delegationPercent - ) - - _, err = pWallet.IssueAddPermissionlessValidatorTx( - &txs.SubnetValidator{ - Validator: txs.Validator{ - NodeID: nodeID, - End: uint64(endTime.Unix()), - Wght: weight, - }, - Subnet: constants.PrimaryNetworkID, - }, - nodePOP, - pWallet.AVAXAssetID(), - &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{rewardKey.Address()}, - }, - &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{rewardKey.Address()}, - }, - delegationShare, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - // Adding a delegator should not break interchain transfer. - ginkgo.By("adding a delegator to the new node", func() { - rewardKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - - _, err = pWallet.IssueAddPermissionlessDelegatorTx( - &txs.SubnetValidator{ - Validator: txs.Validator{ - NodeID: nodeID, - End: uint64(endTime.Unix()), - Wght: weight, - }, - Subnet: constants.PrimaryNetworkID, - }, - pWallet.AVAXAssetID(), - &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{rewardKey.Address()}, - }, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("exporting AVAX from the P-Chain to the X-Chain", func() { - _, err := pWallet.IssueExportTx( - xWallet.BlockchainID(), - exportOutputs, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("importing AVAX from the P-Chain to the X-Chain", func() { - _, err := xWallet.IssueImportTx( - constants.PlatformChainID, - &recipientOwner, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { - balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - ginkgo.By("exporting AVAX from the P-Chain to the C-Chain", func() { - _, err := pWallet.IssueExportTx( - cWallet.BlockchainID(), - exportOutputs, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("initializing a new eth client") - ethClient := e2e.NewEthClient(nodeURI) - - ginkgo.By("importing AVAX from the P-Chain to the C-Chain", func() { - _, err := cWallet.IssueImportTx( - constants.PlatformChainID, - recipientEthAddress, - e2e.WithDefaultContext(), - e2e.WithSuggestedGasPrice(ethClient), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") - balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) - require.NoError(err) - require.Positive(balance.Cmp(big.NewInt(0))) - - ginkgo.By("stopping validator node to free up resources for a bootstrap check") - require.NoError(node.Stop(e2e.DefaultContext())) - - e2e.CheckBootstrapIsPossible(network) - }) -}) +// import ( +// "math/big" +// "time" + +// ginkgo "github.com/onsi/ginkgo/v2" + +// "github.com/spf13/cast" + +// "github.com/stretchr/testify/require" + +// "github.com/ava-labs/coreth/plugin/evm" + +// "github.com/ava-labs/avalanchego/api/info" +// "github.com/ava-labs/avalanchego/config" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/tests/e2e" +// "github.com/ava-labs/avalanchego/tests/fixture/testnet" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/platformvm/reward" +// "github.com/ava-labs/avalanchego/vms/platformvm/txs" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { +// require := require.New(ginkgo.GinkgoT()) + +// const ( +// transferAmount = 10 * units.Avax +// weight = 2_000 * units.Avax // Used for both validation and delegation +// ) + +// ginkgo.It("should ensure that funds can be transferred from the P-Chain to the X-Chain and the C-Chain", func() { +// network := e2e.Env.GetNetwork() + +// ginkgo.By("checking that the network has a compatible minimum stake duration", func() { +// minStakeDuration := cast.ToDuration(network.DefaultFlags[config.MinStakeDurationKey]) +// require.Equal(tmpnet.DefaultMinStakeDuration, minStakeDuration) +// }) + +// ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") +// recipientKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) +// keychain := e2e.Env.NewKeychain(1) +// keychain.Add(recipientKey) +// nodeURI := e2e.Env.GetRandomNodeURI() +// baseWallet := e2e.Env.NewWallet(keychain, nodeURI) +// xWallet := baseWallet.X() +// cWallet := baseWallet.C() +// pWallet := baseWallet.P() + +// ginkgo.By("defining common configuration") +// recipientEthAddress := evm.GetEthAddress(recipientKey) +// avaxAssetID := xWallet.AVAXAssetID() +// // Use the same owner for sending to X-Chain and importing funds to P-Chain +// recipientOwner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// recipientKey.Address(), +// }, +// } +// // Use the same outputs for both X-Chain and C-Chain exports +// exportOutputs := []*avax.TransferableOutput{ +// { +// Asset: avax.Asset{ +// ID: avaxAssetID, +// }, +// Out: &secp256k1fx.TransferOutput{ +// Amt: transferAmount, +// OutputOwners: secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// keychain.Keys[0].Address(), +// }, +// }, +// }, +// }, +// } + +// ginkgo.By("adding new node and waiting for it to report healthy") +// node := e2e.AddEphemeralNode(network, testnet.FlagsMap{}) +// e2e.WaitForHealthy(node) + +// ginkgo.By("retrieving new node's id and pop") +// infoClient := info.NewClient(node.URI) +// nodeID, nodePOP, err := infoClient.GetNodeID(e2e.DefaultContext()) +// require.NoError(err) + +// // Adding a validator should not break interchain transfer. +// endTime := time.Now().Add(30 * time.Second) +// ginkgo.By("adding the new node as a validator", func() { +// rewardKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) + +// const ( +// delegationPercent = 0.10 // 10% +// delegationShare = reward.PercentDenominator * delegationPercent +// ) + +// _, err = pWallet.IssueAddPermissionlessValidatorTx( +// &txs.SubnetValidator{ +// Validator: txs.Validator{ +// NodeID: nodeID, +// End: uint64(endTime.Unix()), +// Wght: weight, +// }, +// Subnet: constants.PrimaryNetworkID, +// }, +// nodePOP, +// pWallet.AVAXAssetID(), +// &secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{rewardKey.Address()}, +// }, +// &secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{rewardKey.Address()}, +// }, +// delegationShare, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// // Adding a delegator should not break interchain transfer. +// ginkgo.By("adding a delegator to the new node", func() { +// rewardKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) + +// _, err = pWallet.IssueAddPermissionlessDelegatorTx( +// &txs.SubnetValidator{ +// Validator: txs.Validator{ +// NodeID: nodeID, +// End: uint64(endTime.Unix()), +// Wght: weight, +// }, +// Subnet: constants.PrimaryNetworkID, +// }, +// pWallet.AVAXAssetID(), +// &secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{rewardKey.Address()}, +// }, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("exporting AVAX from the P-Chain to the X-Chain", func() { +// _, err := pWallet.IssueExportTx( +// xWallet.BlockchainID(), +// exportOutputs, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("importing AVAX from the P-Chain to the X-Chain", func() { +// _, err := xWallet.IssueImportTx( +// constants.PlatformChainID, +// &recipientOwner, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { +// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// ginkgo.By("exporting AVAX from the P-Chain to the C-Chain", func() { +// _, err := pWallet.IssueExportTx( +// cWallet.BlockchainID(), +// exportOutputs, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("initializing a new eth client") +// ethClient := e2e.NewEthClient(nodeURI) + +// ginkgo.By("importing AVAX from the P-Chain to the C-Chain", func() { +// _, err := cWallet.IssueImportTx( +// constants.PlatformChainID, +// recipientEthAddress, +// e2e.WithDefaultContext(), +// e2e.WithSuggestedGasPrice(ethClient), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") +// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) +// require.NoError(err) +// require.Positive(balance.Cmp(big.NewInt(0))) + +// ginkgo.By("stopping validator node to free up resources for a bootstrap check") +// require.NoError(node.Stop(e2e.DefaultContext())) + +// e2e.CheckBootstrapIsPossible(network) +// }) +// }) diff --git a/tests/e2e/x/interchain_workflow.go b/tests/e2e/x/interchain_workflow.go index f0c2951feb84..d738e55a7f7a 100644 --- a/tests/e2e/x/interchain_workflow.go +++ b/tests/e2e/x/interchain_workflow.go @@ -3,151 +3,151 @@ package x -import ( - "math/big" - - ginkgo "github.com/onsi/ginkgo/v2" - - "github.com/stretchr/testify/require" - - "github.com/ava-labs/coreth/plugin/evm" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var _ = e2e.DescribeXChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { - require := require.New(ginkgo.GinkgoT()) - - const transferAmount = 10 * units.Avax - - ginkgo.It("should ensure that funds can be transferred from the X-Chain to the C-Chain and the P-Chain", func() { - nodeURI := e2e.Env.GetRandomNodeURI() - - ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") - recipientKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - keychain := e2e.Env.NewKeychain(1) - keychain.Add(recipientKey) - baseWallet := e2e.NewWallet(keychain, nodeURI) - xWallet := baseWallet.X() - cWallet := baseWallet.C() - pWallet := baseWallet.P() - - ginkgo.By("defining common configuration") - recipientEthAddress := evm.GetEthAddress(recipientKey) - avaxAssetID := xWallet.AVAXAssetID() - // Use the same owner for sending to X-Chain and importing funds to P-Chain - recipientOwner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - recipientKey.Address(), - }, - } - // Use the same outputs for both C-Chain and P-Chain exports - exportOutputs := []*avax.TransferableOutput{ - { - Asset: avax.Asset{ - ID: avaxAssetID, - }, - Out: &secp256k1fx.TransferOutput{ - Amt: transferAmount, - OutputOwners: secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - keychain.Keys[0].Address(), - }, - }, - }, - }, - } - - ginkgo.By("sending funds from one address to another on the X-Chain", func() { - _, err = xWallet.IssueBaseTx( - []*avax.TransferableOutput{{ - Asset: avax.Asset{ - ID: avaxAssetID, - }, - Out: &secp256k1fx.TransferOutput{ - Amt: transferAmount, - OutputOwners: recipientOwner, - }, - }}, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the X-Chain recipient address has received the sent funds", func() { - balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - ginkgo.By("exporting AVAX from the X-Chain to the C-Chain", func() { - _, err := xWallet.IssueExportTx( - cWallet.BlockchainID(), - exportOutputs, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("initializing a new eth client") - ethClient := e2e.NewEthClient(nodeURI) - - ginkgo.By("importing AVAX from the X-Chain to the C-Chain", func() { - _, err := cWallet.IssueImportTx( - xWallet.BlockchainID(), - recipientEthAddress, - e2e.WithDefaultContext(), - e2e.WithSuggestedGasPrice(ethClient), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") - e2e.Eventually(func() bool { - balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) - require.NoError(err) - return balance.Cmp(big.NewInt(0)) > 0 - }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see recipient address funded before timeout") - - ginkgo.By("exporting AVAX from the X-Chain to the P-Chain", func() { - _, err := xWallet.IssueExportTx( - constants.PlatformChainID, - exportOutputs, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("importing AVAX from the X-Chain to the P-Chain", func() { - _, err := pWallet.IssueImportTx( - xWallet.BlockchainID(), - &recipientOwner, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { - balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) - }) -}) +// import ( +// "math/big" + +// ginkgo "github.com/onsi/ginkgo/v2" + +// "github.com/stretchr/testify/require" + +// "github.com/ava-labs/coreth/plugin/evm" + +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/tests/e2e" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var _ = e2e.DescribeXChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { +// require := require.New(ginkgo.GinkgoT()) + +// const transferAmount = 10 * units.Avax + +// ginkgo.It("should ensure that funds can be transferred from the X-Chain to the C-Chain and the P-Chain", func() { +// nodeURI := e2e.Env.GetRandomNodeURI() + +// ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") +// recipientKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) +// keychain := e2e.Env.NewKeychain(1) +// keychain.Add(recipientKey) +// baseWallet := e2e.Env.NewWallet(keychain, nodeURI) +// xWallet := baseWallet.X() +// cWallet := baseWallet.C() +// pWallet := baseWallet.P() + +// ginkgo.By("defining common configuration") +// recipientEthAddress := evm.GetEthAddress(recipientKey) +// avaxAssetID := xWallet.AVAXAssetID() +// // Use the same owner for sending to X-Chain and importing funds to P-Chain +// recipientOwner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// recipientKey.Address(), +// }, +// } +// // Use the same outputs for both C-Chain and P-Chain exports +// exportOutputs := []*avax.TransferableOutput{ +// { +// Asset: avax.Asset{ +// ID: avaxAssetID, +// }, +// Out: &secp256k1fx.TransferOutput{ +// Amt: transferAmount, +// OutputOwners: secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// keychain.Keys[0].Address(), +// }, +// }, +// }, +// }, +// } + +// ginkgo.By("sending funds from one address to another on the X-Chain", func() { +// _, err = xWallet.IssueBaseTx( +// []*avax.TransferableOutput{{ +// Asset: avax.Asset{ +// ID: avaxAssetID, +// }, +// Out: &secp256k1fx.TransferOutput{ +// Amt: transferAmount, +// OutputOwners: recipientOwner, +// }, +// }}, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the X-Chain recipient address has received the sent funds", func() { +// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// ginkgo.By("exporting AVAX from the X-Chain to the C-Chain", func() { +// _, err := xWallet.IssueExportTx( +// cWallet.BlockchainID(), +// exportOutputs, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("initializing a new eth client") +// ethClient := e2e.NewEthClient(nodeURI) + +// ginkgo.By("importing AVAX from the X-Chain to the C-Chain", func() { +// _, err := cWallet.IssueImportTx( +// xWallet.BlockchainID(), +// recipientEthAddress, +// e2e.WithDefaultContext(), +// e2e.WithSuggestedGasPrice(ethClient), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") +// e2e.Eventually(func() bool { +// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) +// require.NoError(err) +// return balance.Cmp(big.NewInt(0)) > 0 +// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see recipient address funded before timeout") + +// ginkgo.By("exporting AVAX from the X-Chain to the P-Chain", func() { +// _, err := xWallet.IssueExportTx( +// constants.PlatformChainID, +// exportOutputs, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("importing AVAX from the X-Chain to the P-Chain", func() { +// _, err := pWallet.IssueImportTx( +// xWallet.BlockchainID(), +// &recipientOwner, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { +// balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) +// }) +// }) diff --git a/tests/fixture/e2e/helpers.go b/tests/fixture/e2e/helpers.go index ddebfbc8b81c..224263818156 100644 --- a/tests/fixture/e2e/helpers.go +++ b/tests/fixture/e2e/helpers.go @@ -5,20 +5,23 @@ package e2e import ( "context" - "errors" - "fmt" - "math/big" + + // "errors" + // "fmt" + // "math/big" + "os" - "strings" + + // "strings" "time" ginkgo "github.com/onsi/ginkgo/v2" "github.com/stretchr/testify/require" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/ethclient" - "github.com/ava-labs/coreth/interfaces" + // "github.com/ava-labs/coreth/core/types" + // "github.com/ava-labs/coreth/ethclient" + // "github.com/ava-labs/coreth/interfaces" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/tests" @@ -60,7 +63,7 @@ func NewWallet(keychain *secp256k1fx.Keychain, nodeURI tmpnet.NodeURI) primary.W baseWallet, err := primary.MakeWallet(DefaultContext(), &primary.WalletConfig{ URI: nodeURI.URI, AVAXKeychain: keychain, - EthKeychain: keychain, + // EthKeychain: keychain, }) require.NoError(ginkgo.GinkgoT(), err) return primary.NewWalletWithOptions( @@ -73,15 +76,15 @@ func NewWallet(keychain *secp256k1fx.Keychain, nodeURI tmpnet.NodeURI) primary.W ) } -// Create a new eth client targeting the specified node URI. -func NewEthClient(nodeURI tmpnet.NodeURI) ethclient.Client { - tests.Outf("{{blue}} initializing a new eth client for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) - nodeAddress := strings.Split(nodeURI.URI, "//")[1] - uri := fmt.Sprintf("ws://%s/ext/bc/C/ws", nodeAddress) - client, err := ethclient.Dial(uri) - require.NoError(ginkgo.GinkgoT(), err) - return client -} +// // Create a new eth client targeting the specified node URI. +// func NewEthClient(nodeURI testnet.NodeURI) ethclient.Client { +// tests.Outf("{{blue}} initializing a new eth client for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) +// nodeAddress := strings.Split(nodeURI.URI, "//")[1] +// uri := fmt.Sprintf("ws://%s/ext/bc/C/ws", nodeAddress) +// client, err := ethclient.Dial(uri) +// require.NoError(ginkgo.GinkgoT(), err) +// return client +// } // Helper simplifying use of a timed context by canceling the context on ginkgo teardown. func ContextWithTimeout(duration time.Duration) context.Context { @@ -144,49 +147,49 @@ func WaitForHealthy(node *tmpnet.Node) { require.NoError(ginkgo.GinkgoT(), tmpnet.WaitForHealthy(ctx, node)) } -// Sends an eth transaction, waits for the transaction receipt to be issued -// and checks that the receipt indicates success. -func SendEthTransaction(ethClient ethclient.Client, signedTx *types.Transaction) *types.Receipt { - require := require.New(ginkgo.GinkgoT()) - - txID := signedTx.Hash() - tests.Outf(" sending eth transaction with ID: %s\n", txID) - - require.NoError(ethClient.SendTransaction(DefaultContext(), signedTx)) - - // Wait for the receipt - var receipt *types.Receipt - Eventually(func() bool { - var err error - receipt, err = ethClient.TransactionReceipt(DefaultContext(), txID) - if errors.Is(err, interfaces.NotFound) { - return false // Transaction is still pending - } - require.NoError(err) - return true - }, DefaultTimeout, DefaultPollingInterval, "failed to see transaction acceptance before timeout") - - require.Equal(receipt.Status, types.ReceiptStatusSuccessful) - return receipt -} - -// Determines the suggested gas price for the configured client that will -// maximize the chances of transaction acceptance. -func SuggestGasPrice(ethClient ethclient.Client) *big.Int { - gasPrice, err := ethClient.SuggestGasPrice(DefaultContext()) - require.NoError(ginkgo.GinkgoT(), err) - // Double the suggested gas price to maximize the chances of - // acceptance. Maybe this can be revisited pending resolution of - // https://github.com/ava-labs/coreth/issues/314. - gasPrice.Add(gasPrice, gasPrice) - return gasPrice -} - -// Helper simplifying use via an option of a gas price appropriate for testing. -func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { - baseFee := SuggestGasPrice(ethClient) - return common.WithBaseFee(baseFee) -} +// // Sends an eth transaction, waits for the transaction receipt to be issued +// // and checks that the receipt indicates success. +// func SendEthTransaction(ethClient ethclient.Client, signedTx *types.Transaction) *types.Receipt { +// require := require.New(ginkgo.GinkgoT()) + +// txID := signedTx.Hash() +// tests.Outf(" sending eth transaction with ID: %s\n", txID) + +// require.NoError(ethClient.SendTransaction(DefaultContext(), signedTx)) + +// // Wait for the receipt +// var receipt *types.Receipt +// Eventually(func() bool { +// var err error +// receipt, err = ethClient.TransactionReceipt(DefaultContext(), txID) +// if errors.Is(err, interfaces.NotFound) { +// return false // Transaction is still pending +// } +// require.NoError(err) +// return true +// }, DefaultTimeout, DefaultPollingInterval, "failed to see transaction acceptance before timeout") + +// require.Equal(receipt.Status, types.ReceiptStatusSuccessful) +// return receipt +// } + +// // Determines the suggested gas price for the configured client that will +// // maximize the chances of transaction acceptance. +// func SuggestGasPrice(ethClient ethclient.Client) *big.Int { +// gasPrice, err := ethClient.SuggestGasPrice(DefaultContext()) +// require.NoError(ginkgo.GinkgoT(), err) +// // Double the suggested gas price to maximize the chances of +// // acceptance. Maybe this can be revisited pending resolution of +// // https://github.com/ava-labs/coreth/issues/314. +// gasPrice.Add(gasPrice, gasPrice) +// return gasPrice +// } + +// // Helper simplifying use via an option of a gas price appropriate for testing. +// func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { +// baseFee := SuggestGasPrice(ethClient) +// return common.WithBaseFee(baseFee) +// } // Verify that a new node can bootstrap into the network. func CheckBootstrapIsPossible(network *tmpnet.Network) { diff --git a/tests/fixture/tmpnet/genesis.go b/tests/fixture/tmpnet/genesis.go index 5ee605702482..db0462b3c0ce 100644 --- a/tests/fixture/tmpnet/genesis.go +++ b/tests/fixture/tmpnet/genesis.go @@ -4,16 +4,10 @@ package tmpnet import ( - "encoding/json" "errors" "fmt" - "math/big" "time" - "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/plugin/evm" - "github.com/ava-labs/avalanchego/genesis" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/constants" @@ -27,12 +21,12 @@ const ( defaultGasLimit = uint64(100_000_000) // Gas limit is arbitrary // Arbitrarily large amount of AVAX to fund keys on the X-Chain for testing - defaultFundedKeyXChainAmount = 30 * units.MegaAvax + // defaultFundedKeyXChainAmount = 30 * units.MegaAvax ) var ( // Arbitrarily large amount of AVAX (10^12) to fund keys on the C-Chain for testing - defaultFundedKeyCChainAmount = new(big.Int).Exp(big.NewInt(10), big.NewInt(30), nil) + // defaultFundedKeyCChainAmount = new(big.Int).Exp(big.NewInt(10), big.NewInt(30), nil) errNoKeysForGenesis = errors.New("no keys to fund for genesis") errInvalidNetworkIDForGenesis = errors.New("network ID can't be mainnet, testnet or local network ID for genesis") @@ -113,13 +107,13 @@ func NewTestGenesis( // Ensure pre-funded keys have arbitrary large balances on both chains to support testing xChainBalances := make(XChainBalanceMap, len(keysToFund)) - cChainBalances := make(core.GenesisAlloc, len(keysToFund)) - for _, key := range keysToFund { - xChainBalances[key.Address()] = defaultFundedKeyXChainAmount - cChainBalances[evm.GetEthAddress(key)] = core.GenesisAccount{ - Balance: defaultFundedKeyCChainAmount, - } - } + // cChainBalances := make(core.GenesisAlloc, len(keysToFund)) + // for _, key := range keysToFund { + // xChainBalances[key.Address()] = defaultFundedKeyXChainAmount + // cChainBalances[evm.GetEthAddress(key)] = core.GenesisAccount{ + // Balance: defaultFundedKeyCChainAmount, + // } + // } // Set X-Chain balances for xChainAddress, balance := range xChainBalances { @@ -147,19 +141,19 @@ func NewTestGenesis( } // Define C-Chain genesis - cChainGenesis := &core.Genesis{ - Config: ¶ms.ChainConfig{ - ChainID: big.NewInt(43112), // Arbitrary chain ID is arbitrary - }, - Difficulty: big.NewInt(0), // Difficulty is a mandatory field - GasLimit: defaultGasLimit, - Alloc: cChainBalances, - } - cChainGenesisBytes, err := json.Marshal(cChainGenesis) - if err != nil { - return nil, fmt.Errorf("failed to marshal C-Chain genesis: %w", err) - } - config.CChainGenesis = string(cChainGenesisBytes) + // cChainGenesis := &core.Genesis{ + // Config: ¶ms.ChainConfig{ + // ChainID: big.NewInt(43112), // Arbitrary chain ID is arbitrary + // }, + // Difficulty: big.NewInt(0), // Difficulty is a mandatory field + // GasLimit: defaultGasLimit, + // Alloc: cChainBalances, + // } + // cChainGenesisBytes, err := json.Marshal(cChainGenesis) + // if err != nil { + // return nil, fmt.Errorf("failed to marshal C-Chain genesis: %w", err) + // } + // config.CChainGenesis = string(cChainGenesisBytes) return config, nil } diff --git a/vms/example/xsvm/cmd/chain/create/cmd.go b/vms/example/xsvm/cmd/chain/create/cmd.go index 1f00491a4ce6..043b4298dcdf 100644 --- a/vms/example/xsvm/cmd/chain/create/cmd.go +++ b/vms/example/xsvm/cmd/chain/create/cmd.go @@ -42,9 +42,9 @@ func createFunc(c *cobra.Command, args []string) error { // that [uri] is hosting. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: config.URI, - AVAXKeychain: kc, - EthKeychain: kc, + URI: config.URI, + AVAXKeychain: kc, + // EthKeychain: kc, PChainTxsToFetch: set.Of(config.SubnetID), }) if err != nil { diff --git a/wallet/chain/c/backend.go b/wallet/chain/c/backend.go index 0a735116b646..b88c8c643bc3 100644 --- a/wallet/chain/c/backend.go +++ b/wallet/chain/c/backend.go @@ -3,153 +3,153 @@ package c -import ( - "errors" - "fmt" - "math/big" - "sync" - - stdcontext "context" - - "github.com/ava-labs/coreth/plugin/evm" - - ethcommon "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/avalanchego/database" - "github.com/ava-labs/avalanchego/utils/math" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var ( - _ Backend = (*backend)(nil) - - errUnknownTxType = errors.New("unknown tx type") -) - -// Backend defines the full interface required to support a C-chain wallet. -type Backend interface { - common.ChainUTXOs - BuilderBackend - SignerBackend - - AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error -} - -type backend struct { - Context - common.ChainUTXOs - - accountsLock sync.RWMutex - accounts map[ethcommon.Address]*Account -} - -type Account struct { - Balance *big.Int - Nonce uint64 -} - -func NewBackend( - ctx Context, - utxos common.ChainUTXOs, - accounts map[ethcommon.Address]*Account, -) Backend { - return &backend{ - Context: ctx, - ChainUTXOs: utxos, - accounts: accounts, - } -} - -func (b *backend) AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error { - switch tx := tx.UnsignedAtomicTx.(type) { - case *evm.UnsignedImportTx: - for _, input := range tx.ImportedInputs { - utxoID := input.InputID() - if err := b.RemoveUTXO(ctx, tx.SourceChain, utxoID); err != nil { - return err - } - } - - b.accountsLock.Lock() - defer b.accountsLock.Unlock() - - for _, output := range tx.Outs { - account, ok := b.accounts[output.Address] - if !ok { - continue - } - - balance := new(big.Int).SetUint64(output.Amount) - balance.Mul(balance, avaxConversionRate) - account.Balance.Add(account.Balance, balance) - } - case *evm.UnsignedExportTx: - txID := tx.ID() - for i, out := range tx.ExportedOutputs { - err := b.AddUTXO( - ctx, - tx.DestinationChain, - &avax.UTXO{ - UTXOID: avax.UTXOID{ - TxID: txID, - OutputIndex: uint32(i), - }, - Asset: avax.Asset{ID: out.AssetID()}, - Out: out.Out, - }, - ) - if err != nil { - return err - } - } - - b.accountsLock.Lock() - defer b.accountsLock.Unlock() - - for _, input := range tx.Ins { - account, ok := b.accounts[input.Address] - if !ok { - continue - } - - balance := new(big.Int).SetUint64(input.Amount) - balance.Mul(balance, avaxConversionRate) - if account.Balance.Cmp(balance) == -1 { - return errInsufficientFunds - } - account.Balance.Sub(account.Balance, balance) - - newNonce, err := math.Add64(input.Nonce, 1) - if err != nil { - return err - } - account.Nonce = newNonce - } - default: - return fmt.Errorf("%w: %T", errUnknownTxType, tx) - } - return nil -} - -func (b *backend) Balance(_ stdcontext.Context, addr ethcommon.Address) (*big.Int, error) { - b.accountsLock.RLock() - defer b.accountsLock.RUnlock() - - account, exists := b.accounts[addr] - if !exists { - return nil, database.ErrNotFound - } - return account.Balance, nil -} - -func (b *backend) Nonce(_ stdcontext.Context, addr ethcommon.Address) (uint64, error) { - b.accountsLock.RLock() - defer b.accountsLock.RUnlock() - - account, exists := b.accounts[addr] - if !exists { - return 0, database.ErrNotFound - } - return account.Nonce, nil -} +// import ( +// "errors" +// "fmt" +// "math/big" +// "sync" + +// stdcontext "context" + +// "github.com/ava-labs/coreth/plugin/evm" + +// ethcommon "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/avalanchego/database" +// "github.com/ava-labs/avalanchego/utils/math" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var ( +// _ Backend = (*backend)(nil) + +// errUnknownTxType = errors.New("unknown tx type") +// ) + +// // Backend defines the full interface required to support a C-chain wallet. +// type Backend interface { +// common.ChainUTXOs +// BuilderBackend +// SignerBackend + +// AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error +// } + +// type backend struct { +// Context +// common.ChainUTXOs + +// accountsLock sync.RWMutex +// accounts map[ethcommon.Address]*Account +// } + +// type Account struct { +// Balance *big.Int +// Nonce uint64 +// } + +// func NewBackend( +// ctx Context, +// utxos common.ChainUTXOs, +// accounts map[ethcommon.Address]*Account, +// ) Backend { +// return &backend{ +// Context: ctx, +// ChainUTXOs: utxos, +// accounts: accounts, +// } +// } + +// func (b *backend) AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error { +// switch tx := tx.UnsignedAtomicTx.(type) { +// case *evm.UnsignedImportTx: +// for _, input := range tx.ImportedInputs { +// utxoID := input.InputID() +// if err := b.RemoveUTXO(ctx, tx.SourceChain, utxoID); err != nil { +// return err +// } +// } + +// b.accountsLock.Lock() +// defer b.accountsLock.Unlock() + +// for _, output := range tx.Outs { +// account, ok := b.accounts[output.Address] +// if !ok { +// continue +// } + +// balance := new(big.Int).SetUint64(output.Amount) +// balance.Mul(balance, avaxConversionRate) +// account.Balance.Add(account.Balance, balance) +// } +// case *evm.UnsignedExportTx: +// txID := tx.ID() +// for i, out := range tx.ExportedOutputs { +// err := b.AddUTXO( +// ctx, +// tx.DestinationChain, +// &avax.UTXO{ +// UTXOID: avax.UTXOID{ +// TxID: txID, +// OutputIndex: uint32(i), +// }, +// Asset: avax.Asset{ID: out.AssetID()}, +// Out: out.Out, +// }, +// ) +// if err != nil { +// return err +// } +// } + +// b.accountsLock.Lock() +// defer b.accountsLock.Unlock() + +// for _, input := range tx.Ins { +// account, ok := b.accounts[input.Address] +// if !ok { +// continue +// } + +// balance := new(big.Int).SetUint64(input.Amount) +// balance.Mul(balance, avaxConversionRate) +// if account.Balance.Cmp(balance) == -1 { +// return errInsufficientFunds +// } +// account.Balance.Sub(account.Balance, balance) + +// newNonce, err := math.Add64(input.Nonce, 1) +// if err != nil { +// return err +// } +// account.Nonce = newNonce +// } +// default: +// return fmt.Errorf("%w: %T", errUnknownTxType, tx) +// } +// return nil +// } + +// func (b *backend) Balance(_ stdcontext.Context, addr ethcommon.Address) (*big.Int, error) { +// b.accountsLock.RLock() +// defer b.accountsLock.RUnlock() + +// account, exists := b.accounts[addr] +// if !exists { +// return nil, database.ErrNotFound +// } +// return account.Balance, nil +// } + +// func (b *backend) Nonce(_ stdcontext.Context, addr ethcommon.Address) (uint64, error) { +// b.accountsLock.RLock() +// defer b.accountsLock.RUnlock() + +// account, exists := b.accounts[addr] +// if !exists { +// return 0, database.ErrNotFound +// } +// return account.Nonce, nil +// } diff --git a/wallet/chain/c/builder.go b/wallet/chain/c/builder.go index 81fcf3aa896a..0e95a91e4fe4 100644 --- a/wallet/chain/c/builder.go +++ b/wallet/chain/c/builder.go @@ -3,409 +3,409 @@ package c -import ( - "errors" - "math/big" - - stdcontext "context" - - "github.com/ava-labs/coreth/plugin/evm" - - ethcommon "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils" - "github.com/ava-labs/avalanchego/utils/math" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -const avaxConversionRateInt = 1_000_000_000 - -var ( - _ Builder = (*builder)(nil) - - errInsufficientFunds = errors.New("insufficient funds") - - // avaxConversionRate is the conversion rate between the smallest - // denomination on the X-Chain and P-chain, 1 nAVAX, and the smallest - // denomination on the C-Chain 1 wei. Where 1 nAVAX = 1 gWei. - // - // This is only required for AVAX because the denomination of 1 AVAX is 9 - // decimal places on the X and P chains, but is 18 decimal places within the - // EVM. - avaxConversionRate = big.NewInt(avaxConversionRateInt) -) - -// Builder provides a convenient interface for building unsigned C-chain -// transactions. -type Builder interface { - // GetBalance calculates the amount of AVAX that this builder has control - // over. - GetBalance( - options ...common.Option, - ) (*big.Int, error) - - // GetImportableBalance calculates the amount of AVAX that this builder - // could import from the provided chain. - // - // - [chainID] specifies the chain the funds are from. - GetImportableBalance( - chainID ids.ID, - options ...common.Option, - ) (uint64, error) - - // NewImportTx creates an import transaction that attempts to consume all - // the available UTXOs and import the funds to [to]. - // - // - [chainID] specifies the chain to be importing funds from. - // - [to] specifies where to send the imported funds to. - // - [baseFee] specifies the fee price willing to be paid by this tx. - NewImportTx( - chainID ids.ID, - to ethcommon.Address, - baseFee *big.Int, - options ...common.Option, - ) (*evm.UnsignedImportTx, error) - - // NewExportTx creates an export transaction that attempts to send all the - // provided [outputs] to the requested [chainID]. - // - // - [chainID] specifies the chain to be exporting the funds to. - // - [outputs] specifies the outputs to send to the [chainID]. - // - [baseFee] specifies the fee price willing to be paid by this tx. - NewExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - baseFee *big.Int, - options ...common.Option, - ) (*evm.UnsignedExportTx, error) -} - -// BuilderBackend specifies the required information needed to build unsigned -// C-chain transactions. -type BuilderBackend interface { - Context - - UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) - Balance(ctx stdcontext.Context, addr ethcommon.Address) (*big.Int, error) - Nonce(ctx stdcontext.Context, addr ethcommon.Address) (uint64, error) -} - -type builder struct { - avaxAddrs set.Set[ids.ShortID] - ethAddrs set.Set[ethcommon.Address] - backend BuilderBackend -} - -// NewBuilder returns a new transaction builder. -// -// - [avaxAddrs] is the set of addresses in the AVAX format that the builder -// assumes can be used when signing the transactions in the future. -// - [ethAddrs] is the set of addresses in the Eth format that the builder -// assumes can be used when signing the transactions in the future. -// - [backend] provides the required access to the chain's context and state -// to build out the transactions. -func NewBuilder( - avaxAddrs set.Set[ids.ShortID], - ethAddrs set.Set[ethcommon.Address], - backend BuilderBackend, -) Builder { - return &builder{ - avaxAddrs: avaxAddrs, - ethAddrs: ethAddrs, - backend: backend, - } -} - -func (b *builder) GetBalance( - options ...common.Option, -) (*big.Int, error) { - var ( - ops = common.NewOptions(options) - ctx = ops.Context() - addrs = ops.EthAddresses(b.ethAddrs) - totalBalance = new(big.Int) - ) - for addr := range addrs { - balance, err := b.backend.Balance(ctx, addr) - if err != nil { - return nil, err - } - totalBalance.Add(totalBalance, balance) - } - - return totalBalance, nil -} - -func (b *builder) GetImportableBalance( - chainID ids.ID, - options ...common.Option, -) (uint64, error) { - ops := common.NewOptions(options) - utxos, err := b.backend.UTXOs(ops.Context(), chainID) - if err != nil { - return 0, err - } - - var ( - addrs = ops.Addresses(b.avaxAddrs) - minIssuanceTime = ops.MinIssuanceTime() - avaxAssetID = b.backend.AVAXAssetID() - balance uint64 - ) - for _, utxo := range utxos { - amount, _, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) - if !ok { - continue - } - - newBalance, err := math.Add64(balance, amount) - if err != nil { - return 0, err - } - balance = newBalance - } - - return balance, nil -} - -func (b *builder) NewImportTx( - chainID ids.ID, - to ethcommon.Address, - baseFee *big.Int, - options ...common.Option, -) (*evm.UnsignedImportTx, error) { - ops := common.NewOptions(options) - utxos, err := b.backend.UTXOs(ops.Context(), chainID) - if err != nil { - return nil, err - } - - var ( - addrs = ops.Addresses(b.avaxAddrs) - minIssuanceTime = ops.MinIssuanceTime() - avaxAssetID = b.backend.AVAXAssetID() - - importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) - importedAmount uint64 - ) - for _, utxo := range utxos { - amount, inputSigIndices, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) - if !ok { - continue - } - - importedInputs = append(importedInputs, &avax.TransferableInput{ - UTXOID: utxo.UTXOID, - Asset: utxo.Asset, - FxID: secp256k1fx.ID, - In: &secp256k1fx.TransferInput{ - Amt: amount, - Input: secp256k1fx.Input{ - SigIndices: inputSigIndices, - }, - }, - }) - - newImportedAmount, err := math.Add64(importedAmount, amount) - if err != nil { - return nil, err - } - importedAmount = newImportedAmount - } - - utils.Sort(importedInputs) - tx := &evm.UnsignedImportTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: b.backend.BlockchainID(), - SourceChain: chainID, - ImportedInputs: importedInputs, - } - - // We must initialize the bytes of the tx to calculate the initial cost - wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} - if err := wrappedTx.Sign(evm.Codec, nil); err != nil { - return nil, err - } - - gasUsedWithoutOutput, err := tx.GasUsed(true /*=IsApricotPhase5*/) - if err != nil { - return nil, err - } - gasUsedWithOutput := gasUsedWithoutOutput + evm.EVMOutputGas - - txFee, err := evm.CalculateDynamicFee(gasUsedWithOutput, baseFee) - if err != nil { - return nil, err - } - - if importedAmount <= txFee { - return nil, errInsufficientFunds - } - - tx.Outs = []evm.EVMOutput{{ - Address: to, - Amount: importedAmount - txFee, - AssetID: avaxAssetID, - }} - return tx, nil -} - -func (b *builder) NewExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - baseFee *big.Int, - options ...common.Option, -) (*evm.UnsignedExportTx, error) { - var ( - avaxAssetID = b.backend.AVAXAssetID() - exportedOutputs = make([]*avax.TransferableOutput, len(outputs)) - exportedAmount uint64 - ) - for i, output := range outputs { - exportedOutputs[i] = &avax.TransferableOutput{ - Asset: avax.Asset{ID: avaxAssetID}, - FxID: secp256k1fx.ID, - Out: output, - } - - newExportedAmount, err := math.Add64(exportedAmount, output.Amt) - if err != nil { - return nil, err - } - exportedAmount = newExportedAmount - } - - avax.SortTransferableOutputs(exportedOutputs, evm.Codec) - tx := &evm.UnsignedExportTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: b.backend.BlockchainID(), - DestinationChain: chainID, - ExportedOutputs: exportedOutputs, - } - - // We must initialize the bytes of the tx to calculate the initial cost - wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} - if err := wrappedTx.Sign(evm.Codec, nil); err != nil { - return nil, err - } - - cost, err := tx.GasUsed(true /*=IsApricotPhase5*/) - if err != nil { - return nil, err - } - - initialFee, err := evm.CalculateDynamicFee(cost, baseFee) - if err != nil { - return nil, err - } - - amountToConsume, err := math.Add64(exportedAmount, initialFee) - if err != nil { - return nil, err - } - - var ( - ops = common.NewOptions(options) - ctx = ops.Context() - addrs = ops.EthAddresses(b.ethAddrs) - inputs = make([]evm.EVMInput, 0, addrs.Len()) - ) - for addr := range addrs { - if amountToConsume == 0 { - break - } - - prevFee, err := evm.CalculateDynamicFee(cost, baseFee) - if err != nil { - return nil, err - } - - newCost := cost + evm.EVMInputGas - newFee, err := evm.CalculateDynamicFee(newCost, baseFee) - if err != nil { - return nil, err - } - - additionalFee := newFee - prevFee - - balance, err := b.backend.Balance(ctx, addr) - if err != nil { - return nil, err - } - - // Since the asset is AVAX, we divide by the avaxConversionRate to - // convert back to the correct denomination of AVAX that can be - // exported. - avaxBalance := new(big.Int).Div(balance, avaxConversionRate).Uint64() - - // If the balance for [addr] is insufficient to cover the additional - // cost of adding an input to the transaction, skip adding the input - // altogether. - if avaxBalance <= additionalFee { - continue - } - - // Update the cost for the next iteration - cost = newCost - - amountToConsume, err = math.Add64(amountToConsume, additionalFee) - if err != nil { - return nil, err - } - - nonce, err := b.backend.Nonce(ctx, addr) - if err != nil { - return nil, err - } - - inputAmount := math.Min(amountToConsume, avaxBalance) - inputs = append(inputs, evm.EVMInput{ - Address: addr, - Amount: inputAmount, - AssetID: avaxAssetID, - Nonce: nonce, - }) - amountToConsume -= inputAmount - } - - if amountToConsume > 0 { - return nil, errInsufficientFunds - } - - utils.Sort(inputs) - tx.Ins = inputs - - snowCtx, err := newSnowContext(b.backend) - if err != nil { - return nil, err - } - for _, out := range tx.ExportedOutputs { - out.InitCtx(snowCtx) - } - return tx, nil -} - -func getSpendableAmount( - utxo *avax.UTXO, - addrs set.Set[ids.ShortID], - minIssuanceTime uint64, - avaxAssetID ids.ID, -) (uint64, []uint32, bool) { - if utxo.Asset.ID != avaxAssetID { - // Only AVAX can be imported - return 0, nil, false - } - - out, ok := utxo.Out.(*secp256k1fx.TransferOutput) - if !ok { - // Can't import an unknown transfer output type - return 0, nil, false - } - - inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) - return out.Amt, inputSigIndices, ok -} +// import ( +// "errors" +// "math/big" + +// stdcontext "context" + +// "github.com/ava-labs/coreth/plugin/evm" + +// ethcommon "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/utils" +// "github.com/ava-labs/avalanchego/utils/math" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// const avaxConversionRateInt = 1_000_000_000 + +// var ( +// _ Builder = (*builder)(nil) + +// errInsufficientFunds = errors.New("insufficient funds") + +// // avaxConversionRate is the conversion rate between the smallest +// // denomination on the X-Chain and P-chain, 1 nAVAX, and the smallest +// // denomination on the C-Chain 1 wei. Where 1 nAVAX = 1 gWei. +// // +// // This is only required for AVAX because the denomination of 1 AVAX is 9 +// // decimal places on the X and P chains, but is 18 decimal places within the +// // EVM. +// avaxConversionRate = big.NewInt(avaxConversionRateInt) +// ) + +// // Builder provides a convenient interface for building unsigned C-chain +// // transactions. +// type Builder interface { +// // GetBalance calculates the amount of AVAX that this builder has control +// // over. +// GetBalance( +// options ...common.Option, +// ) (*big.Int, error) + +// // GetImportableBalance calculates the amount of AVAX that this builder +// // could import from the provided chain. +// // +// // - [chainID] specifies the chain the funds are from. +// GetImportableBalance( +// chainID ids.ID, +// options ...common.Option, +// ) (uint64, error) + +// // NewImportTx creates an import transaction that attempts to consume all +// // the available UTXOs and import the funds to [to]. +// // +// // - [chainID] specifies the chain to be importing funds from. +// // - [to] specifies where to send the imported funds to. +// // - [baseFee] specifies the fee price willing to be paid by this tx. +// NewImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedImportTx, error) + +// // NewExportTx creates an export transaction that attempts to send all the +// // provided [outputs] to the requested [chainID]. +// // +// // - [chainID] specifies the chain to be exporting the funds to. +// // - [outputs] specifies the outputs to send to the [chainID]. +// // - [baseFee] specifies the fee price willing to be paid by this tx. +// NewExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedExportTx, error) +// } + +// // BuilderBackend specifies the required information needed to build unsigned +// // C-chain transactions. +// type BuilderBackend interface { +// Context + +// UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) +// Balance(ctx stdcontext.Context, addr ethcommon.Address) (*big.Int, error) +// Nonce(ctx stdcontext.Context, addr ethcommon.Address) (uint64, error) +// } + +// type builder struct { +// avaxAddrs set.Set[ids.ShortID] +// ethAddrs set.Set[ethcommon.Address] +// backend BuilderBackend +// } + +// // NewBuilder returns a new transaction builder. +// // +// // - [avaxAddrs] is the set of addresses in the AVAX format that the builder +// // assumes can be used when signing the transactions in the future. +// // - [ethAddrs] is the set of addresses in the Eth format that the builder +// // assumes can be used when signing the transactions in the future. +// // - [backend] provides the required access to the chain's context and state +// // to build out the transactions. +// func NewBuilder( +// avaxAddrs set.Set[ids.ShortID], +// ethAddrs set.Set[ethcommon.Address], +// backend BuilderBackend, +// ) Builder { +// return &builder{ +// avaxAddrs: avaxAddrs, +// ethAddrs: ethAddrs, +// backend: backend, +// } +// } + +// func (b *builder) GetBalance( +// options ...common.Option, +// ) (*big.Int, error) { +// var ( +// ops = common.NewOptions(options) +// ctx = ops.Context() +// addrs = ops.EthAddresses(b.ethAddrs) +// totalBalance = new(big.Int) +// ) +// for addr := range addrs { +// balance, err := b.backend.Balance(ctx, addr) +// if err != nil { +// return nil, err +// } +// totalBalance.Add(totalBalance, balance) +// } + +// return totalBalance, nil +// } + +// func (b *builder) GetImportableBalance( +// chainID ids.ID, +// options ...common.Option, +// ) (uint64, error) { +// ops := common.NewOptions(options) +// utxos, err := b.backend.UTXOs(ops.Context(), chainID) +// if err != nil { +// return 0, err +// } + +// var ( +// addrs = ops.Addresses(b.avaxAddrs) +// minIssuanceTime = ops.MinIssuanceTime() +// avaxAssetID = b.backend.AVAXAssetID() +// balance uint64 +// ) +// for _, utxo := range utxos { +// amount, _, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) +// if !ok { +// continue +// } + +// newBalance, err := math.Add64(balance, amount) +// if err != nil { +// return 0, err +// } +// balance = newBalance +// } + +// return balance, nil +// } + +// func (b *builder) NewImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedImportTx, error) { +// ops := common.NewOptions(options) +// utxos, err := b.backend.UTXOs(ops.Context(), chainID) +// if err != nil { +// return nil, err +// } + +// var ( +// addrs = ops.Addresses(b.avaxAddrs) +// minIssuanceTime = ops.MinIssuanceTime() +// avaxAssetID = b.backend.AVAXAssetID() + +// importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) +// importedAmount uint64 +// ) +// for _, utxo := range utxos { +// amount, inputSigIndices, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) +// if !ok { +// continue +// } + +// importedInputs = append(importedInputs, &avax.TransferableInput{ +// UTXOID: utxo.UTXOID, +// Asset: utxo.Asset, +// FxID: secp256k1fx.ID, +// In: &secp256k1fx.TransferInput{ +// Amt: amount, +// Input: secp256k1fx.Input{ +// SigIndices: inputSigIndices, +// }, +// }, +// }) + +// newImportedAmount, err := math.Add64(importedAmount, amount) +// if err != nil { +// return nil, err +// } +// importedAmount = newImportedAmount +// } + +// utils.Sort(importedInputs) +// tx := &evm.UnsignedImportTx{ +// NetworkID: b.backend.NetworkID(), +// BlockchainID: b.backend.BlockchainID(), +// SourceChain: chainID, +// ImportedInputs: importedInputs, +// } + +// // We must initialize the bytes of the tx to calculate the initial cost +// wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} +// if err := wrappedTx.Sign(evm.Codec, nil); err != nil { +// return nil, err +// } + +// gasUsedWithoutOutput, err := tx.GasUsed(true /*=IsApricotPhase5*/) +// if err != nil { +// return nil, err +// } +// gasUsedWithOutput := gasUsedWithoutOutput + evm.EVMOutputGas + +// txFee, err := evm.CalculateDynamicFee(gasUsedWithOutput, baseFee) +// if err != nil { +// return nil, err +// } + +// if importedAmount <= txFee { +// return nil, errInsufficientFunds +// } + +// tx.Outs = []evm.EVMOutput{{ +// Address: to, +// Amount: importedAmount - txFee, +// AssetID: avaxAssetID, +// }} +// return tx, nil +// } + +// func (b *builder) NewExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedExportTx, error) { +// var ( +// avaxAssetID = b.backend.AVAXAssetID() +// exportedOutputs = make([]*avax.TransferableOutput, len(outputs)) +// exportedAmount uint64 +// ) +// for i, output := range outputs { +// exportedOutputs[i] = &avax.TransferableOutput{ +// Asset: avax.Asset{ID: avaxAssetID}, +// FxID: secp256k1fx.ID, +// Out: output, +// } + +// newExportedAmount, err := math.Add64(exportedAmount, output.Amt) +// if err != nil { +// return nil, err +// } +// exportedAmount = newExportedAmount +// } + +// avax.SortTransferableOutputs(exportedOutputs, evm.Codec) +// tx := &evm.UnsignedExportTx{ +// NetworkID: b.backend.NetworkID(), +// BlockchainID: b.backend.BlockchainID(), +// DestinationChain: chainID, +// ExportedOutputs: exportedOutputs, +// } + +// // We must initialize the bytes of the tx to calculate the initial cost +// wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} +// if err := wrappedTx.Sign(evm.Codec, nil); err != nil { +// return nil, err +// } + +// cost, err := tx.GasUsed(true /*=IsApricotPhase5*/) +// if err != nil { +// return nil, err +// } + +// initialFee, err := evm.CalculateDynamicFee(cost, baseFee) +// if err != nil { +// return nil, err +// } + +// amountToConsume, err := math.Add64(exportedAmount, initialFee) +// if err != nil { +// return nil, err +// } + +// var ( +// ops = common.NewOptions(options) +// ctx = ops.Context() +// addrs = ops.EthAddresses(b.ethAddrs) +// inputs = make([]evm.EVMInput, 0, addrs.Len()) +// ) +// for addr := range addrs { +// if amountToConsume == 0 { +// break +// } + +// prevFee, err := evm.CalculateDynamicFee(cost, baseFee) +// if err != nil { +// return nil, err +// } + +// newCost := cost + evm.EVMInputGas +// newFee, err := evm.CalculateDynamicFee(newCost, baseFee) +// if err != nil { +// return nil, err +// } + +// additionalFee := newFee - prevFee + +// balance, err := b.backend.Balance(ctx, addr) +// if err != nil { +// return nil, err +// } + +// // Since the asset is AVAX, we divide by the avaxConversionRate to +// // convert back to the correct denomination of AVAX that can be +// // exported. +// avaxBalance := new(big.Int).Div(balance, avaxConversionRate).Uint64() + +// // If the balance for [addr] is insufficient to cover the additional +// // cost of adding an input to the transaction, skip adding the input +// // altogether. +// if avaxBalance <= additionalFee { +// continue +// } + +// // Update the cost for the next iteration +// cost = newCost + +// amountToConsume, err = math.Add64(amountToConsume, additionalFee) +// if err != nil { +// return nil, err +// } + +// nonce, err := b.backend.Nonce(ctx, addr) +// if err != nil { +// return nil, err +// } + +// inputAmount := math.Min(amountToConsume, avaxBalance) +// inputs = append(inputs, evm.EVMInput{ +// Address: addr, +// Amount: inputAmount, +// AssetID: avaxAssetID, +// Nonce: nonce, +// }) +// amountToConsume -= inputAmount +// } + +// if amountToConsume > 0 { +// return nil, errInsufficientFunds +// } + +// utils.Sort(inputs) +// tx.Ins = inputs + +// snowCtx, err := newSnowContext(b.backend) +// if err != nil { +// return nil, err +// } +// for _, out := range tx.ExportedOutputs { +// out.InitCtx(snowCtx) +// } +// return tx, nil +// } + +// func getSpendableAmount( +// utxo *avax.UTXO, +// addrs set.Set[ids.ShortID], +// minIssuanceTime uint64, +// avaxAssetID ids.ID, +// ) (uint64, []uint32, bool) { +// if utxo.Asset.ID != avaxAssetID { +// // Only AVAX can be imported +// return 0, nil, false +// } + +// out, ok := utxo.Out.(*secp256k1fx.TransferOutput) +// if !ok { +// // Can't import an unknown transfer output type +// return 0, nil, false +// } + +// inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) +// return out.Amt, inputSigIndices, ok +// } diff --git a/wallet/chain/c/builder_with_options.go b/wallet/chain/c/builder_with_options.go index 8416dddf9928..9b7ab8399484 100644 --- a/wallet/chain/c/builder_with_options.go +++ b/wallet/chain/c/builder_with_options.go @@ -3,81 +3,81 @@ package c -import ( - "math/big" +// import ( +// "math/big" - "github.com/ava-labs/coreth/plugin/evm" +// "github.com/ava-labs/coreth/plugin/evm" - ethcommon "github.com/ethereum/go-ethereum/common" +// ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) -var _ Builder = (*builderWithOptions)(nil) +// var _ Builder = (*builderWithOptions)(nil) -type builderWithOptions struct { - Builder - options []common.Option -} +// type builderWithOptions struct { +// Builder +// options []common.Option +// } -// NewBuilderWithOptions returns a new transaction builder that will use the -// given options by default. -// -// - [builder] is the builder that will be called to perform the underlying -// operations. -// - [options] will be provided to the builder in addition to the options -// provided in the method calls. -func NewBuilderWithOptions(builder Builder, options ...common.Option) Builder { - return &builderWithOptions{ - Builder: builder, - options: options, - } -} +// // NewBuilderWithOptions returns a new transaction builder that will use the +// // given options by default. +// // +// // - [builder] is the builder that will be called to perform the underlying +// // operations. +// // - [options] will be provided to the builder in addition to the options +// // provided in the method calls. +// func NewBuilderWithOptions(builder Builder, options ...common.Option) Builder { +// return &builderWithOptions{ +// Builder: builder, +// options: options, +// } +// } -func (b *builderWithOptions) GetBalance( - options ...common.Option, -) (*big.Int, error) { - return b.Builder.GetBalance( - common.UnionOptions(b.options, options)..., - ) -} +// func (b *builderWithOptions) GetBalance( +// options ...common.Option, +// ) (*big.Int, error) { +// return b.Builder.GetBalance( +// common.UnionOptions(b.options, options)..., +// ) +// } -func (b *builderWithOptions) GetImportableBalance( - chainID ids.ID, - options ...common.Option, -) (uint64, error) { - return b.Builder.GetImportableBalance( - chainID, - common.UnionOptions(b.options, options)..., - ) -} +// func (b *builderWithOptions) GetImportableBalance( +// chainID ids.ID, +// options ...common.Option, +// ) (uint64, error) { +// return b.Builder.GetImportableBalance( +// chainID, +// common.UnionOptions(b.options, options)..., +// ) +// } -func (b *builderWithOptions) NewImportTx( - chainID ids.ID, - to ethcommon.Address, - baseFee *big.Int, - options ...common.Option, -) (*evm.UnsignedImportTx, error) { - return b.Builder.NewImportTx( - chainID, - to, - baseFee, - common.UnionOptions(b.options, options)..., - ) -} +// func (b *builderWithOptions) NewImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedImportTx, error) { +// return b.Builder.NewImportTx( +// chainID, +// to, +// baseFee, +// common.UnionOptions(b.options, options)..., +// ) +// } -func (b *builderWithOptions) NewExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - baseFee *big.Int, - options ...common.Option, -) (*evm.UnsignedExportTx, error) { - return b.Builder.NewExportTx( - chainID, - outputs, - baseFee, - common.UnionOptions(b.options, options)..., - ) -} +// func (b *builderWithOptions) NewExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedExportTx, error) { +// return b.Builder.NewExportTx( +// chainID, +// outputs, +// baseFee, +// common.UnionOptions(b.options, options)..., +// ) +// } diff --git a/wallet/chain/c/context.go b/wallet/chain/c/context.go index b9cd41cb5667..c56a114a276e 100644 --- a/wallet/chain/c/context.go +++ b/wallet/chain/c/context.go @@ -3,100 +3,100 @@ package c -import ( - stdcontext "context" - - "github.com/ava-labs/avalanchego/api/info" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/logging" - "github.com/ava-labs/avalanchego/vms/avm" -) - -const Alias = "C" - -var _ Context = (*context)(nil) - -type Context interface { - NetworkID() uint32 - BlockchainID() ids.ID - AVAXAssetID() ids.ID -} - -type context struct { - networkID uint32 - blockchainID ids.ID - avaxAssetID ids.ID -} - -func NewContextFromURI(ctx stdcontext.Context, uri string) (Context, error) { - infoClient := info.NewClient(uri) - xChainClient := avm.NewClient(uri, "X") - return NewContextFromClients(ctx, infoClient, xChainClient) -} - -func NewContextFromClients( - ctx stdcontext.Context, - infoClient info.Client, - xChainClient avm.Client, -) (Context, error) { - networkID, err := infoClient.GetNetworkID(ctx) - if err != nil { - return nil, err - } - - chainID, err := infoClient.GetBlockchainID(ctx, Alias) - if err != nil { - return nil, err - } - - asset, err := xChainClient.GetAssetDescription(ctx, "AVAX") - if err != nil { - return nil, err - } - - return NewContext( - networkID, - chainID, - asset.AssetID, - ), nil -} - -func NewContext( - networkID uint32, - blockchainID ids.ID, - avaxAssetID ids.ID, -) Context { - return &context{ - networkID: networkID, - blockchainID: blockchainID, - avaxAssetID: avaxAssetID, - } -} - -func (c *context) NetworkID() uint32 { - return c.networkID -} - -func (c *context) BlockchainID() ids.ID { - return c.blockchainID -} - -func (c *context) AVAXAssetID() ids.ID { - return c.avaxAssetID -} - -func newSnowContext(c Context) (*snow.Context, error) { - chainID := c.BlockchainID() - lookup := ids.NewAliaser() - return &snow.Context{ - NetworkID: c.NetworkID(), - SubnetID: constants.PrimaryNetworkID, - ChainID: chainID, - CChainID: chainID, - AVAXAssetID: c.AVAXAssetID(), - Log: logging.NoLog{}, - BCLookup: lookup, - }, lookup.Alias(chainID, Alias) -} +// import ( +// stdcontext "context" + +// "github.com/ava-labs/avalanchego/api/info" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/snow" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/logging" +// "github.com/ava-labs/avalanchego/vms/avm" +// ) + +// const Alias = "C" + +// var _ Context = (*context)(nil) + +// type Context interface { +// NetworkID() uint32 +// BlockchainID() ids.ID +// AVAXAssetID() ids.ID +// } + +// type context struct { +// networkID uint32 +// blockchainID ids.ID +// avaxAssetID ids.ID +// } + +// func NewContextFromURI(ctx stdcontext.Context, uri string) (Context, error) { +// infoClient := info.NewClient(uri) +// xChainClient := avm.NewClient(uri, "X") +// return NewContextFromClients(ctx, infoClient, xChainClient) +// } + +// func NewContextFromClients( +// ctx stdcontext.Context, +// infoClient info.Client, +// xChainClient avm.Client, +// ) (Context, error) { +// networkID, err := infoClient.GetNetworkID(ctx) +// if err != nil { +// return nil, err +// } + +// chainID, err := infoClient.GetBlockchainID(ctx, Alias) +// if err != nil { +// return nil, err +// } + +// asset, err := xChainClient.GetAssetDescription(ctx, "AVAX") +// if err != nil { +// return nil, err +// } + +// return NewContext( +// networkID, +// chainID, +// asset.AssetID, +// ), nil +// } + +// func NewContext( +// networkID uint32, +// blockchainID ids.ID, +// avaxAssetID ids.ID, +// ) Context { +// return &context{ +// networkID: networkID, +// blockchainID: blockchainID, +// avaxAssetID: avaxAssetID, +// } +// } + +// func (c *context) NetworkID() uint32 { +// return c.networkID +// } + +// func (c *context) BlockchainID() ids.ID { +// return c.blockchainID +// } + +// func (c *context) AVAXAssetID() ids.ID { +// return c.avaxAssetID +// } + +// func newSnowContext(c Context) (*snow.Context, error) { +// chainID := c.BlockchainID() +// lookup := ids.NewAliaser() +// return &snow.Context{ +// NetworkID: c.NetworkID(), +// SubnetID: constants.PrimaryNetworkID, +// ChainID: chainID, +// CChainID: chainID, +// AVAXAssetID: c.AVAXAssetID(), +// Log: logging.NoLog{}, +// BCLookup: lookup, +// }, lookup.Alias(chainID, Alias) +// } diff --git a/wallet/chain/c/signer.go b/wallet/chain/c/signer.go index 4fd85ed3b532..4bedc378234b 100644 --- a/wallet/chain/c/signer.go +++ b/wallet/chain/c/signer.go @@ -3,221 +3,221 @@ package c -import ( - "errors" - "fmt" - - stdcontext "context" - - "github.com/ava-labs/coreth/plugin/evm" - - ethcommon "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/avalanchego/database" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/crypto/keychain" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/hashing" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/components/verify" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" -) - -const version = 0 - -var ( - _ Signer = (*txSigner)(nil) - - errUnknownInputType = errors.New("unknown input type") - errUnknownCredentialType = errors.New("unknown credential type") - errUnknownOutputType = errors.New("unknown output type") - errInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") - - emptySig [secp256k1.SignatureLen]byte -) - -type Signer interface { - SignUnsignedAtomic(ctx stdcontext.Context, tx evm.UnsignedAtomicTx) (*evm.Tx, error) - SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error -} - -type EthKeychain interface { - // The returned Signer can provide a signature for [addr] - GetEth(addr ethcommon.Address) (keychain.Signer, bool) - // Returns the set of addresses for which the accessor keeps an associated - // signer - EthAddresses() set.Set[ethcommon.Address] -} - -type SignerBackend interface { - GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) -} - -type txSigner struct { - avaxKC keychain.Keychain - ethKC EthKeychain - backend SignerBackend -} - -func NewSigner(avaxKC keychain.Keychain, ethKC EthKeychain, backend SignerBackend) Signer { - return &txSigner{ - avaxKC: avaxKC, - ethKC: ethKC, - backend: backend, - } -} - -func (s *txSigner) SignUnsignedAtomic(ctx stdcontext.Context, utx evm.UnsignedAtomicTx) (*evm.Tx, error) { - tx := &evm.Tx{UnsignedAtomicTx: utx} - return tx, s.SignAtomic(ctx, tx) -} - -func (s *txSigner) SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error { - switch utx := tx.UnsignedAtomicTx.(type) { - case *evm.UnsignedImportTx: - signers, err := s.getImportSigners(ctx, utx.SourceChain, utx.ImportedInputs) - if err != nil { - return err - } - return sign(tx, true, signers) - case *evm.UnsignedExportTx: - signers := s.getExportSigners(utx.Ins) - return sign(tx, true, signers) - default: - return fmt.Errorf("%w: %T", errUnknownTxType, tx) - } -} - -func (s *txSigner) getImportSigners(ctx stdcontext.Context, sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { - txSigners := make([][]keychain.Signer, len(ins)) - for credIndex, transferInput := range ins { - input, ok := transferInput.In.(*secp256k1fx.TransferInput) - if !ok { - return nil, errUnknownInputType - } - - inputSigners := make([]keychain.Signer, len(input.SigIndices)) - txSigners[credIndex] = inputSigners - - utxoID := transferInput.InputID() - utxo, err := s.backend.GetUTXO(ctx, sourceChainID, utxoID) - if err == database.ErrNotFound { - // If we don't have access to the UTXO, then we can't sign this - // transaction. However, we can attempt to partially sign it. - continue - } - if err != nil { - return nil, err - } - - out, ok := utxo.Out.(*secp256k1fx.TransferOutput) - if !ok { - return nil, errUnknownOutputType - } - - for sigIndex, addrIndex := range input.SigIndices { - if addrIndex >= uint32(len(out.Addrs)) { - return nil, errInvalidUTXOSigIndex - } - - addr := out.Addrs[addrIndex] - key, ok := s.avaxKC.Get(addr) - if !ok { - // If we don't have access to the key, then we can't sign this - // transaction. However, we can attempt to partially sign it. - continue - } - inputSigners[sigIndex] = key - } - } - return txSigners, nil -} - -func (s *txSigner) getExportSigners(ins []evm.EVMInput) [][]keychain.Signer { - txSigners := make([][]keychain.Signer, len(ins)) - for credIndex, input := range ins { - inputSigners := make([]keychain.Signer, 1) - txSigners[credIndex] = inputSigners - - key, ok := s.ethKC.GetEth(input.Address) - if !ok { - // If we don't have access to the key, then we can't sign this - // transaction. However, we can attempt to partially sign it. - continue - } - inputSigners[0] = key - } - return txSigners -} - -// TODO: remove [signHash] after the ledger supports signing all transactions. -func sign(tx *evm.Tx, signHash bool, txSigners [][]keychain.Signer) error { - unsignedBytes, err := evm.Codec.Marshal(version, &tx.UnsignedAtomicTx) - if err != nil { - return fmt.Errorf("couldn't marshal unsigned tx: %w", err) - } - unsignedHash := hashing.ComputeHash256(unsignedBytes) - - if expectedLen := len(txSigners); expectedLen != len(tx.Creds) { - tx.Creds = make([]verify.Verifiable, expectedLen) - } - - sigCache := make(map[ids.ShortID][secp256k1.SignatureLen]byte) - for credIndex, inputSigners := range txSigners { - credIntf := tx.Creds[credIndex] - if credIntf == nil { - credIntf = &secp256k1fx.Credential{} - tx.Creds[credIndex] = credIntf - } - - cred, ok := credIntf.(*secp256k1fx.Credential) - if !ok { - return errUnknownCredentialType - } - if expectedLen := len(inputSigners); expectedLen != len(cred.Sigs) { - cred.Sigs = make([][secp256k1.SignatureLen]byte, expectedLen) - } - - for sigIndex, signer := range inputSigners { - if signer == nil { - // If we don't have access to the key, then we can't sign this - // transaction. However, we can attempt to partially sign it. - continue - } - addr := signer.Address() - if sig := cred.Sigs[sigIndex]; sig != emptySig { - // If this signature has already been populated, we can just - // copy the needed signature for the future. - sigCache[addr] = sig - continue - } - - if sig, exists := sigCache[addr]; exists { - // If this key has already produced a signature, we can just - // copy the previous signature. - cred.Sigs[sigIndex] = sig - continue - } - - var sig []byte - if signHash { - sig, err = signer.SignHash(unsignedHash) - } else { - sig, err = signer.Sign(unsignedBytes) - } - if err != nil { - return fmt.Errorf("problem signing tx: %w", err) - } - copy(cred.Sigs[sigIndex][:], sig) - sigCache[addr] = cred.Sigs[sigIndex] - } - } - - signedBytes, err := evm.Codec.Marshal(version, tx) - if err != nil { - return fmt.Errorf("couldn't marshal tx: %w", err) - } - tx.Initialize(unsignedBytes, signedBytes) - return nil -} +// import ( +// "errors" +// "fmt" + +// stdcontext "context" + +// "github.com/ava-labs/coreth/plugin/evm" + +// ethcommon "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/avalanchego/database" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/utils/crypto/keychain" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// "github.com/ava-labs/avalanchego/utils/hashing" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/components/verify" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// ) + +// const version = 0 + +// var ( +// _ Signer = (*txSigner)(nil) + +// errUnknownInputType = errors.New("unknown input type") +// errUnknownCredentialType = errors.New("unknown credential type") +// errUnknownOutputType = errors.New("unknown output type") +// errInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") + +// emptySig [secp256k1.SignatureLen]byte +// ) + +// type Signer interface { +// SignUnsignedAtomic(ctx stdcontext.Context, tx evm.UnsignedAtomicTx) (*evm.Tx, error) +// SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error +// } + +// type EthKeychain interface { +// // The returned Signer can provide a signature for [addr] +// GetEth(addr ethcommon.Address) (keychain.Signer, bool) +// // Returns the set of addresses for which the accessor keeps an associated +// // signer +// EthAddresses() set.Set[ethcommon.Address] +// } + +// type SignerBackend interface { +// GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) +// } + +// type txSigner struct { +// avaxKC keychain.Keychain +// ethKC EthKeychain +// backend SignerBackend +// } + +// func NewSigner(avaxKC keychain.Keychain, ethKC EthKeychain, backend SignerBackend) Signer { +// return &txSigner{ +// avaxKC: avaxKC, +// ethKC: ethKC, +// backend: backend, +// } +// } + +// func (s *txSigner) SignUnsignedAtomic(ctx stdcontext.Context, utx evm.UnsignedAtomicTx) (*evm.Tx, error) { +// tx := &evm.Tx{UnsignedAtomicTx: utx} +// return tx, s.SignAtomic(ctx, tx) +// } + +// func (s *txSigner) SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error { +// switch utx := tx.UnsignedAtomicTx.(type) { +// case *evm.UnsignedImportTx: +// signers, err := s.getImportSigners(ctx, utx.SourceChain, utx.ImportedInputs) +// if err != nil { +// return err +// } +// return sign(tx, true, signers) +// case *evm.UnsignedExportTx: +// signers := s.getExportSigners(utx.Ins) +// return sign(tx, true, signers) +// default: +// return fmt.Errorf("%w: %T", errUnknownTxType, tx) +// } +// } + +// func (s *txSigner) getImportSigners(ctx stdcontext.Context, sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { +// txSigners := make([][]keychain.Signer, len(ins)) +// for credIndex, transferInput := range ins { +// input, ok := transferInput.In.(*secp256k1fx.TransferInput) +// if !ok { +// return nil, errUnknownInputType +// } + +// inputSigners := make([]keychain.Signer, len(input.SigIndices)) +// txSigners[credIndex] = inputSigners + +// utxoID := transferInput.InputID() +// utxo, err := s.backend.GetUTXO(ctx, sourceChainID, utxoID) +// if err == database.ErrNotFound { +// // If we don't have access to the UTXO, then we can't sign this +// // transaction. However, we can attempt to partially sign it. +// continue +// } +// if err != nil { +// return nil, err +// } + +// out, ok := utxo.Out.(*secp256k1fx.TransferOutput) +// if !ok { +// return nil, errUnknownOutputType +// } + +// for sigIndex, addrIndex := range input.SigIndices { +// if addrIndex >= uint32(len(out.Addrs)) { +// return nil, errInvalidUTXOSigIndex +// } + +// addr := out.Addrs[addrIndex] +// key, ok := s.avaxKC.Get(addr) +// if !ok { +// // If we don't have access to the key, then we can't sign this +// // transaction. However, we can attempt to partially sign it. +// continue +// } +// inputSigners[sigIndex] = key +// } +// } +// return txSigners, nil +// } + +// func (s *txSigner) getExportSigners(ins []evm.EVMInput) [][]keychain.Signer { +// txSigners := make([][]keychain.Signer, len(ins)) +// for credIndex, input := range ins { +// inputSigners := make([]keychain.Signer, 1) +// txSigners[credIndex] = inputSigners + +// key, ok := s.ethKC.GetEth(input.Address) +// if !ok { +// // If we don't have access to the key, then we can't sign this +// // transaction. However, we can attempt to partially sign it. +// continue +// } +// inputSigners[0] = key +// } +// return txSigners +// } + +// // TODO: remove [signHash] after the ledger supports signing all transactions. +// func sign(tx *evm.Tx, signHash bool, txSigners [][]keychain.Signer) error { +// unsignedBytes, err := evm.Codec.Marshal(version, &tx.UnsignedAtomicTx) +// if err != nil { +// return fmt.Errorf("couldn't marshal unsigned tx: %w", err) +// } +// unsignedHash := hashing.ComputeHash256(unsignedBytes) + +// if expectedLen := len(txSigners); expectedLen != len(tx.Creds) { +// tx.Creds = make([]verify.Verifiable, expectedLen) +// } + +// sigCache := make(map[ids.ShortID][secp256k1.SignatureLen]byte) +// for credIndex, inputSigners := range txSigners { +// credIntf := tx.Creds[credIndex] +// if credIntf == nil { +// credIntf = &secp256k1fx.Credential{} +// tx.Creds[credIndex] = credIntf +// } + +// cred, ok := credIntf.(*secp256k1fx.Credential) +// if !ok { +// return errUnknownCredentialType +// } +// if expectedLen := len(inputSigners); expectedLen != len(cred.Sigs) { +// cred.Sigs = make([][secp256k1.SignatureLen]byte, expectedLen) +// } + +// for sigIndex, signer := range inputSigners { +// if signer == nil { +// // If we don't have access to the key, then we can't sign this +// // transaction. However, we can attempt to partially sign it. +// continue +// } +// addr := signer.Address() +// if sig := cred.Sigs[sigIndex]; sig != emptySig { +// // If this signature has already been populated, we can just +// // copy the needed signature for the future. +// sigCache[addr] = sig +// continue +// } + +// if sig, exists := sigCache[addr]; exists { +// // If this key has already produced a signature, we can just +// // copy the previous signature. +// cred.Sigs[sigIndex] = sig +// continue +// } + +// var sig []byte +// if signHash { +// sig, err = signer.SignHash(unsignedHash) +// } else { +// sig, err = signer.Sign(unsignedBytes) +// } +// if err != nil { +// return fmt.Errorf("problem signing tx: %w", err) +// } +// copy(cred.Sigs[sigIndex][:], sig) +// sigCache[addr] = cred.Sigs[sigIndex] +// } +// } + +// signedBytes, err := evm.Codec.Marshal(version, tx) +// if err != nil { +// return fmt.Errorf("couldn't marshal tx: %w", err) +// } +// tx.Initialize(unsignedBytes, signedBytes) +// return nil +// } diff --git a/wallet/chain/c/wallet.go b/wallet/chain/c/wallet.go index fb1a83d53dad..ebee50a9a958 100644 --- a/wallet/chain/c/wallet.go +++ b/wallet/chain/c/wallet.go @@ -3,204 +3,204 @@ package c -import ( - "errors" - "math/big" - "time" - - "github.com/ava-labs/coreth/ethclient" - "github.com/ava-labs/coreth/plugin/evm" - - ethcommon "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var ( - _ Wallet = (*wallet)(nil) - - errNotCommitted = errors.New("not committed") -) - -type Wallet interface { - Context - - // Builder returns the builder that will be used to create the transactions. - Builder() Builder - - // Signer returns the signer that will be used to sign the transactions. - Signer() Signer - - // IssueImportTx creates, signs, and issues an import transaction that - // attempts to consume all the available UTXOs and import the funds to [to]. - // - // - [chainID] specifies the chain to be importing funds from. - // - [to] specifies where to send the imported funds to. - IssueImportTx( - chainID ids.ID, - to ethcommon.Address, - options ...common.Option, - ) (*evm.Tx, error) - - // IssueExportTx creates, signs, and issues an export transaction that - // attempts to send all the provided [outputs] to the requested [chainID]. - // - // - [chainID] specifies the chain to be exporting the funds to. - // - [outputs] specifies the outputs to send to the [chainID]. - IssueExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - options ...common.Option, - ) (*evm.Tx, error) - - // IssueUnsignedTx signs and issues the unsigned tx. - IssueUnsignedAtomicTx( - utx evm.UnsignedAtomicTx, - options ...common.Option, - ) (*evm.Tx, error) - - // IssueAtomicTx issues the signed tx. - IssueAtomicTx( - tx *evm.Tx, - options ...common.Option, - ) error -} - -func NewWallet( - builder Builder, - signer Signer, - avaxClient evm.Client, - ethClient ethclient.Client, - backend Backend, -) Wallet { - return &wallet{ - Backend: backend, - builder: builder, - signer: signer, - avaxClient: avaxClient, - ethClient: ethClient, - } -} - -type wallet struct { - Backend - builder Builder - signer Signer - avaxClient evm.Client - ethClient ethclient.Client -} - -func (w *wallet) Builder() Builder { - return w.builder -} - -func (w *wallet) Signer() Signer { - return w.signer -} - -func (w *wallet) IssueImportTx( - chainID ids.ID, - to ethcommon.Address, - options ...common.Option, -) (*evm.Tx, error) { - baseFee, err := w.baseFee(options) - if err != nil { - return nil, err - } - - utx, err := w.builder.NewImportTx(chainID, to, baseFee, options...) - if err != nil { - return nil, err - } - return w.IssueUnsignedAtomicTx(utx, options...) -} - -func (w *wallet) IssueExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - options ...common.Option, -) (*evm.Tx, error) { - baseFee, err := w.baseFee(options) - if err != nil { - return nil, err - } - - utx, err := w.builder.NewExportTx(chainID, outputs, baseFee, options...) - if err != nil { - return nil, err - } - return w.IssueUnsignedAtomicTx(utx, options...) -} - -func (w *wallet) IssueUnsignedAtomicTx( - utx evm.UnsignedAtomicTx, - options ...common.Option, -) (*evm.Tx, error) { - ops := common.NewOptions(options) - ctx := ops.Context() - tx, err := w.signer.SignUnsignedAtomic(ctx, utx) - if err != nil { - return nil, err - } - - return tx, w.IssueAtomicTx(tx, options...) -} - -func (w *wallet) IssueAtomicTx( - tx *evm.Tx, - options ...common.Option, -) error { - ops := common.NewOptions(options) - ctx := ops.Context() - txID, err := w.avaxClient.IssueTx(ctx, tx.SignedBytes()) - if err != nil { - return err - } - - if f := ops.PostIssuanceFunc(); f != nil { - f(txID) - } - - if ops.AssumeDecided() { - return w.Backend.AcceptAtomicTx(ctx, tx) - } - - pollFrequency := ops.PollFrequency() - ticker := time.NewTicker(pollFrequency) - defer ticker.Stop() - - for { - status, err := w.avaxClient.GetAtomicTxStatus(ctx, txID) - if err != nil { - return err - } - - switch status { - case evm.Accepted: - return w.Backend.AcceptAtomicTx(ctx, tx) - case evm.Dropped, evm.Unknown: - return errNotCommitted - } - - // The tx is Processing. - - select { - case <-ticker.C: - case <-ctx.Done(): - return ctx.Err() - } - } -} - -func (w *wallet) baseFee(options []common.Option) (*big.Int, error) { - ops := common.NewOptions(options) - baseFee := ops.BaseFee(nil) - if baseFee != nil { - return baseFee, nil - } - - ctx := ops.Context() - return w.ethClient.EstimateBaseFee(ctx) -} +// import ( +// "errors" +// "math/big" +// "time" + +// "github.com/ava-labs/coreth/ethclient" +// "github.com/ava-labs/coreth/plugin/evm" + +// ethcommon "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var ( +// _ Wallet = (*wallet)(nil) + +// errNotCommitted = errors.New("not committed") +// ) + +// type Wallet interface { +// Context + +// // Builder returns the builder that will be used to create the transactions. +// Builder() Builder + +// // Signer returns the signer that will be used to sign the transactions. +// Signer() Signer + +// // IssueImportTx creates, signs, and issues an import transaction that +// // attempts to consume all the available UTXOs and import the funds to [to]. +// // +// // - [chainID] specifies the chain to be importing funds from. +// // - [to] specifies where to send the imported funds to. +// IssueImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// options ...common.Option, +// ) (*evm.Tx, error) + +// // IssueExportTx creates, signs, and issues an export transaction that +// // attempts to send all the provided [outputs] to the requested [chainID]. +// // +// // - [chainID] specifies the chain to be exporting the funds to. +// // - [outputs] specifies the outputs to send to the [chainID]. +// IssueExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// options ...common.Option, +// ) (*evm.Tx, error) + +// // IssueUnsignedTx signs and issues the unsigned tx. +// IssueUnsignedAtomicTx( +// utx evm.UnsignedAtomicTx, +// options ...common.Option, +// ) (*evm.Tx, error) + +// // IssueAtomicTx issues the signed tx. +// IssueAtomicTx( +// tx *evm.Tx, +// options ...common.Option, +// ) error +// } + +// func NewWallet( +// builder Builder, +// signer Signer, +// avaxClient evm.Client, +// ethClient ethclient.Client, +// backend Backend, +// ) Wallet { +// return &wallet{ +// Backend: backend, +// builder: builder, +// signer: signer, +// avaxClient: avaxClient, +// ethClient: ethClient, +// } +// } + +// type wallet struct { +// Backend +// builder Builder +// signer Signer +// avaxClient evm.Client +// ethClient ethclient.Client +// } + +// func (w *wallet) Builder() Builder { +// return w.builder +// } + +// func (w *wallet) Signer() Signer { +// return w.signer +// } + +// func (w *wallet) IssueImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// options ...common.Option, +// ) (*evm.Tx, error) { +// baseFee, err := w.baseFee(options) +// if err != nil { +// return nil, err +// } + +// utx, err := w.builder.NewImportTx(chainID, to, baseFee, options...) +// if err != nil { +// return nil, err +// } +// return w.IssueUnsignedAtomicTx(utx, options...) +// } + +// func (w *wallet) IssueExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// options ...common.Option, +// ) (*evm.Tx, error) { +// baseFee, err := w.baseFee(options) +// if err != nil { +// return nil, err +// } + +// utx, err := w.builder.NewExportTx(chainID, outputs, baseFee, options...) +// if err != nil { +// return nil, err +// } +// return w.IssueUnsignedAtomicTx(utx, options...) +// } + +// func (w *wallet) IssueUnsignedAtomicTx( +// utx evm.UnsignedAtomicTx, +// options ...common.Option, +// ) (*evm.Tx, error) { +// ops := common.NewOptions(options) +// ctx := ops.Context() +// tx, err := w.signer.SignUnsignedAtomic(ctx, utx) +// if err != nil { +// return nil, err +// } + +// return tx, w.IssueAtomicTx(tx, options...) +// } + +// func (w *wallet) IssueAtomicTx( +// tx *evm.Tx, +// options ...common.Option, +// ) error { +// ops := common.NewOptions(options) +// ctx := ops.Context() +// txID, err := w.avaxClient.IssueTx(ctx, tx.SignedBytes()) +// if err != nil { +// return err +// } + +// if f := ops.PostIssuanceFunc(); f != nil { +// f(txID) +// } + +// if ops.AssumeDecided() { +// return w.Backend.AcceptAtomicTx(ctx, tx) +// } + +// pollFrequency := ops.PollFrequency() +// ticker := time.NewTicker(pollFrequency) +// defer ticker.Stop() + +// for { +// status, err := w.avaxClient.GetAtomicTxStatus(ctx, txID) +// if err != nil { +// return err +// } + +// switch status { +// case evm.Accepted: +// return w.Backend.AcceptAtomicTx(ctx, tx) +// case evm.Dropped, evm.Unknown: +// return errNotCommitted +// } + +// // The tx is Processing. + +// select { +// case <-ticker.C: +// case <-ctx.Done(): +// return ctx.Err() +// } +// } +// } + +// func (w *wallet) baseFee(options []common.Option) (*big.Int, error) { +// ops := common.NewOptions(options) +// baseFee := ops.BaseFee(nil) +// if baseFee != nil { +// return baseFee, nil +// } + +// ctx := ops.Context() +// return w.ethClient.EstimateBaseFee(ctx) +// } diff --git a/wallet/chain/c/wallet_with_options.go b/wallet/chain/c/wallet_with_options.go index 7d6193683d49..fd69a6d4fd02 100644 --- a/wallet/chain/c/wallet_with_options.go +++ b/wallet/chain/c/wallet_with_options.go @@ -3,80 +3,80 @@ package c -import ( - "github.com/ava-labs/coreth/plugin/evm" +// import ( +// "github.com/ava-labs/coreth/plugin/evm" - ethcommon "github.com/ethereum/go-ethereum/common" +// ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) -var _ Wallet = (*walletWithOptions)(nil) +// var _ Wallet = (*walletWithOptions)(nil) -func NewWalletWithOptions( - wallet Wallet, - options ...common.Option, -) Wallet { - return &walletWithOptions{ - Wallet: wallet, - options: options, - } -} +// func NewWalletWithOptions( +// wallet Wallet, +// options ...common.Option, +// ) Wallet { +// return &walletWithOptions{ +// Wallet: wallet, +// options: options, +// } +// } -type walletWithOptions struct { - Wallet - options []common.Option -} +// type walletWithOptions struct { +// Wallet +// options []common.Option +// } -func (w *walletWithOptions) Builder() Builder { - return NewBuilderWithOptions( - w.Wallet.Builder(), - w.options..., - ) -} +// func (w *walletWithOptions) Builder() Builder { +// return NewBuilderWithOptions( +// w.Wallet.Builder(), +// w.options..., +// ) +// } -func (w *walletWithOptions) IssueImportTx( - chainID ids.ID, - to ethcommon.Address, - options ...common.Option, -) (*evm.Tx, error) { - return w.Wallet.IssueImportTx( - chainID, - to, - common.UnionOptions(w.options, options)..., - ) -} +// func (w *walletWithOptions) IssueImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// options ...common.Option, +// ) (*evm.Tx, error) { +// return w.Wallet.IssueImportTx( +// chainID, +// to, +// common.UnionOptions(w.options, options)..., +// ) +// } -func (w *walletWithOptions) IssueExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - options ...common.Option, -) (*evm.Tx, error) { - return w.Wallet.IssueExportTx( - chainID, - outputs, - common.UnionOptions(w.options, options)..., - ) -} +// func (w *walletWithOptions) IssueExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// options ...common.Option, +// ) (*evm.Tx, error) { +// return w.Wallet.IssueExportTx( +// chainID, +// outputs, +// common.UnionOptions(w.options, options)..., +// ) +// } -func (w *walletWithOptions) IssueUnsignedAtomicTx( - utx evm.UnsignedAtomicTx, - options ...common.Option, -) (*evm.Tx, error) { - return w.Wallet.IssueUnsignedAtomicTx( - utx, - common.UnionOptions(w.options, options)..., - ) -} +// func (w *walletWithOptions) IssueUnsignedAtomicTx( +// utx evm.UnsignedAtomicTx, +// options ...common.Option, +// ) (*evm.Tx, error) { +// return w.Wallet.IssueUnsignedAtomicTx( +// utx, +// common.UnionOptions(w.options, options)..., +// ) +// } -func (w *walletWithOptions) IssueAtomicTx( - tx *evm.Tx, - options ...common.Option, -) error { - return w.Wallet.IssueAtomicTx( - tx, - common.UnionOptions(w.options, options)..., - ) -} +// func (w *walletWithOptions) IssueAtomicTx( +// tx *evm.Tx, +// options ...common.Option, +// ) error { +// return w.Wallet.IssueAtomicTx( +// tx, +// common.UnionOptions(w.options, options)..., +// ) +// } diff --git a/wallet/subnet/primary/api.go b/wallet/subnet/primary/api.go index 3ac72c217884..00ebea6090fd 100644 --- a/wallet/subnet/primary/api.go +++ b/wallet/subnet/primary/api.go @@ -5,12 +5,11 @@ package primary import ( "context" - "fmt" + // "fmt" - "github.com/ava-labs/coreth/ethclient" - "github.com/ava-labs/coreth/plugin/evm" + // "github.com/ava-labs/coreth/ethclient" - "github.com/ethereum/go-ethereum/common" + // "github.com/ethereum/go-ethereum/common" "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/codec" @@ -22,7 +21,8 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/wallet/chain/c" + + // "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/x" ) @@ -59,9 +59,9 @@ type AVAXState struct { PCTX p.Context XClient avm.Client XCTX x.Context - CClient evm.Client - CCTX c.Context - UTXOs UTXOs + // CClient evm.Client + // CCTX c.Context + UTXOs UTXOs } func FetchState( @@ -75,7 +75,7 @@ func FetchState( infoClient := info.NewClient(uri) pClient := platformvm.NewClient(uri) xClient := avm.NewClient(uri, "X") - cClient := evm.NewCChainClient(uri) + // cClient := evm.NewCChainClient(uri) pCTX, err := p.NewContextFromClients(ctx, infoClient, xClient) if err != nil { @@ -87,10 +87,10 @@ func FetchState( return nil, err } - cCTX, err := c.NewContextFromClients(ctx, infoClient, xClient) - if err != nil { - return nil, err - } + // cCTX, err := c.NewContextFromClients(ctx, infoClient, xClient) + // if err != nil { + // return nil, err + // } utxos := NewUTXOs() addrList := addrs.List() @@ -109,11 +109,11 @@ func FetchState( client: xClient, codec: x.Parser.Codec(), }, - { - id: cCTX.BlockchainID(), - client: cClient, - codec: evm.Codec, - }, + // { + // id: cCTX.BlockchainID(), + // client: cClient, + // codec: evm.Codec, + // }, } for _, destinationChain := range chains { for _, sourceChain := range chains { @@ -136,52 +136,52 @@ func FetchState( PCTX: pCTX, XClient: xClient, XCTX: xCTX, - CClient: cClient, - CCTX: cCTX, - UTXOs: utxos, + // CClient: cClient, + // CCTX: cCTX, + UTXOs: utxos, }, nil } -type EthState struct { - Client ethclient.Client - Accounts map[common.Address]*c.Account -} - -func FetchEthState( - ctx context.Context, - uri string, - addrs set.Set[common.Address], -) (*EthState, error) { - path := fmt.Sprintf( - "%s/ext/%s/C/rpc", - uri, - constants.ChainAliasPrefix, - ) - client, err := ethclient.Dial(path) - if err != nil { - return nil, err - } - - accounts := make(map[common.Address]*c.Account, addrs.Len()) - for addr := range addrs { - balance, err := client.BalanceAt(ctx, addr, nil) - if err != nil { - return nil, err - } - nonce, err := client.NonceAt(ctx, addr, nil) - if err != nil { - return nil, err - } - accounts[addr] = &c.Account{ - Balance: balance, - Nonce: nonce, - } - } - return &EthState{ - Client: client, - Accounts: accounts, - }, nil -} +// type EthState struct { +// Client ethclient.Client +// Accounts map[common.Address]*c.Account +// } + +// func FetchEthState( +// ctx context.Context, +// uri string, +// addrs set.Set[common.Address], +// ) (*EthState, error) { +// path := fmt.Sprintf( +// "%s/ext/%s/C/rpc", +// uri, +// constants.ChainAliasPrefix, +// ) +// client, err := ethclient.Dial(path) +// if err != nil { +// return nil, err +// } + +// accounts := make(map[common.Address]*c.Account, addrs.Len()) +// for addr := range addrs { +// balance, err := client.BalanceAt(ctx, addr, nil) +// if err != nil { +// return nil, err +// } +// nonce, err := client.NonceAt(ctx, addr, nil) +// if err != nil { +// return nil, err +// } +// accounts[addr] = &c.Account{ +// Balance: balance, +// Nonce: nonce, +// } +// } +// return &EthState{ +// Client: client, +// Accounts: accounts, +// }, nil +// } // AddAllUTXOs fetches all the UTXOs referenced by [addresses] that were sent // from [sourceChainID] to [destinationChainID] from the [client]. It then uses diff --git a/wallet/subnet/primary/example_test.go b/wallet/subnet/primary/example_test.go index 483c049d4ac0..4a73e8c070b2 100644 --- a/wallet/subnet/primary/example_test.go +++ b/wallet/subnet/primary/example_test.go @@ -30,7 +30,7 @@ func ExampleWallet() { wallet, err := MakeWallet(ctx, &WalletConfig{ URI: LocalAPIURI, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet with: %s\n", err) diff --git a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go index d5e8ce422307..21c081d2982b 100644 --- a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go +++ b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go @@ -46,9 +46,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + // EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/examples/add-primary-validator/main.go b/wallet/subnet/primary/examples/add-primary-validator/main.go index a56dae23db3a..13c28f995f63 100644 --- a/wallet/subnet/primary/examples/add-primary-validator/main.go +++ b/wallet/subnet/primary/examples/add-primary-validator/main.go @@ -45,7 +45,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/c-chain-export/main.go b/wallet/subnet/primary/examples/c-chain-export/main.go index fec55c899feb..a6b9a0c810b8 100644 --- a/wallet/subnet/primary/examples/c-chain-export/main.go +++ b/wallet/subnet/primary/examples/c-chain-export/main.go @@ -3,70 +3,70 @@ package main -import ( - "context" - "log" - "time" +// import ( +// "context" +// "log" +// "time" - "github.com/ava-labs/avalanchego/genesis" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary" -) +// "github.com/ava-labs/avalanchego/genesis" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary" +// ) -func main() { - key := genesis.EWOQKey - uri := primary.LocalAPIURI - kc := secp256k1fx.NewKeychain(key) - avaxAddr := key.Address() +// func main() { +// key := genesis.EWOQKey +// uri := primary.LocalAPIURI +// kc := secp256k1fx.NewKeychain(key) +// avaxAddr := key.Address() - ctx := context.Background() +// ctx := context.Background() - // MakeWallet fetches the available UTXOs owned by [kc] on the network that - // [uri] is hosting. - walletSyncStartTime := time.Now() - wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, - }) - if err != nil { - log.Fatalf("failed to initialize wallet: %s\n", err) - } - log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) +// // MakeWallet fetches the available UTXOs owned by [kc] on the network that +// // [uri] is hosting. +// walletSyncStartTime := time.Now() +// wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ +// URI: uri, +// AVAXKeychain: kc, +// EthKeychain: kc, +// }) +// if err != nil { +// log.Fatalf("failed to initialize wallet: %s\n", err) +// } +// log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) - // Get the P-chain wallet - pWallet := wallet.P() - cWallet := wallet.C() +// // Get the P-chain wallet +// pWallet := wallet.P() +// cWallet := wallet.C() - // Pull out useful constants to use when issuing transactions. - cChainID := cWallet.BlockchainID() - owner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - avaxAddr, - }, - } +// // Pull out useful constants to use when issuing transactions. +// cChainID := cWallet.BlockchainID() +// owner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// avaxAddr, +// }, +// } - exportStartTime := time.Now() - exportTx, err := cWallet.IssueExportTx( - constants.PlatformChainID, - []*secp256k1fx.TransferOutput{{ - Amt: units.Avax, - OutputOwners: owner, - }}, - ) - if err != nil { - log.Fatalf("failed to issue export transaction: %s\n", err) - } - log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) +// exportStartTime := time.Now() +// exportTx, err := cWallet.IssueExportTx( +// constants.PlatformChainID, +// []*secp256k1fx.TransferOutput{{ +// Amt: units.Avax, +// OutputOwners: owner, +// }}, +// ) +// if err != nil { +// log.Fatalf("failed to issue export transaction: %s\n", err) +// } +// log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) - importStartTime := time.Now() - importTx, err := pWallet.IssueImportTx(cChainID, &owner) - if err != nil { - log.Fatalf("failed to issue import transaction: %s\n", err) - } - log.Printf("issued import %s in %s\n", importTx.ID(), time.Since(importStartTime)) -} +// importStartTime := time.Now() +// importTx, err := pWallet.IssueImportTx(cChainID, &owner) +// if err != nil { +// log.Fatalf("failed to issue import transaction: %s\n", err) +// } +// log.Printf("issued import %s in %s\n", importTx.ID(), time.Since(importStartTime)) +// } diff --git a/wallet/subnet/primary/examples/c-chain-import/main.go b/wallet/subnet/primary/examples/c-chain-import/main.go index b4dc4e603eb3..2d9b8a244cb0 100644 --- a/wallet/subnet/primary/examples/c-chain-import/main.go +++ b/wallet/subnet/primary/examples/c-chain-import/main.go @@ -3,75 +3,75 @@ package main -import ( - "context" - "log" - "time" +// import ( +// "context" +// "log" +// "time" - "github.com/ava-labs/coreth/plugin/evm" +// "github.com/ava-labs/coreth/plugin/evm" - "github.com/ava-labs/avalanchego/genesis" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary" -) +// "github.com/ava-labs/avalanchego/genesis" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary" +// ) -func main() { - key := genesis.EWOQKey - uri := primary.LocalAPIURI - kc := secp256k1fx.NewKeychain(key) - avaxAddr := key.Address() - ethAddr := evm.PublicKeyToEthAddress(key.PublicKey()) +// func main() { +// key := genesis.EWOQKey +// uri := primary.LocalAPIURI +// kc := secp256k1fx.NewKeychain(key) +// avaxAddr := key.Address() +// ethAddr := evm.PublicKeyToEthAddress(key.PublicKey()) - ctx := context.Background() +// ctx := context.Background() - // MakeWallet fetches the available UTXOs owned by [kc] on the network that - // [uri] is hosting. - walletSyncStartTime := time.Now() - wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, - }) - if err != nil { - log.Fatalf("failed to initialize wallet: %s\n", err) - } - log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) +// // MakeWallet fetches the available UTXOs owned by [kc] on the network that +// // [uri] is hosting. +// walletSyncStartTime := time.Now() +// wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ +// URI: uri, +// AVAXKeychain: kc, +// EthKeychain: kc, +// }) +// if err != nil { +// log.Fatalf("failed to initialize wallet: %s\n", err) +// } +// log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) - // Get the P-chain wallet - pWallet := wallet.P() - cWallet := wallet.C() +// // Get the P-chain wallet +// pWallet := wallet.P() +// cWallet := wallet.C() - // Pull out useful constants to use when issuing transactions. - cChainID := cWallet.BlockchainID() - avaxAssetID := cWallet.AVAXAssetID() - owner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - avaxAddr, - }, - } +// // Pull out useful constants to use when issuing transactions. +// cChainID := cWallet.BlockchainID() +// avaxAssetID := cWallet.AVAXAssetID() +// owner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// avaxAddr, +// }, +// } - exportStartTime := time.Now() - exportTx, err := pWallet.IssueExportTx(cChainID, []*avax.TransferableOutput{{ - Asset: avax.Asset{ID: avaxAssetID}, - Out: &secp256k1fx.TransferOutput{ - Amt: units.Avax, - OutputOwners: owner, - }, - }}) - if err != nil { - log.Fatalf("failed to issue export transaction: %s\n", err) - } - log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) +// exportStartTime := time.Now() +// exportTx, err := pWallet.IssueExportTx(cChainID, []*avax.TransferableOutput{{ +// Asset: avax.Asset{ID: avaxAssetID}, +// Out: &secp256k1fx.TransferOutput{ +// Amt: units.Avax, +// OutputOwners: owner, +// }, +// }}) +// if err != nil { +// log.Fatalf("failed to issue export transaction: %s\n", err) +// } +// log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) - importStartTime := time.Now() - importTx, err := cWallet.IssueImportTx(constants.PlatformChainID, ethAddr) - if err != nil { - log.Fatalf("failed to issue import transaction: %s\n", err) - } - log.Printf("issued import %s to %s in %s\n", importTx.ID(), ethAddr.Hex(), time.Since(importStartTime)) -} +// importStartTime := time.Now() +// importTx, err := cWallet.IssueImportTx(constants.PlatformChainID, ethAddr) +// if err != nil { +// log.Fatalf("failed to issue import transaction: %s\n", err) +// } +// log.Printf("issued import %s to %s in %s\n", importTx.ID(), ethAddr.Hex(), time.Since(importStartTime)) +// } diff --git a/wallet/subnet/primary/examples/create-asset/main.go b/wallet/subnet/primary/examples/create-asset/main.go index 30804f083df6..0bccfbb5fc52 100644 --- a/wallet/subnet/primary/examples/create-asset/main.go +++ b/wallet/subnet/primary/examples/create-asset/main.go @@ -30,7 +30,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/create-chain/main.go b/wallet/subnet/primary/examples/create-chain/main.go index 5e6898a1b649..521a3cca53cf 100644 --- a/wallet/subnet/primary/examples/create-chain/main.go +++ b/wallet/subnet/primary/examples/create-chain/main.go @@ -41,9 +41,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + // EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/examples/create-locked-stakeable/main.go b/wallet/subnet/primary/examples/create-locked-stakeable/main.go index e688968e9e8a..92f1b5cb0e1b 100644 --- a/wallet/subnet/primary/examples/create-locked-stakeable/main.go +++ b/wallet/subnet/primary/examples/create-locked-stakeable/main.go @@ -39,7 +39,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/create-subnet/main.go b/wallet/subnet/primary/examples/create-subnet/main.go index add98ea7931c..3e8d69bc016a 100644 --- a/wallet/subnet/primary/examples/create-subnet/main.go +++ b/wallet/subnet/primary/examples/create-subnet/main.go @@ -28,7 +28,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/remove-subnet-validator/main.go b/wallet/subnet/primary/examples/remove-subnet-validator/main.go index 2842c7c0a790..46f4b85124db 100644 --- a/wallet/subnet/primary/examples/remove-subnet-validator/main.go +++ b/wallet/subnet/primary/examples/remove-subnet-validator/main.go @@ -38,9 +38,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + // EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/wallet.go b/wallet/subnet/primary/wallet.go index 54de390d029c..ae5e4202a099 100644 --- a/wallet/subnet/primary/wallet.go +++ b/wallet/subnet/primary/wallet.go @@ -11,7 +11,8 @@ import ( "github.com/ava-labs/avalanchego/utils/crypto/keychain" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/wallet/chain/c" + + // "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/x" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -23,13 +24,13 @@ var _ Wallet = (*wallet)(nil) type Wallet interface { P() p.Wallet X() x.Wallet - C() c.Wallet + // C() c.Wallet } type wallet struct { p p.Wallet x x.Wallet - c c.Wallet + // c c.Wallet } func (w *wallet) P() p.Wallet { @@ -40,16 +41,16 @@ func (w *wallet) X() x.Wallet { return w.x } -func (w *wallet) C() c.Wallet { - return w.c -} +// func (w *wallet) C() c.Wallet { +// return w.c +// } // Creates a new default wallet -func NewWallet(p p.Wallet, x x.Wallet, c c.Wallet) Wallet { +func NewWallet(p p.Wallet, x x.Wallet /*, c c.Wallet*/) Wallet { return &wallet{ p: p, x: x, - c: c, + // c: c, } } @@ -58,7 +59,7 @@ func NewWalletWithOptions(w Wallet, options ...common.Option) Wallet { return NewWallet( p.NewWalletWithOptions(w.P(), options...), x.NewWalletWithOptions(w.X(), options...), - c.NewWalletWithOptions(w.C(), options...), + // c.NewWalletWithOptions(w.C(), options...), ) } @@ -67,7 +68,7 @@ type WalletConfig struct { URI string // required // Keys to use for signing all transactions. AVAXKeychain keychain.Keychain // required - EthKeychain c.EthKeychain // required + // EthKeychain c.EthKeychain // required // Set of P-chain transactions that the wallet should know about to be able // to generate transactions. PChainTxs map[ids.ID]*txs.Tx // optional @@ -93,11 +94,11 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { return nil, err } - ethAddrs := config.EthKeychain.EthAddresses() - ethState, err := FetchEthState(ctx, config.URI, ethAddrs) - if err != nil { - return nil, err - } + // ethAddrs := config.EthKeychain.EthAddresses() + // ethState, err := FetchEthState(ctx, config.URI, ethAddrs) + // if err != nil { + // return nil, err + // } pChainTxs := config.PChainTxs if pChainTxs == nil { @@ -127,15 +128,15 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { xBuilder := x.NewBuilder(avaxAddrs, xBackend) xSigner := x.NewSigner(config.AVAXKeychain, xBackend) - cChainID := avaxState.CCTX.BlockchainID() - cUTXOs := NewChainUTXOs(cChainID, avaxState.UTXOs) - cBackend := c.NewBackend(avaxState.CCTX, cUTXOs, ethState.Accounts) - cBuilder := c.NewBuilder(avaxAddrs, ethAddrs, cBackend) - cSigner := c.NewSigner(config.AVAXKeychain, config.EthKeychain, cBackend) + // cChainID := avaxState.CCTX.BlockchainID() + // cUTXOs := NewChainUTXOs(cChainID, avaxState.UTXOs) + // cBackend := c.NewBackend(avaxState.CCTX, cUTXOs, ethState.Accounts) + // cBuilder := c.NewBuilder(avaxAddrs, ethAddrs, cBackend) + // cSigner := c.NewSigner(config.AVAXKeychain, config.EthKeychain, cBackend) return NewWallet( p.NewWallet(pBuilder, pSigner, avaxState.PClient, pBackend), x.NewWallet(xBuilder, xSigner, avaxState.XClient, xBackend), - c.NewWallet(cBuilder, cSigner, avaxState.CClient, ethState.Client, cBackend), + // c.NewWallet(cBuilder, cSigner, avaxState.CClient, ethState.Client, cBackend), ), nil } From bf308c89666fa2baf8d760f3f8737d43ea6e2ccc Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 27 Dec 2023 17:03:42 +0100 Subject: [PATCH 10/13] bumped coreth version --- go.mod | 26 +- go.sum | 77 +- node/node.go | 4 +- tests/e2e/c/dynamic_fees.go | 326 +++---- tests/e2e/c/interchain_workflow.go | 320 +++---- tests/e2e/p/interchain_workflow.go | 422 ++++----- tests/e2e/x/interchain_workflow.go | 296 +++---- tests/fixture/e2e/helpers.go | 123 ++- tests/fixture/tmpnet/genesis.go | 50 +- vms/example/xsvm/cmd/chain/create/cmd.go | 6 +- wallet/chain/c/backend.go | 300 +++---- wallet/chain/c/builder.go | 812 +++++++++--------- wallet/chain/c/builder_with_options.go | 136 +-- wallet/chain/c/context.go | 194 ++--- wallet/chain/c/signer.go | 436 +++++----- wallet/chain/c/wallet.go | 402 ++++----- wallet/chain/c/wallet_with_options.go | 134 +-- wallet/subnet/primary/api.go | 122 +-- wallet/subnet/primary/example_test.go | 2 +- .../add-permissioned-subnet-validator/main.go | 6 +- .../examples/add-primary-validator/main.go | 2 +- .../primary/examples/c-chain-export/main.go | 118 +-- .../primary/examples/c-chain-import/main.go | 126 +-- .../primary/examples/create-asset/main.go | 2 +- .../primary/examples/create-chain/main.go | 6 +- .../examples/create-locked-stakeable/main.go | 2 +- .../primary/examples/create-subnet/main.go | 2 +- .../examples/remove-subnet-validator/main.go | 6 +- wallet/subnet/primary/wallet.go | 43 +- 29 files changed, 2301 insertions(+), 2200 deletions(-) diff --git a/go.mod b/go.mod index cd9743e7bdfb..8007addf990f 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 + github.com/ava-labs/coreth v0.12.9-rc.9.0.20231227155207-5b6a157b44c8 github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 @@ -74,6 +75,7 @@ require ( github.com/BurntSushi/toml v1.2.1 // indirect github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect + github.com/VictoriaMetrics/fastcache v1.10.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect @@ -81,28 +83,45 @@ require ( github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/redact v1.1.3 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/deckarep/golang-set/v2 v2.1.0 // indirect + github.com/dlclark/regexp2 v1.7.0 // indirect + github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 // indirect + github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect github.com/frankban/quicktest v1.14.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/getsentry/sentry-go v0.18.0 // indirect github.com/go-logr/logr v1.3.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect + github.com/go-stack/stack v1.8.1 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/go-cmp v0.6.0 // indirect - github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect + github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect + github.com/google/uuid v1.3.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 // indirect + github.com/hashicorp/go-bexpr v0.1.10 // indirect + github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e // indirect github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/klauspost/compress v1.15.15 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/magiconair/properties v1.8.6 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mitchellh/pointerstructure v1.2.0 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -110,12 +129,17 @@ require ( github.com/prometheus/common v0.39.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sanity-io/litter v1.5.1 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/status-im/keycard-go v0.2.0 // indirect github.com/subosito/gotenv v1.3.0 // indirect github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tklauser/numcpus v0.2.2 // indirect + github.com/tyler-smith/go-bip39 v1.1.0 // indirect + github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect diff --git a/go.sum b/go.sum index 3ef5760fbfd8..1416fce80669 100644 --- a/go.sum +++ b/go.sum @@ -56,12 +56,18 @@ github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cq github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= +github.com/VictoriaMetrics/fastcache v1.10.0 h1:5hDJnLsKLpnUEToub7ETuRu8RCkb40woBZAUiKonXzY= +github.com/VictoriaMetrics/fastcache v1.10.0/go.mod h1:tjiYeEfYXCqacuvYw/7UoDIeJaNxq6132xHICNP77w8= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/ava-labs/coreth v0.12.9-rc.9.0.20231227155207-5b6a157b44c8 h1:TE72qt8xRzF8QrR+UUSoCgNINn6fLosq7k2KnD9RYuc= +github.com/ava-labs/coreth v0.12.9-rc.9.0.20231227155207-5b6a157b44c8/go.mod h1:uVX/xG7p07/0bUK4bJBQGsY0HXWvkVfmNLvyd4PGEOA= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= @@ -96,13 +102,18 @@ github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46f github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw= github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA= @@ -134,12 +145,16 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= +github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= @@ -150,6 +165,14 @@ github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6ps github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= +github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 h1:+3HCtB74++ClLy8GgjUQYeC8R4ILzVcIe8+5edAJJnE= +github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= +github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= +github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -166,6 +189,8 @@ github.com/ethereum/go-ethereum v1.12.0 h1:bdnhLPtqETd4m3mS8BGMNvBTf36bO5bx/hxE2 github.com/ethereum/go-ethereum v1.12.0/go.mod h1:/oo2X/dZLJjf2mJ6YT9wcWxa4nNJDBKDBU6sFIpx1Gs= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -174,6 +199,8 @@ github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmV github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= @@ -197,7 +224,11 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= +github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= @@ -284,12 +315,15 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= @@ -310,11 +344,17 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 h1:kr3j8iIMR4ywO/O0rvksXaJvauGGCMg2zAZIiNZ9uIQ= github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0/go.mod h1:ummNFgdgLhhX7aIiy35vVmQNS0rWXknfPE0qe6fmFXg= +github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e h1:pIYdhNkDh+YENVNi3gto8n9hAmRxKxoar0iE6BLucjw= +github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e/go.mod h1:j9cQbcqHQujT0oKJ38PylVfqohClLr3CvDC+Qcg+lhU= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c h1:DZfsyhDK1hnSS5lH8l+JggqzEleHteTYfutAiVlSUM8= @@ -326,6 +366,7 @@ github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3 github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -367,6 +408,7 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -374,6 +416,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= @@ -384,11 +427,17 @@ github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPK github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= @@ -397,8 +446,11 @@ github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -417,6 +469,8 @@ github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -484,6 +538,8 @@ github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sanity-io/litter v1.5.1 h1:dwnrSypP6q56o3lFxTU+t2fwQ9A+U5qrXVO4Qg9KwVU= github.com/sanity-io/litter v1.5.1/go.mod h1:5Z71SvaYy5kcGtyglXOC9rrUi3c1E8CamFWjQsazTh0= @@ -519,6 +575,8 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= +github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= +github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -551,10 +609,14 @@ github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZF github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE= github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa h1:5SqCsI/2Qya2bCzK15ozrqo2sZxkh0FHynJZOTVoV6Q= +github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= @@ -566,6 +628,8 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= @@ -575,6 +639,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= @@ -670,6 +735,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -716,6 +782,7 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -739,6 +806,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -803,8 +871,12 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= @@ -821,6 +893,7 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -884,6 +957,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1010,6 +1084,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= diff --git a/node/node.go b/node/node.go index 151f878ee6d7..22be7d5436eb 100644 --- a/node/node.go +++ b/node/node.go @@ -25,7 +25,7 @@ import ( "go.uber.org/zap" - // coreth "github.com/ava-labs/coreth/plugin/evm" + coreth "github.com/ava-labs/coreth/plugin/evm" "github.com/ava-labs/avalanchego/api/admin" "github.com/ava-labs/avalanchego/api/auth" @@ -1116,7 +1116,7 @@ func (n *Node) initVMs() error { CreateAssetTxFee: n.Config.CreateAssetTxFee, }, }), - // vmRegisterer.Register(context.TODO(), constants.EVMID, &coreth.Factory{}), + vmRegisterer.Register(context.TODO(), constants.EVMID, &coreth.Factory{}), n.VMManager.RegisterFactory(context.TODO(), secp256k1fx.ID, &secp256k1fx.Factory{}), n.VMManager.RegisterFactory(context.TODO(), nftfx.ID, &nftfx.Factory{}), n.VMManager.RegisterFactory(context.TODO(), propertyfx.ID, &propertyfx.Factory{}), diff --git a/tests/e2e/c/dynamic_fees.go b/tests/e2e/c/dynamic_fees.go index 7cd53f52baaf..5e80573542b4 100644 --- a/tests/e2e/c/dynamic_fees.go +++ b/tests/e2e/c/dynamic_fees.go @@ -3,166 +3,166 @@ package c -// import ( -// "math/big" -// "strings" - -// ginkgo "github.com/onsi/ginkgo/v2" - -// "github.com/stretchr/testify/require" - -// "github.com/ethereum/go-ethereum/accounts/abi" -// "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/coreth/core/types" -// "github.com/ava-labs/coreth/params" -// "github.com/ava-labs/coreth/plugin/evm" - -// "github.com/ava-labs/avalanchego/tests" -// "github.com/ava-labs/avalanchego/tests/e2e" -// "github.com/ava-labs/avalanchego/tests/fixture/testnet" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// ) - -// // This test uses the compiled bin for `hashing.sol` as -// // well as its ABI contained in `hashing_contract.go`. - -// var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { -// require := require.New(ginkgo.GinkgoT()) - -// // Need a gas limit much larger than the standard 21_000 to enable -// // the contract to induce a gas price increase -// const largeGasLimit = uint64(8_000_000) - -// // TODO(marun) What is the significance of this value? -// gasTip := big.NewInt(1000 * params.GWei) - -// ginkgo.It("should ensure that the gas price is affected by load", func() { -// ginkgo.By("creating a new private network to ensure isolation from other tests") -// privateNetwork := e2e.Env.NewPrivateNetwork() - -// ginkgo.By("allocating a pre-funded key") -// key := privateNetwork.PreFundedKeys[0] -// ethAddress := evm.GetEthAddress(key) - -// ginkgo.By("initializing a coreth client") -// node := privateNetwork.Nodes[0] -// nodeURI := tmpnet.NodeURI{ -// NodeID: node.NodeID, -// URI: node.URI, -// } -// ethClient := e2e.NewEthClient(nodeURI) - -// ginkgo.By("initializing a transaction signer") -// cChainID, err := ethClient.ChainID(e2e.DefaultContext()) -// require.NoError(err) -// signer := types.NewEIP155Signer(cChainID) -// ecdsaKey := key.ToECDSA() -// sign := func(tx *types.Transaction) *types.Transaction { -// signedTx, err := types.SignTx(tx, signer, ecdsaKey) -// require.NoError(err) -// return signedTx -// } - -// var contractAddress common.Address -// ginkgo.By("deploying an expensive contract", func() { -// // Create transaction -// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) -// require.NoError(err) -// compiledContract := common.Hex2Bytes(hashingCompiledContract) -// tx := types.NewTx(&types.LegacyTx{ -// Nonce: nonce, -// GasPrice: gasTip, -// Gas: largeGasLimit, -// Value: common.Big0, -// Data: compiledContract, -// }) - -// // Send the transaction and wait for acceptance -// signedTx := sign(tx) -// receipt := e2e.SendEthTransaction(ethClient, signedTx) - -// contractAddress = receipt.ContractAddress -// }) - -// var gasPrice *big.Int -// ginkgo.By("calling the expensive contract repeatedly until a gas price increase is detected", func() { -// // Evaluate the bytes representation of the contract -// hashingABI, err := abi.JSON(strings.NewReader(hashingABIJson)) -// require.NoError(err) -// contractData, err := hashingABI.Pack("hashIt") -// require.NoError(err) - -// var initialGasPrice *big.Int -// e2e.Eventually(func() bool { -// // Check the gas price -// var err error -// gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) -// require.NoError(err) -// if initialGasPrice == nil { -// initialGasPrice = gasPrice -// tests.Outf("{{blue}}initial gas price is %v{{/}}\n", initialGasPrice) -// } else if gasPrice.Cmp(initialGasPrice) > 0 { -// // Gas price has increased -// tests.Outf("{{blue}}gas price has increased to %v{{/}}\n", gasPrice) -// return true -// } - -// // Create the transaction -// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) -// require.NoError(err) -// tx := types.NewTx(&types.LegacyTx{ -// Nonce: nonce, -// GasPrice: gasTip, -// Gas: largeGasLimit, -// To: &contractAddress, -// Value: common.Big0, -// Data: contractData, -// }) - -// // Send the transaction and wait for acceptance -// signedTx := sign(tx) -// _ = e2e.SendEthTransaction(ethClient, signedTx) - -// // The gas price will be checked at the start of the next iteration -// return false -// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price increase before timeout") -// }) - -// ginkgo.By("waiting for the gas price to decrease...", func() { -// initialGasPrice := gasPrice -// e2e.Eventually(func() bool { -// var err error -// gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) -// require.NoError(err) -// tests.Outf("{{blue}}.{{/}}") -// return initialGasPrice.Cmp(gasPrice) > 0 -// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price decrease before timeout") -// tests.Outf("\n{{blue}}gas price has decreased to %v{{/}}\n", gasPrice) -// }) - -// ginkgo.By("sending funds at the current gas price", func() { -// // Create a recipient address -// recipientKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) -// recipientEthAddress := evm.GetEthAddress(recipientKey) - -// // Create transaction -// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) -// require.NoError(err) -// tx := types.NewTx(&types.LegacyTx{ -// Nonce: nonce, -// GasPrice: gasPrice, -// Gas: e2e.DefaultGasLimit, -// To: &recipientEthAddress, -// Value: common.Big0, -// }) - -// // Send the transaction and wait for acceptance -// signedTx := sign(tx) -// _ = e2e.SendEthTransaction(ethClient, signedTx) -// }) - -// e2e.CheckBootstrapIsPossible(privateNetwork) -// }) -// }) +import ( + "math/big" + "strings" + + ginkgo "github.com/onsi/ginkgo/v2" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm" + + "github.com/ava-labs/avalanchego/tests" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +) + +// This test uses the compiled bin for `hashing.sol` as +// well as its ABI contained in `hashing_contract.go`. + +var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { + require := require.New(ginkgo.GinkgoT()) + + // Need a gas limit much larger than the standard 21_000 to enable + // the contract to induce a gas price increase + const largeGasLimit = uint64(8_000_000) + + // TODO(marun) What is the significance of this value? + gasTip := big.NewInt(1000 * params.GWei) + + ginkgo.It("should ensure that the gas price is affected by load", func() { + ginkgo.By("creating a new private network to ensure isolation from other tests") + privateNetwork := e2e.Env.NewPrivateNetwork() + + ginkgo.By("allocating a pre-funded key") + key := privateNetwork.PreFundedKeys[0] + ethAddress := evm.GetEthAddress(key) + + ginkgo.By("initializing a coreth client") + node := privateNetwork.Nodes[0] + nodeURI := tmpnet.NodeURI{ + NodeID: node.NodeID, + URI: node.URI, + } + ethClient := e2e.NewEthClient(nodeURI) + + ginkgo.By("initializing a transaction signer") + cChainID, err := ethClient.ChainID(e2e.DefaultContext()) + require.NoError(err) + signer := types.NewEIP155Signer(cChainID) + ecdsaKey := key.ToECDSA() + sign := func(tx *types.Transaction) *types.Transaction { + signedTx, err := types.SignTx(tx, signer, ecdsaKey) + require.NoError(err) + return signedTx + } + + var contractAddress common.Address + ginkgo.By("deploying an expensive contract", func() { + // Create transaction + nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) + require.NoError(err) + compiledContract := common.Hex2Bytes(hashingCompiledContract) + tx := types.NewTx(&types.LegacyTx{ + Nonce: nonce, + GasPrice: gasTip, + Gas: largeGasLimit, + Value: common.Big0, + Data: compiledContract, + }) + + // Send the transaction and wait for acceptance + signedTx := sign(tx) + receipt := e2e.SendEthTransaction(ethClient, signedTx) + + contractAddress = receipt.ContractAddress + }) + + var gasPrice *big.Int + ginkgo.By("calling the expensive contract repeatedly until a gas price increase is detected", func() { + // Evaluate the bytes representation of the contract + hashingABI, err := abi.JSON(strings.NewReader(hashingABIJson)) + require.NoError(err) + contractData, err := hashingABI.Pack("hashIt") + require.NoError(err) + + var initialGasPrice *big.Int + e2e.Eventually(func() bool { + // Check the gas price + var err error + gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) + require.NoError(err) + if initialGasPrice == nil { + initialGasPrice = gasPrice + tests.Outf("{{blue}}initial gas price is %v{{/}}\n", initialGasPrice) + } else if gasPrice.Cmp(initialGasPrice) > 0 { + // Gas price has increased + tests.Outf("{{blue}}gas price has increased to %v{{/}}\n", gasPrice) + return true + } + + // Create the transaction + nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) + require.NoError(err) + tx := types.NewTx(&types.LegacyTx{ + Nonce: nonce, + GasPrice: gasTip, + Gas: largeGasLimit, + To: &contractAddress, + Value: common.Big0, + Data: contractData, + }) + + // Send the transaction and wait for acceptance + signedTx := sign(tx) + _ = e2e.SendEthTransaction(ethClient, signedTx) + + // The gas price will be checked at the start of the next iteration + return false + }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price increase before timeout") + }) + + ginkgo.By("waiting for the gas price to decrease...", func() { + initialGasPrice := gasPrice + e2e.Eventually(func() bool { + var err error + gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) + require.NoError(err) + tests.Outf("{{blue}}.{{/}}") + return initialGasPrice.Cmp(gasPrice) > 0 + }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price decrease before timeout") + tests.Outf("\n{{blue}}gas price has decreased to %v{{/}}\n", gasPrice) + }) + + ginkgo.By("sending funds at the current gas price", func() { + // Create a recipient address + recipientKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + recipientEthAddress := evm.GetEthAddress(recipientKey) + + // Create transaction + nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) + require.NoError(err) + tx := types.NewTx(&types.LegacyTx{ + Nonce: nonce, + GasPrice: gasPrice, + Gas: e2e.DefaultGasLimit, + To: &recipientEthAddress, + Value: common.Big0, + }) + + // Send the transaction and wait for acceptance + signedTx := sign(tx) + _ = e2e.SendEthTransaction(ethClient, signedTx) + }) + + e2e.CheckBootstrapIsPossible(privateNetwork) + }) +}) diff --git a/tests/e2e/c/interchain_workflow.go b/tests/e2e/c/interchain_workflow.go index a111029b543a..e959418e878a 100644 --- a/tests/e2e/c/interchain_workflow.go +++ b/tests/e2e/c/interchain_workflow.go @@ -3,163 +3,163 @@ package c -// import ( -// "math/big" - -// ginkgo "github.com/onsi/ginkgo/v2" - -// "github.com/stretchr/testify/require" - -// "github.com/ava-labs/coreth/core/types" -// "github.com/ava-labs/coreth/plugin/evm" - -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/tests/e2e" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var _ = e2e.DescribeCChain("[Interchain Workflow]", func() { -// require := require.New(ginkgo.GinkgoT()) - -// const txAmount = 10 * units.Avax // Arbitrary amount to send and transfer - -// ginkgo.It("should ensure that funds can be transferred from the C-Chain to the X-Chain and the P-Chain", func() { -// ginkgo.By("initializing a new eth client") -// // Select a random node URI to use for both the eth client and -// // the wallet to avoid having to verify that all nodes are at -// // the same height before initializing the wallet. -// nodeURI := e2e.Env.GetRandomNodeURI() -// ethClient := e2e.NewEthClient(nodeURI) - -// ginkgo.By("allocating a pre-funded key to send from and a recipient key to deliver to") -// senderKey := e2e.Env.AllocatePreFundedKey() -// senderEthAddress := evm.GetEthAddress(senderKey) -// recipientKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) -// recipientEthAddress := evm.GetEthAddress(recipientKey) - -// ginkgo.By("sending funds from one address to another on the C-Chain", func() { -// // Create transaction -// acceptedNonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), senderEthAddress) -// require.NoError(err) -// gasPrice := e2e.SuggestGasPrice(ethClient) -// tx := types.NewTransaction( -// acceptedNonce, -// recipientEthAddress, -// big.NewInt(int64(txAmount)), -// e2e.DefaultGasLimit, -// gasPrice, -// nil, -// ) - -// // Sign transaction -// cChainID, err := ethClient.ChainID(e2e.DefaultContext()) -// require.NoError(err) -// signer := types.NewEIP155Signer(cChainID) -// signedTx, err := types.SignTx(tx, signer, senderKey.ToECDSA()) -// require.NoError(err) - -// _ = e2e.SendEthTransaction(ethClient, signedTx) - -// ginkgo.By("waiting for the C-Chain recipient address to have received the sent funds") -// e2e.Eventually(func() bool { -// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) -// require.NoError(err) -// return balance.Cmp(big.NewInt(0)) > 0 -// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see funds delivered before timeout") -// }) - -// // Wallet must be initialized after sending funds on the -// // C-Chain with the same node URI to ensure wallet state -// // matches on-chain state. -// ginkgo.By("initializing a keychain and associated wallet") -// keychain := secp256k1fx.NewKeychain(senderKey, recipientKey) -// baseWallet := e2e.NewWallet(keychain, nodeURI) -// xWallet := baseWallet.X() -// cWallet := baseWallet.C() -// pWallet := baseWallet.P() - -// ginkgo.By("defining common configuration") -// avaxAssetID := xWallet.AVAXAssetID() -// // Use the same owner for import funds to X-Chain and P-Chain -// recipientOwner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// recipientKey.Address(), -// }, -// } -// // Use the same outputs for both X-Chain and P-Chain exports -// exportOutputs := []*secp256k1fx.TransferOutput{ -// { -// Amt: txAmount, -// OutputOwners: secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// keychain.Keys[0].Address(), -// }, -// }, -// }, -// } - -// ginkgo.By("exporting AVAX from the C-Chain to the X-Chain", func() { -// _, err := cWallet.IssueExportTx( -// xWallet.BlockchainID(), -// exportOutputs, -// e2e.WithDefaultContext(), -// e2e.WithSuggestedGasPrice(ethClient), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("importing AVAX from the C-Chain to the X-Chain", func() { -// _, err := xWallet.IssueImportTx( -// cWallet.BlockchainID(), -// &recipientOwner, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { -// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// ginkgo.By("exporting AVAX from the C-Chain to the P-Chain", func() { -// _, err := cWallet.IssueExportTx( -// constants.PlatformChainID, -// exportOutputs, -// e2e.WithDefaultContext(), -// e2e.WithSuggestedGasPrice(ethClient), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("importing AVAX from the C-Chain to the P-Chain", func() { -// _, err = pWallet.IssueImportTx( -// cWallet.BlockchainID(), -// &recipientOwner, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { -// balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) -// }) -// }) +import ( + "math/big" + + ginkgo "github.com/onsi/ginkgo/v2" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/coreth/plugin/evm" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var _ = e2e.DescribeCChain("[Interchain Workflow]", func() { + require := require.New(ginkgo.GinkgoT()) + + const txAmount = 10 * units.Avax // Arbitrary amount to send and transfer + + ginkgo.It("should ensure that funds can be transferred from the C-Chain to the X-Chain and the P-Chain", func() { + ginkgo.By("initializing a new eth client") + // Select a random node URI to use for both the eth client and + // the wallet to avoid having to verify that all nodes are at + // the same height before initializing the wallet. + nodeURI := e2e.Env.GetRandomNodeURI() + ethClient := e2e.NewEthClient(nodeURI) + + ginkgo.By("allocating a pre-funded key to send from and a recipient key to deliver to") + senderKey := e2e.Env.AllocatePreFundedKey() + senderEthAddress := evm.GetEthAddress(senderKey) + recipientKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + recipientEthAddress := evm.GetEthAddress(recipientKey) + + ginkgo.By("sending funds from one address to another on the C-Chain", func() { + // Create transaction + acceptedNonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), senderEthAddress) + require.NoError(err) + gasPrice := e2e.SuggestGasPrice(ethClient) + tx := types.NewTransaction( + acceptedNonce, + recipientEthAddress, + big.NewInt(int64(txAmount)), + e2e.DefaultGasLimit, + gasPrice, + nil, + ) + + // Sign transaction + cChainID, err := ethClient.ChainID(e2e.DefaultContext()) + require.NoError(err) + signer := types.NewEIP155Signer(cChainID) + signedTx, err := types.SignTx(tx, signer, senderKey.ToECDSA()) + require.NoError(err) + + _ = e2e.SendEthTransaction(ethClient, signedTx) + + ginkgo.By("waiting for the C-Chain recipient address to have received the sent funds") + e2e.Eventually(func() bool { + balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) + require.NoError(err) + return balance.Cmp(big.NewInt(0)) > 0 + }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see funds delivered before timeout") + }) + + // Wallet must be initialized after sending funds on the + // C-Chain with the same node URI to ensure wallet state + // matches on-chain state. + ginkgo.By("initializing a keychain and associated wallet") + keychain := secp256k1fx.NewKeychain(senderKey, recipientKey) + baseWallet := e2e.NewWallet(keychain, nodeURI) + xWallet := baseWallet.X() + cWallet := baseWallet.C() + pWallet := baseWallet.P() + + ginkgo.By("defining common configuration") + avaxAssetID := xWallet.AVAXAssetID() + // Use the same owner for import funds to X-Chain and P-Chain + recipientOwner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + recipientKey.Address(), + }, + } + // Use the same outputs for both X-Chain and P-Chain exports + exportOutputs := []*secp256k1fx.TransferOutput{ + { + Amt: txAmount, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + keychain.Keys[0].Address(), + }, + }, + }, + } + + ginkgo.By("exporting AVAX from the C-Chain to the X-Chain", func() { + _, err := cWallet.IssueExportTx( + xWallet.BlockchainID(), + exportOutputs, + e2e.WithDefaultContext(), + e2e.WithSuggestedGasPrice(ethClient), + ) + require.NoError(err) + }) + + ginkgo.By("importing AVAX from the C-Chain to the X-Chain", func() { + _, err := xWallet.IssueImportTx( + cWallet.BlockchainID(), + &recipientOwner, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { + balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + ginkgo.By("exporting AVAX from the C-Chain to the P-Chain", func() { + _, err := cWallet.IssueExportTx( + constants.PlatformChainID, + exportOutputs, + e2e.WithDefaultContext(), + e2e.WithSuggestedGasPrice(ethClient), + ) + require.NoError(err) + }) + + ginkgo.By("importing AVAX from the C-Chain to the P-Chain", func() { + _, err = pWallet.IssueImportTx( + cWallet.BlockchainID(), + &recipientOwner, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { + balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) + }) +}) diff --git a/tests/e2e/p/interchain_workflow.go b/tests/e2e/p/interchain_workflow.go index b300ba4b2bd3..59e90198bed0 100644 --- a/tests/e2e/p/interchain_workflow.go +++ b/tests/e2e/p/interchain_workflow.go @@ -3,214 +3,214 @@ package p -// import ( -// "math/big" -// "time" - -// ginkgo "github.com/onsi/ginkgo/v2" - -// "github.com/spf13/cast" - -// "github.com/stretchr/testify/require" - -// "github.com/ava-labs/coreth/plugin/evm" - -// "github.com/ava-labs/avalanchego/api/info" -// "github.com/ava-labs/avalanchego/config" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/tests/e2e" -// "github.com/ava-labs/avalanchego/tests/fixture/testnet" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/platformvm/reward" -// "github.com/ava-labs/avalanchego/vms/platformvm/txs" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { -// require := require.New(ginkgo.GinkgoT()) - -// const ( -// transferAmount = 10 * units.Avax -// weight = 2_000 * units.Avax // Used for both validation and delegation -// ) - -// ginkgo.It("should ensure that funds can be transferred from the P-Chain to the X-Chain and the C-Chain", func() { -// network := e2e.Env.GetNetwork() - -// ginkgo.By("checking that the network has a compatible minimum stake duration", func() { -// minStakeDuration := cast.ToDuration(network.DefaultFlags[config.MinStakeDurationKey]) -// require.Equal(tmpnet.DefaultMinStakeDuration, minStakeDuration) -// }) - -// ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") -// recipientKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) -// keychain := e2e.Env.NewKeychain(1) -// keychain.Add(recipientKey) -// nodeURI := e2e.Env.GetRandomNodeURI() -// baseWallet := e2e.Env.NewWallet(keychain, nodeURI) -// xWallet := baseWallet.X() -// cWallet := baseWallet.C() -// pWallet := baseWallet.P() - -// ginkgo.By("defining common configuration") -// recipientEthAddress := evm.GetEthAddress(recipientKey) -// avaxAssetID := xWallet.AVAXAssetID() -// // Use the same owner for sending to X-Chain and importing funds to P-Chain -// recipientOwner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// recipientKey.Address(), -// }, -// } -// // Use the same outputs for both X-Chain and C-Chain exports -// exportOutputs := []*avax.TransferableOutput{ -// { -// Asset: avax.Asset{ -// ID: avaxAssetID, -// }, -// Out: &secp256k1fx.TransferOutput{ -// Amt: transferAmount, -// OutputOwners: secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// keychain.Keys[0].Address(), -// }, -// }, -// }, -// }, -// } - -// ginkgo.By("adding new node and waiting for it to report healthy") -// node := e2e.AddEphemeralNode(network, testnet.FlagsMap{}) -// e2e.WaitForHealthy(node) - -// ginkgo.By("retrieving new node's id and pop") -// infoClient := info.NewClient(node.URI) -// nodeID, nodePOP, err := infoClient.GetNodeID(e2e.DefaultContext()) -// require.NoError(err) - -// // Adding a validator should not break interchain transfer. -// endTime := time.Now().Add(30 * time.Second) -// ginkgo.By("adding the new node as a validator", func() { -// rewardKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) - -// const ( -// delegationPercent = 0.10 // 10% -// delegationShare = reward.PercentDenominator * delegationPercent -// ) - -// _, err = pWallet.IssueAddPermissionlessValidatorTx( -// &txs.SubnetValidator{ -// Validator: txs.Validator{ -// NodeID: nodeID, -// End: uint64(endTime.Unix()), -// Wght: weight, -// }, -// Subnet: constants.PrimaryNetworkID, -// }, -// nodePOP, -// pWallet.AVAXAssetID(), -// &secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{rewardKey.Address()}, -// }, -// &secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{rewardKey.Address()}, -// }, -// delegationShare, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// // Adding a delegator should not break interchain transfer. -// ginkgo.By("adding a delegator to the new node", func() { -// rewardKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) - -// _, err = pWallet.IssueAddPermissionlessDelegatorTx( -// &txs.SubnetValidator{ -// Validator: txs.Validator{ -// NodeID: nodeID, -// End: uint64(endTime.Unix()), -// Wght: weight, -// }, -// Subnet: constants.PrimaryNetworkID, -// }, -// pWallet.AVAXAssetID(), -// &secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{rewardKey.Address()}, -// }, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("exporting AVAX from the P-Chain to the X-Chain", func() { -// _, err := pWallet.IssueExportTx( -// xWallet.BlockchainID(), -// exportOutputs, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("importing AVAX from the P-Chain to the X-Chain", func() { -// _, err := xWallet.IssueImportTx( -// constants.PlatformChainID, -// &recipientOwner, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { -// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// ginkgo.By("exporting AVAX from the P-Chain to the C-Chain", func() { -// _, err := pWallet.IssueExportTx( -// cWallet.BlockchainID(), -// exportOutputs, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("initializing a new eth client") -// ethClient := e2e.NewEthClient(nodeURI) - -// ginkgo.By("importing AVAX from the P-Chain to the C-Chain", func() { -// _, err := cWallet.IssueImportTx( -// constants.PlatformChainID, -// recipientEthAddress, -// e2e.WithDefaultContext(), -// e2e.WithSuggestedGasPrice(ethClient), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") -// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) -// require.NoError(err) -// require.Positive(balance.Cmp(big.NewInt(0))) - -// ginkgo.By("stopping validator node to free up resources for a bootstrap check") -// require.NoError(node.Stop(e2e.DefaultContext())) - -// e2e.CheckBootstrapIsPossible(network) -// }) -// }) +import ( + "math/big" + "time" + + ginkgo "github.com/onsi/ginkgo/v2" + + "github.com/spf13/cast" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/coreth/plugin/evm" + + "github.com/ava-labs/avalanchego/api/info" + "github.com/ava-labs/avalanchego/config" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/platformvm/reward" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { + require := require.New(ginkgo.GinkgoT()) + + const ( + transferAmount = 10 * units.Avax + weight = 2_000 * units.Avax // Used for both validation and delegation + ) + + ginkgo.It("should ensure that funds can be transferred from the P-Chain to the X-Chain and the C-Chain", func() { + network := e2e.Env.GetNetwork() + + ginkgo.By("checking that the network has a compatible minimum stake duration", func() { + minStakeDuration := cast.ToDuration(network.DefaultFlags[config.MinStakeDurationKey]) + require.Equal(tmpnet.DefaultMinStakeDuration, minStakeDuration) + }) + + ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") + recipientKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + keychain := e2e.Env.NewKeychain(1) + keychain.Add(recipientKey) + nodeURI := e2e.Env.GetRandomNodeURI() + baseWallet := e2e.NewWallet(keychain, nodeURI) + xWallet := baseWallet.X() + cWallet := baseWallet.C() + pWallet := baseWallet.P() + + ginkgo.By("defining common configuration") + recipientEthAddress := evm.GetEthAddress(recipientKey) + avaxAssetID := xWallet.AVAXAssetID() + // Use the same owner for sending to X-Chain and importing funds to P-Chain + recipientOwner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + recipientKey.Address(), + }, + } + // Use the same outputs for both X-Chain and C-Chain exports + exportOutputs := []*avax.TransferableOutput{ + { + Asset: avax.Asset{ + ID: avaxAssetID, + }, + Out: &secp256k1fx.TransferOutput{ + Amt: transferAmount, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + keychain.Keys[0].Address(), + }, + }, + }, + }, + } + + ginkgo.By("adding new node and waiting for it to report healthy") + node := e2e.AddEphemeralNode(network, tmpnet.FlagsMap{}) + e2e.WaitForHealthy(node) + + ginkgo.By("retrieving new node's id and pop") + infoClient := info.NewClient(node.URI) + nodeID, nodePOP, err := infoClient.GetNodeID(e2e.DefaultContext()) + require.NoError(err) + + // Adding a validator should not break interchain transfer. + endTime := time.Now().Add(30 * time.Second) + ginkgo.By("adding the new node as a validator", func() { + rewardKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + + const ( + delegationPercent = 0.10 // 10% + delegationShare = reward.PercentDenominator * delegationPercent + ) + + _, err = pWallet.IssueAddPermissionlessValidatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + End: uint64(endTime.Unix()), + Wght: weight, + }, + Subnet: constants.PrimaryNetworkID, + }, + nodePOP, + pWallet.AVAXAssetID(), + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardKey.Address()}, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardKey.Address()}, + }, + delegationShare, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + // Adding a delegator should not break interchain transfer. + ginkgo.By("adding a delegator to the new node", func() { + rewardKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + + _, err = pWallet.IssueAddPermissionlessDelegatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + End: uint64(endTime.Unix()), + Wght: weight, + }, + Subnet: constants.PrimaryNetworkID, + }, + pWallet.AVAXAssetID(), + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardKey.Address()}, + }, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("exporting AVAX from the P-Chain to the X-Chain", func() { + _, err := pWallet.IssueExportTx( + xWallet.BlockchainID(), + exportOutputs, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("importing AVAX from the P-Chain to the X-Chain", func() { + _, err := xWallet.IssueImportTx( + constants.PlatformChainID, + &recipientOwner, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { + balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + ginkgo.By("exporting AVAX from the P-Chain to the C-Chain", func() { + _, err := pWallet.IssueExportTx( + cWallet.BlockchainID(), + exportOutputs, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("initializing a new eth client") + ethClient := e2e.NewEthClient(nodeURI) + + ginkgo.By("importing AVAX from the P-Chain to the C-Chain", func() { + _, err := cWallet.IssueImportTx( + constants.PlatformChainID, + recipientEthAddress, + e2e.WithDefaultContext(), + e2e.WithSuggestedGasPrice(ethClient), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") + balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) + require.NoError(err) + require.Positive(balance.Cmp(big.NewInt(0))) + + ginkgo.By("stopping validator node to free up resources for a bootstrap check") + require.NoError(node.Stop(e2e.DefaultContext())) + + e2e.CheckBootstrapIsPossible(network) + }) +}) diff --git a/tests/e2e/x/interchain_workflow.go b/tests/e2e/x/interchain_workflow.go index d738e55a7f7a..f0c2951feb84 100644 --- a/tests/e2e/x/interchain_workflow.go +++ b/tests/e2e/x/interchain_workflow.go @@ -3,151 +3,151 @@ package x -// import ( -// "math/big" - -// ginkgo "github.com/onsi/ginkgo/v2" - -// "github.com/stretchr/testify/require" - -// "github.com/ava-labs/coreth/plugin/evm" - -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/tests/e2e" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var _ = e2e.DescribeXChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { -// require := require.New(ginkgo.GinkgoT()) - -// const transferAmount = 10 * units.Avax - -// ginkgo.It("should ensure that funds can be transferred from the X-Chain to the C-Chain and the P-Chain", func() { -// nodeURI := e2e.Env.GetRandomNodeURI() - -// ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") -// recipientKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) -// keychain := e2e.Env.NewKeychain(1) -// keychain.Add(recipientKey) -// baseWallet := e2e.Env.NewWallet(keychain, nodeURI) -// xWallet := baseWallet.X() -// cWallet := baseWallet.C() -// pWallet := baseWallet.P() - -// ginkgo.By("defining common configuration") -// recipientEthAddress := evm.GetEthAddress(recipientKey) -// avaxAssetID := xWallet.AVAXAssetID() -// // Use the same owner for sending to X-Chain and importing funds to P-Chain -// recipientOwner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// recipientKey.Address(), -// }, -// } -// // Use the same outputs for both C-Chain and P-Chain exports -// exportOutputs := []*avax.TransferableOutput{ -// { -// Asset: avax.Asset{ -// ID: avaxAssetID, -// }, -// Out: &secp256k1fx.TransferOutput{ -// Amt: transferAmount, -// OutputOwners: secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// keychain.Keys[0].Address(), -// }, -// }, -// }, -// }, -// } - -// ginkgo.By("sending funds from one address to another on the X-Chain", func() { -// _, err = xWallet.IssueBaseTx( -// []*avax.TransferableOutput{{ -// Asset: avax.Asset{ -// ID: avaxAssetID, -// }, -// Out: &secp256k1fx.TransferOutput{ -// Amt: transferAmount, -// OutputOwners: recipientOwner, -// }, -// }}, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the X-Chain recipient address has received the sent funds", func() { -// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// ginkgo.By("exporting AVAX from the X-Chain to the C-Chain", func() { -// _, err := xWallet.IssueExportTx( -// cWallet.BlockchainID(), -// exportOutputs, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("initializing a new eth client") -// ethClient := e2e.NewEthClient(nodeURI) - -// ginkgo.By("importing AVAX from the X-Chain to the C-Chain", func() { -// _, err := cWallet.IssueImportTx( -// xWallet.BlockchainID(), -// recipientEthAddress, -// e2e.WithDefaultContext(), -// e2e.WithSuggestedGasPrice(ethClient), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") -// e2e.Eventually(func() bool { -// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) -// require.NoError(err) -// return balance.Cmp(big.NewInt(0)) > 0 -// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see recipient address funded before timeout") - -// ginkgo.By("exporting AVAX from the X-Chain to the P-Chain", func() { -// _, err := xWallet.IssueExportTx( -// constants.PlatformChainID, -// exportOutputs, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("importing AVAX from the X-Chain to the P-Chain", func() { -// _, err := pWallet.IssueImportTx( -// xWallet.BlockchainID(), -// &recipientOwner, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { -// balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) -// }) -// }) +import ( + "math/big" + + ginkgo "github.com/onsi/ginkgo/v2" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/coreth/plugin/evm" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var _ = e2e.DescribeXChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { + require := require.New(ginkgo.GinkgoT()) + + const transferAmount = 10 * units.Avax + + ginkgo.It("should ensure that funds can be transferred from the X-Chain to the C-Chain and the P-Chain", func() { + nodeURI := e2e.Env.GetRandomNodeURI() + + ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") + recipientKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + keychain := e2e.Env.NewKeychain(1) + keychain.Add(recipientKey) + baseWallet := e2e.NewWallet(keychain, nodeURI) + xWallet := baseWallet.X() + cWallet := baseWallet.C() + pWallet := baseWallet.P() + + ginkgo.By("defining common configuration") + recipientEthAddress := evm.GetEthAddress(recipientKey) + avaxAssetID := xWallet.AVAXAssetID() + // Use the same owner for sending to X-Chain and importing funds to P-Chain + recipientOwner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + recipientKey.Address(), + }, + } + // Use the same outputs for both C-Chain and P-Chain exports + exportOutputs := []*avax.TransferableOutput{ + { + Asset: avax.Asset{ + ID: avaxAssetID, + }, + Out: &secp256k1fx.TransferOutput{ + Amt: transferAmount, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + keychain.Keys[0].Address(), + }, + }, + }, + }, + } + + ginkgo.By("sending funds from one address to another on the X-Chain", func() { + _, err = xWallet.IssueBaseTx( + []*avax.TransferableOutput{{ + Asset: avax.Asset{ + ID: avaxAssetID, + }, + Out: &secp256k1fx.TransferOutput{ + Amt: transferAmount, + OutputOwners: recipientOwner, + }, + }}, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the X-Chain recipient address has received the sent funds", func() { + balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + ginkgo.By("exporting AVAX from the X-Chain to the C-Chain", func() { + _, err := xWallet.IssueExportTx( + cWallet.BlockchainID(), + exportOutputs, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("initializing a new eth client") + ethClient := e2e.NewEthClient(nodeURI) + + ginkgo.By("importing AVAX from the X-Chain to the C-Chain", func() { + _, err := cWallet.IssueImportTx( + xWallet.BlockchainID(), + recipientEthAddress, + e2e.WithDefaultContext(), + e2e.WithSuggestedGasPrice(ethClient), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") + e2e.Eventually(func() bool { + balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) + require.NoError(err) + return balance.Cmp(big.NewInt(0)) > 0 + }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see recipient address funded before timeout") + + ginkgo.By("exporting AVAX from the X-Chain to the P-Chain", func() { + _, err := xWallet.IssueExportTx( + constants.PlatformChainID, + exportOutputs, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("importing AVAX from the X-Chain to the P-Chain", func() { + _, err := pWallet.IssueImportTx( + xWallet.BlockchainID(), + &recipientOwner, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { + balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) + }) +}) diff --git a/tests/fixture/e2e/helpers.go b/tests/fixture/e2e/helpers.go index 224263818156..ddebfbc8b81c 100644 --- a/tests/fixture/e2e/helpers.go +++ b/tests/fixture/e2e/helpers.go @@ -5,23 +5,20 @@ package e2e import ( "context" - - // "errors" - // "fmt" - // "math/big" - + "errors" + "fmt" + "math/big" "os" - - // "strings" + "strings" "time" ginkgo "github.com/onsi/ginkgo/v2" "github.com/stretchr/testify/require" - // "github.com/ava-labs/coreth/core/types" - // "github.com/ava-labs/coreth/ethclient" - // "github.com/ava-labs/coreth/interfaces" + "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/coreth/ethclient" + "github.com/ava-labs/coreth/interfaces" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/tests" @@ -63,7 +60,7 @@ func NewWallet(keychain *secp256k1fx.Keychain, nodeURI tmpnet.NodeURI) primary.W baseWallet, err := primary.MakeWallet(DefaultContext(), &primary.WalletConfig{ URI: nodeURI.URI, AVAXKeychain: keychain, - // EthKeychain: keychain, + EthKeychain: keychain, }) require.NoError(ginkgo.GinkgoT(), err) return primary.NewWalletWithOptions( @@ -76,15 +73,15 @@ func NewWallet(keychain *secp256k1fx.Keychain, nodeURI tmpnet.NodeURI) primary.W ) } -// // Create a new eth client targeting the specified node URI. -// func NewEthClient(nodeURI testnet.NodeURI) ethclient.Client { -// tests.Outf("{{blue}} initializing a new eth client for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) -// nodeAddress := strings.Split(nodeURI.URI, "//")[1] -// uri := fmt.Sprintf("ws://%s/ext/bc/C/ws", nodeAddress) -// client, err := ethclient.Dial(uri) -// require.NoError(ginkgo.GinkgoT(), err) -// return client -// } +// Create a new eth client targeting the specified node URI. +func NewEthClient(nodeURI tmpnet.NodeURI) ethclient.Client { + tests.Outf("{{blue}} initializing a new eth client for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) + nodeAddress := strings.Split(nodeURI.URI, "//")[1] + uri := fmt.Sprintf("ws://%s/ext/bc/C/ws", nodeAddress) + client, err := ethclient.Dial(uri) + require.NoError(ginkgo.GinkgoT(), err) + return client +} // Helper simplifying use of a timed context by canceling the context on ginkgo teardown. func ContextWithTimeout(duration time.Duration) context.Context { @@ -147,49 +144,49 @@ func WaitForHealthy(node *tmpnet.Node) { require.NoError(ginkgo.GinkgoT(), tmpnet.WaitForHealthy(ctx, node)) } -// // Sends an eth transaction, waits for the transaction receipt to be issued -// // and checks that the receipt indicates success. -// func SendEthTransaction(ethClient ethclient.Client, signedTx *types.Transaction) *types.Receipt { -// require := require.New(ginkgo.GinkgoT()) - -// txID := signedTx.Hash() -// tests.Outf(" sending eth transaction with ID: %s\n", txID) - -// require.NoError(ethClient.SendTransaction(DefaultContext(), signedTx)) - -// // Wait for the receipt -// var receipt *types.Receipt -// Eventually(func() bool { -// var err error -// receipt, err = ethClient.TransactionReceipt(DefaultContext(), txID) -// if errors.Is(err, interfaces.NotFound) { -// return false // Transaction is still pending -// } -// require.NoError(err) -// return true -// }, DefaultTimeout, DefaultPollingInterval, "failed to see transaction acceptance before timeout") - -// require.Equal(receipt.Status, types.ReceiptStatusSuccessful) -// return receipt -// } - -// // Determines the suggested gas price for the configured client that will -// // maximize the chances of transaction acceptance. -// func SuggestGasPrice(ethClient ethclient.Client) *big.Int { -// gasPrice, err := ethClient.SuggestGasPrice(DefaultContext()) -// require.NoError(ginkgo.GinkgoT(), err) -// // Double the suggested gas price to maximize the chances of -// // acceptance. Maybe this can be revisited pending resolution of -// // https://github.com/ava-labs/coreth/issues/314. -// gasPrice.Add(gasPrice, gasPrice) -// return gasPrice -// } - -// // Helper simplifying use via an option of a gas price appropriate for testing. -// func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { -// baseFee := SuggestGasPrice(ethClient) -// return common.WithBaseFee(baseFee) -// } +// Sends an eth transaction, waits for the transaction receipt to be issued +// and checks that the receipt indicates success. +func SendEthTransaction(ethClient ethclient.Client, signedTx *types.Transaction) *types.Receipt { + require := require.New(ginkgo.GinkgoT()) + + txID := signedTx.Hash() + tests.Outf(" sending eth transaction with ID: %s\n", txID) + + require.NoError(ethClient.SendTransaction(DefaultContext(), signedTx)) + + // Wait for the receipt + var receipt *types.Receipt + Eventually(func() bool { + var err error + receipt, err = ethClient.TransactionReceipt(DefaultContext(), txID) + if errors.Is(err, interfaces.NotFound) { + return false // Transaction is still pending + } + require.NoError(err) + return true + }, DefaultTimeout, DefaultPollingInterval, "failed to see transaction acceptance before timeout") + + require.Equal(receipt.Status, types.ReceiptStatusSuccessful) + return receipt +} + +// Determines the suggested gas price for the configured client that will +// maximize the chances of transaction acceptance. +func SuggestGasPrice(ethClient ethclient.Client) *big.Int { + gasPrice, err := ethClient.SuggestGasPrice(DefaultContext()) + require.NoError(ginkgo.GinkgoT(), err) + // Double the suggested gas price to maximize the chances of + // acceptance. Maybe this can be revisited pending resolution of + // https://github.com/ava-labs/coreth/issues/314. + gasPrice.Add(gasPrice, gasPrice) + return gasPrice +} + +// Helper simplifying use via an option of a gas price appropriate for testing. +func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { + baseFee := SuggestGasPrice(ethClient) + return common.WithBaseFee(baseFee) +} // Verify that a new node can bootstrap into the network. func CheckBootstrapIsPossible(network *tmpnet.Network) { diff --git a/tests/fixture/tmpnet/genesis.go b/tests/fixture/tmpnet/genesis.go index db0462b3c0ce..5ee605702482 100644 --- a/tests/fixture/tmpnet/genesis.go +++ b/tests/fixture/tmpnet/genesis.go @@ -4,10 +4,16 @@ package tmpnet import ( + "encoding/json" "errors" "fmt" + "math/big" "time" + "github.com/ava-labs/coreth/core" + "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm" + "github.com/ava-labs/avalanchego/genesis" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/constants" @@ -21,12 +27,12 @@ const ( defaultGasLimit = uint64(100_000_000) // Gas limit is arbitrary // Arbitrarily large amount of AVAX to fund keys on the X-Chain for testing - // defaultFundedKeyXChainAmount = 30 * units.MegaAvax + defaultFundedKeyXChainAmount = 30 * units.MegaAvax ) var ( // Arbitrarily large amount of AVAX (10^12) to fund keys on the C-Chain for testing - // defaultFundedKeyCChainAmount = new(big.Int).Exp(big.NewInt(10), big.NewInt(30), nil) + defaultFundedKeyCChainAmount = new(big.Int).Exp(big.NewInt(10), big.NewInt(30), nil) errNoKeysForGenesis = errors.New("no keys to fund for genesis") errInvalidNetworkIDForGenesis = errors.New("network ID can't be mainnet, testnet or local network ID for genesis") @@ -107,13 +113,13 @@ func NewTestGenesis( // Ensure pre-funded keys have arbitrary large balances on both chains to support testing xChainBalances := make(XChainBalanceMap, len(keysToFund)) - // cChainBalances := make(core.GenesisAlloc, len(keysToFund)) - // for _, key := range keysToFund { - // xChainBalances[key.Address()] = defaultFundedKeyXChainAmount - // cChainBalances[evm.GetEthAddress(key)] = core.GenesisAccount{ - // Balance: defaultFundedKeyCChainAmount, - // } - // } + cChainBalances := make(core.GenesisAlloc, len(keysToFund)) + for _, key := range keysToFund { + xChainBalances[key.Address()] = defaultFundedKeyXChainAmount + cChainBalances[evm.GetEthAddress(key)] = core.GenesisAccount{ + Balance: defaultFundedKeyCChainAmount, + } + } // Set X-Chain balances for xChainAddress, balance := range xChainBalances { @@ -141,19 +147,19 @@ func NewTestGenesis( } // Define C-Chain genesis - // cChainGenesis := &core.Genesis{ - // Config: ¶ms.ChainConfig{ - // ChainID: big.NewInt(43112), // Arbitrary chain ID is arbitrary - // }, - // Difficulty: big.NewInt(0), // Difficulty is a mandatory field - // GasLimit: defaultGasLimit, - // Alloc: cChainBalances, - // } - // cChainGenesisBytes, err := json.Marshal(cChainGenesis) - // if err != nil { - // return nil, fmt.Errorf("failed to marshal C-Chain genesis: %w", err) - // } - // config.CChainGenesis = string(cChainGenesisBytes) + cChainGenesis := &core.Genesis{ + Config: ¶ms.ChainConfig{ + ChainID: big.NewInt(43112), // Arbitrary chain ID is arbitrary + }, + Difficulty: big.NewInt(0), // Difficulty is a mandatory field + GasLimit: defaultGasLimit, + Alloc: cChainBalances, + } + cChainGenesisBytes, err := json.Marshal(cChainGenesis) + if err != nil { + return nil, fmt.Errorf("failed to marshal C-Chain genesis: %w", err) + } + config.CChainGenesis = string(cChainGenesisBytes) return config, nil } diff --git a/vms/example/xsvm/cmd/chain/create/cmd.go b/vms/example/xsvm/cmd/chain/create/cmd.go index 043b4298dcdf..1f00491a4ce6 100644 --- a/vms/example/xsvm/cmd/chain/create/cmd.go +++ b/vms/example/xsvm/cmd/chain/create/cmd.go @@ -42,9 +42,9 @@ func createFunc(c *cobra.Command, args []string) error { // that [uri] is hosting. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: config.URI, - AVAXKeychain: kc, - // EthKeychain: kc, + URI: config.URI, + AVAXKeychain: kc, + EthKeychain: kc, PChainTxsToFetch: set.Of(config.SubnetID), }) if err != nil { diff --git a/wallet/chain/c/backend.go b/wallet/chain/c/backend.go index b88c8c643bc3..0a735116b646 100644 --- a/wallet/chain/c/backend.go +++ b/wallet/chain/c/backend.go @@ -3,153 +3,153 @@ package c -// import ( -// "errors" -// "fmt" -// "math/big" -// "sync" - -// stdcontext "context" - -// "github.com/ava-labs/coreth/plugin/evm" - -// ethcommon "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/avalanchego/database" -// "github.com/ava-labs/avalanchego/utils/math" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var ( -// _ Backend = (*backend)(nil) - -// errUnknownTxType = errors.New("unknown tx type") -// ) - -// // Backend defines the full interface required to support a C-chain wallet. -// type Backend interface { -// common.ChainUTXOs -// BuilderBackend -// SignerBackend - -// AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error -// } - -// type backend struct { -// Context -// common.ChainUTXOs - -// accountsLock sync.RWMutex -// accounts map[ethcommon.Address]*Account -// } - -// type Account struct { -// Balance *big.Int -// Nonce uint64 -// } - -// func NewBackend( -// ctx Context, -// utxos common.ChainUTXOs, -// accounts map[ethcommon.Address]*Account, -// ) Backend { -// return &backend{ -// Context: ctx, -// ChainUTXOs: utxos, -// accounts: accounts, -// } -// } - -// func (b *backend) AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error { -// switch tx := tx.UnsignedAtomicTx.(type) { -// case *evm.UnsignedImportTx: -// for _, input := range tx.ImportedInputs { -// utxoID := input.InputID() -// if err := b.RemoveUTXO(ctx, tx.SourceChain, utxoID); err != nil { -// return err -// } -// } - -// b.accountsLock.Lock() -// defer b.accountsLock.Unlock() - -// for _, output := range tx.Outs { -// account, ok := b.accounts[output.Address] -// if !ok { -// continue -// } - -// balance := new(big.Int).SetUint64(output.Amount) -// balance.Mul(balance, avaxConversionRate) -// account.Balance.Add(account.Balance, balance) -// } -// case *evm.UnsignedExportTx: -// txID := tx.ID() -// for i, out := range tx.ExportedOutputs { -// err := b.AddUTXO( -// ctx, -// tx.DestinationChain, -// &avax.UTXO{ -// UTXOID: avax.UTXOID{ -// TxID: txID, -// OutputIndex: uint32(i), -// }, -// Asset: avax.Asset{ID: out.AssetID()}, -// Out: out.Out, -// }, -// ) -// if err != nil { -// return err -// } -// } - -// b.accountsLock.Lock() -// defer b.accountsLock.Unlock() - -// for _, input := range tx.Ins { -// account, ok := b.accounts[input.Address] -// if !ok { -// continue -// } - -// balance := new(big.Int).SetUint64(input.Amount) -// balance.Mul(balance, avaxConversionRate) -// if account.Balance.Cmp(balance) == -1 { -// return errInsufficientFunds -// } -// account.Balance.Sub(account.Balance, balance) - -// newNonce, err := math.Add64(input.Nonce, 1) -// if err != nil { -// return err -// } -// account.Nonce = newNonce -// } -// default: -// return fmt.Errorf("%w: %T", errUnknownTxType, tx) -// } -// return nil -// } - -// func (b *backend) Balance(_ stdcontext.Context, addr ethcommon.Address) (*big.Int, error) { -// b.accountsLock.RLock() -// defer b.accountsLock.RUnlock() - -// account, exists := b.accounts[addr] -// if !exists { -// return nil, database.ErrNotFound -// } -// return account.Balance, nil -// } - -// func (b *backend) Nonce(_ stdcontext.Context, addr ethcommon.Address) (uint64, error) { -// b.accountsLock.RLock() -// defer b.accountsLock.RUnlock() - -// account, exists := b.accounts[addr] -// if !exists { -// return 0, database.ErrNotFound -// } -// return account.Nonce, nil -// } +import ( + "errors" + "fmt" + "math/big" + "sync" + + stdcontext "context" + + "github.com/ava-labs/coreth/plugin/evm" + + ethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/avalanchego/database" + "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var ( + _ Backend = (*backend)(nil) + + errUnknownTxType = errors.New("unknown tx type") +) + +// Backend defines the full interface required to support a C-chain wallet. +type Backend interface { + common.ChainUTXOs + BuilderBackend + SignerBackend + + AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error +} + +type backend struct { + Context + common.ChainUTXOs + + accountsLock sync.RWMutex + accounts map[ethcommon.Address]*Account +} + +type Account struct { + Balance *big.Int + Nonce uint64 +} + +func NewBackend( + ctx Context, + utxos common.ChainUTXOs, + accounts map[ethcommon.Address]*Account, +) Backend { + return &backend{ + Context: ctx, + ChainUTXOs: utxos, + accounts: accounts, + } +} + +func (b *backend) AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error { + switch tx := tx.UnsignedAtomicTx.(type) { + case *evm.UnsignedImportTx: + for _, input := range tx.ImportedInputs { + utxoID := input.InputID() + if err := b.RemoveUTXO(ctx, tx.SourceChain, utxoID); err != nil { + return err + } + } + + b.accountsLock.Lock() + defer b.accountsLock.Unlock() + + for _, output := range tx.Outs { + account, ok := b.accounts[output.Address] + if !ok { + continue + } + + balance := new(big.Int).SetUint64(output.Amount) + balance.Mul(balance, avaxConversionRate) + account.Balance.Add(account.Balance, balance) + } + case *evm.UnsignedExportTx: + txID := tx.ID() + for i, out := range tx.ExportedOutputs { + err := b.AddUTXO( + ctx, + tx.DestinationChain, + &avax.UTXO{ + UTXOID: avax.UTXOID{ + TxID: txID, + OutputIndex: uint32(i), + }, + Asset: avax.Asset{ID: out.AssetID()}, + Out: out.Out, + }, + ) + if err != nil { + return err + } + } + + b.accountsLock.Lock() + defer b.accountsLock.Unlock() + + for _, input := range tx.Ins { + account, ok := b.accounts[input.Address] + if !ok { + continue + } + + balance := new(big.Int).SetUint64(input.Amount) + balance.Mul(balance, avaxConversionRate) + if account.Balance.Cmp(balance) == -1 { + return errInsufficientFunds + } + account.Balance.Sub(account.Balance, balance) + + newNonce, err := math.Add64(input.Nonce, 1) + if err != nil { + return err + } + account.Nonce = newNonce + } + default: + return fmt.Errorf("%w: %T", errUnknownTxType, tx) + } + return nil +} + +func (b *backend) Balance(_ stdcontext.Context, addr ethcommon.Address) (*big.Int, error) { + b.accountsLock.RLock() + defer b.accountsLock.RUnlock() + + account, exists := b.accounts[addr] + if !exists { + return nil, database.ErrNotFound + } + return account.Balance, nil +} + +func (b *backend) Nonce(_ stdcontext.Context, addr ethcommon.Address) (uint64, error) { + b.accountsLock.RLock() + defer b.accountsLock.RUnlock() + + account, exists := b.accounts[addr] + if !exists { + return 0, database.ErrNotFound + } + return account.Nonce, nil +} diff --git a/wallet/chain/c/builder.go b/wallet/chain/c/builder.go index 0e95a91e4fe4..81fcf3aa896a 100644 --- a/wallet/chain/c/builder.go +++ b/wallet/chain/c/builder.go @@ -3,409 +3,409 @@ package c -// import ( -// "errors" -// "math/big" - -// stdcontext "context" - -// "github.com/ava-labs/coreth/plugin/evm" - -// ethcommon "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/utils" -// "github.com/ava-labs/avalanchego/utils/math" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// const avaxConversionRateInt = 1_000_000_000 - -// var ( -// _ Builder = (*builder)(nil) - -// errInsufficientFunds = errors.New("insufficient funds") - -// // avaxConversionRate is the conversion rate between the smallest -// // denomination on the X-Chain and P-chain, 1 nAVAX, and the smallest -// // denomination on the C-Chain 1 wei. Where 1 nAVAX = 1 gWei. -// // -// // This is only required for AVAX because the denomination of 1 AVAX is 9 -// // decimal places on the X and P chains, but is 18 decimal places within the -// // EVM. -// avaxConversionRate = big.NewInt(avaxConversionRateInt) -// ) - -// // Builder provides a convenient interface for building unsigned C-chain -// // transactions. -// type Builder interface { -// // GetBalance calculates the amount of AVAX that this builder has control -// // over. -// GetBalance( -// options ...common.Option, -// ) (*big.Int, error) - -// // GetImportableBalance calculates the amount of AVAX that this builder -// // could import from the provided chain. -// // -// // - [chainID] specifies the chain the funds are from. -// GetImportableBalance( -// chainID ids.ID, -// options ...common.Option, -// ) (uint64, error) - -// // NewImportTx creates an import transaction that attempts to consume all -// // the available UTXOs and import the funds to [to]. -// // -// // - [chainID] specifies the chain to be importing funds from. -// // - [to] specifies where to send the imported funds to. -// // - [baseFee] specifies the fee price willing to be paid by this tx. -// NewImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedImportTx, error) - -// // NewExportTx creates an export transaction that attempts to send all the -// // provided [outputs] to the requested [chainID]. -// // -// // - [chainID] specifies the chain to be exporting the funds to. -// // - [outputs] specifies the outputs to send to the [chainID]. -// // - [baseFee] specifies the fee price willing to be paid by this tx. -// NewExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedExportTx, error) -// } - -// // BuilderBackend specifies the required information needed to build unsigned -// // C-chain transactions. -// type BuilderBackend interface { -// Context - -// UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) -// Balance(ctx stdcontext.Context, addr ethcommon.Address) (*big.Int, error) -// Nonce(ctx stdcontext.Context, addr ethcommon.Address) (uint64, error) -// } - -// type builder struct { -// avaxAddrs set.Set[ids.ShortID] -// ethAddrs set.Set[ethcommon.Address] -// backend BuilderBackend -// } - -// // NewBuilder returns a new transaction builder. -// // -// // - [avaxAddrs] is the set of addresses in the AVAX format that the builder -// // assumes can be used when signing the transactions in the future. -// // - [ethAddrs] is the set of addresses in the Eth format that the builder -// // assumes can be used when signing the transactions in the future. -// // - [backend] provides the required access to the chain's context and state -// // to build out the transactions. -// func NewBuilder( -// avaxAddrs set.Set[ids.ShortID], -// ethAddrs set.Set[ethcommon.Address], -// backend BuilderBackend, -// ) Builder { -// return &builder{ -// avaxAddrs: avaxAddrs, -// ethAddrs: ethAddrs, -// backend: backend, -// } -// } - -// func (b *builder) GetBalance( -// options ...common.Option, -// ) (*big.Int, error) { -// var ( -// ops = common.NewOptions(options) -// ctx = ops.Context() -// addrs = ops.EthAddresses(b.ethAddrs) -// totalBalance = new(big.Int) -// ) -// for addr := range addrs { -// balance, err := b.backend.Balance(ctx, addr) -// if err != nil { -// return nil, err -// } -// totalBalance.Add(totalBalance, balance) -// } - -// return totalBalance, nil -// } - -// func (b *builder) GetImportableBalance( -// chainID ids.ID, -// options ...common.Option, -// ) (uint64, error) { -// ops := common.NewOptions(options) -// utxos, err := b.backend.UTXOs(ops.Context(), chainID) -// if err != nil { -// return 0, err -// } - -// var ( -// addrs = ops.Addresses(b.avaxAddrs) -// minIssuanceTime = ops.MinIssuanceTime() -// avaxAssetID = b.backend.AVAXAssetID() -// balance uint64 -// ) -// for _, utxo := range utxos { -// amount, _, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) -// if !ok { -// continue -// } - -// newBalance, err := math.Add64(balance, amount) -// if err != nil { -// return 0, err -// } -// balance = newBalance -// } - -// return balance, nil -// } - -// func (b *builder) NewImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedImportTx, error) { -// ops := common.NewOptions(options) -// utxos, err := b.backend.UTXOs(ops.Context(), chainID) -// if err != nil { -// return nil, err -// } - -// var ( -// addrs = ops.Addresses(b.avaxAddrs) -// minIssuanceTime = ops.MinIssuanceTime() -// avaxAssetID = b.backend.AVAXAssetID() - -// importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) -// importedAmount uint64 -// ) -// for _, utxo := range utxos { -// amount, inputSigIndices, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) -// if !ok { -// continue -// } - -// importedInputs = append(importedInputs, &avax.TransferableInput{ -// UTXOID: utxo.UTXOID, -// Asset: utxo.Asset, -// FxID: secp256k1fx.ID, -// In: &secp256k1fx.TransferInput{ -// Amt: amount, -// Input: secp256k1fx.Input{ -// SigIndices: inputSigIndices, -// }, -// }, -// }) - -// newImportedAmount, err := math.Add64(importedAmount, amount) -// if err != nil { -// return nil, err -// } -// importedAmount = newImportedAmount -// } - -// utils.Sort(importedInputs) -// tx := &evm.UnsignedImportTx{ -// NetworkID: b.backend.NetworkID(), -// BlockchainID: b.backend.BlockchainID(), -// SourceChain: chainID, -// ImportedInputs: importedInputs, -// } - -// // We must initialize the bytes of the tx to calculate the initial cost -// wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} -// if err := wrappedTx.Sign(evm.Codec, nil); err != nil { -// return nil, err -// } - -// gasUsedWithoutOutput, err := tx.GasUsed(true /*=IsApricotPhase5*/) -// if err != nil { -// return nil, err -// } -// gasUsedWithOutput := gasUsedWithoutOutput + evm.EVMOutputGas - -// txFee, err := evm.CalculateDynamicFee(gasUsedWithOutput, baseFee) -// if err != nil { -// return nil, err -// } - -// if importedAmount <= txFee { -// return nil, errInsufficientFunds -// } - -// tx.Outs = []evm.EVMOutput{{ -// Address: to, -// Amount: importedAmount - txFee, -// AssetID: avaxAssetID, -// }} -// return tx, nil -// } - -// func (b *builder) NewExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedExportTx, error) { -// var ( -// avaxAssetID = b.backend.AVAXAssetID() -// exportedOutputs = make([]*avax.TransferableOutput, len(outputs)) -// exportedAmount uint64 -// ) -// for i, output := range outputs { -// exportedOutputs[i] = &avax.TransferableOutput{ -// Asset: avax.Asset{ID: avaxAssetID}, -// FxID: secp256k1fx.ID, -// Out: output, -// } - -// newExportedAmount, err := math.Add64(exportedAmount, output.Amt) -// if err != nil { -// return nil, err -// } -// exportedAmount = newExportedAmount -// } - -// avax.SortTransferableOutputs(exportedOutputs, evm.Codec) -// tx := &evm.UnsignedExportTx{ -// NetworkID: b.backend.NetworkID(), -// BlockchainID: b.backend.BlockchainID(), -// DestinationChain: chainID, -// ExportedOutputs: exportedOutputs, -// } - -// // We must initialize the bytes of the tx to calculate the initial cost -// wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} -// if err := wrappedTx.Sign(evm.Codec, nil); err != nil { -// return nil, err -// } - -// cost, err := tx.GasUsed(true /*=IsApricotPhase5*/) -// if err != nil { -// return nil, err -// } - -// initialFee, err := evm.CalculateDynamicFee(cost, baseFee) -// if err != nil { -// return nil, err -// } - -// amountToConsume, err := math.Add64(exportedAmount, initialFee) -// if err != nil { -// return nil, err -// } - -// var ( -// ops = common.NewOptions(options) -// ctx = ops.Context() -// addrs = ops.EthAddresses(b.ethAddrs) -// inputs = make([]evm.EVMInput, 0, addrs.Len()) -// ) -// for addr := range addrs { -// if amountToConsume == 0 { -// break -// } - -// prevFee, err := evm.CalculateDynamicFee(cost, baseFee) -// if err != nil { -// return nil, err -// } - -// newCost := cost + evm.EVMInputGas -// newFee, err := evm.CalculateDynamicFee(newCost, baseFee) -// if err != nil { -// return nil, err -// } - -// additionalFee := newFee - prevFee - -// balance, err := b.backend.Balance(ctx, addr) -// if err != nil { -// return nil, err -// } - -// // Since the asset is AVAX, we divide by the avaxConversionRate to -// // convert back to the correct denomination of AVAX that can be -// // exported. -// avaxBalance := new(big.Int).Div(balance, avaxConversionRate).Uint64() - -// // If the balance for [addr] is insufficient to cover the additional -// // cost of adding an input to the transaction, skip adding the input -// // altogether. -// if avaxBalance <= additionalFee { -// continue -// } - -// // Update the cost for the next iteration -// cost = newCost - -// amountToConsume, err = math.Add64(amountToConsume, additionalFee) -// if err != nil { -// return nil, err -// } - -// nonce, err := b.backend.Nonce(ctx, addr) -// if err != nil { -// return nil, err -// } - -// inputAmount := math.Min(amountToConsume, avaxBalance) -// inputs = append(inputs, evm.EVMInput{ -// Address: addr, -// Amount: inputAmount, -// AssetID: avaxAssetID, -// Nonce: nonce, -// }) -// amountToConsume -= inputAmount -// } - -// if amountToConsume > 0 { -// return nil, errInsufficientFunds -// } - -// utils.Sort(inputs) -// tx.Ins = inputs - -// snowCtx, err := newSnowContext(b.backend) -// if err != nil { -// return nil, err -// } -// for _, out := range tx.ExportedOutputs { -// out.InitCtx(snowCtx) -// } -// return tx, nil -// } - -// func getSpendableAmount( -// utxo *avax.UTXO, -// addrs set.Set[ids.ShortID], -// minIssuanceTime uint64, -// avaxAssetID ids.ID, -// ) (uint64, []uint32, bool) { -// if utxo.Asset.ID != avaxAssetID { -// // Only AVAX can be imported -// return 0, nil, false -// } - -// out, ok := utxo.Out.(*secp256k1fx.TransferOutput) -// if !ok { -// // Can't import an unknown transfer output type -// return 0, nil, false -// } - -// inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) -// return out.Amt, inputSigIndices, ok -// } +import ( + "errors" + "math/big" + + stdcontext "context" + + "github.com/ava-labs/coreth/plugin/evm" + + ethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils" + "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +const avaxConversionRateInt = 1_000_000_000 + +var ( + _ Builder = (*builder)(nil) + + errInsufficientFunds = errors.New("insufficient funds") + + // avaxConversionRate is the conversion rate between the smallest + // denomination on the X-Chain and P-chain, 1 nAVAX, and the smallest + // denomination on the C-Chain 1 wei. Where 1 nAVAX = 1 gWei. + // + // This is only required for AVAX because the denomination of 1 AVAX is 9 + // decimal places on the X and P chains, but is 18 decimal places within the + // EVM. + avaxConversionRate = big.NewInt(avaxConversionRateInt) +) + +// Builder provides a convenient interface for building unsigned C-chain +// transactions. +type Builder interface { + // GetBalance calculates the amount of AVAX that this builder has control + // over. + GetBalance( + options ...common.Option, + ) (*big.Int, error) + + // GetImportableBalance calculates the amount of AVAX that this builder + // could import from the provided chain. + // + // - [chainID] specifies the chain the funds are from. + GetImportableBalance( + chainID ids.ID, + options ...common.Option, + ) (uint64, error) + + // NewImportTx creates an import transaction that attempts to consume all + // the available UTXOs and import the funds to [to]. + // + // - [chainID] specifies the chain to be importing funds from. + // - [to] specifies where to send the imported funds to. + // - [baseFee] specifies the fee price willing to be paid by this tx. + NewImportTx( + chainID ids.ID, + to ethcommon.Address, + baseFee *big.Int, + options ...common.Option, + ) (*evm.UnsignedImportTx, error) + + // NewExportTx creates an export transaction that attempts to send all the + // provided [outputs] to the requested [chainID]. + // + // - [chainID] specifies the chain to be exporting the funds to. + // - [outputs] specifies the outputs to send to the [chainID]. + // - [baseFee] specifies the fee price willing to be paid by this tx. + NewExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + baseFee *big.Int, + options ...common.Option, + ) (*evm.UnsignedExportTx, error) +} + +// BuilderBackend specifies the required information needed to build unsigned +// C-chain transactions. +type BuilderBackend interface { + Context + + UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) + Balance(ctx stdcontext.Context, addr ethcommon.Address) (*big.Int, error) + Nonce(ctx stdcontext.Context, addr ethcommon.Address) (uint64, error) +} + +type builder struct { + avaxAddrs set.Set[ids.ShortID] + ethAddrs set.Set[ethcommon.Address] + backend BuilderBackend +} + +// NewBuilder returns a new transaction builder. +// +// - [avaxAddrs] is the set of addresses in the AVAX format that the builder +// assumes can be used when signing the transactions in the future. +// - [ethAddrs] is the set of addresses in the Eth format that the builder +// assumes can be used when signing the transactions in the future. +// - [backend] provides the required access to the chain's context and state +// to build out the transactions. +func NewBuilder( + avaxAddrs set.Set[ids.ShortID], + ethAddrs set.Set[ethcommon.Address], + backend BuilderBackend, +) Builder { + return &builder{ + avaxAddrs: avaxAddrs, + ethAddrs: ethAddrs, + backend: backend, + } +} + +func (b *builder) GetBalance( + options ...common.Option, +) (*big.Int, error) { + var ( + ops = common.NewOptions(options) + ctx = ops.Context() + addrs = ops.EthAddresses(b.ethAddrs) + totalBalance = new(big.Int) + ) + for addr := range addrs { + balance, err := b.backend.Balance(ctx, addr) + if err != nil { + return nil, err + } + totalBalance.Add(totalBalance, balance) + } + + return totalBalance, nil +} + +func (b *builder) GetImportableBalance( + chainID ids.ID, + options ...common.Option, +) (uint64, error) { + ops := common.NewOptions(options) + utxos, err := b.backend.UTXOs(ops.Context(), chainID) + if err != nil { + return 0, err + } + + var ( + addrs = ops.Addresses(b.avaxAddrs) + minIssuanceTime = ops.MinIssuanceTime() + avaxAssetID = b.backend.AVAXAssetID() + balance uint64 + ) + for _, utxo := range utxos { + amount, _, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) + if !ok { + continue + } + + newBalance, err := math.Add64(balance, amount) + if err != nil { + return 0, err + } + balance = newBalance + } + + return balance, nil +} + +func (b *builder) NewImportTx( + chainID ids.ID, + to ethcommon.Address, + baseFee *big.Int, + options ...common.Option, +) (*evm.UnsignedImportTx, error) { + ops := common.NewOptions(options) + utxos, err := b.backend.UTXOs(ops.Context(), chainID) + if err != nil { + return nil, err + } + + var ( + addrs = ops.Addresses(b.avaxAddrs) + minIssuanceTime = ops.MinIssuanceTime() + avaxAssetID = b.backend.AVAXAssetID() + + importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) + importedAmount uint64 + ) + for _, utxo := range utxos { + amount, inputSigIndices, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) + if !ok { + continue + } + + importedInputs = append(importedInputs, &avax.TransferableInput{ + UTXOID: utxo.UTXOID, + Asset: utxo.Asset, + FxID: secp256k1fx.ID, + In: &secp256k1fx.TransferInput{ + Amt: amount, + Input: secp256k1fx.Input{ + SigIndices: inputSigIndices, + }, + }, + }) + + newImportedAmount, err := math.Add64(importedAmount, amount) + if err != nil { + return nil, err + } + importedAmount = newImportedAmount + } + + utils.Sort(importedInputs) + tx := &evm.UnsignedImportTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: b.backend.BlockchainID(), + SourceChain: chainID, + ImportedInputs: importedInputs, + } + + // We must initialize the bytes of the tx to calculate the initial cost + wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} + if err := wrappedTx.Sign(evm.Codec, nil); err != nil { + return nil, err + } + + gasUsedWithoutOutput, err := tx.GasUsed(true /*=IsApricotPhase5*/) + if err != nil { + return nil, err + } + gasUsedWithOutput := gasUsedWithoutOutput + evm.EVMOutputGas + + txFee, err := evm.CalculateDynamicFee(gasUsedWithOutput, baseFee) + if err != nil { + return nil, err + } + + if importedAmount <= txFee { + return nil, errInsufficientFunds + } + + tx.Outs = []evm.EVMOutput{{ + Address: to, + Amount: importedAmount - txFee, + AssetID: avaxAssetID, + }} + return tx, nil +} + +func (b *builder) NewExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + baseFee *big.Int, + options ...common.Option, +) (*evm.UnsignedExportTx, error) { + var ( + avaxAssetID = b.backend.AVAXAssetID() + exportedOutputs = make([]*avax.TransferableOutput, len(outputs)) + exportedAmount uint64 + ) + for i, output := range outputs { + exportedOutputs[i] = &avax.TransferableOutput{ + Asset: avax.Asset{ID: avaxAssetID}, + FxID: secp256k1fx.ID, + Out: output, + } + + newExportedAmount, err := math.Add64(exportedAmount, output.Amt) + if err != nil { + return nil, err + } + exportedAmount = newExportedAmount + } + + avax.SortTransferableOutputs(exportedOutputs, evm.Codec) + tx := &evm.UnsignedExportTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: b.backend.BlockchainID(), + DestinationChain: chainID, + ExportedOutputs: exportedOutputs, + } + + // We must initialize the bytes of the tx to calculate the initial cost + wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} + if err := wrappedTx.Sign(evm.Codec, nil); err != nil { + return nil, err + } + + cost, err := tx.GasUsed(true /*=IsApricotPhase5*/) + if err != nil { + return nil, err + } + + initialFee, err := evm.CalculateDynamicFee(cost, baseFee) + if err != nil { + return nil, err + } + + amountToConsume, err := math.Add64(exportedAmount, initialFee) + if err != nil { + return nil, err + } + + var ( + ops = common.NewOptions(options) + ctx = ops.Context() + addrs = ops.EthAddresses(b.ethAddrs) + inputs = make([]evm.EVMInput, 0, addrs.Len()) + ) + for addr := range addrs { + if amountToConsume == 0 { + break + } + + prevFee, err := evm.CalculateDynamicFee(cost, baseFee) + if err != nil { + return nil, err + } + + newCost := cost + evm.EVMInputGas + newFee, err := evm.CalculateDynamicFee(newCost, baseFee) + if err != nil { + return nil, err + } + + additionalFee := newFee - prevFee + + balance, err := b.backend.Balance(ctx, addr) + if err != nil { + return nil, err + } + + // Since the asset is AVAX, we divide by the avaxConversionRate to + // convert back to the correct denomination of AVAX that can be + // exported. + avaxBalance := new(big.Int).Div(balance, avaxConversionRate).Uint64() + + // If the balance for [addr] is insufficient to cover the additional + // cost of adding an input to the transaction, skip adding the input + // altogether. + if avaxBalance <= additionalFee { + continue + } + + // Update the cost for the next iteration + cost = newCost + + amountToConsume, err = math.Add64(amountToConsume, additionalFee) + if err != nil { + return nil, err + } + + nonce, err := b.backend.Nonce(ctx, addr) + if err != nil { + return nil, err + } + + inputAmount := math.Min(amountToConsume, avaxBalance) + inputs = append(inputs, evm.EVMInput{ + Address: addr, + Amount: inputAmount, + AssetID: avaxAssetID, + Nonce: nonce, + }) + amountToConsume -= inputAmount + } + + if amountToConsume > 0 { + return nil, errInsufficientFunds + } + + utils.Sort(inputs) + tx.Ins = inputs + + snowCtx, err := newSnowContext(b.backend) + if err != nil { + return nil, err + } + for _, out := range tx.ExportedOutputs { + out.InitCtx(snowCtx) + } + return tx, nil +} + +func getSpendableAmount( + utxo *avax.UTXO, + addrs set.Set[ids.ShortID], + minIssuanceTime uint64, + avaxAssetID ids.ID, +) (uint64, []uint32, bool) { + if utxo.Asset.ID != avaxAssetID { + // Only AVAX can be imported + return 0, nil, false + } + + out, ok := utxo.Out.(*secp256k1fx.TransferOutput) + if !ok { + // Can't import an unknown transfer output type + return 0, nil, false + } + + inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) + return out.Amt, inputSigIndices, ok +} diff --git a/wallet/chain/c/builder_with_options.go b/wallet/chain/c/builder_with_options.go index 9b7ab8399484..8416dddf9928 100644 --- a/wallet/chain/c/builder_with_options.go +++ b/wallet/chain/c/builder_with_options.go @@ -3,81 +3,81 @@ package c -// import ( -// "math/big" +import ( + "math/big" -// "github.com/ava-labs/coreth/plugin/evm" + "github.com/ava-labs/coreth/plugin/evm" -// ethcommon "github.com/ethereum/go-ethereum/common" + ethcommon "github.com/ethereum/go-ethereum/common" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) -// var _ Builder = (*builderWithOptions)(nil) +var _ Builder = (*builderWithOptions)(nil) -// type builderWithOptions struct { -// Builder -// options []common.Option -// } +type builderWithOptions struct { + Builder + options []common.Option +} -// // NewBuilderWithOptions returns a new transaction builder that will use the -// // given options by default. -// // -// // - [builder] is the builder that will be called to perform the underlying -// // operations. -// // - [options] will be provided to the builder in addition to the options -// // provided in the method calls. -// func NewBuilderWithOptions(builder Builder, options ...common.Option) Builder { -// return &builderWithOptions{ -// Builder: builder, -// options: options, -// } -// } +// NewBuilderWithOptions returns a new transaction builder that will use the +// given options by default. +// +// - [builder] is the builder that will be called to perform the underlying +// operations. +// - [options] will be provided to the builder in addition to the options +// provided in the method calls. +func NewBuilderWithOptions(builder Builder, options ...common.Option) Builder { + return &builderWithOptions{ + Builder: builder, + options: options, + } +} -// func (b *builderWithOptions) GetBalance( -// options ...common.Option, -// ) (*big.Int, error) { -// return b.Builder.GetBalance( -// common.UnionOptions(b.options, options)..., -// ) -// } +func (b *builderWithOptions) GetBalance( + options ...common.Option, +) (*big.Int, error) { + return b.Builder.GetBalance( + common.UnionOptions(b.options, options)..., + ) +} -// func (b *builderWithOptions) GetImportableBalance( -// chainID ids.ID, -// options ...common.Option, -// ) (uint64, error) { -// return b.Builder.GetImportableBalance( -// chainID, -// common.UnionOptions(b.options, options)..., -// ) -// } +func (b *builderWithOptions) GetImportableBalance( + chainID ids.ID, + options ...common.Option, +) (uint64, error) { + return b.Builder.GetImportableBalance( + chainID, + common.UnionOptions(b.options, options)..., + ) +} -// func (b *builderWithOptions) NewImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedImportTx, error) { -// return b.Builder.NewImportTx( -// chainID, -// to, -// baseFee, -// common.UnionOptions(b.options, options)..., -// ) -// } +func (b *builderWithOptions) NewImportTx( + chainID ids.ID, + to ethcommon.Address, + baseFee *big.Int, + options ...common.Option, +) (*evm.UnsignedImportTx, error) { + return b.Builder.NewImportTx( + chainID, + to, + baseFee, + common.UnionOptions(b.options, options)..., + ) +} -// func (b *builderWithOptions) NewExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedExportTx, error) { -// return b.Builder.NewExportTx( -// chainID, -// outputs, -// baseFee, -// common.UnionOptions(b.options, options)..., -// ) -// } +func (b *builderWithOptions) NewExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + baseFee *big.Int, + options ...common.Option, +) (*evm.UnsignedExportTx, error) { + return b.Builder.NewExportTx( + chainID, + outputs, + baseFee, + common.UnionOptions(b.options, options)..., + ) +} diff --git a/wallet/chain/c/context.go b/wallet/chain/c/context.go index c56a114a276e..b9cd41cb5667 100644 --- a/wallet/chain/c/context.go +++ b/wallet/chain/c/context.go @@ -3,100 +3,100 @@ package c -// import ( -// stdcontext "context" - -// "github.com/ava-labs/avalanchego/api/info" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/snow" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/logging" -// "github.com/ava-labs/avalanchego/vms/avm" -// ) - -// const Alias = "C" - -// var _ Context = (*context)(nil) - -// type Context interface { -// NetworkID() uint32 -// BlockchainID() ids.ID -// AVAXAssetID() ids.ID -// } - -// type context struct { -// networkID uint32 -// blockchainID ids.ID -// avaxAssetID ids.ID -// } - -// func NewContextFromURI(ctx stdcontext.Context, uri string) (Context, error) { -// infoClient := info.NewClient(uri) -// xChainClient := avm.NewClient(uri, "X") -// return NewContextFromClients(ctx, infoClient, xChainClient) -// } - -// func NewContextFromClients( -// ctx stdcontext.Context, -// infoClient info.Client, -// xChainClient avm.Client, -// ) (Context, error) { -// networkID, err := infoClient.GetNetworkID(ctx) -// if err != nil { -// return nil, err -// } - -// chainID, err := infoClient.GetBlockchainID(ctx, Alias) -// if err != nil { -// return nil, err -// } - -// asset, err := xChainClient.GetAssetDescription(ctx, "AVAX") -// if err != nil { -// return nil, err -// } - -// return NewContext( -// networkID, -// chainID, -// asset.AssetID, -// ), nil -// } - -// func NewContext( -// networkID uint32, -// blockchainID ids.ID, -// avaxAssetID ids.ID, -// ) Context { -// return &context{ -// networkID: networkID, -// blockchainID: blockchainID, -// avaxAssetID: avaxAssetID, -// } -// } - -// func (c *context) NetworkID() uint32 { -// return c.networkID -// } - -// func (c *context) BlockchainID() ids.ID { -// return c.blockchainID -// } - -// func (c *context) AVAXAssetID() ids.ID { -// return c.avaxAssetID -// } - -// func newSnowContext(c Context) (*snow.Context, error) { -// chainID := c.BlockchainID() -// lookup := ids.NewAliaser() -// return &snow.Context{ -// NetworkID: c.NetworkID(), -// SubnetID: constants.PrimaryNetworkID, -// ChainID: chainID, -// CChainID: chainID, -// AVAXAssetID: c.AVAXAssetID(), -// Log: logging.NoLog{}, -// BCLookup: lookup, -// }, lookup.Alias(chainID, Alias) -// } +import ( + stdcontext "context" + + "github.com/ava-labs/avalanchego/api/info" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/vms/avm" +) + +const Alias = "C" + +var _ Context = (*context)(nil) + +type Context interface { + NetworkID() uint32 + BlockchainID() ids.ID + AVAXAssetID() ids.ID +} + +type context struct { + networkID uint32 + blockchainID ids.ID + avaxAssetID ids.ID +} + +func NewContextFromURI(ctx stdcontext.Context, uri string) (Context, error) { + infoClient := info.NewClient(uri) + xChainClient := avm.NewClient(uri, "X") + return NewContextFromClients(ctx, infoClient, xChainClient) +} + +func NewContextFromClients( + ctx stdcontext.Context, + infoClient info.Client, + xChainClient avm.Client, +) (Context, error) { + networkID, err := infoClient.GetNetworkID(ctx) + if err != nil { + return nil, err + } + + chainID, err := infoClient.GetBlockchainID(ctx, Alias) + if err != nil { + return nil, err + } + + asset, err := xChainClient.GetAssetDescription(ctx, "AVAX") + if err != nil { + return nil, err + } + + return NewContext( + networkID, + chainID, + asset.AssetID, + ), nil +} + +func NewContext( + networkID uint32, + blockchainID ids.ID, + avaxAssetID ids.ID, +) Context { + return &context{ + networkID: networkID, + blockchainID: blockchainID, + avaxAssetID: avaxAssetID, + } +} + +func (c *context) NetworkID() uint32 { + return c.networkID +} + +func (c *context) BlockchainID() ids.ID { + return c.blockchainID +} + +func (c *context) AVAXAssetID() ids.ID { + return c.avaxAssetID +} + +func newSnowContext(c Context) (*snow.Context, error) { + chainID := c.BlockchainID() + lookup := ids.NewAliaser() + return &snow.Context{ + NetworkID: c.NetworkID(), + SubnetID: constants.PrimaryNetworkID, + ChainID: chainID, + CChainID: chainID, + AVAXAssetID: c.AVAXAssetID(), + Log: logging.NoLog{}, + BCLookup: lookup, + }, lookup.Alias(chainID, Alias) +} diff --git a/wallet/chain/c/signer.go b/wallet/chain/c/signer.go index 4bedc378234b..4fd85ed3b532 100644 --- a/wallet/chain/c/signer.go +++ b/wallet/chain/c/signer.go @@ -3,221 +3,221 @@ package c -// import ( -// "errors" -// "fmt" - -// stdcontext "context" - -// "github.com/ava-labs/coreth/plugin/evm" - -// ethcommon "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/avalanchego/database" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/utils/crypto/keychain" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// "github.com/ava-labs/avalanchego/utils/hashing" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/components/verify" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// ) - -// const version = 0 - -// var ( -// _ Signer = (*txSigner)(nil) - -// errUnknownInputType = errors.New("unknown input type") -// errUnknownCredentialType = errors.New("unknown credential type") -// errUnknownOutputType = errors.New("unknown output type") -// errInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") - -// emptySig [secp256k1.SignatureLen]byte -// ) - -// type Signer interface { -// SignUnsignedAtomic(ctx stdcontext.Context, tx evm.UnsignedAtomicTx) (*evm.Tx, error) -// SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error -// } - -// type EthKeychain interface { -// // The returned Signer can provide a signature for [addr] -// GetEth(addr ethcommon.Address) (keychain.Signer, bool) -// // Returns the set of addresses for which the accessor keeps an associated -// // signer -// EthAddresses() set.Set[ethcommon.Address] -// } - -// type SignerBackend interface { -// GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) -// } - -// type txSigner struct { -// avaxKC keychain.Keychain -// ethKC EthKeychain -// backend SignerBackend -// } - -// func NewSigner(avaxKC keychain.Keychain, ethKC EthKeychain, backend SignerBackend) Signer { -// return &txSigner{ -// avaxKC: avaxKC, -// ethKC: ethKC, -// backend: backend, -// } -// } - -// func (s *txSigner) SignUnsignedAtomic(ctx stdcontext.Context, utx evm.UnsignedAtomicTx) (*evm.Tx, error) { -// tx := &evm.Tx{UnsignedAtomicTx: utx} -// return tx, s.SignAtomic(ctx, tx) -// } - -// func (s *txSigner) SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error { -// switch utx := tx.UnsignedAtomicTx.(type) { -// case *evm.UnsignedImportTx: -// signers, err := s.getImportSigners(ctx, utx.SourceChain, utx.ImportedInputs) -// if err != nil { -// return err -// } -// return sign(tx, true, signers) -// case *evm.UnsignedExportTx: -// signers := s.getExportSigners(utx.Ins) -// return sign(tx, true, signers) -// default: -// return fmt.Errorf("%w: %T", errUnknownTxType, tx) -// } -// } - -// func (s *txSigner) getImportSigners(ctx stdcontext.Context, sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { -// txSigners := make([][]keychain.Signer, len(ins)) -// for credIndex, transferInput := range ins { -// input, ok := transferInput.In.(*secp256k1fx.TransferInput) -// if !ok { -// return nil, errUnknownInputType -// } - -// inputSigners := make([]keychain.Signer, len(input.SigIndices)) -// txSigners[credIndex] = inputSigners - -// utxoID := transferInput.InputID() -// utxo, err := s.backend.GetUTXO(ctx, sourceChainID, utxoID) -// if err == database.ErrNotFound { -// // If we don't have access to the UTXO, then we can't sign this -// // transaction. However, we can attempt to partially sign it. -// continue -// } -// if err != nil { -// return nil, err -// } - -// out, ok := utxo.Out.(*secp256k1fx.TransferOutput) -// if !ok { -// return nil, errUnknownOutputType -// } - -// for sigIndex, addrIndex := range input.SigIndices { -// if addrIndex >= uint32(len(out.Addrs)) { -// return nil, errInvalidUTXOSigIndex -// } - -// addr := out.Addrs[addrIndex] -// key, ok := s.avaxKC.Get(addr) -// if !ok { -// // If we don't have access to the key, then we can't sign this -// // transaction. However, we can attempt to partially sign it. -// continue -// } -// inputSigners[sigIndex] = key -// } -// } -// return txSigners, nil -// } - -// func (s *txSigner) getExportSigners(ins []evm.EVMInput) [][]keychain.Signer { -// txSigners := make([][]keychain.Signer, len(ins)) -// for credIndex, input := range ins { -// inputSigners := make([]keychain.Signer, 1) -// txSigners[credIndex] = inputSigners - -// key, ok := s.ethKC.GetEth(input.Address) -// if !ok { -// // If we don't have access to the key, then we can't sign this -// // transaction. However, we can attempt to partially sign it. -// continue -// } -// inputSigners[0] = key -// } -// return txSigners -// } - -// // TODO: remove [signHash] after the ledger supports signing all transactions. -// func sign(tx *evm.Tx, signHash bool, txSigners [][]keychain.Signer) error { -// unsignedBytes, err := evm.Codec.Marshal(version, &tx.UnsignedAtomicTx) -// if err != nil { -// return fmt.Errorf("couldn't marshal unsigned tx: %w", err) -// } -// unsignedHash := hashing.ComputeHash256(unsignedBytes) - -// if expectedLen := len(txSigners); expectedLen != len(tx.Creds) { -// tx.Creds = make([]verify.Verifiable, expectedLen) -// } - -// sigCache := make(map[ids.ShortID][secp256k1.SignatureLen]byte) -// for credIndex, inputSigners := range txSigners { -// credIntf := tx.Creds[credIndex] -// if credIntf == nil { -// credIntf = &secp256k1fx.Credential{} -// tx.Creds[credIndex] = credIntf -// } - -// cred, ok := credIntf.(*secp256k1fx.Credential) -// if !ok { -// return errUnknownCredentialType -// } -// if expectedLen := len(inputSigners); expectedLen != len(cred.Sigs) { -// cred.Sigs = make([][secp256k1.SignatureLen]byte, expectedLen) -// } - -// for sigIndex, signer := range inputSigners { -// if signer == nil { -// // If we don't have access to the key, then we can't sign this -// // transaction. However, we can attempt to partially sign it. -// continue -// } -// addr := signer.Address() -// if sig := cred.Sigs[sigIndex]; sig != emptySig { -// // If this signature has already been populated, we can just -// // copy the needed signature for the future. -// sigCache[addr] = sig -// continue -// } - -// if sig, exists := sigCache[addr]; exists { -// // If this key has already produced a signature, we can just -// // copy the previous signature. -// cred.Sigs[sigIndex] = sig -// continue -// } - -// var sig []byte -// if signHash { -// sig, err = signer.SignHash(unsignedHash) -// } else { -// sig, err = signer.Sign(unsignedBytes) -// } -// if err != nil { -// return fmt.Errorf("problem signing tx: %w", err) -// } -// copy(cred.Sigs[sigIndex][:], sig) -// sigCache[addr] = cred.Sigs[sigIndex] -// } -// } - -// signedBytes, err := evm.Codec.Marshal(version, tx) -// if err != nil { -// return fmt.Errorf("couldn't marshal tx: %w", err) -// } -// tx.Initialize(unsignedBytes, signedBytes) -// return nil -// } +import ( + "errors" + "fmt" + + stdcontext "context" + + "github.com/ava-labs/coreth/plugin/evm" + + ethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/avalanchego/database" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/crypto/keychain" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/hashing" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/components/verify" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" +) + +const version = 0 + +var ( + _ Signer = (*txSigner)(nil) + + errUnknownInputType = errors.New("unknown input type") + errUnknownCredentialType = errors.New("unknown credential type") + errUnknownOutputType = errors.New("unknown output type") + errInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") + + emptySig [secp256k1.SignatureLen]byte +) + +type Signer interface { + SignUnsignedAtomic(ctx stdcontext.Context, tx evm.UnsignedAtomicTx) (*evm.Tx, error) + SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error +} + +type EthKeychain interface { + // The returned Signer can provide a signature for [addr] + GetEth(addr ethcommon.Address) (keychain.Signer, bool) + // Returns the set of addresses for which the accessor keeps an associated + // signer + EthAddresses() set.Set[ethcommon.Address] +} + +type SignerBackend interface { + GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) +} + +type txSigner struct { + avaxKC keychain.Keychain + ethKC EthKeychain + backend SignerBackend +} + +func NewSigner(avaxKC keychain.Keychain, ethKC EthKeychain, backend SignerBackend) Signer { + return &txSigner{ + avaxKC: avaxKC, + ethKC: ethKC, + backend: backend, + } +} + +func (s *txSigner) SignUnsignedAtomic(ctx stdcontext.Context, utx evm.UnsignedAtomicTx) (*evm.Tx, error) { + tx := &evm.Tx{UnsignedAtomicTx: utx} + return tx, s.SignAtomic(ctx, tx) +} + +func (s *txSigner) SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error { + switch utx := tx.UnsignedAtomicTx.(type) { + case *evm.UnsignedImportTx: + signers, err := s.getImportSigners(ctx, utx.SourceChain, utx.ImportedInputs) + if err != nil { + return err + } + return sign(tx, true, signers) + case *evm.UnsignedExportTx: + signers := s.getExportSigners(utx.Ins) + return sign(tx, true, signers) + default: + return fmt.Errorf("%w: %T", errUnknownTxType, tx) + } +} + +func (s *txSigner) getImportSigners(ctx stdcontext.Context, sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { + txSigners := make([][]keychain.Signer, len(ins)) + for credIndex, transferInput := range ins { + input, ok := transferInput.In.(*secp256k1fx.TransferInput) + if !ok { + return nil, errUnknownInputType + } + + inputSigners := make([]keychain.Signer, len(input.SigIndices)) + txSigners[credIndex] = inputSigners + + utxoID := transferInput.InputID() + utxo, err := s.backend.GetUTXO(ctx, sourceChainID, utxoID) + if err == database.ErrNotFound { + // If we don't have access to the UTXO, then we can't sign this + // transaction. However, we can attempt to partially sign it. + continue + } + if err != nil { + return nil, err + } + + out, ok := utxo.Out.(*secp256k1fx.TransferOutput) + if !ok { + return nil, errUnknownOutputType + } + + for sigIndex, addrIndex := range input.SigIndices { + if addrIndex >= uint32(len(out.Addrs)) { + return nil, errInvalidUTXOSigIndex + } + + addr := out.Addrs[addrIndex] + key, ok := s.avaxKC.Get(addr) + if !ok { + // If we don't have access to the key, then we can't sign this + // transaction. However, we can attempt to partially sign it. + continue + } + inputSigners[sigIndex] = key + } + } + return txSigners, nil +} + +func (s *txSigner) getExportSigners(ins []evm.EVMInput) [][]keychain.Signer { + txSigners := make([][]keychain.Signer, len(ins)) + for credIndex, input := range ins { + inputSigners := make([]keychain.Signer, 1) + txSigners[credIndex] = inputSigners + + key, ok := s.ethKC.GetEth(input.Address) + if !ok { + // If we don't have access to the key, then we can't sign this + // transaction. However, we can attempt to partially sign it. + continue + } + inputSigners[0] = key + } + return txSigners +} + +// TODO: remove [signHash] after the ledger supports signing all transactions. +func sign(tx *evm.Tx, signHash bool, txSigners [][]keychain.Signer) error { + unsignedBytes, err := evm.Codec.Marshal(version, &tx.UnsignedAtomicTx) + if err != nil { + return fmt.Errorf("couldn't marshal unsigned tx: %w", err) + } + unsignedHash := hashing.ComputeHash256(unsignedBytes) + + if expectedLen := len(txSigners); expectedLen != len(tx.Creds) { + tx.Creds = make([]verify.Verifiable, expectedLen) + } + + sigCache := make(map[ids.ShortID][secp256k1.SignatureLen]byte) + for credIndex, inputSigners := range txSigners { + credIntf := tx.Creds[credIndex] + if credIntf == nil { + credIntf = &secp256k1fx.Credential{} + tx.Creds[credIndex] = credIntf + } + + cred, ok := credIntf.(*secp256k1fx.Credential) + if !ok { + return errUnknownCredentialType + } + if expectedLen := len(inputSigners); expectedLen != len(cred.Sigs) { + cred.Sigs = make([][secp256k1.SignatureLen]byte, expectedLen) + } + + for sigIndex, signer := range inputSigners { + if signer == nil { + // If we don't have access to the key, then we can't sign this + // transaction. However, we can attempt to partially sign it. + continue + } + addr := signer.Address() + if sig := cred.Sigs[sigIndex]; sig != emptySig { + // If this signature has already been populated, we can just + // copy the needed signature for the future. + sigCache[addr] = sig + continue + } + + if sig, exists := sigCache[addr]; exists { + // If this key has already produced a signature, we can just + // copy the previous signature. + cred.Sigs[sigIndex] = sig + continue + } + + var sig []byte + if signHash { + sig, err = signer.SignHash(unsignedHash) + } else { + sig, err = signer.Sign(unsignedBytes) + } + if err != nil { + return fmt.Errorf("problem signing tx: %w", err) + } + copy(cred.Sigs[sigIndex][:], sig) + sigCache[addr] = cred.Sigs[sigIndex] + } + } + + signedBytes, err := evm.Codec.Marshal(version, tx) + if err != nil { + return fmt.Errorf("couldn't marshal tx: %w", err) + } + tx.Initialize(unsignedBytes, signedBytes) + return nil +} diff --git a/wallet/chain/c/wallet.go b/wallet/chain/c/wallet.go index ebee50a9a958..fb1a83d53dad 100644 --- a/wallet/chain/c/wallet.go +++ b/wallet/chain/c/wallet.go @@ -3,204 +3,204 @@ package c -// import ( -// "errors" -// "math/big" -// "time" - -// "github.com/ava-labs/coreth/ethclient" -// "github.com/ava-labs/coreth/plugin/evm" - -// ethcommon "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var ( -// _ Wallet = (*wallet)(nil) - -// errNotCommitted = errors.New("not committed") -// ) - -// type Wallet interface { -// Context - -// // Builder returns the builder that will be used to create the transactions. -// Builder() Builder - -// // Signer returns the signer that will be used to sign the transactions. -// Signer() Signer - -// // IssueImportTx creates, signs, and issues an import transaction that -// // attempts to consume all the available UTXOs and import the funds to [to]. -// // -// // - [chainID] specifies the chain to be importing funds from. -// // - [to] specifies where to send the imported funds to. -// IssueImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// options ...common.Option, -// ) (*evm.Tx, error) - -// // IssueExportTx creates, signs, and issues an export transaction that -// // attempts to send all the provided [outputs] to the requested [chainID]. -// // -// // - [chainID] specifies the chain to be exporting the funds to. -// // - [outputs] specifies the outputs to send to the [chainID]. -// IssueExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// options ...common.Option, -// ) (*evm.Tx, error) - -// // IssueUnsignedTx signs and issues the unsigned tx. -// IssueUnsignedAtomicTx( -// utx evm.UnsignedAtomicTx, -// options ...common.Option, -// ) (*evm.Tx, error) - -// // IssueAtomicTx issues the signed tx. -// IssueAtomicTx( -// tx *evm.Tx, -// options ...common.Option, -// ) error -// } - -// func NewWallet( -// builder Builder, -// signer Signer, -// avaxClient evm.Client, -// ethClient ethclient.Client, -// backend Backend, -// ) Wallet { -// return &wallet{ -// Backend: backend, -// builder: builder, -// signer: signer, -// avaxClient: avaxClient, -// ethClient: ethClient, -// } -// } - -// type wallet struct { -// Backend -// builder Builder -// signer Signer -// avaxClient evm.Client -// ethClient ethclient.Client -// } - -// func (w *wallet) Builder() Builder { -// return w.builder -// } - -// func (w *wallet) Signer() Signer { -// return w.signer -// } - -// func (w *wallet) IssueImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// options ...common.Option, -// ) (*evm.Tx, error) { -// baseFee, err := w.baseFee(options) -// if err != nil { -// return nil, err -// } - -// utx, err := w.builder.NewImportTx(chainID, to, baseFee, options...) -// if err != nil { -// return nil, err -// } -// return w.IssueUnsignedAtomicTx(utx, options...) -// } - -// func (w *wallet) IssueExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// options ...common.Option, -// ) (*evm.Tx, error) { -// baseFee, err := w.baseFee(options) -// if err != nil { -// return nil, err -// } - -// utx, err := w.builder.NewExportTx(chainID, outputs, baseFee, options...) -// if err != nil { -// return nil, err -// } -// return w.IssueUnsignedAtomicTx(utx, options...) -// } - -// func (w *wallet) IssueUnsignedAtomicTx( -// utx evm.UnsignedAtomicTx, -// options ...common.Option, -// ) (*evm.Tx, error) { -// ops := common.NewOptions(options) -// ctx := ops.Context() -// tx, err := w.signer.SignUnsignedAtomic(ctx, utx) -// if err != nil { -// return nil, err -// } - -// return tx, w.IssueAtomicTx(tx, options...) -// } - -// func (w *wallet) IssueAtomicTx( -// tx *evm.Tx, -// options ...common.Option, -// ) error { -// ops := common.NewOptions(options) -// ctx := ops.Context() -// txID, err := w.avaxClient.IssueTx(ctx, tx.SignedBytes()) -// if err != nil { -// return err -// } - -// if f := ops.PostIssuanceFunc(); f != nil { -// f(txID) -// } - -// if ops.AssumeDecided() { -// return w.Backend.AcceptAtomicTx(ctx, tx) -// } - -// pollFrequency := ops.PollFrequency() -// ticker := time.NewTicker(pollFrequency) -// defer ticker.Stop() - -// for { -// status, err := w.avaxClient.GetAtomicTxStatus(ctx, txID) -// if err != nil { -// return err -// } - -// switch status { -// case evm.Accepted: -// return w.Backend.AcceptAtomicTx(ctx, tx) -// case evm.Dropped, evm.Unknown: -// return errNotCommitted -// } - -// // The tx is Processing. - -// select { -// case <-ticker.C: -// case <-ctx.Done(): -// return ctx.Err() -// } -// } -// } - -// func (w *wallet) baseFee(options []common.Option) (*big.Int, error) { -// ops := common.NewOptions(options) -// baseFee := ops.BaseFee(nil) -// if baseFee != nil { -// return baseFee, nil -// } - -// ctx := ops.Context() -// return w.ethClient.EstimateBaseFee(ctx) -// } +import ( + "errors" + "math/big" + "time" + + "github.com/ava-labs/coreth/ethclient" + "github.com/ava-labs/coreth/plugin/evm" + + ethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var ( + _ Wallet = (*wallet)(nil) + + errNotCommitted = errors.New("not committed") +) + +type Wallet interface { + Context + + // Builder returns the builder that will be used to create the transactions. + Builder() Builder + + // Signer returns the signer that will be used to sign the transactions. + Signer() Signer + + // IssueImportTx creates, signs, and issues an import transaction that + // attempts to consume all the available UTXOs and import the funds to [to]. + // + // - [chainID] specifies the chain to be importing funds from. + // - [to] specifies where to send the imported funds to. + IssueImportTx( + chainID ids.ID, + to ethcommon.Address, + options ...common.Option, + ) (*evm.Tx, error) + + // IssueExportTx creates, signs, and issues an export transaction that + // attempts to send all the provided [outputs] to the requested [chainID]. + // + // - [chainID] specifies the chain to be exporting the funds to. + // - [outputs] specifies the outputs to send to the [chainID]. + IssueExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + options ...common.Option, + ) (*evm.Tx, error) + + // IssueUnsignedTx signs and issues the unsigned tx. + IssueUnsignedAtomicTx( + utx evm.UnsignedAtomicTx, + options ...common.Option, + ) (*evm.Tx, error) + + // IssueAtomicTx issues the signed tx. + IssueAtomicTx( + tx *evm.Tx, + options ...common.Option, + ) error +} + +func NewWallet( + builder Builder, + signer Signer, + avaxClient evm.Client, + ethClient ethclient.Client, + backend Backend, +) Wallet { + return &wallet{ + Backend: backend, + builder: builder, + signer: signer, + avaxClient: avaxClient, + ethClient: ethClient, + } +} + +type wallet struct { + Backend + builder Builder + signer Signer + avaxClient evm.Client + ethClient ethclient.Client +} + +func (w *wallet) Builder() Builder { + return w.builder +} + +func (w *wallet) Signer() Signer { + return w.signer +} + +func (w *wallet) IssueImportTx( + chainID ids.ID, + to ethcommon.Address, + options ...common.Option, +) (*evm.Tx, error) { + baseFee, err := w.baseFee(options) + if err != nil { + return nil, err + } + + utx, err := w.builder.NewImportTx(chainID, to, baseFee, options...) + if err != nil { + return nil, err + } + return w.IssueUnsignedAtomicTx(utx, options...) +} + +func (w *wallet) IssueExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + options ...common.Option, +) (*evm.Tx, error) { + baseFee, err := w.baseFee(options) + if err != nil { + return nil, err + } + + utx, err := w.builder.NewExportTx(chainID, outputs, baseFee, options...) + if err != nil { + return nil, err + } + return w.IssueUnsignedAtomicTx(utx, options...) +} + +func (w *wallet) IssueUnsignedAtomicTx( + utx evm.UnsignedAtomicTx, + options ...common.Option, +) (*evm.Tx, error) { + ops := common.NewOptions(options) + ctx := ops.Context() + tx, err := w.signer.SignUnsignedAtomic(ctx, utx) + if err != nil { + return nil, err + } + + return tx, w.IssueAtomicTx(tx, options...) +} + +func (w *wallet) IssueAtomicTx( + tx *evm.Tx, + options ...common.Option, +) error { + ops := common.NewOptions(options) + ctx := ops.Context() + txID, err := w.avaxClient.IssueTx(ctx, tx.SignedBytes()) + if err != nil { + return err + } + + if f := ops.PostIssuanceFunc(); f != nil { + f(txID) + } + + if ops.AssumeDecided() { + return w.Backend.AcceptAtomicTx(ctx, tx) + } + + pollFrequency := ops.PollFrequency() + ticker := time.NewTicker(pollFrequency) + defer ticker.Stop() + + for { + status, err := w.avaxClient.GetAtomicTxStatus(ctx, txID) + if err != nil { + return err + } + + switch status { + case evm.Accepted: + return w.Backend.AcceptAtomicTx(ctx, tx) + case evm.Dropped, evm.Unknown: + return errNotCommitted + } + + // The tx is Processing. + + select { + case <-ticker.C: + case <-ctx.Done(): + return ctx.Err() + } + } +} + +func (w *wallet) baseFee(options []common.Option) (*big.Int, error) { + ops := common.NewOptions(options) + baseFee := ops.BaseFee(nil) + if baseFee != nil { + return baseFee, nil + } + + ctx := ops.Context() + return w.ethClient.EstimateBaseFee(ctx) +} diff --git a/wallet/chain/c/wallet_with_options.go b/wallet/chain/c/wallet_with_options.go index fd69a6d4fd02..7d6193683d49 100644 --- a/wallet/chain/c/wallet_with_options.go +++ b/wallet/chain/c/wallet_with_options.go @@ -3,80 +3,80 @@ package c -// import ( -// "github.com/ava-labs/coreth/plugin/evm" +import ( + "github.com/ava-labs/coreth/plugin/evm" -// ethcommon "github.com/ethereum/go-ethereum/common" + ethcommon "github.com/ethereum/go-ethereum/common" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) -// var _ Wallet = (*walletWithOptions)(nil) +var _ Wallet = (*walletWithOptions)(nil) -// func NewWalletWithOptions( -// wallet Wallet, -// options ...common.Option, -// ) Wallet { -// return &walletWithOptions{ -// Wallet: wallet, -// options: options, -// } -// } +func NewWalletWithOptions( + wallet Wallet, + options ...common.Option, +) Wallet { + return &walletWithOptions{ + Wallet: wallet, + options: options, + } +} -// type walletWithOptions struct { -// Wallet -// options []common.Option -// } +type walletWithOptions struct { + Wallet + options []common.Option +} -// func (w *walletWithOptions) Builder() Builder { -// return NewBuilderWithOptions( -// w.Wallet.Builder(), -// w.options..., -// ) -// } +func (w *walletWithOptions) Builder() Builder { + return NewBuilderWithOptions( + w.Wallet.Builder(), + w.options..., + ) +} -// func (w *walletWithOptions) IssueImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// options ...common.Option, -// ) (*evm.Tx, error) { -// return w.Wallet.IssueImportTx( -// chainID, -// to, -// common.UnionOptions(w.options, options)..., -// ) -// } +func (w *walletWithOptions) IssueImportTx( + chainID ids.ID, + to ethcommon.Address, + options ...common.Option, +) (*evm.Tx, error) { + return w.Wallet.IssueImportTx( + chainID, + to, + common.UnionOptions(w.options, options)..., + ) +} -// func (w *walletWithOptions) IssueExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// options ...common.Option, -// ) (*evm.Tx, error) { -// return w.Wallet.IssueExportTx( -// chainID, -// outputs, -// common.UnionOptions(w.options, options)..., -// ) -// } +func (w *walletWithOptions) IssueExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + options ...common.Option, +) (*evm.Tx, error) { + return w.Wallet.IssueExportTx( + chainID, + outputs, + common.UnionOptions(w.options, options)..., + ) +} -// func (w *walletWithOptions) IssueUnsignedAtomicTx( -// utx evm.UnsignedAtomicTx, -// options ...common.Option, -// ) (*evm.Tx, error) { -// return w.Wallet.IssueUnsignedAtomicTx( -// utx, -// common.UnionOptions(w.options, options)..., -// ) -// } +func (w *walletWithOptions) IssueUnsignedAtomicTx( + utx evm.UnsignedAtomicTx, + options ...common.Option, +) (*evm.Tx, error) { + return w.Wallet.IssueUnsignedAtomicTx( + utx, + common.UnionOptions(w.options, options)..., + ) +} -// func (w *walletWithOptions) IssueAtomicTx( -// tx *evm.Tx, -// options ...common.Option, -// ) error { -// return w.Wallet.IssueAtomicTx( -// tx, -// common.UnionOptions(w.options, options)..., -// ) -// } +func (w *walletWithOptions) IssueAtomicTx( + tx *evm.Tx, + options ...common.Option, +) error { + return w.Wallet.IssueAtomicTx( + tx, + common.UnionOptions(w.options, options)..., + ) +} diff --git a/wallet/subnet/primary/api.go b/wallet/subnet/primary/api.go index 00ebea6090fd..3ac72c217884 100644 --- a/wallet/subnet/primary/api.go +++ b/wallet/subnet/primary/api.go @@ -5,11 +5,12 @@ package primary import ( "context" - // "fmt" + "fmt" - // "github.com/ava-labs/coreth/ethclient" + "github.com/ava-labs/coreth/ethclient" + "github.com/ava-labs/coreth/plugin/evm" - // "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common" "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/codec" @@ -21,8 +22,7 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - - // "github.com/ava-labs/avalanchego/wallet/chain/c" + "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/x" ) @@ -59,9 +59,9 @@ type AVAXState struct { PCTX p.Context XClient avm.Client XCTX x.Context - // CClient evm.Client - // CCTX c.Context - UTXOs UTXOs + CClient evm.Client + CCTX c.Context + UTXOs UTXOs } func FetchState( @@ -75,7 +75,7 @@ func FetchState( infoClient := info.NewClient(uri) pClient := platformvm.NewClient(uri) xClient := avm.NewClient(uri, "X") - // cClient := evm.NewCChainClient(uri) + cClient := evm.NewCChainClient(uri) pCTX, err := p.NewContextFromClients(ctx, infoClient, xClient) if err != nil { @@ -87,10 +87,10 @@ func FetchState( return nil, err } - // cCTX, err := c.NewContextFromClients(ctx, infoClient, xClient) - // if err != nil { - // return nil, err - // } + cCTX, err := c.NewContextFromClients(ctx, infoClient, xClient) + if err != nil { + return nil, err + } utxos := NewUTXOs() addrList := addrs.List() @@ -109,11 +109,11 @@ func FetchState( client: xClient, codec: x.Parser.Codec(), }, - // { - // id: cCTX.BlockchainID(), - // client: cClient, - // codec: evm.Codec, - // }, + { + id: cCTX.BlockchainID(), + client: cClient, + codec: evm.Codec, + }, } for _, destinationChain := range chains { for _, sourceChain := range chains { @@ -136,52 +136,52 @@ func FetchState( PCTX: pCTX, XClient: xClient, XCTX: xCTX, - // CClient: cClient, - // CCTX: cCTX, - UTXOs: utxos, + CClient: cClient, + CCTX: cCTX, + UTXOs: utxos, }, nil } -// type EthState struct { -// Client ethclient.Client -// Accounts map[common.Address]*c.Account -// } - -// func FetchEthState( -// ctx context.Context, -// uri string, -// addrs set.Set[common.Address], -// ) (*EthState, error) { -// path := fmt.Sprintf( -// "%s/ext/%s/C/rpc", -// uri, -// constants.ChainAliasPrefix, -// ) -// client, err := ethclient.Dial(path) -// if err != nil { -// return nil, err -// } - -// accounts := make(map[common.Address]*c.Account, addrs.Len()) -// for addr := range addrs { -// balance, err := client.BalanceAt(ctx, addr, nil) -// if err != nil { -// return nil, err -// } -// nonce, err := client.NonceAt(ctx, addr, nil) -// if err != nil { -// return nil, err -// } -// accounts[addr] = &c.Account{ -// Balance: balance, -// Nonce: nonce, -// } -// } -// return &EthState{ -// Client: client, -// Accounts: accounts, -// }, nil -// } +type EthState struct { + Client ethclient.Client + Accounts map[common.Address]*c.Account +} + +func FetchEthState( + ctx context.Context, + uri string, + addrs set.Set[common.Address], +) (*EthState, error) { + path := fmt.Sprintf( + "%s/ext/%s/C/rpc", + uri, + constants.ChainAliasPrefix, + ) + client, err := ethclient.Dial(path) + if err != nil { + return nil, err + } + + accounts := make(map[common.Address]*c.Account, addrs.Len()) + for addr := range addrs { + balance, err := client.BalanceAt(ctx, addr, nil) + if err != nil { + return nil, err + } + nonce, err := client.NonceAt(ctx, addr, nil) + if err != nil { + return nil, err + } + accounts[addr] = &c.Account{ + Balance: balance, + Nonce: nonce, + } + } + return &EthState{ + Client: client, + Accounts: accounts, + }, nil +} // AddAllUTXOs fetches all the UTXOs referenced by [addresses] that were sent // from [sourceChainID] to [destinationChainID] from the [client]. It then uses diff --git a/wallet/subnet/primary/example_test.go b/wallet/subnet/primary/example_test.go index 4a73e8c070b2..483c049d4ac0 100644 --- a/wallet/subnet/primary/example_test.go +++ b/wallet/subnet/primary/example_test.go @@ -30,7 +30,7 @@ func ExampleWallet() { wallet, err := MakeWallet(ctx, &WalletConfig{ URI: LocalAPIURI, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet with: %s\n", err) diff --git a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go index 21c081d2982b..d5e8ce422307 100644 --- a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go +++ b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go @@ -46,9 +46,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - // EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/examples/add-primary-validator/main.go b/wallet/subnet/primary/examples/add-primary-validator/main.go index 13c28f995f63..a56dae23db3a 100644 --- a/wallet/subnet/primary/examples/add-primary-validator/main.go +++ b/wallet/subnet/primary/examples/add-primary-validator/main.go @@ -45,7 +45,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/c-chain-export/main.go b/wallet/subnet/primary/examples/c-chain-export/main.go index a6b9a0c810b8..fec55c899feb 100644 --- a/wallet/subnet/primary/examples/c-chain-export/main.go +++ b/wallet/subnet/primary/examples/c-chain-export/main.go @@ -3,70 +3,70 @@ package main -// import ( -// "context" -// "log" -// "time" +import ( + "context" + "log" + "time" -// "github.com/ava-labs/avalanchego/genesis" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary" -// ) + "github.com/ava-labs/avalanchego/genesis" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary" +) -// func main() { -// key := genesis.EWOQKey -// uri := primary.LocalAPIURI -// kc := secp256k1fx.NewKeychain(key) -// avaxAddr := key.Address() +func main() { + key := genesis.EWOQKey + uri := primary.LocalAPIURI + kc := secp256k1fx.NewKeychain(key) + avaxAddr := key.Address() -// ctx := context.Background() + ctx := context.Background() -// // MakeWallet fetches the available UTXOs owned by [kc] on the network that -// // [uri] is hosting. -// walletSyncStartTime := time.Now() -// wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ -// URI: uri, -// AVAXKeychain: kc, -// EthKeychain: kc, -// }) -// if err != nil { -// log.Fatalf("failed to initialize wallet: %s\n", err) -// } -// log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) + // MakeWallet fetches the available UTXOs owned by [kc] on the network that + // [uri] is hosting. + walletSyncStartTime := time.Now() + wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, + }) + if err != nil { + log.Fatalf("failed to initialize wallet: %s\n", err) + } + log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) -// // Get the P-chain wallet -// pWallet := wallet.P() -// cWallet := wallet.C() + // Get the P-chain wallet + pWallet := wallet.P() + cWallet := wallet.C() -// // Pull out useful constants to use when issuing transactions. -// cChainID := cWallet.BlockchainID() -// owner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// avaxAddr, -// }, -// } + // Pull out useful constants to use when issuing transactions. + cChainID := cWallet.BlockchainID() + owner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + avaxAddr, + }, + } -// exportStartTime := time.Now() -// exportTx, err := cWallet.IssueExportTx( -// constants.PlatformChainID, -// []*secp256k1fx.TransferOutput{{ -// Amt: units.Avax, -// OutputOwners: owner, -// }}, -// ) -// if err != nil { -// log.Fatalf("failed to issue export transaction: %s\n", err) -// } -// log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) + exportStartTime := time.Now() + exportTx, err := cWallet.IssueExportTx( + constants.PlatformChainID, + []*secp256k1fx.TransferOutput{{ + Amt: units.Avax, + OutputOwners: owner, + }}, + ) + if err != nil { + log.Fatalf("failed to issue export transaction: %s\n", err) + } + log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) -// importStartTime := time.Now() -// importTx, err := pWallet.IssueImportTx(cChainID, &owner) -// if err != nil { -// log.Fatalf("failed to issue import transaction: %s\n", err) -// } -// log.Printf("issued import %s in %s\n", importTx.ID(), time.Since(importStartTime)) -// } + importStartTime := time.Now() + importTx, err := pWallet.IssueImportTx(cChainID, &owner) + if err != nil { + log.Fatalf("failed to issue import transaction: %s\n", err) + } + log.Printf("issued import %s in %s\n", importTx.ID(), time.Since(importStartTime)) +} diff --git a/wallet/subnet/primary/examples/c-chain-import/main.go b/wallet/subnet/primary/examples/c-chain-import/main.go index 2d9b8a244cb0..b4dc4e603eb3 100644 --- a/wallet/subnet/primary/examples/c-chain-import/main.go +++ b/wallet/subnet/primary/examples/c-chain-import/main.go @@ -3,75 +3,75 @@ package main -// import ( -// "context" -// "log" -// "time" +import ( + "context" + "log" + "time" -// "github.com/ava-labs/coreth/plugin/evm" + "github.com/ava-labs/coreth/plugin/evm" -// "github.com/ava-labs/avalanchego/genesis" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary" -// ) + "github.com/ava-labs/avalanchego/genesis" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary" +) -// func main() { -// key := genesis.EWOQKey -// uri := primary.LocalAPIURI -// kc := secp256k1fx.NewKeychain(key) -// avaxAddr := key.Address() -// ethAddr := evm.PublicKeyToEthAddress(key.PublicKey()) +func main() { + key := genesis.EWOQKey + uri := primary.LocalAPIURI + kc := secp256k1fx.NewKeychain(key) + avaxAddr := key.Address() + ethAddr := evm.PublicKeyToEthAddress(key.PublicKey()) -// ctx := context.Background() + ctx := context.Background() -// // MakeWallet fetches the available UTXOs owned by [kc] on the network that -// // [uri] is hosting. -// walletSyncStartTime := time.Now() -// wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ -// URI: uri, -// AVAXKeychain: kc, -// EthKeychain: kc, -// }) -// if err != nil { -// log.Fatalf("failed to initialize wallet: %s\n", err) -// } -// log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) + // MakeWallet fetches the available UTXOs owned by [kc] on the network that + // [uri] is hosting. + walletSyncStartTime := time.Now() + wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, + }) + if err != nil { + log.Fatalf("failed to initialize wallet: %s\n", err) + } + log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) -// // Get the P-chain wallet -// pWallet := wallet.P() -// cWallet := wallet.C() + // Get the P-chain wallet + pWallet := wallet.P() + cWallet := wallet.C() -// // Pull out useful constants to use when issuing transactions. -// cChainID := cWallet.BlockchainID() -// avaxAssetID := cWallet.AVAXAssetID() -// owner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// avaxAddr, -// }, -// } + // Pull out useful constants to use when issuing transactions. + cChainID := cWallet.BlockchainID() + avaxAssetID := cWallet.AVAXAssetID() + owner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + avaxAddr, + }, + } -// exportStartTime := time.Now() -// exportTx, err := pWallet.IssueExportTx(cChainID, []*avax.TransferableOutput{{ -// Asset: avax.Asset{ID: avaxAssetID}, -// Out: &secp256k1fx.TransferOutput{ -// Amt: units.Avax, -// OutputOwners: owner, -// }, -// }}) -// if err != nil { -// log.Fatalf("failed to issue export transaction: %s\n", err) -// } -// log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) + exportStartTime := time.Now() + exportTx, err := pWallet.IssueExportTx(cChainID, []*avax.TransferableOutput{{ + Asset: avax.Asset{ID: avaxAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: units.Avax, + OutputOwners: owner, + }, + }}) + if err != nil { + log.Fatalf("failed to issue export transaction: %s\n", err) + } + log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) -// importStartTime := time.Now() -// importTx, err := cWallet.IssueImportTx(constants.PlatformChainID, ethAddr) -// if err != nil { -// log.Fatalf("failed to issue import transaction: %s\n", err) -// } -// log.Printf("issued import %s to %s in %s\n", importTx.ID(), ethAddr.Hex(), time.Since(importStartTime)) -// } + importStartTime := time.Now() + importTx, err := cWallet.IssueImportTx(constants.PlatformChainID, ethAddr) + if err != nil { + log.Fatalf("failed to issue import transaction: %s\n", err) + } + log.Printf("issued import %s to %s in %s\n", importTx.ID(), ethAddr.Hex(), time.Since(importStartTime)) +} diff --git a/wallet/subnet/primary/examples/create-asset/main.go b/wallet/subnet/primary/examples/create-asset/main.go index 0bccfbb5fc52..30804f083df6 100644 --- a/wallet/subnet/primary/examples/create-asset/main.go +++ b/wallet/subnet/primary/examples/create-asset/main.go @@ -30,7 +30,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/create-chain/main.go b/wallet/subnet/primary/examples/create-chain/main.go index 521a3cca53cf..5e6898a1b649 100644 --- a/wallet/subnet/primary/examples/create-chain/main.go +++ b/wallet/subnet/primary/examples/create-chain/main.go @@ -41,9 +41,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - // EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/examples/create-locked-stakeable/main.go b/wallet/subnet/primary/examples/create-locked-stakeable/main.go index 92f1b5cb0e1b..e688968e9e8a 100644 --- a/wallet/subnet/primary/examples/create-locked-stakeable/main.go +++ b/wallet/subnet/primary/examples/create-locked-stakeable/main.go @@ -39,7 +39,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/create-subnet/main.go b/wallet/subnet/primary/examples/create-subnet/main.go index 3e8d69bc016a..add98ea7931c 100644 --- a/wallet/subnet/primary/examples/create-subnet/main.go +++ b/wallet/subnet/primary/examples/create-subnet/main.go @@ -28,7 +28,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/remove-subnet-validator/main.go b/wallet/subnet/primary/examples/remove-subnet-validator/main.go index 46f4b85124db..2842c7c0a790 100644 --- a/wallet/subnet/primary/examples/remove-subnet-validator/main.go +++ b/wallet/subnet/primary/examples/remove-subnet-validator/main.go @@ -38,9 +38,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - // EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/wallet.go b/wallet/subnet/primary/wallet.go index ae5e4202a099..54de390d029c 100644 --- a/wallet/subnet/primary/wallet.go +++ b/wallet/subnet/primary/wallet.go @@ -11,8 +11,7 @@ import ( "github.com/ava-labs/avalanchego/utils/crypto/keychain" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - - // "github.com/ava-labs/avalanchego/wallet/chain/c" + "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/x" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -24,13 +23,13 @@ var _ Wallet = (*wallet)(nil) type Wallet interface { P() p.Wallet X() x.Wallet - // C() c.Wallet + C() c.Wallet } type wallet struct { p p.Wallet x x.Wallet - // c c.Wallet + c c.Wallet } func (w *wallet) P() p.Wallet { @@ -41,16 +40,16 @@ func (w *wallet) X() x.Wallet { return w.x } -// func (w *wallet) C() c.Wallet { -// return w.c -// } +func (w *wallet) C() c.Wallet { + return w.c +} // Creates a new default wallet -func NewWallet(p p.Wallet, x x.Wallet /*, c c.Wallet*/) Wallet { +func NewWallet(p p.Wallet, x x.Wallet, c c.Wallet) Wallet { return &wallet{ p: p, x: x, - // c: c, + c: c, } } @@ -59,7 +58,7 @@ func NewWalletWithOptions(w Wallet, options ...common.Option) Wallet { return NewWallet( p.NewWalletWithOptions(w.P(), options...), x.NewWalletWithOptions(w.X(), options...), - // c.NewWalletWithOptions(w.C(), options...), + c.NewWalletWithOptions(w.C(), options...), ) } @@ -68,7 +67,7 @@ type WalletConfig struct { URI string // required // Keys to use for signing all transactions. AVAXKeychain keychain.Keychain // required - // EthKeychain c.EthKeychain // required + EthKeychain c.EthKeychain // required // Set of P-chain transactions that the wallet should know about to be able // to generate transactions. PChainTxs map[ids.ID]*txs.Tx // optional @@ -94,11 +93,11 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { return nil, err } - // ethAddrs := config.EthKeychain.EthAddresses() - // ethState, err := FetchEthState(ctx, config.URI, ethAddrs) - // if err != nil { - // return nil, err - // } + ethAddrs := config.EthKeychain.EthAddresses() + ethState, err := FetchEthState(ctx, config.URI, ethAddrs) + if err != nil { + return nil, err + } pChainTxs := config.PChainTxs if pChainTxs == nil { @@ -128,15 +127,15 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { xBuilder := x.NewBuilder(avaxAddrs, xBackend) xSigner := x.NewSigner(config.AVAXKeychain, xBackend) - // cChainID := avaxState.CCTX.BlockchainID() - // cUTXOs := NewChainUTXOs(cChainID, avaxState.UTXOs) - // cBackend := c.NewBackend(avaxState.CCTX, cUTXOs, ethState.Accounts) - // cBuilder := c.NewBuilder(avaxAddrs, ethAddrs, cBackend) - // cSigner := c.NewSigner(config.AVAXKeychain, config.EthKeychain, cBackend) + cChainID := avaxState.CCTX.BlockchainID() + cUTXOs := NewChainUTXOs(cChainID, avaxState.UTXOs) + cBackend := c.NewBackend(avaxState.CCTX, cUTXOs, ethState.Accounts) + cBuilder := c.NewBuilder(avaxAddrs, ethAddrs, cBackend) + cSigner := c.NewSigner(config.AVAXKeychain, config.EthKeychain, cBackend) return NewWallet( p.NewWallet(pBuilder, pSigner, avaxState.PClient, pBackend), x.NewWallet(xBuilder, xSigner, avaxState.XClient, xBackend), - // c.NewWallet(cBuilder, cSigner, avaxState.CClient, ethState.Client, cBackend), + c.NewWallet(cBuilder, cSigner, avaxState.CClient, ethState.Client, cBackend), ), nil } From 6c1a40a894e56da0ba1be0b848bfff14b67b44cc Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 30 Oct 2023 08:28:32 +0100 Subject: [PATCH 11/13] cut coreth dependency --- go.mod | 26 +- go.sum | 77 +- node/node.go | 4 +- tests/e2e/c/dynamic_fees.go | 326 +++---- tests/e2e/c/interchain_workflow.go | 320 +++---- tests/e2e/p/interchain_workflow.go | 422 ++++----- tests/e2e/x/interchain_workflow.go | 296 +++---- tests/fixture/e2e/helpers.go | 123 +-- tests/fixture/tmpnet/genesis.go | 50 +- vms/example/xsvm/cmd/chain/create/cmd.go | 6 +- wallet/chain/c/backend.go | 300 +++---- wallet/chain/c/builder.go | 812 +++++++++--------- wallet/chain/c/builder_with_options.go | 136 +-- wallet/chain/c/context.go | 194 ++--- wallet/chain/c/signer.go | 436 +++++----- wallet/chain/c/wallet.go | 402 ++++----- wallet/chain/c/wallet_with_options.go | 134 +-- wallet/subnet/primary/api.go | 122 +-- wallet/subnet/primary/example_test.go | 2 +- .../add-permissioned-subnet-validator/main.go | 6 +- .../examples/add-primary-validator/main.go | 2 +- .../primary/examples/c-chain-export/main.go | 118 +-- .../primary/examples/c-chain-import/main.go | 126 +-- .../primary/examples/create-asset/main.go | 2 +- .../primary/examples/create-chain/main.go | 6 +- .../examples/create-locked-stakeable/main.go | 2 +- .../primary/examples/create-subnet/main.go | 2 +- .../examples/remove-subnet-validator/main.go | 6 +- wallet/subnet/primary/wallet.go | 43 +- 29 files changed, 2200 insertions(+), 2301 deletions(-) diff --git a/go.mod b/go.mod index 8007addf990f..cd9743e7bdfb 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,6 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 - github.com/ava-labs/coreth v0.12.9-rc.9.0.20231227155207-5b6a157b44c8 github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 @@ -75,7 +74,6 @@ require ( github.com/BurntSushi/toml v1.2.1 // indirect github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect - github.com/VictoriaMetrics/fastcache v1.10.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect @@ -83,45 +81,28 @@ require ( github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/redact v1.1.3 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/deckarep/golang-set/v2 v2.1.0 // indirect - github.com/dlclark/regexp2 v1.7.0 // indirect - github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 // indirect - github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect github.com/frankban/quicktest v1.14.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/getsentry/sentry-go v0.18.0 // indirect github.com/go-logr/logr v1.3.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect - github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect - github.com/go-stack/stack v1.8.1 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/go-cmp v0.6.0 // indirect - github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect - github.com/google/uuid v1.3.0 // indirect + github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 // indirect - github.com/hashicorp/go-bexpr v0.1.10 // indirect - github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e // indirect github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/klauspost/compress v1.15.15 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/magiconair/properties v1.8.6 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect - github.com/mattn/go-runewidth v0.0.9 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/mitchellh/pointerstructure v1.2.0 // indirect - github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -129,17 +110,12 @@ require ( github.com/prometheus/common v0.39.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sanity-io/litter v1.5.1 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/status-im/keycard-go v0.2.0 // indirect github.com/subosito/gotenv v1.3.0 // indirect github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tklauser/numcpus v0.2.2 // indirect - github.com/tyler-smith/go-bip39 v1.1.0 // indirect - github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa // indirect - github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect diff --git a/go.sum b/go.sum index 1416fce80669..3ef5760fbfd8 100644 --- a/go.sum +++ b/go.sum @@ -56,18 +56,12 @@ github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cq github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= -github.com/VictoriaMetrics/fastcache v1.10.0 h1:5hDJnLsKLpnUEToub7ETuRu8RCkb40woBZAUiKonXzY= -github.com/VictoriaMetrics/fastcache v1.10.0/go.mod h1:tjiYeEfYXCqacuvYw/7UoDIeJaNxq6132xHICNP77w8= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/coreth v0.12.9-rc.9.0.20231227155207-5b6a157b44c8 h1:TE72qt8xRzF8QrR+UUSoCgNINn6fLosq7k2KnD9RYuc= -github.com/ava-labs/coreth v0.12.9-rc.9.0.20231227155207-5b6a157b44c8/go.mod h1:uVX/xG7p07/0bUK4bJBQGsY0HXWvkVfmNLvyd4PGEOA= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= @@ -102,18 +96,13 @@ github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46f github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw= github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA= @@ -145,16 +134,12 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= -github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= @@ -165,14 +150,6 @@ github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6ps github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= -github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= -github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 h1:+3HCtB74++ClLy8GgjUQYeC8R4ILzVcIe8+5edAJJnE= -github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= -github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= -github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -189,8 +166,6 @@ github.com/ethereum/go-ethereum v1.12.0 h1:bdnhLPtqETd4m3mS8BGMNvBTf36bO5bx/hxE2 github.com/ethereum/go-ethereum v1.12.0/go.mod h1:/oo2X/dZLJjf2mJ6YT9wcWxa4nNJDBKDBU6sFIpx1Gs= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -199,8 +174,6 @@ github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmV github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= -github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= -github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= @@ -224,11 +197,7 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= -github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= -github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= @@ -315,15 +284,12 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= -github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= @@ -344,17 +310,11 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 h1:kr3j8iIMR4ywO/O0rvksXaJvauGGCMg2zAZIiNZ9uIQ= github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0/go.mod h1:ummNFgdgLhhX7aIiy35vVmQNS0rWXknfPE0qe6fmFXg= -github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= -github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e h1:pIYdhNkDh+YENVNi3gto8n9hAmRxKxoar0iE6BLucjw= -github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e/go.mod h1:j9cQbcqHQujT0oKJ38PylVfqohClLr3CvDC+Qcg+lhU= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c h1:DZfsyhDK1hnSS5lH8l+JggqzEleHteTYfutAiVlSUM8= @@ -366,7 +326,6 @@ github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3 github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -408,7 +367,6 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -416,7 +374,6 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= @@ -427,17 +384,11 @@ github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPK github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= @@ -446,11 +397,8 @@ github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= -github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -469,8 +417,6 @@ github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= -github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -538,8 +484,6 @@ github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sanity-io/litter v1.5.1 h1:dwnrSypP6q56o3lFxTU+t2fwQ9A+U5qrXVO4Qg9KwVU= github.com/sanity-io/litter v1.5.1/go.mod h1:5Z71SvaYy5kcGtyglXOC9rrUi3c1E8CamFWjQsazTh0= @@ -575,8 +519,6 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= -github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= -github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -609,14 +551,10 @@ github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZF github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE= github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE= -github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= -github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa h1:5SqCsI/2Qya2bCzK15ozrqo2sZxkh0FHynJZOTVoV6Q= -github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= @@ -628,8 +566,6 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= @@ -639,7 +575,6 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= @@ -735,7 +670,6 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -782,7 +716,6 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -806,7 +739,6 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -871,12 +803,8 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= @@ -893,7 +821,6 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -957,7 +884,6 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1084,7 +1010,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= diff --git a/node/node.go b/node/node.go index 22be7d5436eb..151f878ee6d7 100644 --- a/node/node.go +++ b/node/node.go @@ -25,7 +25,7 @@ import ( "go.uber.org/zap" - coreth "github.com/ava-labs/coreth/plugin/evm" + // coreth "github.com/ava-labs/coreth/plugin/evm" "github.com/ava-labs/avalanchego/api/admin" "github.com/ava-labs/avalanchego/api/auth" @@ -1116,7 +1116,7 @@ func (n *Node) initVMs() error { CreateAssetTxFee: n.Config.CreateAssetTxFee, }, }), - vmRegisterer.Register(context.TODO(), constants.EVMID, &coreth.Factory{}), + // vmRegisterer.Register(context.TODO(), constants.EVMID, &coreth.Factory{}), n.VMManager.RegisterFactory(context.TODO(), secp256k1fx.ID, &secp256k1fx.Factory{}), n.VMManager.RegisterFactory(context.TODO(), nftfx.ID, &nftfx.Factory{}), n.VMManager.RegisterFactory(context.TODO(), propertyfx.ID, &propertyfx.Factory{}), diff --git a/tests/e2e/c/dynamic_fees.go b/tests/e2e/c/dynamic_fees.go index 5e80573542b4..7cd53f52baaf 100644 --- a/tests/e2e/c/dynamic_fees.go +++ b/tests/e2e/c/dynamic_fees.go @@ -3,166 +3,166 @@ package c -import ( - "math/big" - "strings" - - ginkgo "github.com/onsi/ginkgo/v2" - - "github.com/stretchr/testify/require" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/plugin/evm" - - "github.com/ava-labs/avalanchego/tests" - "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -) - -// This test uses the compiled bin for `hashing.sol` as -// well as its ABI contained in `hashing_contract.go`. - -var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { - require := require.New(ginkgo.GinkgoT()) - - // Need a gas limit much larger than the standard 21_000 to enable - // the contract to induce a gas price increase - const largeGasLimit = uint64(8_000_000) - - // TODO(marun) What is the significance of this value? - gasTip := big.NewInt(1000 * params.GWei) - - ginkgo.It("should ensure that the gas price is affected by load", func() { - ginkgo.By("creating a new private network to ensure isolation from other tests") - privateNetwork := e2e.Env.NewPrivateNetwork() - - ginkgo.By("allocating a pre-funded key") - key := privateNetwork.PreFundedKeys[0] - ethAddress := evm.GetEthAddress(key) - - ginkgo.By("initializing a coreth client") - node := privateNetwork.Nodes[0] - nodeURI := tmpnet.NodeURI{ - NodeID: node.NodeID, - URI: node.URI, - } - ethClient := e2e.NewEthClient(nodeURI) - - ginkgo.By("initializing a transaction signer") - cChainID, err := ethClient.ChainID(e2e.DefaultContext()) - require.NoError(err) - signer := types.NewEIP155Signer(cChainID) - ecdsaKey := key.ToECDSA() - sign := func(tx *types.Transaction) *types.Transaction { - signedTx, err := types.SignTx(tx, signer, ecdsaKey) - require.NoError(err) - return signedTx - } - - var contractAddress common.Address - ginkgo.By("deploying an expensive contract", func() { - // Create transaction - nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) - require.NoError(err) - compiledContract := common.Hex2Bytes(hashingCompiledContract) - tx := types.NewTx(&types.LegacyTx{ - Nonce: nonce, - GasPrice: gasTip, - Gas: largeGasLimit, - Value: common.Big0, - Data: compiledContract, - }) - - // Send the transaction and wait for acceptance - signedTx := sign(tx) - receipt := e2e.SendEthTransaction(ethClient, signedTx) - - contractAddress = receipt.ContractAddress - }) - - var gasPrice *big.Int - ginkgo.By("calling the expensive contract repeatedly until a gas price increase is detected", func() { - // Evaluate the bytes representation of the contract - hashingABI, err := abi.JSON(strings.NewReader(hashingABIJson)) - require.NoError(err) - contractData, err := hashingABI.Pack("hashIt") - require.NoError(err) - - var initialGasPrice *big.Int - e2e.Eventually(func() bool { - // Check the gas price - var err error - gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) - require.NoError(err) - if initialGasPrice == nil { - initialGasPrice = gasPrice - tests.Outf("{{blue}}initial gas price is %v{{/}}\n", initialGasPrice) - } else if gasPrice.Cmp(initialGasPrice) > 0 { - // Gas price has increased - tests.Outf("{{blue}}gas price has increased to %v{{/}}\n", gasPrice) - return true - } - - // Create the transaction - nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) - require.NoError(err) - tx := types.NewTx(&types.LegacyTx{ - Nonce: nonce, - GasPrice: gasTip, - Gas: largeGasLimit, - To: &contractAddress, - Value: common.Big0, - Data: contractData, - }) - - // Send the transaction and wait for acceptance - signedTx := sign(tx) - _ = e2e.SendEthTransaction(ethClient, signedTx) - - // The gas price will be checked at the start of the next iteration - return false - }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price increase before timeout") - }) - - ginkgo.By("waiting for the gas price to decrease...", func() { - initialGasPrice := gasPrice - e2e.Eventually(func() bool { - var err error - gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) - require.NoError(err) - tests.Outf("{{blue}}.{{/}}") - return initialGasPrice.Cmp(gasPrice) > 0 - }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price decrease before timeout") - tests.Outf("\n{{blue}}gas price has decreased to %v{{/}}\n", gasPrice) - }) - - ginkgo.By("sending funds at the current gas price", func() { - // Create a recipient address - recipientKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - recipientEthAddress := evm.GetEthAddress(recipientKey) - - // Create transaction - nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) - require.NoError(err) - tx := types.NewTx(&types.LegacyTx{ - Nonce: nonce, - GasPrice: gasPrice, - Gas: e2e.DefaultGasLimit, - To: &recipientEthAddress, - Value: common.Big0, - }) - - // Send the transaction and wait for acceptance - signedTx := sign(tx) - _ = e2e.SendEthTransaction(ethClient, signedTx) - }) - - e2e.CheckBootstrapIsPossible(privateNetwork) - }) -}) +// import ( +// "math/big" +// "strings" + +// ginkgo "github.com/onsi/ginkgo/v2" + +// "github.com/stretchr/testify/require" + +// "github.com/ethereum/go-ethereum/accounts/abi" +// "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/coreth/core/types" +// "github.com/ava-labs/coreth/params" +// "github.com/ava-labs/coreth/plugin/evm" + +// "github.com/ava-labs/avalanchego/tests" +// "github.com/ava-labs/avalanchego/tests/e2e" +// "github.com/ava-labs/avalanchego/tests/fixture/testnet" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// ) + +// // This test uses the compiled bin for `hashing.sol` as +// // well as its ABI contained in `hashing_contract.go`. + +// var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { +// require := require.New(ginkgo.GinkgoT()) + +// // Need a gas limit much larger than the standard 21_000 to enable +// // the contract to induce a gas price increase +// const largeGasLimit = uint64(8_000_000) + +// // TODO(marun) What is the significance of this value? +// gasTip := big.NewInt(1000 * params.GWei) + +// ginkgo.It("should ensure that the gas price is affected by load", func() { +// ginkgo.By("creating a new private network to ensure isolation from other tests") +// privateNetwork := e2e.Env.NewPrivateNetwork() + +// ginkgo.By("allocating a pre-funded key") +// key := privateNetwork.PreFundedKeys[0] +// ethAddress := evm.GetEthAddress(key) + +// ginkgo.By("initializing a coreth client") +// node := privateNetwork.Nodes[0] +// nodeURI := tmpnet.NodeURI{ +// NodeID: node.NodeID, +// URI: node.URI, +// } +// ethClient := e2e.NewEthClient(nodeURI) + +// ginkgo.By("initializing a transaction signer") +// cChainID, err := ethClient.ChainID(e2e.DefaultContext()) +// require.NoError(err) +// signer := types.NewEIP155Signer(cChainID) +// ecdsaKey := key.ToECDSA() +// sign := func(tx *types.Transaction) *types.Transaction { +// signedTx, err := types.SignTx(tx, signer, ecdsaKey) +// require.NoError(err) +// return signedTx +// } + +// var contractAddress common.Address +// ginkgo.By("deploying an expensive contract", func() { +// // Create transaction +// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) +// require.NoError(err) +// compiledContract := common.Hex2Bytes(hashingCompiledContract) +// tx := types.NewTx(&types.LegacyTx{ +// Nonce: nonce, +// GasPrice: gasTip, +// Gas: largeGasLimit, +// Value: common.Big0, +// Data: compiledContract, +// }) + +// // Send the transaction and wait for acceptance +// signedTx := sign(tx) +// receipt := e2e.SendEthTransaction(ethClient, signedTx) + +// contractAddress = receipt.ContractAddress +// }) + +// var gasPrice *big.Int +// ginkgo.By("calling the expensive contract repeatedly until a gas price increase is detected", func() { +// // Evaluate the bytes representation of the contract +// hashingABI, err := abi.JSON(strings.NewReader(hashingABIJson)) +// require.NoError(err) +// contractData, err := hashingABI.Pack("hashIt") +// require.NoError(err) + +// var initialGasPrice *big.Int +// e2e.Eventually(func() bool { +// // Check the gas price +// var err error +// gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) +// require.NoError(err) +// if initialGasPrice == nil { +// initialGasPrice = gasPrice +// tests.Outf("{{blue}}initial gas price is %v{{/}}\n", initialGasPrice) +// } else if gasPrice.Cmp(initialGasPrice) > 0 { +// // Gas price has increased +// tests.Outf("{{blue}}gas price has increased to %v{{/}}\n", gasPrice) +// return true +// } + +// // Create the transaction +// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) +// require.NoError(err) +// tx := types.NewTx(&types.LegacyTx{ +// Nonce: nonce, +// GasPrice: gasTip, +// Gas: largeGasLimit, +// To: &contractAddress, +// Value: common.Big0, +// Data: contractData, +// }) + +// // Send the transaction and wait for acceptance +// signedTx := sign(tx) +// _ = e2e.SendEthTransaction(ethClient, signedTx) + +// // The gas price will be checked at the start of the next iteration +// return false +// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price increase before timeout") +// }) + +// ginkgo.By("waiting for the gas price to decrease...", func() { +// initialGasPrice := gasPrice +// e2e.Eventually(func() bool { +// var err error +// gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) +// require.NoError(err) +// tests.Outf("{{blue}}.{{/}}") +// return initialGasPrice.Cmp(gasPrice) > 0 +// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price decrease before timeout") +// tests.Outf("\n{{blue}}gas price has decreased to %v{{/}}\n", gasPrice) +// }) + +// ginkgo.By("sending funds at the current gas price", func() { +// // Create a recipient address +// recipientKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) +// recipientEthAddress := evm.GetEthAddress(recipientKey) + +// // Create transaction +// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) +// require.NoError(err) +// tx := types.NewTx(&types.LegacyTx{ +// Nonce: nonce, +// GasPrice: gasPrice, +// Gas: e2e.DefaultGasLimit, +// To: &recipientEthAddress, +// Value: common.Big0, +// }) + +// // Send the transaction and wait for acceptance +// signedTx := sign(tx) +// _ = e2e.SendEthTransaction(ethClient, signedTx) +// }) + +// e2e.CheckBootstrapIsPossible(privateNetwork) +// }) +// }) diff --git a/tests/e2e/c/interchain_workflow.go b/tests/e2e/c/interchain_workflow.go index e959418e878a..a111029b543a 100644 --- a/tests/e2e/c/interchain_workflow.go +++ b/tests/e2e/c/interchain_workflow.go @@ -3,163 +3,163 @@ package c -import ( - "math/big" - - ginkgo "github.com/onsi/ginkgo/v2" - - "github.com/stretchr/testify/require" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/plugin/evm" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var _ = e2e.DescribeCChain("[Interchain Workflow]", func() { - require := require.New(ginkgo.GinkgoT()) - - const txAmount = 10 * units.Avax // Arbitrary amount to send and transfer - - ginkgo.It("should ensure that funds can be transferred from the C-Chain to the X-Chain and the P-Chain", func() { - ginkgo.By("initializing a new eth client") - // Select a random node URI to use for both the eth client and - // the wallet to avoid having to verify that all nodes are at - // the same height before initializing the wallet. - nodeURI := e2e.Env.GetRandomNodeURI() - ethClient := e2e.NewEthClient(nodeURI) - - ginkgo.By("allocating a pre-funded key to send from and a recipient key to deliver to") - senderKey := e2e.Env.AllocatePreFundedKey() - senderEthAddress := evm.GetEthAddress(senderKey) - recipientKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - recipientEthAddress := evm.GetEthAddress(recipientKey) - - ginkgo.By("sending funds from one address to another on the C-Chain", func() { - // Create transaction - acceptedNonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), senderEthAddress) - require.NoError(err) - gasPrice := e2e.SuggestGasPrice(ethClient) - tx := types.NewTransaction( - acceptedNonce, - recipientEthAddress, - big.NewInt(int64(txAmount)), - e2e.DefaultGasLimit, - gasPrice, - nil, - ) - - // Sign transaction - cChainID, err := ethClient.ChainID(e2e.DefaultContext()) - require.NoError(err) - signer := types.NewEIP155Signer(cChainID) - signedTx, err := types.SignTx(tx, signer, senderKey.ToECDSA()) - require.NoError(err) - - _ = e2e.SendEthTransaction(ethClient, signedTx) - - ginkgo.By("waiting for the C-Chain recipient address to have received the sent funds") - e2e.Eventually(func() bool { - balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) - require.NoError(err) - return balance.Cmp(big.NewInt(0)) > 0 - }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see funds delivered before timeout") - }) - - // Wallet must be initialized after sending funds on the - // C-Chain with the same node URI to ensure wallet state - // matches on-chain state. - ginkgo.By("initializing a keychain and associated wallet") - keychain := secp256k1fx.NewKeychain(senderKey, recipientKey) - baseWallet := e2e.NewWallet(keychain, nodeURI) - xWallet := baseWallet.X() - cWallet := baseWallet.C() - pWallet := baseWallet.P() - - ginkgo.By("defining common configuration") - avaxAssetID := xWallet.AVAXAssetID() - // Use the same owner for import funds to X-Chain and P-Chain - recipientOwner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - recipientKey.Address(), - }, - } - // Use the same outputs for both X-Chain and P-Chain exports - exportOutputs := []*secp256k1fx.TransferOutput{ - { - Amt: txAmount, - OutputOwners: secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - keychain.Keys[0].Address(), - }, - }, - }, - } - - ginkgo.By("exporting AVAX from the C-Chain to the X-Chain", func() { - _, err := cWallet.IssueExportTx( - xWallet.BlockchainID(), - exportOutputs, - e2e.WithDefaultContext(), - e2e.WithSuggestedGasPrice(ethClient), - ) - require.NoError(err) - }) - - ginkgo.By("importing AVAX from the C-Chain to the X-Chain", func() { - _, err := xWallet.IssueImportTx( - cWallet.BlockchainID(), - &recipientOwner, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { - balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - ginkgo.By("exporting AVAX from the C-Chain to the P-Chain", func() { - _, err := cWallet.IssueExportTx( - constants.PlatformChainID, - exportOutputs, - e2e.WithDefaultContext(), - e2e.WithSuggestedGasPrice(ethClient), - ) - require.NoError(err) - }) - - ginkgo.By("importing AVAX from the C-Chain to the P-Chain", func() { - _, err = pWallet.IssueImportTx( - cWallet.BlockchainID(), - &recipientOwner, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { - balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) - }) -}) +// import ( +// "math/big" + +// ginkgo "github.com/onsi/ginkgo/v2" + +// "github.com/stretchr/testify/require" + +// "github.com/ava-labs/coreth/core/types" +// "github.com/ava-labs/coreth/plugin/evm" + +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/tests/e2e" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var _ = e2e.DescribeCChain("[Interchain Workflow]", func() { +// require := require.New(ginkgo.GinkgoT()) + +// const txAmount = 10 * units.Avax // Arbitrary amount to send and transfer + +// ginkgo.It("should ensure that funds can be transferred from the C-Chain to the X-Chain and the P-Chain", func() { +// ginkgo.By("initializing a new eth client") +// // Select a random node URI to use for both the eth client and +// // the wallet to avoid having to verify that all nodes are at +// // the same height before initializing the wallet. +// nodeURI := e2e.Env.GetRandomNodeURI() +// ethClient := e2e.NewEthClient(nodeURI) + +// ginkgo.By("allocating a pre-funded key to send from and a recipient key to deliver to") +// senderKey := e2e.Env.AllocatePreFundedKey() +// senderEthAddress := evm.GetEthAddress(senderKey) +// recipientKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) +// recipientEthAddress := evm.GetEthAddress(recipientKey) + +// ginkgo.By("sending funds from one address to another on the C-Chain", func() { +// // Create transaction +// acceptedNonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), senderEthAddress) +// require.NoError(err) +// gasPrice := e2e.SuggestGasPrice(ethClient) +// tx := types.NewTransaction( +// acceptedNonce, +// recipientEthAddress, +// big.NewInt(int64(txAmount)), +// e2e.DefaultGasLimit, +// gasPrice, +// nil, +// ) + +// // Sign transaction +// cChainID, err := ethClient.ChainID(e2e.DefaultContext()) +// require.NoError(err) +// signer := types.NewEIP155Signer(cChainID) +// signedTx, err := types.SignTx(tx, signer, senderKey.ToECDSA()) +// require.NoError(err) + +// _ = e2e.SendEthTransaction(ethClient, signedTx) + +// ginkgo.By("waiting for the C-Chain recipient address to have received the sent funds") +// e2e.Eventually(func() bool { +// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) +// require.NoError(err) +// return balance.Cmp(big.NewInt(0)) > 0 +// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see funds delivered before timeout") +// }) + +// // Wallet must be initialized after sending funds on the +// // C-Chain with the same node URI to ensure wallet state +// // matches on-chain state. +// ginkgo.By("initializing a keychain and associated wallet") +// keychain := secp256k1fx.NewKeychain(senderKey, recipientKey) +// baseWallet := e2e.NewWallet(keychain, nodeURI) +// xWallet := baseWallet.X() +// cWallet := baseWallet.C() +// pWallet := baseWallet.P() + +// ginkgo.By("defining common configuration") +// avaxAssetID := xWallet.AVAXAssetID() +// // Use the same owner for import funds to X-Chain and P-Chain +// recipientOwner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// recipientKey.Address(), +// }, +// } +// // Use the same outputs for both X-Chain and P-Chain exports +// exportOutputs := []*secp256k1fx.TransferOutput{ +// { +// Amt: txAmount, +// OutputOwners: secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// keychain.Keys[0].Address(), +// }, +// }, +// }, +// } + +// ginkgo.By("exporting AVAX from the C-Chain to the X-Chain", func() { +// _, err := cWallet.IssueExportTx( +// xWallet.BlockchainID(), +// exportOutputs, +// e2e.WithDefaultContext(), +// e2e.WithSuggestedGasPrice(ethClient), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("importing AVAX from the C-Chain to the X-Chain", func() { +// _, err := xWallet.IssueImportTx( +// cWallet.BlockchainID(), +// &recipientOwner, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { +// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// ginkgo.By("exporting AVAX from the C-Chain to the P-Chain", func() { +// _, err := cWallet.IssueExportTx( +// constants.PlatformChainID, +// exportOutputs, +// e2e.WithDefaultContext(), +// e2e.WithSuggestedGasPrice(ethClient), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("importing AVAX from the C-Chain to the P-Chain", func() { +// _, err = pWallet.IssueImportTx( +// cWallet.BlockchainID(), +// &recipientOwner, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { +// balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) +// }) +// }) diff --git a/tests/e2e/p/interchain_workflow.go b/tests/e2e/p/interchain_workflow.go index 59e90198bed0..b300ba4b2bd3 100644 --- a/tests/e2e/p/interchain_workflow.go +++ b/tests/e2e/p/interchain_workflow.go @@ -3,214 +3,214 @@ package p -import ( - "math/big" - "time" - - ginkgo "github.com/onsi/ginkgo/v2" - - "github.com/spf13/cast" - - "github.com/stretchr/testify/require" - - "github.com/ava-labs/coreth/plugin/evm" - - "github.com/ava-labs/avalanchego/api/info" - "github.com/ava-labs/avalanchego/config" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/platformvm/reward" - "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { - require := require.New(ginkgo.GinkgoT()) - - const ( - transferAmount = 10 * units.Avax - weight = 2_000 * units.Avax // Used for both validation and delegation - ) - - ginkgo.It("should ensure that funds can be transferred from the P-Chain to the X-Chain and the C-Chain", func() { - network := e2e.Env.GetNetwork() - - ginkgo.By("checking that the network has a compatible minimum stake duration", func() { - minStakeDuration := cast.ToDuration(network.DefaultFlags[config.MinStakeDurationKey]) - require.Equal(tmpnet.DefaultMinStakeDuration, minStakeDuration) - }) - - ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") - recipientKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - keychain := e2e.Env.NewKeychain(1) - keychain.Add(recipientKey) - nodeURI := e2e.Env.GetRandomNodeURI() - baseWallet := e2e.NewWallet(keychain, nodeURI) - xWallet := baseWallet.X() - cWallet := baseWallet.C() - pWallet := baseWallet.P() - - ginkgo.By("defining common configuration") - recipientEthAddress := evm.GetEthAddress(recipientKey) - avaxAssetID := xWallet.AVAXAssetID() - // Use the same owner for sending to X-Chain and importing funds to P-Chain - recipientOwner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - recipientKey.Address(), - }, - } - // Use the same outputs for both X-Chain and C-Chain exports - exportOutputs := []*avax.TransferableOutput{ - { - Asset: avax.Asset{ - ID: avaxAssetID, - }, - Out: &secp256k1fx.TransferOutput{ - Amt: transferAmount, - OutputOwners: secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - keychain.Keys[0].Address(), - }, - }, - }, - }, - } - - ginkgo.By("adding new node and waiting for it to report healthy") - node := e2e.AddEphemeralNode(network, tmpnet.FlagsMap{}) - e2e.WaitForHealthy(node) - - ginkgo.By("retrieving new node's id and pop") - infoClient := info.NewClient(node.URI) - nodeID, nodePOP, err := infoClient.GetNodeID(e2e.DefaultContext()) - require.NoError(err) - - // Adding a validator should not break interchain transfer. - endTime := time.Now().Add(30 * time.Second) - ginkgo.By("adding the new node as a validator", func() { - rewardKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - - const ( - delegationPercent = 0.10 // 10% - delegationShare = reward.PercentDenominator * delegationPercent - ) - - _, err = pWallet.IssueAddPermissionlessValidatorTx( - &txs.SubnetValidator{ - Validator: txs.Validator{ - NodeID: nodeID, - End: uint64(endTime.Unix()), - Wght: weight, - }, - Subnet: constants.PrimaryNetworkID, - }, - nodePOP, - pWallet.AVAXAssetID(), - &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{rewardKey.Address()}, - }, - &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{rewardKey.Address()}, - }, - delegationShare, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - // Adding a delegator should not break interchain transfer. - ginkgo.By("adding a delegator to the new node", func() { - rewardKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - - _, err = pWallet.IssueAddPermissionlessDelegatorTx( - &txs.SubnetValidator{ - Validator: txs.Validator{ - NodeID: nodeID, - End: uint64(endTime.Unix()), - Wght: weight, - }, - Subnet: constants.PrimaryNetworkID, - }, - pWallet.AVAXAssetID(), - &secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{rewardKey.Address()}, - }, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("exporting AVAX from the P-Chain to the X-Chain", func() { - _, err := pWallet.IssueExportTx( - xWallet.BlockchainID(), - exportOutputs, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("importing AVAX from the P-Chain to the X-Chain", func() { - _, err := xWallet.IssueImportTx( - constants.PlatformChainID, - &recipientOwner, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { - balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - ginkgo.By("exporting AVAX from the P-Chain to the C-Chain", func() { - _, err := pWallet.IssueExportTx( - cWallet.BlockchainID(), - exportOutputs, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("initializing a new eth client") - ethClient := e2e.NewEthClient(nodeURI) - - ginkgo.By("importing AVAX from the P-Chain to the C-Chain", func() { - _, err := cWallet.IssueImportTx( - constants.PlatformChainID, - recipientEthAddress, - e2e.WithDefaultContext(), - e2e.WithSuggestedGasPrice(ethClient), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") - balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) - require.NoError(err) - require.Positive(balance.Cmp(big.NewInt(0))) - - ginkgo.By("stopping validator node to free up resources for a bootstrap check") - require.NoError(node.Stop(e2e.DefaultContext())) - - e2e.CheckBootstrapIsPossible(network) - }) -}) +// import ( +// "math/big" +// "time" + +// ginkgo "github.com/onsi/ginkgo/v2" + +// "github.com/spf13/cast" + +// "github.com/stretchr/testify/require" + +// "github.com/ava-labs/coreth/plugin/evm" + +// "github.com/ava-labs/avalanchego/api/info" +// "github.com/ava-labs/avalanchego/config" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/tests/e2e" +// "github.com/ava-labs/avalanchego/tests/fixture/testnet" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/platformvm/reward" +// "github.com/ava-labs/avalanchego/vms/platformvm/txs" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { +// require := require.New(ginkgo.GinkgoT()) + +// const ( +// transferAmount = 10 * units.Avax +// weight = 2_000 * units.Avax // Used for both validation and delegation +// ) + +// ginkgo.It("should ensure that funds can be transferred from the P-Chain to the X-Chain and the C-Chain", func() { +// network := e2e.Env.GetNetwork() + +// ginkgo.By("checking that the network has a compatible minimum stake duration", func() { +// minStakeDuration := cast.ToDuration(network.DefaultFlags[config.MinStakeDurationKey]) +// require.Equal(tmpnet.DefaultMinStakeDuration, minStakeDuration) +// }) + +// ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") +// recipientKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) +// keychain := e2e.Env.NewKeychain(1) +// keychain.Add(recipientKey) +// nodeURI := e2e.Env.GetRandomNodeURI() +// baseWallet := e2e.Env.NewWallet(keychain, nodeURI) +// xWallet := baseWallet.X() +// cWallet := baseWallet.C() +// pWallet := baseWallet.P() + +// ginkgo.By("defining common configuration") +// recipientEthAddress := evm.GetEthAddress(recipientKey) +// avaxAssetID := xWallet.AVAXAssetID() +// // Use the same owner for sending to X-Chain and importing funds to P-Chain +// recipientOwner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// recipientKey.Address(), +// }, +// } +// // Use the same outputs for both X-Chain and C-Chain exports +// exportOutputs := []*avax.TransferableOutput{ +// { +// Asset: avax.Asset{ +// ID: avaxAssetID, +// }, +// Out: &secp256k1fx.TransferOutput{ +// Amt: transferAmount, +// OutputOwners: secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// keychain.Keys[0].Address(), +// }, +// }, +// }, +// }, +// } + +// ginkgo.By("adding new node and waiting for it to report healthy") +// node := e2e.AddEphemeralNode(network, testnet.FlagsMap{}) +// e2e.WaitForHealthy(node) + +// ginkgo.By("retrieving new node's id and pop") +// infoClient := info.NewClient(node.URI) +// nodeID, nodePOP, err := infoClient.GetNodeID(e2e.DefaultContext()) +// require.NoError(err) + +// // Adding a validator should not break interchain transfer. +// endTime := time.Now().Add(30 * time.Second) +// ginkgo.By("adding the new node as a validator", func() { +// rewardKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) + +// const ( +// delegationPercent = 0.10 // 10% +// delegationShare = reward.PercentDenominator * delegationPercent +// ) + +// _, err = pWallet.IssueAddPermissionlessValidatorTx( +// &txs.SubnetValidator{ +// Validator: txs.Validator{ +// NodeID: nodeID, +// End: uint64(endTime.Unix()), +// Wght: weight, +// }, +// Subnet: constants.PrimaryNetworkID, +// }, +// nodePOP, +// pWallet.AVAXAssetID(), +// &secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{rewardKey.Address()}, +// }, +// &secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{rewardKey.Address()}, +// }, +// delegationShare, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// // Adding a delegator should not break interchain transfer. +// ginkgo.By("adding a delegator to the new node", func() { +// rewardKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) + +// _, err = pWallet.IssueAddPermissionlessDelegatorTx( +// &txs.SubnetValidator{ +// Validator: txs.Validator{ +// NodeID: nodeID, +// End: uint64(endTime.Unix()), +// Wght: weight, +// }, +// Subnet: constants.PrimaryNetworkID, +// }, +// pWallet.AVAXAssetID(), +// &secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{rewardKey.Address()}, +// }, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("exporting AVAX from the P-Chain to the X-Chain", func() { +// _, err := pWallet.IssueExportTx( +// xWallet.BlockchainID(), +// exportOutputs, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("importing AVAX from the P-Chain to the X-Chain", func() { +// _, err := xWallet.IssueImportTx( +// constants.PlatformChainID, +// &recipientOwner, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { +// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// ginkgo.By("exporting AVAX from the P-Chain to the C-Chain", func() { +// _, err := pWallet.IssueExportTx( +// cWallet.BlockchainID(), +// exportOutputs, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("initializing a new eth client") +// ethClient := e2e.NewEthClient(nodeURI) + +// ginkgo.By("importing AVAX from the P-Chain to the C-Chain", func() { +// _, err := cWallet.IssueImportTx( +// constants.PlatformChainID, +// recipientEthAddress, +// e2e.WithDefaultContext(), +// e2e.WithSuggestedGasPrice(ethClient), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") +// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) +// require.NoError(err) +// require.Positive(balance.Cmp(big.NewInt(0))) + +// ginkgo.By("stopping validator node to free up resources for a bootstrap check") +// require.NoError(node.Stop(e2e.DefaultContext())) + +// e2e.CheckBootstrapIsPossible(network) +// }) +// }) diff --git a/tests/e2e/x/interchain_workflow.go b/tests/e2e/x/interchain_workflow.go index f0c2951feb84..d738e55a7f7a 100644 --- a/tests/e2e/x/interchain_workflow.go +++ b/tests/e2e/x/interchain_workflow.go @@ -3,151 +3,151 @@ package x -import ( - "math/big" - - ginkgo "github.com/onsi/ginkgo/v2" - - "github.com/stretchr/testify/require" - - "github.com/ava-labs/coreth/plugin/evm" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/tests/fixture/e2e" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var _ = e2e.DescribeXChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { - require := require.New(ginkgo.GinkgoT()) - - const transferAmount = 10 * units.Avax - - ginkgo.It("should ensure that funds can be transferred from the X-Chain to the C-Chain and the P-Chain", func() { - nodeURI := e2e.Env.GetRandomNodeURI() - - ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") - recipientKey, err := secp256k1.NewPrivateKey() - require.NoError(err) - keychain := e2e.Env.NewKeychain(1) - keychain.Add(recipientKey) - baseWallet := e2e.NewWallet(keychain, nodeURI) - xWallet := baseWallet.X() - cWallet := baseWallet.C() - pWallet := baseWallet.P() - - ginkgo.By("defining common configuration") - recipientEthAddress := evm.GetEthAddress(recipientKey) - avaxAssetID := xWallet.AVAXAssetID() - // Use the same owner for sending to X-Chain and importing funds to P-Chain - recipientOwner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - recipientKey.Address(), - }, - } - // Use the same outputs for both C-Chain and P-Chain exports - exportOutputs := []*avax.TransferableOutput{ - { - Asset: avax.Asset{ - ID: avaxAssetID, - }, - Out: &secp256k1fx.TransferOutput{ - Amt: transferAmount, - OutputOwners: secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - keychain.Keys[0].Address(), - }, - }, - }, - }, - } - - ginkgo.By("sending funds from one address to another on the X-Chain", func() { - _, err = xWallet.IssueBaseTx( - []*avax.TransferableOutput{{ - Asset: avax.Asset{ - ID: avaxAssetID, - }, - Out: &secp256k1fx.TransferOutput{ - Amt: transferAmount, - OutputOwners: recipientOwner, - }, - }}, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the X-Chain recipient address has received the sent funds", func() { - balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - ginkgo.By("exporting AVAX from the X-Chain to the C-Chain", func() { - _, err := xWallet.IssueExportTx( - cWallet.BlockchainID(), - exportOutputs, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("initializing a new eth client") - ethClient := e2e.NewEthClient(nodeURI) - - ginkgo.By("importing AVAX from the X-Chain to the C-Chain", func() { - _, err := cWallet.IssueImportTx( - xWallet.BlockchainID(), - recipientEthAddress, - e2e.WithDefaultContext(), - e2e.WithSuggestedGasPrice(ethClient), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") - e2e.Eventually(func() bool { - balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) - require.NoError(err) - return balance.Cmp(big.NewInt(0)) > 0 - }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see recipient address funded before timeout") - - ginkgo.By("exporting AVAX from the X-Chain to the P-Chain", func() { - _, err := xWallet.IssueExportTx( - constants.PlatformChainID, - exportOutputs, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("importing AVAX from the X-Chain to the P-Chain", func() { - _, err := pWallet.IssueImportTx( - xWallet.BlockchainID(), - &recipientOwner, - e2e.WithDefaultContext(), - ) - require.NoError(err) - }) - - ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { - balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( - recipientKey.Address(), - ))) - require.NoError(err) - require.Positive(balances[avaxAssetID]) - }) - - e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) - }) -}) +// import ( +// "math/big" + +// ginkgo "github.com/onsi/ginkgo/v2" + +// "github.com/stretchr/testify/require" + +// "github.com/ava-labs/coreth/plugin/evm" + +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/tests/e2e" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var _ = e2e.DescribeXChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { +// require := require.New(ginkgo.GinkgoT()) + +// const transferAmount = 10 * units.Avax + +// ginkgo.It("should ensure that funds can be transferred from the X-Chain to the C-Chain and the P-Chain", func() { +// nodeURI := e2e.Env.GetRandomNodeURI() + +// ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") +// recipientKey, err := secp256k1.NewPrivateKey() +// require.NoError(err) +// keychain := e2e.Env.NewKeychain(1) +// keychain.Add(recipientKey) +// baseWallet := e2e.Env.NewWallet(keychain, nodeURI) +// xWallet := baseWallet.X() +// cWallet := baseWallet.C() +// pWallet := baseWallet.P() + +// ginkgo.By("defining common configuration") +// recipientEthAddress := evm.GetEthAddress(recipientKey) +// avaxAssetID := xWallet.AVAXAssetID() +// // Use the same owner for sending to X-Chain and importing funds to P-Chain +// recipientOwner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// recipientKey.Address(), +// }, +// } +// // Use the same outputs for both C-Chain and P-Chain exports +// exportOutputs := []*avax.TransferableOutput{ +// { +// Asset: avax.Asset{ +// ID: avaxAssetID, +// }, +// Out: &secp256k1fx.TransferOutput{ +// Amt: transferAmount, +// OutputOwners: secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// keychain.Keys[0].Address(), +// }, +// }, +// }, +// }, +// } + +// ginkgo.By("sending funds from one address to another on the X-Chain", func() { +// _, err = xWallet.IssueBaseTx( +// []*avax.TransferableOutput{{ +// Asset: avax.Asset{ +// ID: avaxAssetID, +// }, +// Out: &secp256k1fx.TransferOutput{ +// Amt: transferAmount, +// OutputOwners: recipientOwner, +// }, +// }}, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the X-Chain recipient address has received the sent funds", func() { +// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// ginkgo.By("exporting AVAX from the X-Chain to the C-Chain", func() { +// _, err := xWallet.IssueExportTx( +// cWallet.BlockchainID(), +// exportOutputs, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("initializing a new eth client") +// ethClient := e2e.NewEthClient(nodeURI) + +// ginkgo.By("importing AVAX from the X-Chain to the C-Chain", func() { +// _, err := cWallet.IssueImportTx( +// xWallet.BlockchainID(), +// recipientEthAddress, +// e2e.WithDefaultContext(), +// e2e.WithSuggestedGasPrice(ethClient), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") +// e2e.Eventually(func() bool { +// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) +// require.NoError(err) +// return balance.Cmp(big.NewInt(0)) > 0 +// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see recipient address funded before timeout") + +// ginkgo.By("exporting AVAX from the X-Chain to the P-Chain", func() { +// _, err := xWallet.IssueExportTx( +// constants.PlatformChainID, +// exportOutputs, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("importing AVAX from the X-Chain to the P-Chain", func() { +// _, err := pWallet.IssueImportTx( +// xWallet.BlockchainID(), +// &recipientOwner, +// e2e.WithDefaultContext(), +// ) +// require.NoError(err) +// }) + +// ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { +// balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( +// recipientKey.Address(), +// ))) +// require.NoError(err) +// require.Positive(balances[avaxAssetID]) +// }) + +// e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) +// }) +// }) diff --git a/tests/fixture/e2e/helpers.go b/tests/fixture/e2e/helpers.go index ddebfbc8b81c..224263818156 100644 --- a/tests/fixture/e2e/helpers.go +++ b/tests/fixture/e2e/helpers.go @@ -5,20 +5,23 @@ package e2e import ( "context" - "errors" - "fmt" - "math/big" + + // "errors" + // "fmt" + // "math/big" + "os" - "strings" + + // "strings" "time" ginkgo "github.com/onsi/ginkgo/v2" "github.com/stretchr/testify/require" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/ethclient" - "github.com/ava-labs/coreth/interfaces" + // "github.com/ava-labs/coreth/core/types" + // "github.com/ava-labs/coreth/ethclient" + // "github.com/ava-labs/coreth/interfaces" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/tests" @@ -60,7 +63,7 @@ func NewWallet(keychain *secp256k1fx.Keychain, nodeURI tmpnet.NodeURI) primary.W baseWallet, err := primary.MakeWallet(DefaultContext(), &primary.WalletConfig{ URI: nodeURI.URI, AVAXKeychain: keychain, - EthKeychain: keychain, + // EthKeychain: keychain, }) require.NoError(ginkgo.GinkgoT(), err) return primary.NewWalletWithOptions( @@ -73,15 +76,15 @@ func NewWallet(keychain *secp256k1fx.Keychain, nodeURI tmpnet.NodeURI) primary.W ) } -// Create a new eth client targeting the specified node URI. -func NewEthClient(nodeURI tmpnet.NodeURI) ethclient.Client { - tests.Outf("{{blue}} initializing a new eth client for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) - nodeAddress := strings.Split(nodeURI.URI, "//")[1] - uri := fmt.Sprintf("ws://%s/ext/bc/C/ws", nodeAddress) - client, err := ethclient.Dial(uri) - require.NoError(ginkgo.GinkgoT(), err) - return client -} +// // Create a new eth client targeting the specified node URI. +// func NewEthClient(nodeURI testnet.NodeURI) ethclient.Client { +// tests.Outf("{{blue}} initializing a new eth client for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) +// nodeAddress := strings.Split(nodeURI.URI, "//")[1] +// uri := fmt.Sprintf("ws://%s/ext/bc/C/ws", nodeAddress) +// client, err := ethclient.Dial(uri) +// require.NoError(ginkgo.GinkgoT(), err) +// return client +// } // Helper simplifying use of a timed context by canceling the context on ginkgo teardown. func ContextWithTimeout(duration time.Duration) context.Context { @@ -144,49 +147,49 @@ func WaitForHealthy(node *tmpnet.Node) { require.NoError(ginkgo.GinkgoT(), tmpnet.WaitForHealthy(ctx, node)) } -// Sends an eth transaction, waits for the transaction receipt to be issued -// and checks that the receipt indicates success. -func SendEthTransaction(ethClient ethclient.Client, signedTx *types.Transaction) *types.Receipt { - require := require.New(ginkgo.GinkgoT()) - - txID := signedTx.Hash() - tests.Outf(" sending eth transaction with ID: %s\n", txID) - - require.NoError(ethClient.SendTransaction(DefaultContext(), signedTx)) - - // Wait for the receipt - var receipt *types.Receipt - Eventually(func() bool { - var err error - receipt, err = ethClient.TransactionReceipt(DefaultContext(), txID) - if errors.Is(err, interfaces.NotFound) { - return false // Transaction is still pending - } - require.NoError(err) - return true - }, DefaultTimeout, DefaultPollingInterval, "failed to see transaction acceptance before timeout") - - require.Equal(receipt.Status, types.ReceiptStatusSuccessful) - return receipt -} - -// Determines the suggested gas price for the configured client that will -// maximize the chances of transaction acceptance. -func SuggestGasPrice(ethClient ethclient.Client) *big.Int { - gasPrice, err := ethClient.SuggestGasPrice(DefaultContext()) - require.NoError(ginkgo.GinkgoT(), err) - // Double the suggested gas price to maximize the chances of - // acceptance. Maybe this can be revisited pending resolution of - // https://github.com/ava-labs/coreth/issues/314. - gasPrice.Add(gasPrice, gasPrice) - return gasPrice -} - -// Helper simplifying use via an option of a gas price appropriate for testing. -func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { - baseFee := SuggestGasPrice(ethClient) - return common.WithBaseFee(baseFee) -} +// // Sends an eth transaction, waits for the transaction receipt to be issued +// // and checks that the receipt indicates success. +// func SendEthTransaction(ethClient ethclient.Client, signedTx *types.Transaction) *types.Receipt { +// require := require.New(ginkgo.GinkgoT()) + +// txID := signedTx.Hash() +// tests.Outf(" sending eth transaction with ID: %s\n", txID) + +// require.NoError(ethClient.SendTransaction(DefaultContext(), signedTx)) + +// // Wait for the receipt +// var receipt *types.Receipt +// Eventually(func() bool { +// var err error +// receipt, err = ethClient.TransactionReceipt(DefaultContext(), txID) +// if errors.Is(err, interfaces.NotFound) { +// return false // Transaction is still pending +// } +// require.NoError(err) +// return true +// }, DefaultTimeout, DefaultPollingInterval, "failed to see transaction acceptance before timeout") + +// require.Equal(receipt.Status, types.ReceiptStatusSuccessful) +// return receipt +// } + +// // Determines the suggested gas price for the configured client that will +// // maximize the chances of transaction acceptance. +// func SuggestGasPrice(ethClient ethclient.Client) *big.Int { +// gasPrice, err := ethClient.SuggestGasPrice(DefaultContext()) +// require.NoError(ginkgo.GinkgoT(), err) +// // Double the suggested gas price to maximize the chances of +// // acceptance. Maybe this can be revisited pending resolution of +// // https://github.com/ava-labs/coreth/issues/314. +// gasPrice.Add(gasPrice, gasPrice) +// return gasPrice +// } + +// // Helper simplifying use via an option of a gas price appropriate for testing. +// func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { +// baseFee := SuggestGasPrice(ethClient) +// return common.WithBaseFee(baseFee) +// } // Verify that a new node can bootstrap into the network. func CheckBootstrapIsPossible(network *tmpnet.Network) { diff --git a/tests/fixture/tmpnet/genesis.go b/tests/fixture/tmpnet/genesis.go index 5ee605702482..db0462b3c0ce 100644 --- a/tests/fixture/tmpnet/genesis.go +++ b/tests/fixture/tmpnet/genesis.go @@ -4,16 +4,10 @@ package tmpnet import ( - "encoding/json" "errors" "fmt" - "math/big" "time" - "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/plugin/evm" - "github.com/ava-labs/avalanchego/genesis" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/constants" @@ -27,12 +21,12 @@ const ( defaultGasLimit = uint64(100_000_000) // Gas limit is arbitrary // Arbitrarily large amount of AVAX to fund keys on the X-Chain for testing - defaultFundedKeyXChainAmount = 30 * units.MegaAvax + // defaultFundedKeyXChainAmount = 30 * units.MegaAvax ) var ( // Arbitrarily large amount of AVAX (10^12) to fund keys on the C-Chain for testing - defaultFundedKeyCChainAmount = new(big.Int).Exp(big.NewInt(10), big.NewInt(30), nil) + // defaultFundedKeyCChainAmount = new(big.Int).Exp(big.NewInt(10), big.NewInt(30), nil) errNoKeysForGenesis = errors.New("no keys to fund for genesis") errInvalidNetworkIDForGenesis = errors.New("network ID can't be mainnet, testnet or local network ID for genesis") @@ -113,13 +107,13 @@ func NewTestGenesis( // Ensure pre-funded keys have arbitrary large balances on both chains to support testing xChainBalances := make(XChainBalanceMap, len(keysToFund)) - cChainBalances := make(core.GenesisAlloc, len(keysToFund)) - for _, key := range keysToFund { - xChainBalances[key.Address()] = defaultFundedKeyXChainAmount - cChainBalances[evm.GetEthAddress(key)] = core.GenesisAccount{ - Balance: defaultFundedKeyCChainAmount, - } - } + // cChainBalances := make(core.GenesisAlloc, len(keysToFund)) + // for _, key := range keysToFund { + // xChainBalances[key.Address()] = defaultFundedKeyXChainAmount + // cChainBalances[evm.GetEthAddress(key)] = core.GenesisAccount{ + // Balance: defaultFundedKeyCChainAmount, + // } + // } // Set X-Chain balances for xChainAddress, balance := range xChainBalances { @@ -147,19 +141,19 @@ func NewTestGenesis( } // Define C-Chain genesis - cChainGenesis := &core.Genesis{ - Config: ¶ms.ChainConfig{ - ChainID: big.NewInt(43112), // Arbitrary chain ID is arbitrary - }, - Difficulty: big.NewInt(0), // Difficulty is a mandatory field - GasLimit: defaultGasLimit, - Alloc: cChainBalances, - } - cChainGenesisBytes, err := json.Marshal(cChainGenesis) - if err != nil { - return nil, fmt.Errorf("failed to marshal C-Chain genesis: %w", err) - } - config.CChainGenesis = string(cChainGenesisBytes) + // cChainGenesis := &core.Genesis{ + // Config: ¶ms.ChainConfig{ + // ChainID: big.NewInt(43112), // Arbitrary chain ID is arbitrary + // }, + // Difficulty: big.NewInt(0), // Difficulty is a mandatory field + // GasLimit: defaultGasLimit, + // Alloc: cChainBalances, + // } + // cChainGenesisBytes, err := json.Marshal(cChainGenesis) + // if err != nil { + // return nil, fmt.Errorf("failed to marshal C-Chain genesis: %w", err) + // } + // config.CChainGenesis = string(cChainGenesisBytes) return config, nil } diff --git a/vms/example/xsvm/cmd/chain/create/cmd.go b/vms/example/xsvm/cmd/chain/create/cmd.go index e562c8567b06..56acfeaa703c 100644 --- a/vms/example/xsvm/cmd/chain/create/cmd.go +++ b/vms/example/xsvm/cmd/chain/create/cmd.go @@ -42,9 +42,9 @@ func createFunc(c *cobra.Command, args []string) error { // that [uri] is hosting. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: config.URI, - AVAXKeychain: kc, - EthKeychain: kc, + URI: config.URI, + AVAXKeychain: kc, + // EthKeychain: kc, PChainTxsToFetch: set.Of(config.SubnetID), }) if err != nil { diff --git a/wallet/chain/c/backend.go b/wallet/chain/c/backend.go index 0a735116b646..b88c8c643bc3 100644 --- a/wallet/chain/c/backend.go +++ b/wallet/chain/c/backend.go @@ -3,153 +3,153 @@ package c -import ( - "errors" - "fmt" - "math/big" - "sync" - - stdcontext "context" - - "github.com/ava-labs/coreth/plugin/evm" - - ethcommon "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/avalanchego/database" - "github.com/ava-labs/avalanchego/utils/math" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var ( - _ Backend = (*backend)(nil) - - errUnknownTxType = errors.New("unknown tx type") -) - -// Backend defines the full interface required to support a C-chain wallet. -type Backend interface { - common.ChainUTXOs - BuilderBackend - SignerBackend - - AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error -} - -type backend struct { - Context - common.ChainUTXOs - - accountsLock sync.RWMutex - accounts map[ethcommon.Address]*Account -} - -type Account struct { - Balance *big.Int - Nonce uint64 -} - -func NewBackend( - ctx Context, - utxos common.ChainUTXOs, - accounts map[ethcommon.Address]*Account, -) Backend { - return &backend{ - Context: ctx, - ChainUTXOs: utxos, - accounts: accounts, - } -} - -func (b *backend) AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error { - switch tx := tx.UnsignedAtomicTx.(type) { - case *evm.UnsignedImportTx: - for _, input := range tx.ImportedInputs { - utxoID := input.InputID() - if err := b.RemoveUTXO(ctx, tx.SourceChain, utxoID); err != nil { - return err - } - } - - b.accountsLock.Lock() - defer b.accountsLock.Unlock() - - for _, output := range tx.Outs { - account, ok := b.accounts[output.Address] - if !ok { - continue - } - - balance := new(big.Int).SetUint64(output.Amount) - balance.Mul(balance, avaxConversionRate) - account.Balance.Add(account.Balance, balance) - } - case *evm.UnsignedExportTx: - txID := tx.ID() - for i, out := range tx.ExportedOutputs { - err := b.AddUTXO( - ctx, - tx.DestinationChain, - &avax.UTXO{ - UTXOID: avax.UTXOID{ - TxID: txID, - OutputIndex: uint32(i), - }, - Asset: avax.Asset{ID: out.AssetID()}, - Out: out.Out, - }, - ) - if err != nil { - return err - } - } - - b.accountsLock.Lock() - defer b.accountsLock.Unlock() - - for _, input := range tx.Ins { - account, ok := b.accounts[input.Address] - if !ok { - continue - } - - balance := new(big.Int).SetUint64(input.Amount) - balance.Mul(balance, avaxConversionRate) - if account.Balance.Cmp(balance) == -1 { - return errInsufficientFunds - } - account.Balance.Sub(account.Balance, balance) - - newNonce, err := math.Add64(input.Nonce, 1) - if err != nil { - return err - } - account.Nonce = newNonce - } - default: - return fmt.Errorf("%w: %T", errUnknownTxType, tx) - } - return nil -} - -func (b *backend) Balance(_ stdcontext.Context, addr ethcommon.Address) (*big.Int, error) { - b.accountsLock.RLock() - defer b.accountsLock.RUnlock() - - account, exists := b.accounts[addr] - if !exists { - return nil, database.ErrNotFound - } - return account.Balance, nil -} - -func (b *backend) Nonce(_ stdcontext.Context, addr ethcommon.Address) (uint64, error) { - b.accountsLock.RLock() - defer b.accountsLock.RUnlock() - - account, exists := b.accounts[addr] - if !exists { - return 0, database.ErrNotFound - } - return account.Nonce, nil -} +// import ( +// "errors" +// "fmt" +// "math/big" +// "sync" + +// stdcontext "context" + +// "github.com/ava-labs/coreth/plugin/evm" + +// ethcommon "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/avalanchego/database" +// "github.com/ava-labs/avalanchego/utils/math" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var ( +// _ Backend = (*backend)(nil) + +// errUnknownTxType = errors.New("unknown tx type") +// ) + +// // Backend defines the full interface required to support a C-chain wallet. +// type Backend interface { +// common.ChainUTXOs +// BuilderBackend +// SignerBackend + +// AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error +// } + +// type backend struct { +// Context +// common.ChainUTXOs + +// accountsLock sync.RWMutex +// accounts map[ethcommon.Address]*Account +// } + +// type Account struct { +// Balance *big.Int +// Nonce uint64 +// } + +// func NewBackend( +// ctx Context, +// utxos common.ChainUTXOs, +// accounts map[ethcommon.Address]*Account, +// ) Backend { +// return &backend{ +// Context: ctx, +// ChainUTXOs: utxos, +// accounts: accounts, +// } +// } + +// func (b *backend) AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error { +// switch tx := tx.UnsignedAtomicTx.(type) { +// case *evm.UnsignedImportTx: +// for _, input := range tx.ImportedInputs { +// utxoID := input.InputID() +// if err := b.RemoveUTXO(ctx, tx.SourceChain, utxoID); err != nil { +// return err +// } +// } + +// b.accountsLock.Lock() +// defer b.accountsLock.Unlock() + +// for _, output := range tx.Outs { +// account, ok := b.accounts[output.Address] +// if !ok { +// continue +// } + +// balance := new(big.Int).SetUint64(output.Amount) +// balance.Mul(balance, avaxConversionRate) +// account.Balance.Add(account.Balance, balance) +// } +// case *evm.UnsignedExportTx: +// txID := tx.ID() +// for i, out := range tx.ExportedOutputs { +// err := b.AddUTXO( +// ctx, +// tx.DestinationChain, +// &avax.UTXO{ +// UTXOID: avax.UTXOID{ +// TxID: txID, +// OutputIndex: uint32(i), +// }, +// Asset: avax.Asset{ID: out.AssetID()}, +// Out: out.Out, +// }, +// ) +// if err != nil { +// return err +// } +// } + +// b.accountsLock.Lock() +// defer b.accountsLock.Unlock() + +// for _, input := range tx.Ins { +// account, ok := b.accounts[input.Address] +// if !ok { +// continue +// } + +// balance := new(big.Int).SetUint64(input.Amount) +// balance.Mul(balance, avaxConversionRate) +// if account.Balance.Cmp(balance) == -1 { +// return errInsufficientFunds +// } +// account.Balance.Sub(account.Balance, balance) + +// newNonce, err := math.Add64(input.Nonce, 1) +// if err != nil { +// return err +// } +// account.Nonce = newNonce +// } +// default: +// return fmt.Errorf("%w: %T", errUnknownTxType, tx) +// } +// return nil +// } + +// func (b *backend) Balance(_ stdcontext.Context, addr ethcommon.Address) (*big.Int, error) { +// b.accountsLock.RLock() +// defer b.accountsLock.RUnlock() + +// account, exists := b.accounts[addr] +// if !exists { +// return nil, database.ErrNotFound +// } +// return account.Balance, nil +// } + +// func (b *backend) Nonce(_ stdcontext.Context, addr ethcommon.Address) (uint64, error) { +// b.accountsLock.RLock() +// defer b.accountsLock.RUnlock() + +// account, exists := b.accounts[addr] +// if !exists { +// return 0, database.ErrNotFound +// } +// return account.Nonce, nil +// } diff --git a/wallet/chain/c/builder.go b/wallet/chain/c/builder.go index 81fcf3aa896a..0e95a91e4fe4 100644 --- a/wallet/chain/c/builder.go +++ b/wallet/chain/c/builder.go @@ -3,409 +3,409 @@ package c -import ( - "errors" - "math/big" - - stdcontext "context" - - "github.com/ava-labs/coreth/plugin/evm" - - ethcommon "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils" - "github.com/ava-labs/avalanchego/utils/math" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -const avaxConversionRateInt = 1_000_000_000 - -var ( - _ Builder = (*builder)(nil) - - errInsufficientFunds = errors.New("insufficient funds") - - // avaxConversionRate is the conversion rate between the smallest - // denomination on the X-Chain and P-chain, 1 nAVAX, and the smallest - // denomination on the C-Chain 1 wei. Where 1 nAVAX = 1 gWei. - // - // This is only required for AVAX because the denomination of 1 AVAX is 9 - // decimal places on the X and P chains, but is 18 decimal places within the - // EVM. - avaxConversionRate = big.NewInt(avaxConversionRateInt) -) - -// Builder provides a convenient interface for building unsigned C-chain -// transactions. -type Builder interface { - // GetBalance calculates the amount of AVAX that this builder has control - // over. - GetBalance( - options ...common.Option, - ) (*big.Int, error) - - // GetImportableBalance calculates the amount of AVAX that this builder - // could import from the provided chain. - // - // - [chainID] specifies the chain the funds are from. - GetImportableBalance( - chainID ids.ID, - options ...common.Option, - ) (uint64, error) - - // NewImportTx creates an import transaction that attempts to consume all - // the available UTXOs and import the funds to [to]. - // - // - [chainID] specifies the chain to be importing funds from. - // - [to] specifies where to send the imported funds to. - // - [baseFee] specifies the fee price willing to be paid by this tx. - NewImportTx( - chainID ids.ID, - to ethcommon.Address, - baseFee *big.Int, - options ...common.Option, - ) (*evm.UnsignedImportTx, error) - - // NewExportTx creates an export transaction that attempts to send all the - // provided [outputs] to the requested [chainID]. - // - // - [chainID] specifies the chain to be exporting the funds to. - // - [outputs] specifies the outputs to send to the [chainID]. - // - [baseFee] specifies the fee price willing to be paid by this tx. - NewExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - baseFee *big.Int, - options ...common.Option, - ) (*evm.UnsignedExportTx, error) -} - -// BuilderBackend specifies the required information needed to build unsigned -// C-chain transactions. -type BuilderBackend interface { - Context - - UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) - Balance(ctx stdcontext.Context, addr ethcommon.Address) (*big.Int, error) - Nonce(ctx stdcontext.Context, addr ethcommon.Address) (uint64, error) -} - -type builder struct { - avaxAddrs set.Set[ids.ShortID] - ethAddrs set.Set[ethcommon.Address] - backend BuilderBackend -} - -// NewBuilder returns a new transaction builder. -// -// - [avaxAddrs] is the set of addresses in the AVAX format that the builder -// assumes can be used when signing the transactions in the future. -// - [ethAddrs] is the set of addresses in the Eth format that the builder -// assumes can be used when signing the transactions in the future. -// - [backend] provides the required access to the chain's context and state -// to build out the transactions. -func NewBuilder( - avaxAddrs set.Set[ids.ShortID], - ethAddrs set.Set[ethcommon.Address], - backend BuilderBackend, -) Builder { - return &builder{ - avaxAddrs: avaxAddrs, - ethAddrs: ethAddrs, - backend: backend, - } -} - -func (b *builder) GetBalance( - options ...common.Option, -) (*big.Int, error) { - var ( - ops = common.NewOptions(options) - ctx = ops.Context() - addrs = ops.EthAddresses(b.ethAddrs) - totalBalance = new(big.Int) - ) - for addr := range addrs { - balance, err := b.backend.Balance(ctx, addr) - if err != nil { - return nil, err - } - totalBalance.Add(totalBalance, balance) - } - - return totalBalance, nil -} - -func (b *builder) GetImportableBalance( - chainID ids.ID, - options ...common.Option, -) (uint64, error) { - ops := common.NewOptions(options) - utxos, err := b.backend.UTXOs(ops.Context(), chainID) - if err != nil { - return 0, err - } - - var ( - addrs = ops.Addresses(b.avaxAddrs) - minIssuanceTime = ops.MinIssuanceTime() - avaxAssetID = b.backend.AVAXAssetID() - balance uint64 - ) - for _, utxo := range utxos { - amount, _, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) - if !ok { - continue - } - - newBalance, err := math.Add64(balance, amount) - if err != nil { - return 0, err - } - balance = newBalance - } - - return balance, nil -} - -func (b *builder) NewImportTx( - chainID ids.ID, - to ethcommon.Address, - baseFee *big.Int, - options ...common.Option, -) (*evm.UnsignedImportTx, error) { - ops := common.NewOptions(options) - utxos, err := b.backend.UTXOs(ops.Context(), chainID) - if err != nil { - return nil, err - } - - var ( - addrs = ops.Addresses(b.avaxAddrs) - minIssuanceTime = ops.MinIssuanceTime() - avaxAssetID = b.backend.AVAXAssetID() - - importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) - importedAmount uint64 - ) - for _, utxo := range utxos { - amount, inputSigIndices, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) - if !ok { - continue - } - - importedInputs = append(importedInputs, &avax.TransferableInput{ - UTXOID: utxo.UTXOID, - Asset: utxo.Asset, - FxID: secp256k1fx.ID, - In: &secp256k1fx.TransferInput{ - Amt: amount, - Input: secp256k1fx.Input{ - SigIndices: inputSigIndices, - }, - }, - }) - - newImportedAmount, err := math.Add64(importedAmount, amount) - if err != nil { - return nil, err - } - importedAmount = newImportedAmount - } - - utils.Sort(importedInputs) - tx := &evm.UnsignedImportTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: b.backend.BlockchainID(), - SourceChain: chainID, - ImportedInputs: importedInputs, - } - - // We must initialize the bytes of the tx to calculate the initial cost - wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} - if err := wrappedTx.Sign(evm.Codec, nil); err != nil { - return nil, err - } - - gasUsedWithoutOutput, err := tx.GasUsed(true /*=IsApricotPhase5*/) - if err != nil { - return nil, err - } - gasUsedWithOutput := gasUsedWithoutOutput + evm.EVMOutputGas - - txFee, err := evm.CalculateDynamicFee(gasUsedWithOutput, baseFee) - if err != nil { - return nil, err - } - - if importedAmount <= txFee { - return nil, errInsufficientFunds - } - - tx.Outs = []evm.EVMOutput{{ - Address: to, - Amount: importedAmount - txFee, - AssetID: avaxAssetID, - }} - return tx, nil -} - -func (b *builder) NewExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - baseFee *big.Int, - options ...common.Option, -) (*evm.UnsignedExportTx, error) { - var ( - avaxAssetID = b.backend.AVAXAssetID() - exportedOutputs = make([]*avax.TransferableOutput, len(outputs)) - exportedAmount uint64 - ) - for i, output := range outputs { - exportedOutputs[i] = &avax.TransferableOutput{ - Asset: avax.Asset{ID: avaxAssetID}, - FxID: secp256k1fx.ID, - Out: output, - } - - newExportedAmount, err := math.Add64(exportedAmount, output.Amt) - if err != nil { - return nil, err - } - exportedAmount = newExportedAmount - } - - avax.SortTransferableOutputs(exportedOutputs, evm.Codec) - tx := &evm.UnsignedExportTx{ - NetworkID: b.backend.NetworkID(), - BlockchainID: b.backend.BlockchainID(), - DestinationChain: chainID, - ExportedOutputs: exportedOutputs, - } - - // We must initialize the bytes of the tx to calculate the initial cost - wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} - if err := wrappedTx.Sign(evm.Codec, nil); err != nil { - return nil, err - } - - cost, err := tx.GasUsed(true /*=IsApricotPhase5*/) - if err != nil { - return nil, err - } - - initialFee, err := evm.CalculateDynamicFee(cost, baseFee) - if err != nil { - return nil, err - } - - amountToConsume, err := math.Add64(exportedAmount, initialFee) - if err != nil { - return nil, err - } - - var ( - ops = common.NewOptions(options) - ctx = ops.Context() - addrs = ops.EthAddresses(b.ethAddrs) - inputs = make([]evm.EVMInput, 0, addrs.Len()) - ) - for addr := range addrs { - if amountToConsume == 0 { - break - } - - prevFee, err := evm.CalculateDynamicFee(cost, baseFee) - if err != nil { - return nil, err - } - - newCost := cost + evm.EVMInputGas - newFee, err := evm.CalculateDynamicFee(newCost, baseFee) - if err != nil { - return nil, err - } - - additionalFee := newFee - prevFee - - balance, err := b.backend.Balance(ctx, addr) - if err != nil { - return nil, err - } - - // Since the asset is AVAX, we divide by the avaxConversionRate to - // convert back to the correct denomination of AVAX that can be - // exported. - avaxBalance := new(big.Int).Div(balance, avaxConversionRate).Uint64() - - // If the balance for [addr] is insufficient to cover the additional - // cost of adding an input to the transaction, skip adding the input - // altogether. - if avaxBalance <= additionalFee { - continue - } - - // Update the cost for the next iteration - cost = newCost - - amountToConsume, err = math.Add64(amountToConsume, additionalFee) - if err != nil { - return nil, err - } - - nonce, err := b.backend.Nonce(ctx, addr) - if err != nil { - return nil, err - } - - inputAmount := math.Min(amountToConsume, avaxBalance) - inputs = append(inputs, evm.EVMInput{ - Address: addr, - Amount: inputAmount, - AssetID: avaxAssetID, - Nonce: nonce, - }) - amountToConsume -= inputAmount - } - - if amountToConsume > 0 { - return nil, errInsufficientFunds - } - - utils.Sort(inputs) - tx.Ins = inputs - - snowCtx, err := newSnowContext(b.backend) - if err != nil { - return nil, err - } - for _, out := range tx.ExportedOutputs { - out.InitCtx(snowCtx) - } - return tx, nil -} - -func getSpendableAmount( - utxo *avax.UTXO, - addrs set.Set[ids.ShortID], - minIssuanceTime uint64, - avaxAssetID ids.ID, -) (uint64, []uint32, bool) { - if utxo.Asset.ID != avaxAssetID { - // Only AVAX can be imported - return 0, nil, false - } - - out, ok := utxo.Out.(*secp256k1fx.TransferOutput) - if !ok { - // Can't import an unknown transfer output type - return 0, nil, false - } - - inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) - return out.Amt, inputSigIndices, ok -} +// import ( +// "errors" +// "math/big" + +// stdcontext "context" + +// "github.com/ava-labs/coreth/plugin/evm" + +// ethcommon "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/utils" +// "github.com/ava-labs/avalanchego/utils/math" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// const avaxConversionRateInt = 1_000_000_000 + +// var ( +// _ Builder = (*builder)(nil) + +// errInsufficientFunds = errors.New("insufficient funds") + +// // avaxConversionRate is the conversion rate between the smallest +// // denomination on the X-Chain and P-chain, 1 nAVAX, and the smallest +// // denomination on the C-Chain 1 wei. Where 1 nAVAX = 1 gWei. +// // +// // This is only required for AVAX because the denomination of 1 AVAX is 9 +// // decimal places on the X and P chains, but is 18 decimal places within the +// // EVM. +// avaxConversionRate = big.NewInt(avaxConversionRateInt) +// ) + +// // Builder provides a convenient interface for building unsigned C-chain +// // transactions. +// type Builder interface { +// // GetBalance calculates the amount of AVAX that this builder has control +// // over. +// GetBalance( +// options ...common.Option, +// ) (*big.Int, error) + +// // GetImportableBalance calculates the amount of AVAX that this builder +// // could import from the provided chain. +// // +// // - [chainID] specifies the chain the funds are from. +// GetImportableBalance( +// chainID ids.ID, +// options ...common.Option, +// ) (uint64, error) + +// // NewImportTx creates an import transaction that attempts to consume all +// // the available UTXOs and import the funds to [to]. +// // +// // - [chainID] specifies the chain to be importing funds from. +// // - [to] specifies where to send the imported funds to. +// // - [baseFee] specifies the fee price willing to be paid by this tx. +// NewImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedImportTx, error) + +// // NewExportTx creates an export transaction that attempts to send all the +// // provided [outputs] to the requested [chainID]. +// // +// // - [chainID] specifies the chain to be exporting the funds to. +// // - [outputs] specifies the outputs to send to the [chainID]. +// // - [baseFee] specifies the fee price willing to be paid by this tx. +// NewExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedExportTx, error) +// } + +// // BuilderBackend specifies the required information needed to build unsigned +// // C-chain transactions. +// type BuilderBackend interface { +// Context + +// UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) +// Balance(ctx stdcontext.Context, addr ethcommon.Address) (*big.Int, error) +// Nonce(ctx stdcontext.Context, addr ethcommon.Address) (uint64, error) +// } + +// type builder struct { +// avaxAddrs set.Set[ids.ShortID] +// ethAddrs set.Set[ethcommon.Address] +// backend BuilderBackend +// } + +// // NewBuilder returns a new transaction builder. +// // +// // - [avaxAddrs] is the set of addresses in the AVAX format that the builder +// // assumes can be used when signing the transactions in the future. +// // - [ethAddrs] is the set of addresses in the Eth format that the builder +// // assumes can be used when signing the transactions in the future. +// // - [backend] provides the required access to the chain's context and state +// // to build out the transactions. +// func NewBuilder( +// avaxAddrs set.Set[ids.ShortID], +// ethAddrs set.Set[ethcommon.Address], +// backend BuilderBackend, +// ) Builder { +// return &builder{ +// avaxAddrs: avaxAddrs, +// ethAddrs: ethAddrs, +// backend: backend, +// } +// } + +// func (b *builder) GetBalance( +// options ...common.Option, +// ) (*big.Int, error) { +// var ( +// ops = common.NewOptions(options) +// ctx = ops.Context() +// addrs = ops.EthAddresses(b.ethAddrs) +// totalBalance = new(big.Int) +// ) +// for addr := range addrs { +// balance, err := b.backend.Balance(ctx, addr) +// if err != nil { +// return nil, err +// } +// totalBalance.Add(totalBalance, balance) +// } + +// return totalBalance, nil +// } + +// func (b *builder) GetImportableBalance( +// chainID ids.ID, +// options ...common.Option, +// ) (uint64, error) { +// ops := common.NewOptions(options) +// utxos, err := b.backend.UTXOs(ops.Context(), chainID) +// if err != nil { +// return 0, err +// } + +// var ( +// addrs = ops.Addresses(b.avaxAddrs) +// minIssuanceTime = ops.MinIssuanceTime() +// avaxAssetID = b.backend.AVAXAssetID() +// balance uint64 +// ) +// for _, utxo := range utxos { +// amount, _, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) +// if !ok { +// continue +// } + +// newBalance, err := math.Add64(balance, amount) +// if err != nil { +// return 0, err +// } +// balance = newBalance +// } + +// return balance, nil +// } + +// func (b *builder) NewImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedImportTx, error) { +// ops := common.NewOptions(options) +// utxos, err := b.backend.UTXOs(ops.Context(), chainID) +// if err != nil { +// return nil, err +// } + +// var ( +// addrs = ops.Addresses(b.avaxAddrs) +// minIssuanceTime = ops.MinIssuanceTime() +// avaxAssetID = b.backend.AVAXAssetID() + +// importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) +// importedAmount uint64 +// ) +// for _, utxo := range utxos { +// amount, inputSigIndices, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) +// if !ok { +// continue +// } + +// importedInputs = append(importedInputs, &avax.TransferableInput{ +// UTXOID: utxo.UTXOID, +// Asset: utxo.Asset, +// FxID: secp256k1fx.ID, +// In: &secp256k1fx.TransferInput{ +// Amt: amount, +// Input: secp256k1fx.Input{ +// SigIndices: inputSigIndices, +// }, +// }, +// }) + +// newImportedAmount, err := math.Add64(importedAmount, amount) +// if err != nil { +// return nil, err +// } +// importedAmount = newImportedAmount +// } + +// utils.Sort(importedInputs) +// tx := &evm.UnsignedImportTx{ +// NetworkID: b.backend.NetworkID(), +// BlockchainID: b.backend.BlockchainID(), +// SourceChain: chainID, +// ImportedInputs: importedInputs, +// } + +// // We must initialize the bytes of the tx to calculate the initial cost +// wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} +// if err := wrappedTx.Sign(evm.Codec, nil); err != nil { +// return nil, err +// } + +// gasUsedWithoutOutput, err := tx.GasUsed(true /*=IsApricotPhase5*/) +// if err != nil { +// return nil, err +// } +// gasUsedWithOutput := gasUsedWithoutOutput + evm.EVMOutputGas + +// txFee, err := evm.CalculateDynamicFee(gasUsedWithOutput, baseFee) +// if err != nil { +// return nil, err +// } + +// if importedAmount <= txFee { +// return nil, errInsufficientFunds +// } + +// tx.Outs = []evm.EVMOutput{{ +// Address: to, +// Amount: importedAmount - txFee, +// AssetID: avaxAssetID, +// }} +// return tx, nil +// } + +// func (b *builder) NewExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedExportTx, error) { +// var ( +// avaxAssetID = b.backend.AVAXAssetID() +// exportedOutputs = make([]*avax.TransferableOutput, len(outputs)) +// exportedAmount uint64 +// ) +// for i, output := range outputs { +// exportedOutputs[i] = &avax.TransferableOutput{ +// Asset: avax.Asset{ID: avaxAssetID}, +// FxID: secp256k1fx.ID, +// Out: output, +// } + +// newExportedAmount, err := math.Add64(exportedAmount, output.Amt) +// if err != nil { +// return nil, err +// } +// exportedAmount = newExportedAmount +// } + +// avax.SortTransferableOutputs(exportedOutputs, evm.Codec) +// tx := &evm.UnsignedExportTx{ +// NetworkID: b.backend.NetworkID(), +// BlockchainID: b.backend.BlockchainID(), +// DestinationChain: chainID, +// ExportedOutputs: exportedOutputs, +// } + +// // We must initialize the bytes of the tx to calculate the initial cost +// wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} +// if err := wrappedTx.Sign(evm.Codec, nil); err != nil { +// return nil, err +// } + +// cost, err := tx.GasUsed(true /*=IsApricotPhase5*/) +// if err != nil { +// return nil, err +// } + +// initialFee, err := evm.CalculateDynamicFee(cost, baseFee) +// if err != nil { +// return nil, err +// } + +// amountToConsume, err := math.Add64(exportedAmount, initialFee) +// if err != nil { +// return nil, err +// } + +// var ( +// ops = common.NewOptions(options) +// ctx = ops.Context() +// addrs = ops.EthAddresses(b.ethAddrs) +// inputs = make([]evm.EVMInput, 0, addrs.Len()) +// ) +// for addr := range addrs { +// if amountToConsume == 0 { +// break +// } + +// prevFee, err := evm.CalculateDynamicFee(cost, baseFee) +// if err != nil { +// return nil, err +// } + +// newCost := cost + evm.EVMInputGas +// newFee, err := evm.CalculateDynamicFee(newCost, baseFee) +// if err != nil { +// return nil, err +// } + +// additionalFee := newFee - prevFee + +// balance, err := b.backend.Balance(ctx, addr) +// if err != nil { +// return nil, err +// } + +// // Since the asset is AVAX, we divide by the avaxConversionRate to +// // convert back to the correct denomination of AVAX that can be +// // exported. +// avaxBalance := new(big.Int).Div(balance, avaxConversionRate).Uint64() + +// // If the balance for [addr] is insufficient to cover the additional +// // cost of adding an input to the transaction, skip adding the input +// // altogether. +// if avaxBalance <= additionalFee { +// continue +// } + +// // Update the cost for the next iteration +// cost = newCost + +// amountToConsume, err = math.Add64(amountToConsume, additionalFee) +// if err != nil { +// return nil, err +// } + +// nonce, err := b.backend.Nonce(ctx, addr) +// if err != nil { +// return nil, err +// } + +// inputAmount := math.Min(amountToConsume, avaxBalance) +// inputs = append(inputs, evm.EVMInput{ +// Address: addr, +// Amount: inputAmount, +// AssetID: avaxAssetID, +// Nonce: nonce, +// }) +// amountToConsume -= inputAmount +// } + +// if amountToConsume > 0 { +// return nil, errInsufficientFunds +// } + +// utils.Sort(inputs) +// tx.Ins = inputs + +// snowCtx, err := newSnowContext(b.backend) +// if err != nil { +// return nil, err +// } +// for _, out := range tx.ExportedOutputs { +// out.InitCtx(snowCtx) +// } +// return tx, nil +// } + +// func getSpendableAmount( +// utxo *avax.UTXO, +// addrs set.Set[ids.ShortID], +// minIssuanceTime uint64, +// avaxAssetID ids.ID, +// ) (uint64, []uint32, bool) { +// if utxo.Asset.ID != avaxAssetID { +// // Only AVAX can be imported +// return 0, nil, false +// } + +// out, ok := utxo.Out.(*secp256k1fx.TransferOutput) +// if !ok { +// // Can't import an unknown transfer output type +// return 0, nil, false +// } + +// inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) +// return out.Amt, inputSigIndices, ok +// } diff --git a/wallet/chain/c/builder_with_options.go b/wallet/chain/c/builder_with_options.go index 8416dddf9928..9b7ab8399484 100644 --- a/wallet/chain/c/builder_with_options.go +++ b/wallet/chain/c/builder_with_options.go @@ -3,81 +3,81 @@ package c -import ( - "math/big" +// import ( +// "math/big" - "github.com/ava-labs/coreth/plugin/evm" +// "github.com/ava-labs/coreth/plugin/evm" - ethcommon "github.com/ethereum/go-ethereum/common" +// ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) -var _ Builder = (*builderWithOptions)(nil) +// var _ Builder = (*builderWithOptions)(nil) -type builderWithOptions struct { - Builder - options []common.Option -} +// type builderWithOptions struct { +// Builder +// options []common.Option +// } -// NewBuilderWithOptions returns a new transaction builder that will use the -// given options by default. -// -// - [builder] is the builder that will be called to perform the underlying -// operations. -// - [options] will be provided to the builder in addition to the options -// provided in the method calls. -func NewBuilderWithOptions(builder Builder, options ...common.Option) Builder { - return &builderWithOptions{ - Builder: builder, - options: options, - } -} +// // NewBuilderWithOptions returns a new transaction builder that will use the +// // given options by default. +// // +// // - [builder] is the builder that will be called to perform the underlying +// // operations. +// // - [options] will be provided to the builder in addition to the options +// // provided in the method calls. +// func NewBuilderWithOptions(builder Builder, options ...common.Option) Builder { +// return &builderWithOptions{ +// Builder: builder, +// options: options, +// } +// } -func (b *builderWithOptions) GetBalance( - options ...common.Option, -) (*big.Int, error) { - return b.Builder.GetBalance( - common.UnionOptions(b.options, options)..., - ) -} +// func (b *builderWithOptions) GetBalance( +// options ...common.Option, +// ) (*big.Int, error) { +// return b.Builder.GetBalance( +// common.UnionOptions(b.options, options)..., +// ) +// } -func (b *builderWithOptions) GetImportableBalance( - chainID ids.ID, - options ...common.Option, -) (uint64, error) { - return b.Builder.GetImportableBalance( - chainID, - common.UnionOptions(b.options, options)..., - ) -} +// func (b *builderWithOptions) GetImportableBalance( +// chainID ids.ID, +// options ...common.Option, +// ) (uint64, error) { +// return b.Builder.GetImportableBalance( +// chainID, +// common.UnionOptions(b.options, options)..., +// ) +// } -func (b *builderWithOptions) NewImportTx( - chainID ids.ID, - to ethcommon.Address, - baseFee *big.Int, - options ...common.Option, -) (*evm.UnsignedImportTx, error) { - return b.Builder.NewImportTx( - chainID, - to, - baseFee, - common.UnionOptions(b.options, options)..., - ) -} +// func (b *builderWithOptions) NewImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedImportTx, error) { +// return b.Builder.NewImportTx( +// chainID, +// to, +// baseFee, +// common.UnionOptions(b.options, options)..., +// ) +// } -func (b *builderWithOptions) NewExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - baseFee *big.Int, - options ...common.Option, -) (*evm.UnsignedExportTx, error) { - return b.Builder.NewExportTx( - chainID, - outputs, - baseFee, - common.UnionOptions(b.options, options)..., - ) -} +// func (b *builderWithOptions) NewExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// baseFee *big.Int, +// options ...common.Option, +// ) (*evm.UnsignedExportTx, error) { +// return b.Builder.NewExportTx( +// chainID, +// outputs, +// baseFee, +// common.UnionOptions(b.options, options)..., +// ) +// } diff --git a/wallet/chain/c/context.go b/wallet/chain/c/context.go index b9cd41cb5667..c56a114a276e 100644 --- a/wallet/chain/c/context.go +++ b/wallet/chain/c/context.go @@ -3,100 +3,100 @@ package c -import ( - stdcontext "context" - - "github.com/ava-labs/avalanchego/api/info" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/logging" - "github.com/ava-labs/avalanchego/vms/avm" -) - -const Alias = "C" - -var _ Context = (*context)(nil) - -type Context interface { - NetworkID() uint32 - BlockchainID() ids.ID - AVAXAssetID() ids.ID -} - -type context struct { - networkID uint32 - blockchainID ids.ID - avaxAssetID ids.ID -} - -func NewContextFromURI(ctx stdcontext.Context, uri string) (Context, error) { - infoClient := info.NewClient(uri) - xChainClient := avm.NewClient(uri, "X") - return NewContextFromClients(ctx, infoClient, xChainClient) -} - -func NewContextFromClients( - ctx stdcontext.Context, - infoClient info.Client, - xChainClient avm.Client, -) (Context, error) { - networkID, err := infoClient.GetNetworkID(ctx) - if err != nil { - return nil, err - } - - chainID, err := infoClient.GetBlockchainID(ctx, Alias) - if err != nil { - return nil, err - } - - asset, err := xChainClient.GetAssetDescription(ctx, "AVAX") - if err != nil { - return nil, err - } - - return NewContext( - networkID, - chainID, - asset.AssetID, - ), nil -} - -func NewContext( - networkID uint32, - blockchainID ids.ID, - avaxAssetID ids.ID, -) Context { - return &context{ - networkID: networkID, - blockchainID: blockchainID, - avaxAssetID: avaxAssetID, - } -} - -func (c *context) NetworkID() uint32 { - return c.networkID -} - -func (c *context) BlockchainID() ids.ID { - return c.blockchainID -} - -func (c *context) AVAXAssetID() ids.ID { - return c.avaxAssetID -} - -func newSnowContext(c Context) (*snow.Context, error) { - chainID := c.BlockchainID() - lookup := ids.NewAliaser() - return &snow.Context{ - NetworkID: c.NetworkID(), - SubnetID: constants.PrimaryNetworkID, - ChainID: chainID, - CChainID: chainID, - AVAXAssetID: c.AVAXAssetID(), - Log: logging.NoLog{}, - BCLookup: lookup, - }, lookup.Alias(chainID, Alias) -} +// import ( +// stdcontext "context" + +// "github.com/ava-labs/avalanchego/api/info" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/snow" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/logging" +// "github.com/ava-labs/avalanchego/vms/avm" +// ) + +// const Alias = "C" + +// var _ Context = (*context)(nil) + +// type Context interface { +// NetworkID() uint32 +// BlockchainID() ids.ID +// AVAXAssetID() ids.ID +// } + +// type context struct { +// networkID uint32 +// blockchainID ids.ID +// avaxAssetID ids.ID +// } + +// func NewContextFromURI(ctx stdcontext.Context, uri string) (Context, error) { +// infoClient := info.NewClient(uri) +// xChainClient := avm.NewClient(uri, "X") +// return NewContextFromClients(ctx, infoClient, xChainClient) +// } + +// func NewContextFromClients( +// ctx stdcontext.Context, +// infoClient info.Client, +// xChainClient avm.Client, +// ) (Context, error) { +// networkID, err := infoClient.GetNetworkID(ctx) +// if err != nil { +// return nil, err +// } + +// chainID, err := infoClient.GetBlockchainID(ctx, Alias) +// if err != nil { +// return nil, err +// } + +// asset, err := xChainClient.GetAssetDescription(ctx, "AVAX") +// if err != nil { +// return nil, err +// } + +// return NewContext( +// networkID, +// chainID, +// asset.AssetID, +// ), nil +// } + +// func NewContext( +// networkID uint32, +// blockchainID ids.ID, +// avaxAssetID ids.ID, +// ) Context { +// return &context{ +// networkID: networkID, +// blockchainID: blockchainID, +// avaxAssetID: avaxAssetID, +// } +// } + +// func (c *context) NetworkID() uint32 { +// return c.networkID +// } + +// func (c *context) BlockchainID() ids.ID { +// return c.blockchainID +// } + +// func (c *context) AVAXAssetID() ids.ID { +// return c.avaxAssetID +// } + +// func newSnowContext(c Context) (*snow.Context, error) { +// chainID := c.BlockchainID() +// lookup := ids.NewAliaser() +// return &snow.Context{ +// NetworkID: c.NetworkID(), +// SubnetID: constants.PrimaryNetworkID, +// ChainID: chainID, +// CChainID: chainID, +// AVAXAssetID: c.AVAXAssetID(), +// Log: logging.NoLog{}, +// BCLookup: lookup, +// }, lookup.Alias(chainID, Alias) +// } diff --git a/wallet/chain/c/signer.go b/wallet/chain/c/signer.go index 4fd85ed3b532..4bedc378234b 100644 --- a/wallet/chain/c/signer.go +++ b/wallet/chain/c/signer.go @@ -3,221 +3,221 @@ package c -import ( - "errors" - "fmt" - - stdcontext "context" - - "github.com/ava-labs/coreth/plugin/evm" - - ethcommon "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/avalanchego/database" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/crypto/keychain" - "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" - "github.com/ava-labs/avalanchego/utils/hashing" - "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/components/verify" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" -) - -const version = 0 - -var ( - _ Signer = (*txSigner)(nil) - - errUnknownInputType = errors.New("unknown input type") - errUnknownCredentialType = errors.New("unknown credential type") - errUnknownOutputType = errors.New("unknown output type") - errInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") - - emptySig [secp256k1.SignatureLen]byte -) - -type Signer interface { - SignUnsignedAtomic(ctx stdcontext.Context, tx evm.UnsignedAtomicTx) (*evm.Tx, error) - SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error -} - -type EthKeychain interface { - // The returned Signer can provide a signature for [addr] - GetEth(addr ethcommon.Address) (keychain.Signer, bool) - // Returns the set of addresses for which the accessor keeps an associated - // signer - EthAddresses() set.Set[ethcommon.Address] -} - -type SignerBackend interface { - GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) -} - -type txSigner struct { - avaxKC keychain.Keychain - ethKC EthKeychain - backend SignerBackend -} - -func NewSigner(avaxKC keychain.Keychain, ethKC EthKeychain, backend SignerBackend) Signer { - return &txSigner{ - avaxKC: avaxKC, - ethKC: ethKC, - backend: backend, - } -} - -func (s *txSigner) SignUnsignedAtomic(ctx stdcontext.Context, utx evm.UnsignedAtomicTx) (*evm.Tx, error) { - tx := &evm.Tx{UnsignedAtomicTx: utx} - return tx, s.SignAtomic(ctx, tx) -} - -func (s *txSigner) SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error { - switch utx := tx.UnsignedAtomicTx.(type) { - case *evm.UnsignedImportTx: - signers, err := s.getImportSigners(ctx, utx.SourceChain, utx.ImportedInputs) - if err != nil { - return err - } - return sign(tx, true, signers) - case *evm.UnsignedExportTx: - signers := s.getExportSigners(utx.Ins) - return sign(tx, true, signers) - default: - return fmt.Errorf("%w: %T", errUnknownTxType, tx) - } -} - -func (s *txSigner) getImportSigners(ctx stdcontext.Context, sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { - txSigners := make([][]keychain.Signer, len(ins)) - for credIndex, transferInput := range ins { - input, ok := transferInput.In.(*secp256k1fx.TransferInput) - if !ok { - return nil, errUnknownInputType - } - - inputSigners := make([]keychain.Signer, len(input.SigIndices)) - txSigners[credIndex] = inputSigners - - utxoID := transferInput.InputID() - utxo, err := s.backend.GetUTXO(ctx, sourceChainID, utxoID) - if err == database.ErrNotFound { - // If we don't have access to the UTXO, then we can't sign this - // transaction. However, we can attempt to partially sign it. - continue - } - if err != nil { - return nil, err - } - - out, ok := utxo.Out.(*secp256k1fx.TransferOutput) - if !ok { - return nil, errUnknownOutputType - } - - for sigIndex, addrIndex := range input.SigIndices { - if addrIndex >= uint32(len(out.Addrs)) { - return nil, errInvalidUTXOSigIndex - } - - addr := out.Addrs[addrIndex] - key, ok := s.avaxKC.Get(addr) - if !ok { - // If we don't have access to the key, then we can't sign this - // transaction. However, we can attempt to partially sign it. - continue - } - inputSigners[sigIndex] = key - } - } - return txSigners, nil -} - -func (s *txSigner) getExportSigners(ins []evm.EVMInput) [][]keychain.Signer { - txSigners := make([][]keychain.Signer, len(ins)) - for credIndex, input := range ins { - inputSigners := make([]keychain.Signer, 1) - txSigners[credIndex] = inputSigners - - key, ok := s.ethKC.GetEth(input.Address) - if !ok { - // If we don't have access to the key, then we can't sign this - // transaction. However, we can attempt to partially sign it. - continue - } - inputSigners[0] = key - } - return txSigners -} - -// TODO: remove [signHash] after the ledger supports signing all transactions. -func sign(tx *evm.Tx, signHash bool, txSigners [][]keychain.Signer) error { - unsignedBytes, err := evm.Codec.Marshal(version, &tx.UnsignedAtomicTx) - if err != nil { - return fmt.Errorf("couldn't marshal unsigned tx: %w", err) - } - unsignedHash := hashing.ComputeHash256(unsignedBytes) - - if expectedLen := len(txSigners); expectedLen != len(tx.Creds) { - tx.Creds = make([]verify.Verifiable, expectedLen) - } - - sigCache := make(map[ids.ShortID][secp256k1.SignatureLen]byte) - for credIndex, inputSigners := range txSigners { - credIntf := tx.Creds[credIndex] - if credIntf == nil { - credIntf = &secp256k1fx.Credential{} - tx.Creds[credIndex] = credIntf - } - - cred, ok := credIntf.(*secp256k1fx.Credential) - if !ok { - return errUnknownCredentialType - } - if expectedLen := len(inputSigners); expectedLen != len(cred.Sigs) { - cred.Sigs = make([][secp256k1.SignatureLen]byte, expectedLen) - } - - for sigIndex, signer := range inputSigners { - if signer == nil { - // If we don't have access to the key, then we can't sign this - // transaction. However, we can attempt to partially sign it. - continue - } - addr := signer.Address() - if sig := cred.Sigs[sigIndex]; sig != emptySig { - // If this signature has already been populated, we can just - // copy the needed signature for the future. - sigCache[addr] = sig - continue - } - - if sig, exists := sigCache[addr]; exists { - // If this key has already produced a signature, we can just - // copy the previous signature. - cred.Sigs[sigIndex] = sig - continue - } - - var sig []byte - if signHash { - sig, err = signer.SignHash(unsignedHash) - } else { - sig, err = signer.Sign(unsignedBytes) - } - if err != nil { - return fmt.Errorf("problem signing tx: %w", err) - } - copy(cred.Sigs[sigIndex][:], sig) - sigCache[addr] = cred.Sigs[sigIndex] - } - } - - signedBytes, err := evm.Codec.Marshal(version, tx) - if err != nil { - return fmt.Errorf("couldn't marshal tx: %w", err) - } - tx.Initialize(unsignedBytes, signedBytes) - return nil -} +// import ( +// "errors" +// "fmt" + +// stdcontext "context" + +// "github.com/ava-labs/coreth/plugin/evm" + +// ethcommon "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/avalanchego/database" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/utils/crypto/keychain" +// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +// "github.com/ava-labs/avalanchego/utils/hashing" +// "github.com/ava-labs/avalanchego/utils/set" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/components/verify" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// ) + +// const version = 0 + +// var ( +// _ Signer = (*txSigner)(nil) + +// errUnknownInputType = errors.New("unknown input type") +// errUnknownCredentialType = errors.New("unknown credential type") +// errUnknownOutputType = errors.New("unknown output type") +// errInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") + +// emptySig [secp256k1.SignatureLen]byte +// ) + +// type Signer interface { +// SignUnsignedAtomic(ctx stdcontext.Context, tx evm.UnsignedAtomicTx) (*evm.Tx, error) +// SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error +// } + +// type EthKeychain interface { +// // The returned Signer can provide a signature for [addr] +// GetEth(addr ethcommon.Address) (keychain.Signer, bool) +// // Returns the set of addresses for which the accessor keeps an associated +// // signer +// EthAddresses() set.Set[ethcommon.Address] +// } + +// type SignerBackend interface { +// GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) +// } + +// type txSigner struct { +// avaxKC keychain.Keychain +// ethKC EthKeychain +// backend SignerBackend +// } + +// func NewSigner(avaxKC keychain.Keychain, ethKC EthKeychain, backend SignerBackend) Signer { +// return &txSigner{ +// avaxKC: avaxKC, +// ethKC: ethKC, +// backend: backend, +// } +// } + +// func (s *txSigner) SignUnsignedAtomic(ctx stdcontext.Context, utx evm.UnsignedAtomicTx) (*evm.Tx, error) { +// tx := &evm.Tx{UnsignedAtomicTx: utx} +// return tx, s.SignAtomic(ctx, tx) +// } + +// func (s *txSigner) SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error { +// switch utx := tx.UnsignedAtomicTx.(type) { +// case *evm.UnsignedImportTx: +// signers, err := s.getImportSigners(ctx, utx.SourceChain, utx.ImportedInputs) +// if err != nil { +// return err +// } +// return sign(tx, true, signers) +// case *evm.UnsignedExportTx: +// signers := s.getExportSigners(utx.Ins) +// return sign(tx, true, signers) +// default: +// return fmt.Errorf("%w: %T", errUnknownTxType, tx) +// } +// } + +// func (s *txSigner) getImportSigners(ctx stdcontext.Context, sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { +// txSigners := make([][]keychain.Signer, len(ins)) +// for credIndex, transferInput := range ins { +// input, ok := transferInput.In.(*secp256k1fx.TransferInput) +// if !ok { +// return nil, errUnknownInputType +// } + +// inputSigners := make([]keychain.Signer, len(input.SigIndices)) +// txSigners[credIndex] = inputSigners + +// utxoID := transferInput.InputID() +// utxo, err := s.backend.GetUTXO(ctx, sourceChainID, utxoID) +// if err == database.ErrNotFound { +// // If we don't have access to the UTXO, then we can't sign this +// // transaction. However, we can attempt to partially sign it. +// continue +// } +// if err != nil { +// return nil, err +// } + +// out, ok := utxo.Out.(*secp256k1fx.TransferOutput) +// if !ok { +// return nil, errUnknownOutputType +// } + +// for sigIndex, addrIndex := range input.SigIndices { +// if addrIndex >= uint32(len(out.Addrs)) { +// return nil, errInvalidUTXOSigIndex +// } + +// addr := out.Addrs[addrIndex] +// key, ok := s.avaxKC.Get(addr) +// if !ok { +// // If we don't have access to the key, then we can't sign this +// // transaction. However, we can attempt to partially sign it. +// continue +// } +// inputSigners[sigIndex] = key +// } +// } +// return txSigners, nil +// } + +// func (s *txSigner) getExportSigners(ins []evm.EVMInput) [][]keychain.Signer { +// txSigners := make([][]keychain.Signer, len(ins)) +// for credIndex, input := range ins { +// inputSigners := make([]keychain.Signer, 1) +// txSigners[credIndex] = inputSigners + +// key, ok := s.ethKC.GetEth(input.Address) +// if !ok { +// // If we don't have access to the key, then we can't sign this +// // transaction. However, we can attempt to partially sign it. +// continue +// } +// inputSigners[0] = key +// } +// return txSigners +// } + +// // TODO: remove [signHash] after the ledger supports signing all transactions. +// func sign(tx *evm.Tx, signHash bool, txSigners [][]keychain.Signer) error { +// unsignedBytes, err := evm.Codec.Marshal(version, &tx.UnsignedAtomicTx) +// if err != nil { +// return fmt.Errorf("couldn't marshal unsigned tx: %w", err) +// } +// unsignedHash := hashing.ComputeHash256(unsignedBytes) + +// if expectedLen := len(txSigners); expectedLen != len(tx.Creds) { +// tx.Creds = make([]verify.Verifiable, expectedLen) +// } + +// sigCache := make(map[ids.ShortID][secp256k1.SignatureLen]byte) +// for credIndex, inputSigners := range txSigners { +// credIntf := tx.Creds[credIndex] +// if credIntf == nil { +// credIntf = &secp256k1fx.Credential{} +// tx.Creds[credIndex] = credIntf +// } + +// cred, ok := credIntf.(*secp256k1fx.Credential) +// if !ok { +// return errUnknownCredentialType +// } +// if expectedLen := len(inputSigners); expectedLen != len(cred.Sigs) { +// cred.Sigs = make([][secp256k1.SignatureLen]byte, expectedLen) +// } + +// for sigIndex, signer := range inputSigners { +// if signer == nil { +// // If we don't have access to the key, then we can't sign this +// // transaction. However, we can attempt to partially sign it. +// continue +// } +// addr := signer.Address() +// if sig := cred.Sigs[sigIndex]; sig != emptySig { +// // If this signature has already been populated, we can just +// // copy the needed signature for the future. +// sigCache[addr] = sig +// continue +// } + +// if sig, exists := sigCache[addr]; exists { +// // If this key has already produced a signature, we can just +// // copy the previous signature. +// cred.Sigs[sigIndex] = sig +// continue +// } + +// var sig []byte +// if signHash { +// sig, err = signer.SignHash(unsignedHash) +// } else { +// sig, err = signer.Sign(unsignedBytes) +// } +// if err != nil { +// return fmt.Errorf("problem signing tx: %w", err) +// } +// copy(cred.Sigs[sigIndex][:], sig) +// sigCache[addr] = cred.Sigs[sigIndex] +// } +// } + +// signedBytes, err := evm.Codec.Marshal(version, tx) +// if err != nil { +// return fmt.Errorf("couldn't marshal tx: %w", err) +// } +// tx.Initialize(unsignedBytes, signedBytes) +// return nil +// } diff --git a/wallet/chain/c/wallet.go b/wallet/chain/c/wallet.go index fb1a83d53dad..ebee50a9a958 100644 --- a/wallet/chain/c/wallet.go +++ b/wallet/chain/c/wallet.go @@ -3,204 +3,204 @@ package c -import ( - "errors" - "math/big" - "time" - - "github.com/ava-labs/coreth/ethclient" - "github.com/ava-labs/coreth/plugin/evm" - - ethcommon "github.com/ethereum/go-ethereum/common" - - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) - -var ( - _ Wallet = (*wallet)(nil) - - errNotCommitted = errors.New("not committed") -) - -type Wallet interface { - Context - - // Builder returns the builder that will be used to create the transactions. - Builder() Builder - - // Signer returns the signer that will be used to sign the transactions. - Signer() Signer - - // IssueImportTx creates, signs, and issues an import transaction that - // attempts to consume all the available UTXOs and import the funds to [to]. - // - // - [chainID] specifies the chain to be importing funds from. - // - [to] specifies where to send the imported funds to. - IssueImportTx( - chainID ids.ID, - to ethcommon.Address, - options ...common.Option, - ) (*evm.Tx, error) - - // IssueExportTx creates, signs, and issues an export transaction that - // attempts to send all the provided [outputs] to the requested [chainID]. - // - // - [chainID] specifies the chain to be exporting the funds to. - // - [outputs] specifies the outputs to send to the [chainID]. - IssueExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - options ...common.Option, - ) (*evm.Tx, error) - - // IssueUnsignedTx signs and issues the unsigned tx. - IssueUnsignedAtomicTx( - utx evm.UnsignedAtomicTx, - options ...common.Option, - ) (*evm.Tx, error) - - // IssueAtomicTx issues the signed tx. - IssueAtomicTx( - tx *evm.Tx, - options ...common.Option, - ) error -} - -func NewWallet( - builder Builder, - signer Signer, - avaxClient evm.Client, - ethClient ethclient.Client, - backend Backend, -) Wallet { - return &wallet{ - Backend: backend, - builder: builder, - signer: signer, - avaxClient: avaxClient, - ethClient: ethClient, - } -} - -type wallet struct { - Backend - builder Builder - signer Signer - avaxClient evm.Client - ethClient ethclient.Client -} - -func (w *wallet) Builder() Builder { - return w.builder -} - -func (w *wallet) Signer() Signer { - return w.signer -} - -func (w *wallet) IssueImportTx( - chainID ids.ID, - to ethcommon.Address, - options ...common.Option, -) (*evm.Tx, error) { - baseFee, err := w.baseFee(options) - if err != nil { - return nil, err - } - - utx, err := w.builder.NewImportTx(chainID, to, baseFee, options...) - if err != nil { - return nil, err - } - return w.IssueUnsignedAtomicTx(utx, options...) -} - -func (w *wallet) IssueExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - options ...common.Option, -) (*evm.Tx, error) { - baseFee, err := w.baseFee(options) - if err != nil { - return nil, err - } - - utx, err := w.builder.NewExportTx(chainID, outputs, baseFee, options...) - if err != nil { - return nil, err - } - return w.IssueUnsignedAtomicTx(utx, options...) -} - -func (w *wallet) IssueUnsignedAtomicTx( - utx evm.UnsignedAtomicTx, - options ...common.Option, -) (*evm.Tx, error) { - ops := common.NewOptions(options) - ctx := ops.Context() - tx, err := w.signer.SignUnsignedAtomic(ctx, utx) - if err != nil { - return nil, err - } - - return tx, w.IssueAtomicTx(tx, options...) -} - -func (w *wallet) IssueAtomicTx( - tx *evm.Tx, - options ...common.Option, -) error { - ops := common.NewOptions(options) - ctx := ops.Context() - txID, err := w.avaxClient.IssueTx(ctx, tx.SignedBytes()) - if err != nil { - return err - } - - if f := ops.PostIssuanceFunc(); f != nil { - f(txID) - } - - if ops.AssumeDecided() { - return w.Backend.AcceptAtomicTx(ctx, tx) - } - - pollFrequency := ops.PollFrequency() - ticker := time.NewTicker(pollFrequency) - defer ticker.Stop() - - for { - status, err := w.avaxClient.GetAtomicTxStatus(ctx, txID) - if err != nil { - return err - } - - switch status { - case evm.Accepted: - return w.Backend.AcceptAtomicTx(ctx, tx) - case evm.Dropped, evm.Unknown: - return errNotCommitted - } - - // The tx is Processing. - - select { - case <-ticker.C: - case <-ctx.Done(): - return ctx.Err() - } - } -} - -func (w *wallet) baseFee(options []common.Option) (*big.Int, error) { - ops := common.NewOptions(options) - baseFee := ops.BaseFee(nil) - if baseFee != nil { - return baseFee, nil - } - - ctx := ops.Context() - return w.ethClient.EstimateBaseFee(ctx) -} +// import ( +// "errors" +// "math/big" +// "time" + +// "github.com/ava-labs/coreth/ethclient" +// "github.com/ava-labs/coreth/plugin/evm" + +// ethcommon "github.com/ethereum/go-ethereum/common" + +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) + +// var ( +// _ Wallet = (*wallet)(nil) + +// errNotCommitted = errors.New("not committed") +// ) + +// type Wallet interface { +// Context + +// // Builder returns the builder that will be used to create the transactions. +// Builder() Builder + +// // Signer returns the signer that will be used to sign the transactions. +// Signer() Signer + +// // IssueImportTx creates, signs, and issues an import transaction that +// // attempts to consume all the available UTXOs and import the funds to [to]. +// // +// // - [chainID] specifies the chain to be importing funds from. +// // - [to] specifies where to send the imported funds to. +// IssueImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// options ...common.Option, +// ) (*evm.Tx, error) + +// // IssueExportTx creates, signs, and issues an export transaction that +// // attempts to send all the provided [outputs] to the requested [chainID]. +// // +// // - [chainID] specifies the chain to be exporting the funds to. +// // - [outputs] specifies the outputs to send to the [chainID]. +// IssueExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// options ...common.Option, +// ) (*evm.Tx, error) + +// // IssueUnsignedTx signs and issues the unsigned tx. +// IssueUnsignedAtomicTx( +// utx evm.UnsignedAtomicTx, +// options ...common.Option, +// ) (*evm.Tx, error) + +// // IssueAtomicTx issues the signed tx. +// IssueAtomicTx( +// tx *evm.Tx, +// options ...common.Option, +// ) error +// } + +// func NewWallet( +// builder Builder, +// signer Signer, +// avaxClient evm.Client, +// ethClient ethclient.Client, +// backend Backend, +// ) Wallet { +// return &wallet{ +// Backend: backend, +// builder: builder, +// signer: signer, +// avaxClient: avaxClient, +// ethClient: ethClient, +// } +// } + +// type wallet struct { +// Backend +// builder Builder +// signer Signer +// avaxClient evm.Client +// ethClient ethclient.Client +// } + +// func (w *wallet) Builder() Builder { +// return w.builder +// } + +// func (w *wallet) Signer() Signer { +// return w.signer +// } + +// func (w *wallet) IssueImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// options ...common.Option, +// ) (*evm.Tx, error) { +// baseFee, err := w.baseFee(options) +// if err != nil { +// return nil, err +// } + +// utx, err := w.builder.NewImportTx(chainID, to, baseFee, options...) +// if err != nil { +// return nil, err +// } +// return w.IssueUnsignedAtomicTx(utx, options...) +// } + +// func (w *wallet) IssueExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// options ...common.Option, +// ) (*evm.Tx, error) { +// baseFee, err := w.baseFee(options) +// if err != nil { +// return nil, err +// } + +// utx, err := w.builder.NewExportTx(chainID, outputs, baseFee, options...) +// if err != nil { +// return nil, err +// } +// return w.IssueUnsignedAtomicTx(utx, options...) +// } + +// func (w *wallet) IssueUnsignedAtomicTx( +// utx evm.UnsignedAtomicTx, +// options ...common.Option, +// ) (*evm.Tx, error) { +// ops := common.NewOptions(options) +// ctx := ops.Context() +// tx, err := w.signer.SignUnsignedAtomic(ctx, utx) +// if err != nil { +// return nil, err +// } + +// return tx, w.IssueAtomicTx(tx, options...) +// } + +// func (w *wallet) IssueAtomicTx( +// tx *evm.Tx, +// options ...common.Option, +// ) error { +// ops := common.NewOptions(options) +// ctx := ops.Context() +// txID, err := w.avaxClient.IssueTx(ctx, tx.SignedBytes()) +// if err != nil { +// return err +// } + +// if f := ops.PostIssuanceFunc(); f != nil { +// f(txID) +// } + +// if ops.AssumeDecided() { +// return w.Backend.AcceptAtomicTx(ctx, tx) +// } + +// pollFrequency := ops.PollFrequency() +// ticker := time.NewTicker(pollFrequency) +// defer ticker.Stop() + +// for { +// status, err := w.avaxClient.GetAtomicTxStatus(ctx, txID) +// if err != nil { +// return err +// } + +// switch status { +// case evm.Accepted: +// return w.Backend.AcceptAtomicTx(ctx, tx) +// case evm.Dropped, evm.Unknown: +// return errNotCommitted +// } + +// // The tx is Processing. + +// select { +// case <-ticker.C: +// case <-ctx.Done(): +// return ctx.Err() +// } +// } +// } + +// func (w *wallet) baseFee(options []common.Option) (*big.Int, error) { +// ops := common.NewOptions(options) +// baseFee := ops.BaseFee(nil) +// if baseFee != nil { +// return baseFee, nil +// } + +// ctx := ops.Context() +// return w.ethClient.EstimateBaseFee(ctx) +// } diff --git a/wallet/chain/c/wallet_with_options.go b/wallet/chain/c/wallet_with_options.go index 7d6193683d49..fd69a6d4fd02 100644 --- a/wallet/chain/c/wallet_with_options.go +++ b/wallet/chain/c/wallet_with_options.go @@ -3,80 +3,80 @@ package c -import ( - "github.com/ava-labs/coreth/plugin/evm" +// import ( +// "github.com/ava-labs/coreth/plugin/evm" - ethcommon "github.com/ethereum/go-ethereum/common" +// ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -) +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +// ) -var _ Wallet = (*walletWithOptions)(nil) +// var _ Wallet = (*walletWithOptions)(nil) -func NewWalletWithOptions( - wallet Wallet, - options ...common.Option, -) Wallet { - return &walletWithOptions{ - Wallet: wallet, - options: options, - } -} +// func NewWalletWithOptions( +// wallet Wallet, +// options ...common.Option, +// ) Wallet { +// return &walletWithOptions{ +// Wallet: wallet, +// options: options, +// } +// } -type walletWithOptions struct { - Wallet - options []common.Option -} +// type walletWithOptions struct { +// Wallet +// options []common.Option +// } -func (w *walletWithOptions) Builder() Builder { - return NewBuilderWithOptions( - w.Wallet.Builder(), - w.options..., - ) -} +// func (w *walletWithOptions) Builder() Builder { +// return NewBuilderWithOptions( +// w.Wallet.Builder(), +// w.options..., +// ) +// } -func (w *walletWithOptions) IssueImportTx( - chainID ids.ID, - to ethcommon.Address, - options ...common.Option, -) (*evm.Tx, error) { - return w.Wallet.IssueImportTx( - chainID, - to, - common.UnionOptions(w.options, options)..., - ) -} +// func (w *walletWithOptions) IssueImportTx( +// chainID ids.ID, +// to ethcommon.Address, +// options ...common.Option, +// ) (*evm.Tx, error) { +// return w.Wallet.IssueImportTx( +// chainID, +// to, +// common.UnionOptions(w.options, options)..., +// ) +// } -func (w *walletWithOptions) IssueExportTx( - chainID ids.ID, - outputs []*secp256k1fx.TransferOutput, - options ...common.Option, -) (*evm.Tx, error) { - return w.Wallet.IssueExportTx( - chainID, - outputs, - common.UnionOptions(w.options, options)..., - ) -} +// func (w *walletWithOptions) IssueExportTx( +// chainID ids.ID, +// outputs []*secp256k1fx.TransferOutput, +// options ...common.Option, +// ) (*evm.Tx, error) { +// return w.Wallet.IssueExportTx( +// chainID, +// outputs, +// common.UnionOptions(w.options, options)..., +// ) +// } -func (w *walletWithOptions) IssueUnsignedAtomicTx( - utx evm.UnsignedAtomicTx, - options ...common.Option, -) (*evm.Tx, error) { - return w.Wallet.IssueUnsignedAtomicTx( - utx, - common.UnionOptions(w.options, options)..., - ) -} +// func (w *walletWithOptions) IssueUnsignedAtomicTx( +// utx evm.UnsignedAtomicTx, +// options ...common.Option, +// ) (*evm.Tx, error) { +// return w.Wallet.IssueUnsignedAtomicTx( +// utx, +// common.UnionOptions(w.options, options)..., +// ) +// } -func (w *walletWithOptions) IssueAtomicTx( - tx *evm.Tx, - options ...common.Option, -) error { - return w.Wallet.IssueAtomicTx( - tx, - common.UnionOptions(w.options, options)..., - ) -} +// func (w *walletWithOptions) IssueAtomicTx( +// tx *evm.Tx, +// options ...common.Option, +// ) error { +// return w.Wallet.IssueAtomicTx( +// tx, +// common.UnionOptions(w.options, options)..., +// ) +// } diff --git a/wallet/subnet/primary/api.go b/wallet/subnet/primary/api.go index 3ac72c217884..00ebea6090fd 100644 --- a/wallet/subnet/primary/api.go +++ b/wallet/subnet/primary/api.go @@ -5,12 +5,11 @@ package primary import ( "context" - "fmt" + // "fmt" - "github.com/ava-labs/coreth/ethclient" - "github.com/ava-labs/coreth/plugin/evm" + // "github.com/ava-labs/coreth/ethclient" - "github.com/ethereum/go-ethereum/common" + // "github.com/ethereum/go-ethereum/common" "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/codec" @@ -22,7 +21,8 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/wallet/chain/c" + + // "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/x" ) @@ -59,9 +59,9 @@ type AVAXState struct { PCTX p.Context XClient avm.Client XCTX x.Context - CClient evm.Client - CCTX c.Context - UTXOs UTXOs + // CClient evm.Client + // CCTX c.Context + UTXOs UTXOs } func FetchState( @@ -75,7 +75,7 @@ func FetchState( infoClient := info.NewClient(uri) pClient := platformvm.NewClient(uri) xClient := avm.NewClient(uri, "X") - cClient := evm.NewCChainClient(uri) + // cClient := evm.NewCChainClient(uri) pCTX, err := p.NewContextFromClients(ctx, infoClient, xClient) if err != nil { @@ -87,10 +87,10 @@ func FetchState( return nil, err } - cCTX, err := c.NewContextFromClients(ctx, infoClient, xClient) - if err != nil { - return nil, err - } + // cCTX, err := c.NewContextFromClients(ctx, infoClient, xClient) + // if err != nil { + // return nil, err + // } utxos := NewUTXOs() addrList := addrs.List() @@ -109,11 +109,11 @@ func FetchState( client: xClient, codec: x.Parser.Codec(), }, - { - id: cCTX.BlockchainID(), - client: cClient, - codec: evm.Codec, - }, + // { + // id: cCTX.BlockchainID(), + // client: cClient, + // codec: evm.Codec, + // }, } for _, destinationChain := range chains { for _, sourceChain := range chains { @@ -136,52 +136,52 @@ func FetchState( PCTX: pCTX, XClient: xClient, XCTX: xCTX, - CClient: cClient, - CCTX: cCTX, - UTXOs: utxos, + // CClient: cClient, + // CCTX: cCTX, + UTXOs: utxos, }, nil } -type EthState struct { - Client ethclient.Client - Accounts map[common.Address]*c.Account -} - -func FetchEthState( - ctx context.Context, - uri string, - addrs set.Set[common.Address], -) (*EthState, error) { - path := fmt.Sprintf( - "%s/ext/%s/C/rpc", - uri, - constants.ChainAliasPrefix, - ) - client, err := ethclient.Dial(path) - if err != nil { - return nil, err - } - - accounts := make(map[common.Address]*c.Account, addrs.Len()) - for addr := range addrs { - balance, err := client.BalanceAt(ctx, addr, nil) - if err != nil { - return nil, err - } - nonce, err := client.NonceAt(ctx, addr, nil) - if err != nil { - return nil, err - } - accounts[addr] = &c.Account{ - Balance: balance, - Nonce: nonce, - } - } - return &EthState{ - Client: client, - Accounts: accounts, - }, nil -} +// type EthState struct { +// Client ethclient.Client +// Accounts map[common.Address]*c.Account +// } + +// func FetchEthState( +// ctx context.Context, +// uri string, +// addrs set.Set[common.Address], +// ) (*EthState, error) { +// path := fmt.Sprintf( +// "%s/ext/%s/C/rpc", +// uri, +// constants.ChainAliasPrefix, +// ) +// client, err := ethclient.Dial(path) +// if err != nil { +// return nil, err +// } + +// accounts := make(map[common.Address]*c.Account, addrs.Len()) +// for addr := range addrs { +// balance, err := client.BalanceAt(ctx, addr, nil) +// if err != nil { +// return nil, err +// } +// nonce, err := client.NonceAt(ctx, addr, nil) +// if err != nil { +// return nil, err +// } +// accounts[addr] = &c.Account{ +// Balance: balance, +// Nonce: nonce, +// } +// } +// return &EthState{ +// Client: client, +// Accounts: accounts, +// }, nil +// } // AddAllUTXOs fetches all the UTXOs referenced by [addresses] that were sent // from [sourceChainID] to [destinationChainID] from the [client]. It then uses diff --git a/wallet/subnet/primary/example_test.go b/wallet/subnet/primary/example_test.go index 483c049d4ac0..4a73e8c070b2 100644 --- a/wallet/subnet/primary/example_test.go +++ b/wallet/subnet/primary/example_test.go @@ -30,7 +30,7 @@ func ExampleWallet() { wallet, err := MakeWallet(ctx, &WalletConfig{ URI: LocalAPIURI, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet with: %s\n", err) diff --git a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go index d5e8ce422307..21c081d2982b 100644 --- a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go +++ b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go @@ -46,9 +46,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + // EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/examples/add-primary-validator/main.go b/wallet/subnet/primary/examples/add-primary-validator/main.go index a56dae23db3a..13c28f995f63 100644 --- a/wallet/subnet/primary/examples/add-primary-validator/main.go +++ b/wallet/subnet/primary/examples/add-primary-validator/main.go @@ -45,7 +45,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/c-chain-export/main.go b/wallet/subnet/primary/examples/c-chain-export/main.go index fec55c899feb..a6b9a0c810b8 100644 --- a/wallet/subnet/primary/examples/c-chain-export/main.go +++ b/wallet/subnet/primary/examples/c-chain-export/main.go @@ -3,70 +3,70 @@ package main -import ( - "context" - "log" - "time" +// import ( +// "context" +// "log" +// "time" - "github.com/ava-labs/avalanchego/genesis" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary" -) +// "github.com/ava-labs/avalanchego/genesis" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary" +// ) -func main() { - key := genesis.EWOQKey - uri := primary.LocalAPIURI - kc := secp256k1fx.NewKeychain(key) - avaxAddr := key.Address() +// func main() { +// key := genesis.EWOQKey +// uri := primary.LocalAPIURI +// kc := secp256k1fx.NewKeychain(key) +// avaxAddr := key.Address() - ctx := context.Background() +// ctx := context.Background() - // MakeWallet fetches the available UTXOs owned by [kc] on the network that - // [uri] is hosting. - walletSyncStartTime := time.Now() - wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, - }) - if err != nil { - log.Fatalf("failed to initialize wallet: %s\n", err) - } - log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) +// // MakeWallet fetches the available UTXOs owned by [kc] on the network that +// // [uri] is hosting. +// walletSyncStartTime := time.Now() +// wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ +// URI: uri, +// AVAXKeychain: kc, +// EthKeychain: kc, +// }) +// if err != nil { +// log.Fatalf("failed to initialize wallet: %s\n", err) +// } +// log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) - // Get the P-chain wallet - pWallet := wallet.P() - cWallet := wallet.C() +// // Get the P-chain wallet +// pWallet := wallet.P() +// cWallet := wallet.C() - // Pull out useful constants to use when issuing transactions. - cChainID := cWallet.BlockchainID() - owner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - avaxAddr, - }, - } +// // Pull out useful constants to use when issuing transactions. +// cChainID := cWallet.BlockchainID() +// owner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// avaxAddr, +// }, +// } - exportStartTime := time.Now() - exportTx, err := cWallet.IssueExportTx( - constants.PlatformChainID, - []*secp256k1fx.TransferOutput{{ - Amt: units.Avax, - OutputOwners: owner, - }}, - ) - if err != nil { - log.Fatalf("failed to issue export transaction: %s\n", err) - } - log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) +// exportStartTime := time.Now() +// exportTx, err := cWallet.IssueExportTx( +// constants.PlatformChainID, +// []*secp256k1fx.TransferOutput{{ +// Amt: units.Avax, +// OutputOwners: owner, +// }}, +// ) +// if err != nil { +// log.Fatalf("failed to issue export transaction: %s\n", err) +// } +// log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) - importStartTime := time.Now() - importTx, err := pWallet.IssueImportTx(cChainID, &owner) - if err != nil { - log.Fatalf("failed to issue import transaction: %s\n", err) - } - log.Printf("issued import %s in %s\n", importTx.ID(), time.Since(importStartTime)) -} +// importStartTime := time.Now() +// importTx, err := pWallet.IssueImportTx(cChainID, &owner) +// if err != nil { +// log.Fatalf("failed to issue import transaction: %s\n", err) +// } +// log.Printf("issued import %s in %s\n", importTx.ID(), time.Since(importStartTime)) +// } diff --git a/wallet/subnet/primary/examples/c-chain-import/main.go b/wallet/subnet/primary/examples/c-chain-import/main.go index b4dc4e603eb3..2d9b8a244cb0 100644 --- a/wallet/subnet/primary/examples/c-chain-import/main.go +++ b/wallet/subnet/primary/examples/c-chain-import/main.go @@ -3,75 +3,75 @@ package main -import ( - "context" - "log" - "time" +// import ( +// "context" +// "log" +// "time" - "github.com/ava-labs/coreth/plugin/evm" +// "github.com/ava-labs/coreth/plugin/evm" - "github.com/ava-labs/avalanchego/genesis" - "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/avalanchego/vms/components/avax" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/avalanchego/wallet/subnet/primary" -) +// "github.com/ava-labs/avalanchego/genesis" +// "github.com/ava-labs/avalanchego/ids" +// "github.com/ava-labs/avalanchego/utils/constants" +// "github.com/ava-labs/avalanchego/utils/units" +// "github.com/ava-labs/avalanchego/vms/components/avax" +// "github.com/ava-labs/avalanchego/vms/secp256k1fx" +// "github.com/ava-labs/avalanchego/wallet/subnet/primary" +// ) -func main() { - key := genesis.EWOQKey - uri := primary.LocalAPIURI - kc := secp256k1fx.NewKeychain(key) - avaxAddr := key.Address() - ethAddr := evm.PublicKeyToEthAddress(key.PublicKey()) +// func main() { +// key := genesis.EWOQKey +// uri := primary.LocalAPIURI +// kc := secp256k1fx.NewKeychain(key) +// avaxAddr := key.Address() +// ethAddr := evm.PublicKeyToEthAddress(key.PublicKey()) - ctx := context.Background() +// ctx := context.Background() - // MakeWallet fetches the available UTXOs owned by [kc] on the network that - // [uri] is hosting. - walletSyncStartTime := time.Now() - wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, - }) - if err != nil { - log.Fatalf("failed to initialize wallet: %s\n", err) - } - log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) +// // MakeWallet fetches the available UTXOs owned by [kc] on the network that +// // [uri] is hosting. +// walletSyncStartTime := time.Now() +// wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ +// URI: uri, +// AVAXKeychain: kc, +// EthKeychain: kc, +// }) +// if err != nil { +// log.Fatalf("failed to initialize wallet: %s\n", err) +// } +// log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) - // Get the P-chain wallet - pWallet := wallet.P() - cWallet := wallet.C() +// // Get the P-chain wallet +// pWallet := wallet.P() +// cWallet := wallet.C() - // Pull out useful constants to use when issuing transactions. - cChainID := cWallet.BlockchainID() - avaxAssetID := cWallet.AVAXAssetID() - owner := secp256k1fx.OutputOwners{ - Threshold: 1, - Addrs: []ids.ShortID{ - avaxAddr, - }, - } +// // Pull out useful constants to use when issuing transactions. +// cChainID := cWallet.BlockchainID() +// avaxAssetID := cWallet.AVAXAssetID() +// owner := secp256k1fx.OutputOwners{ +// Threshold: 1, +// Addrs: []ids.ShortID{ +// avaxAddr, +// }, +// } - exportStartTime := time.Now() - exportTx, err := pWallet.IssueExportTx(cChainID, []*avax.TransferableOutput{{ - Asset: avax.Asset{ID: avaxAssetID}, - Out: &secp256k1fx.TransferOutput{ - Amt: units.Avax, - OutputOwners: owner, - }, - }}) - if err != nil { - log.Fatalf("failed to issue export transaction: %s\n", err) - } - log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) +// exportStartTime := time.Now() +// exportTx, err := pWallet.IssueExportTx(cChainID, []*avax.TransferableOutput{{ +// Asset: avax.Asset{ID: avaxAssetID}, +// Out: &secp256k1fx.TransferOutput{ +// Amt: units.Avax, +// OutputOwners: owner, +// }, +// }}) +// if err != nil { +// log.Fatalf("failed to issue export transaction: %s\n", err) +// } +// log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) - importStartTime := time.Now() - importTx, err := cWallet.IssueImportTx(constants.PlatformChainID, ethAddr) - if err != nil { - log.Fatalf("failed to issue import transaction: %s\n", err) - } - log.Printf("issued import %s to %s in %s\n", importTx.ID(), ethAddr.Hex(), time.Since(importStartTime)) -} +// importStartTime := time.Now() +// importTx, err := cWallet.IssueImportTx(constants.PlatformChainID, ethAddr) +// if err != nil { +// log.Fatalf("failed to issue import transaction: %s\n", err) +// } +// log.Printf("issued import %s to %s in %s\n", importTx.ID(), ethAddr.Hex(), time.Since(importStartTime)) +// } diff --git a/wallet/subnet/primary/examples/create-asset/main.go b/wallet/subnet/primary/examples/create-asset/main.go index 30804f083df6..0bccfbb5fc52 100644 --- a/wallet/subnet/primary/examples/create-asset/main.go +++ b/wallet/subnet/primary/examples/create-asset/main.go @@ -30,7 +30,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/create-chain/main.go b/wallet/subnet/primary/examples/create-chain/main.go index 5e6898a1b649..521a3cca53cf 100644 --- a/wallet/subnet/primary/examples/create-chain/main.go +++ b/wallet/subnet/primary/examples/create-chain/main.go @@ -41,9 +41,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + // EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/examples/create-locked-stakeable/main.go b/wallet/subnet/primary/examples/create-locked-stakeable/main.go index e688968e9e8a..92f1b5cb0e1b 100644 --- a/wallet/subnet/primary/examples/create-locked-stakeable/main.go +++ b/wallet/subnet/primary/examples/create-locked-stakeable/main.go @@ -39,7 +39,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/create-subnet/main.go b/wallet/subnet/primary/examples/create-subnet/main.go index add98ea7931c..3e8d69bc016a 100644 --- a/wallet/subnet/primary/examples/create-subnet/main.go +++ b/wallet/subnet/primary/examples/create-subnet/main.go @@ -28,7 +28,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - EthKeychain: kc, + // EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/remove-subnet-validator/main.go b/wallet/subnet/primary/examples/remove-subnet-validator/main.go index 2842c7c0a790..46f4b85124db 100644 --- a/wallet/subnet/primary/examples/remove-subnet-validator/main.go +++ b/wallet/subnet/primary/examples/remove-subnet-validator/main.go @@ -38,9 +38,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + // EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/wallet.go b/wallet/subnet/primary/wallet.go index 54de390d029c..ae5e4202a099 100644 --- a/wallet/subnet/primary/wallet.go +++ b/wallet/subnet/primary/wallet.go @@ -11,7 +11,8 @@ import ( "github.com/ava-labs/avalanchego/utils/crypto/keychain" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/wallet/chain/c" + + // "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/x" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -23,13 +24,13 @@ var _ Wallet = (*wallet)(nil) type Wallet interface { P() p.Wallet X() x.Wallet - C() c.Wallet + // C() c.Wallet } type wallet struct { p p.Wallet x x.Wallet - c c.Wallet + // c c.Wallet } func (w *wallet) P() p.Wallet { @@ -40,16 +41,16 @@ func (w *wallet) X() x.Wallet { return w.x } -func (w *wallet) C() c.Wallet { - return w.c -} +// func (w *wallet) C() c.Wallet { +// return w.c +// } // Creates a new default wallet -func NewWallet(p p.Wallet, x x.Wallet, c c.Wallet) Wallet { +func NewWallet(p p.Wallet, x x.Wallet /*, c c.Wallet*/) Wallet { return &wallet{ p: p, x: x, - c: c, + // c: c, } } @@ -58,7 +59,7 @@ func NewWalletWithOptions(w Wallet, options ...common.Option) Wallet { return NewWallet( p.NewWalletWithOptions(w.P(), options...), x.NewWalletWithOptions(w.X(), options...), - c.NewWalletWithOptions(w.C(), options...), + // c.NewWalletWithOptions(w.C(), options...), ) } @@ -67,7 +68,7 @@ type WalletConfig struct { URI string // required // Keys to use for signing all transactions. AVAXKeychain keychain.Keychain // required - EthKeychain c.EthKeychain // required + // EthKeychain c.EthKeychain // required // Set of P-chain transactions that the wallet should know about to be able // to generate transactions. PChainTxs map[ids.ID]*txs.Tx // optional @@ -93,11 +94,11 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { return nil, err } - ethAddrs := config.EthKeychain.EthAddresses() - ethState, err := FetchEthState(ctx, config.URI, ethAddrs) - if err != nil { - return nil, err - } + // ethAddrs := config.EthKeychain.EthAddresses() + // ethState, err := FetchEthState(ctx, config.URI, ethAddrs) + // if err != nil { + // return nil, err + // } pChainTxs := config.PChainTxs if pChainTxs == nil { @@ -127,15 +128,15 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { xBuilder := x.NewBuilder(avaxAddrs, xBackend) xSigner := x.NewSigner(config.AVAXKeychain, xBackend) - cChainID := avaxState.CCTX.BlockchainID() - cUTXOs := NewChainUTXOs(cChainID, avaxState.UTXOs) - cBackend := c.NewBackend(avaxState.CCTX, cUTXOs, ethState.Accounts) - cBuilder := c.NewBuilder(avaxAddrs, ethAddrs, cBackend) - cSigner := c.NewSigner(config.AVAXKeychain, config.EthKeychain, cBackend) + // cChainID := avaxState.CCTX.BlockchainID() + // cUTXOs := NewChainUTXOs(cChainID, avaxState.UTXOs) + // cBackend := c.NewBackend(avaxState.CCTX, cUTXOs, ethState.Accounts) + // cBuilder := c.NewBuilder(avaxAddrs, ethAddrs, cBackend) + // cSigner := c.NewSigner(config.AVAXKeychain, config.EthKeychain, cBackend) return NewWallet( p.NewWallet(pBuilder, pSigner, avaxState.PClient, pBackend), x.NewWallet(xBuilder, xSigner, avaxState.XClient, xBackend), - c.NewWallet(cBuilder, cSigner, avaxState.CClient, ethState.Client, cBackend), + // c.NewWallet(cBuilder, cSigner, avaxState.CClient, ethState.Client, cBackend), ), nil } From fa12327b9b85bacaa0ab503296b3aaad52393e10 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 2 Jan 2024 10:35:50 +0100 Subject: [PATCH 12/13] bumped coreth version --- go.mod | 26 +- go.sum | 77 +- node/node.go | 4 +- tests/e2e/c/dynamic_fees.go | 326 +++---- tests/e2e/c/interchain_workflow.go | 320 +++---- tests/e2e/p/interchain_workflow.go | 422 ++++----- tests/e2e/x/interchain_workflow.go | 296 +++---- tests/fixture/e2e/helpers.go | 123 ++- tests/fixture/tmpnet/genesis.go | 50 +- vms/example/xsvm/cmd/chain/create/cmd.go | 6 +- wallet/chain/c/backend.go | 300 +++---- wallet/chain/c/builder.go | 812 +++++++++--------- wallet/chain/c/builder_with_options.go | 136 +-- wallet/chain/c/context.go | 194 ++--- wallet/chain/c/signer.go | 436 +++++----- wallet/chain/c/wallet.go | 402 ++++----- wallet/chain/c/wallet_with_options.go | 134 +-- wallet/subnet/primary/api.go | 122 +-- wallet/subnet/primary/example_test.go | 2 +- .../add-permissioned-subnet-validator/main.go | 6 +- .../examples/add-primary-validator/main.go | 2 +- .../primary/examples/c-chain-export/main.go | 118 +-- .../primary/examples/c-chain-import/main.go | 126 +-- .../primary/examples/create-asset/main.go | 2 +- .../primary/examples/create-chain/main.go | 6 +- .../examples/create-locked-stakeable/main.go | 2 +- .../primary/examples/create-subnet/main.go | 2 +- .../examples/remove-subnet-validator/main.go | 6 +- wallet/subnet/primary/wallet.go | 43 +- 29 files changed, 2301 insertions(+), 2200 deletions(-) diff --git a/go.mod b/go.mod index cd9743e7bdfb..b6f490835846 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/Microsoft/go-winio v0.5.2 github.com/NYTimes/gziphandler v1.1.1 + github.com/ava-labs/coreth v0.12.9-rc.9.0.20240102092814-d949adb6f925 github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 @@ -74,6 +75,7 @@ require ( github.com/BurntSushi/toml v1.2.1 // indirect github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect + github.com/VictoriaMetrics/fastcache v1.10.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect @@ -81,28 +83,45 @@ require ( github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/redact v1.1.3 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/deckarep/golang-set/v2 v2.1.0 // indirect + github.com/dlclark/regexp2 v1.7.0 // indirect + github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 // indirect + github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect github.com/frankban/quicktest v1.14.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/getsentry/sentry-go v0.18.0 // indirect github.com/go-logr/logr v1.3.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect + github.com/go-stack/stack v1.8.1 // indirect github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/go-cmp v0.6.0 // indirect - github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect + github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect + github.com/google/uuid v1.3.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 // indirect + github.com/hashicorp/go-bexpr v0.1.10 // indirect + github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e // indirect github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/klauspost/compress v1.15.15 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/magiconair/properties v1.8.6 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/mitchellh/pointerstructure v1.2.0 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -110,12 +129,17 @@ require ( github.com/prometheus/common v0.39.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sanity-io/litter v1.5.1 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/status-im/keycard-go v0.2.0 // indirect github.com/subosito/gotenv v1.3.0 // indirect github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tklauser/numcpus v0.2.2 // indirect + github.com/tyler-smith/go-bip39 v1.1.0 // indirect + github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect diff --git a/go.sum b/go.sum index 3ef5760fbfd8..dc6ec25a1d4f 100644 --- a/go.sum +++ b/go.sum @@ -56,12 +56,18 @@ github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cq github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= +github.com/VictoriaMetrics/fastcache v1.10.0 h1:5hDJnLsKLpnUEToub7ETuRu8RCkb40woBZAUiKonXzY= +github.com/VictoriaMetrics/fastcache v1.10.0/go.mod h1:tjiYeEfYXCqacuvYw/7UoDIeJaNxq6132xHICNP77w8= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/ava-labs/coreth v0.12.9-rc.9.0.20240102092814-d949adb6f925 h1:KOHtYLQe1bOZiUKyiSDazLL02mYZgvzzwnDt3Hv0VA0= +github.com/ava-labs/coreth v0.12.9-rc.9.0.20240102092814-d949adb6f925/go.mod h1:T12n5GJrWOdzveIVyou/Xe7Dqlutd9fzGZne1wpHEYA= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34 h1:mg9Uw6oZFJKytJxgxnl3uxZOs/SB8CVHg6Io4Tf99Zc= github.com/ava-labs/ledger-avalanche/go v0.0.0-20231102202641-ae2ebdaeac34/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= @@ -96,13 +102,18 @@ github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46f github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw= github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA= @@ -134,12 +145,16 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= +github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= @@ -150,6 +165,14 @@ github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6ps github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= +github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 h1:+3HCtB74++ClLy8GgjUQYeC8R4ILzVcIe8+5edAJJnE= +github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= +github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= +github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -166,6 +189,8 @@ github.com/ethereum/go-ethereum v1.12.0 h1:bdnhLPtqETd4m3mS8BGMNvBTf36bO5bx/hxE2 github.com/ethereum/go-ethereum v1.12.0/go.mod h1:/oo2X/dZLJjf2mJ6YT9wcWxa4nNJDBKDBU6sFIpx1Gs= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -174,6 +199,8 @@ github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmV github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= @@ -197,7 +224,11 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= +github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= @@ -284,12 +315,15 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= @@ -310,11 +344,17 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 h1:kr3j8iIMR4ywO/O0rvksXaJvauGGCMg2zAZIiNZ9uIQ= github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0/go.mod h1:ummNFgdgLhhX7aIiy35vVmQNS0rWXknfPE0qe6fmFXg= +github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= +github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e h1:pIYdhNkDh+YENVNi3gto8n9hAmRxKxoar0iE6BLucjw= +github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e/go.mod h1:j9cQbcqHQujT0oKJ38PylVfqohClLr3CvDC+Qcg+lhU= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c h1:DZfsyhDK1hnSS5lH8l+JggqzEleHteTYfutAiVlSUM8= @@ -326,6 +366,7 @@ github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3 github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -367,6 +408,7 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -374,6 +416,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= @@ -384,11 +427,17 @@ github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPK github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= @@ -397,8 +446,11 @@ github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -417,6 +469,8 @@ github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -484,6 +538,8 @@ github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sanity-io/litter v1.5.1 h1:dwnrSypP6q56o3lFxTU+t2fwQ9A+U5qrXVO4Qg9KwVU= github.com/sanity-io/litter v1.5.1/go.mod h1:5Z71SvaYy5kcGtyglXOC9rrUi3c1E8CamFWjQsazTh0= @@ -519,6 +575,8 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= +github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= +github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -551,10 +609,14 @@ github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZF github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE= github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa h1:5SqCsI/2Qya2bCzK15ozrqo2sZxkh0FHynJZOTVoV6Q= +github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= @@ -566,6 +628,8 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= @@ -575,6 +639,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= @@ -670,6 +735,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -716,6 +782,7 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -739,6 +806,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -803,8 +871,12 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= @@ -821,6 +893,7 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -884,6 +957,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1010,6 +1084,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= diff --git a/node/node.go b/node/node.go index 151f878ee6d7..22be7d5436eb 100644 --- a/node/node.go +++ b/node/node.go @@ -25,7 +25,7 @@ import ( "go.uber.org/zap" - // coreth "github.com/ava-labs/coreth/plugin/evm" + coreth "github.com/ava-labs/coreth/plugin/evm" "github.com/ava-labs/avalanchego/api/admin" "github.com/ava-labs/avalanchego/api/auth" @@ -1116,7 +1116,7 @@ func (n *Node) initVMs() error { CreateAssetTxFee: n.Config.CreateAssetTxFee, }, }), - // vmRegisterer.Register(context.TODO(), constants.EVMID, &coreth.Factory{}), + vmRegisterer.Register(context.TODO(), constants.EVMID, &coreth.Factory{}), n.VMManager.RegisterFactory(context.TODO(), secp256k1fx.ID, &secp256k1fx.Factory{}), n.VMManager.RegisterFactory(context.TODO(), nftfx.ID, &nftfx.Factory{}), n.VMManager.RegisterFactory(context.TODO(), propertyfx.ID, &propertyfx.Factory{}), diff --git a/tests/e2e/c/dynamic_fees.go b/tests/e2e/c/dynamic_fees.go index 7cd53f52baaf..5e80573542b4 100644 --- a/tests/e2e/c/dynamic_fees.go +++ b/tests/e2e/c/dynamic_fees.go @@ -3,166 +3,166 @@ package c -// import ( -// "math/big" -// "strings" - -// ginkgo "github.com/onsi/ginkgo/v2" - -// "github.com/stretchr/testify/require" - -// "github.com/ethereum/go-ethereum/accounts/abi" -// "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/coreth/core/types" -// "github.com/ava-labs/coreth/params" -// "github.com/ava-labs/coreth/plugin/evm" - -// "github.com/ava-labs/avalanchego/tests" -// "github.com/ava-labs/avalanchego/tests/e2e" -// "github.com/ava-labs/avalanchego/tests/fixture/testnet" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// ) - -// // This test uses the compiled bin for `hashing.sol` as -// // well as its ABI contained in `hashing_contract.go`. - -// var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { -// require := require.New(ginkgo.GinkgoT()) - -// // Need a gas limit much larger than the standard 21_000 to enable -// // the contract to induce a gas price increase -// const largeGasLimit = uint64(8_000_000) - -// // TODO(marun) What is the significance of this value? -// gasTip := big.NewInt(1000 * params.GWei) - -// ginkgo.It("should ensure that the gas price is affected by load", func() { -// ginkgo.By("creating a new private network to ensure isolation from other tests") -// privateNetwork := e2e.Env.NewPrivateNetwork() - -// ginkgo.By("allocating a pre-funded key") -// key := privateNetwork.PreFundedKeys[0] -// ethAddress := evm.GetEthAddress(key) - -// ginkgo.By("initializing a coreth client") -// node := privateNetwork.Nodes[0] -// nodeURI := tmpnet.NodeURI{ -// NodeID: node.NodeID, -// URI: node.URI, -// } -// ethClient := e2e.NewEthClient(nodeURI) - -// ginkgo.By("initializing a transaction signer") -// cChainID, err := ethClient.ChainID(e2e.DefaultContext()) -// require.NoError(err) -// signer := types.NewEIP155Signer(cChainID) -// ecdsaKey := key.ToECDSA() -// sign := func(tx *types.Transaction) *types.Transaction { -// signedTx, err := types.SignTx(tx, signer, ecdsaKey) -// require.NoError(err) -// return signedTx -// } - -// var contractAddress common.Address -// ginkgo.By("deploying an expensive contract", func() { -// // Create transaction -// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) -// require.NoError(err) -// compiledContract := common.Hex2Bytes(hashingCompiledContract) -// tx := types.NewTx(&types.LegacyTx{ -// Nonce: nonce, -// GasPrice: gasTip, -// Gas: largeGasLimit, -// Value: common.Big0, -// Data: compiledContract, -// }) - -// // Send the transaction and wait for acceptance -// signedTx := sign(tx) -// receipt := e2e.SendEthTransaction(ethClient, signedTx) - -// contractAddress = receipt.ContractAddress -// }) - -// var gasPrice *big.Int -// ginkgo.By("calling the expensive contract repeatedly until a gas price increase is detected", func() { -// // Evaluate the bytes representation of the contract -// hashingABI, err := abi.JSON(strings.NewReader(hashingABIJson)) -// require.NoError(err) -// contractData, err := hashingABI.Pack("hashIt") -// require.NoError(err) - -// var initialGasPrice *big.Int -// e2e.Eventually(func() bool { -// // Check the gas price -// var err error -// gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) -// require.NoError(err) -// if initialGasPrice == nil { -// initialGasPrice = gasPrice -// tests.Outf("{{blue}}initial gas price is %v{{/}}\n", initialGasPrice) -// } else if gasPrice.Cmp(initialGasPrice) > 0 { -// // Gas price has increased -// tests.Outf("{{blue}}gas price has increased to %v{{/}}\n", gasPrice) -// return true -// } - -// // Create the transaction -// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) -// require.NoError(err) -// tx := types.NewTx(&types.LegacyTx{ -// Nonce: nonce, -// GasPrice: gasTip, -// Gas: largeGasLimit, -// To: &contractAddress, -// Value: common.Big0, -// Data: contractData, -// }) - -// // Send the transaction and wait for acceptance -// signedTx := sign(tx) -// _ = e2e.SendEthTransaction(ethClient, signedTx) - -// // The gas price will be checked at the start of the next iteration -// return false -// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price increase before timeout") -// }) - -// ginkgo.By("waiting for the gas price to decrease...", func() { -// initialGasPrice := gasPrice -// e2e.Eventually(func() bool { -// var err error -// gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) -// require.NoError(err) -// tests.Outf("{{blue}}.{{/}}") -// return initialGasPrice.Cmp(gasPrice) > 0 -// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price decrease before timeout") -// tests.Outf("\n{{blue}}gas price has decreased to %v{{/}}\n", gasPrice) -// }) - -// ginkgo.By("sending funds at the current gas price", func() { -// // Create a recipient address -// recipientKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) -// recipientEthAddress := evm.GetEthAddress(recipientKey) - -// // Create transaction -// nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) -// require.NoError(err) -// tx := types.NewTx(&types.LegacyTx{ -// Nonce: nonce, -// GasPrice: gasPrice, -// Gas: e2e.DefaultGasLimit, -// To: &recipientEthAddress, -// Value: common.Big0, -// }) - -// // Send the transaction and wait for acceptance -// signedTx := sign(tx) -// _ = e2e.SendEthTransaction(ethClient, signedTx) -// }) - -// e2e.CheckBootstrapIsPossible(privateNetwork) -// }) -// }) +import ( + "math/big" + "strings" + + ginkgo "github.com/onsi/ginkgo/v2" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm" + + "github.com/ava-labs/avalanchego/tests" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" +) + +// This test uses the compiled bin for `hashing.sol` as +// well as its ABI contained in `hashing_contract.go`. + +var _ = e2e.DescribeCChain("[Dynamic Fees]", func() { + require := require.New(ginkgo.GinkgoT()) + + // Need a gas limit much larger than the standard 21_000 to enable + // the contract to induce a gas price increase + const largeGasLimit = uint64(8_000_000) + + // TODO(marun) What is the significance of this value? + gasTip := big.NewInt(1000 * params.GWei) + + ginkgo.It("should ensure that the gas price is affected by load", func() { + ginkgo.By("creating a new private network to ensure isolation from other tests") + privateNetwork := e2e.Env.NewPrivateNetwork() + + ginkgo.By("allocating a pre-funded key") + key := privateNetwork.PreFundedKeys[0] + ethAddress := evm.GetEthAddress(key) + + ginkgo.By("initializing a coreth client") + node := privateNetwork.Nodes[0] + nodeURI := tmpnet.NodeURI{ + NodeID: node.NodeID, + URI: node.URI, + } + ethClient := e2e.NewEthClient(nodeURI) + + ginkgo.By("initializing a transaction signer") + cChainID, err := ethClient.ChainID(e2e.DefaultContext()) + require.NoError(err) + signer := types.NewEIP155Signer(cChainID) + ecdsaKey := key.ToECDSA() + sign := func(tx *types.Transaction) *types.Transaction { + signedTx, err := types.SignTx(tx, signer, ecdsaKey) + require.NoError(err) + return signedTx + } + + var contractAddress common.Address + ginkgo.By("deploying an expensive contract", func() { + // Create transaction + nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) + require.NoError(err) + compiledContract := common.Hex2Bytes(hashingCompiledContract) + tx := types.NewTx(&types.LegacyTx{ + Nonce: nonce, + GasPrice: gasTip, + Gas: largeGasLimit, + Value: common.Big0, + Data: compiledContract, + }) + + // Send the transaction and wait for acceptance + signedTx := sign(tx) + receipt := e2e.SendEthTransaction(ethClient, signedTx) + + contractAddress = receipt.ContractAddress + }) + + var gasPrice *big.Int + ginkgo.By("calling the expensive contract repeatedly until a gas price increase is detected", func() { + // Evaluate the bytes representation of the contract + hashingABI, err := abi.JSON(strings.NewReader(hashingABIJson)) + require.NoError(err) + contractData, err := hashingABI.Pack("hashIt") + require.NoError(err) + + var initialGasPrice *big.Int + e2e.Eventually(func() bool { + // Check the gas price + var err error + gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) + require.NoError(err) + if initialGasPrice == nil { + initialGasPrice = gasPrice + tests.Outf("{{blue}}initial gas price is %v{{/}}\n", initialGasPrice) + } else if gasPrice.Cmp(initialGasPrice) > 0 { + // Gas price has increased + tests.Outf("{{blue}}gas price has increased to %v{{/}}\n", gasPrice) + return true + } + + // Create the transaction + nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) + require.NoError(err) + tx := types.NewTx(&types.LegacyTx{ + Nonce: nonce, + GasPrice: gasTip, + Gas: largeGasLimit, + To: &contractAddress, + Value: common.Big0, + Data: contractData, + }) + + // Send the transaction and wait for acceptance + signedTx := sign(tx) + _ = e2e.SendEthTransaction(ethClient, signedTx) + + // The gas price will be checked at the start of the next iteration + return false + }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price increase before timeout") + }) + + ginkgo.By("waiting for the gas price to decrease...", func() { + initialGasPrice := gasPrice + e2e.Eventually(func() bool { + var err error + gasPrice, err = ethClient.SuggestGasPrice(e2e.DefaultContext()) + require.NoError(err) + tests.Outf("{{blue}}.{{/}}") + return initialGasPrice.Cmp(gasPrice) > 0 + }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see gas price decrease before timeout") + tests.Outf("\n{{blue}}gas price has decreased to %v{{/}}\n", gasPrice) + }) + + ginkgo.By("sending funds at the current gas price", func() { + // Create a recipient address + recipientKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + recipientEthAddress := evm.GetEthAddress(recipientKey) + + // Create transaction + nonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), ethAddress) + require.NoError(err) + tx := types.NewTx(&types.LegacyTx{ + Nonce: nonce, + GasPrice: gasPrice, + Gas: e2e.DefaultGasLimit, + To: &recipientEthAddress, + Value: common.Big0, + }) + + // Send the transaction and wait for acceptance + signedTx := sign(tx) + _ = e2e.SendEthTransaction(ethClient, signedTx) + }) + + e2e.CheckBootstrapIsPossible(privateNetwork) + }) +}) diff --git a/tests/e2e/c/interchain_workflow.go b/tests/e2e/c/interchain_workflow.go index a111029b543a..e959418e878a 100644 --- a/tests/e2e/c/interchain_workflow.go +++ b/tests/e2e/c/interchain_workflow.go @@ -3,163 +3,163 @@ package c -// import ( -// "math/big" - -// ginkgo "github.com/onsi/ginkgo/v2" - -// "github.com/stretchr/testify/require" - -// "github.com/ava-labs/coreth/core/types" -// "github.com/ava-labs/coreth/plugin/evm" - -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/tests/e2e" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var _ = e2e.DescribeCChain("[Interchain Workflow]", func() { -// require := require.New(ginkgo.GinkgoT()) - -// const txAmount = 10 * units.Avax // Arbitrary amount to send and transfer - -// ginkgo.It("should ensure that funds can be transferred from the C-Chain to the X-Chain and the P-Chain", func() { -// ginkgo.By("initializing a new eth client") -// // Select a random node URI to use for both the eth client and -// // the wallet to avoid having to verify that all nodes are at -// // the same height before initializing the wallet. -// nodeURI := e2e.Env.GetRandomNodeURI() -// ethClient := e2e.NewEthClient(nodeURI) - -// ginkgo.By("allocating a pre-funded key to send from and a recipient key to deliver to") -// senderKey := e2e.Env.AllocatePreFundedKey() -// senderEthAddress := evm.GetEthAddress(senderKey) -// recipientKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) -// recipientEthAddress := evm.GetEthAddress(recipientKey) - -// ginkgo.By("sending funds from one address to another on the C-Chain", func() { -// // Create transaction -// acceptedNonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), senderEthAddress) -// require.NoError(err) -// gasPrice := e2e.SuggestGasPrice(ethClient) -// tx := types.NewTransaction( -// acceptedNonce, -// recipientEthAddress, -// big.NewInt(int64(txAmount)), -// e2e.DefaultGasLimit, -// gasPrice, -// nil, -// ) - -// // Sign transaction -// cChainID, err := ethClient.ChainID(e2e.DefaultContext()) -// require.NoError(err) -// signer := types.NewEIP155Signer(cChainID) -// signedTx, err := types.SignTx(tx, signer, senderKey.ToECDSA()) -// require.NoError(err) - -// _ = e2e.SendEthTransaction(ethClient, signedTx) - -// ginkgo.By("waiting for the C-Chain recipient address to have received the sent funds") -// e2e.Eventually(func() bool { -// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) -// require.NoError(err) -// return balance.Cmp(big.NewInt(0)) > 0 -// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see funds delivered before timeout") -// }) - -// // Wallet must be initialized after sending funds on the -// // C-Chain with the same node URI to ensure wallet state -// // matches on-chain state. -// ginkgo.By("initializing a keychain and associated wallet") -// keychain := secp256k1fx.NewKeychain(senderKey, recipientKey) -// baseWallet := e2e.NewWallet(keychain, nodeURI) -// xWallet := baseWallet.X() -// cWallet := baseWallet.C() -// pWallet := baseWallet.P() - -// ginkgo.By("defining common configuration") -// avaxAssetID := xWallet.AVAXAssetID() -// // Use the same owner for import funds to X-Chain and P-Chain -// recipientOwner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// recipientKey.Address(), -// }, -// } -// // Use the same outputs for both X-Chain and P-Chain exports -// exportOutputs := []*secp256k1fx.TransferOutput{ -// { -// Amt: txAmount, -// OutputOwners: secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// keychain.Keys[0].Address(), -// }, -// }, -// }, -// } - -// ginkgo.By("exporting AVAX from the C-Chain to the X-Chain", func() { -// _, err := cWallet.IssueExportTx( -// xWallet.BlockchainID(), -// exportOutputs, -// e2e.WithDefaultContext(), -// e2e.WithSuggestedGasPrice(ethClient), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("importing AVAX from the C-Chain to the X-Chain", func() { -// _, err := xWallet.IssueImportTx( -// cWallet.BlockchainID(), -// &recipientOwner, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { -// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// ginkgo.By("exporting AVAX from the C-Chain to the P-Chain", func() { -// _, err := cWallet.IssueExportTx( -// constants.PlatformChainID, -// exportOutputs, -// e2e.WithDefaultContext(), -// e2e.WithSuggestedGasPrice(ethClient), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("importing AVAX from the C-Chain to the P-Chain", func() { -// _, err = pWallet.IssueImportTx( -// cWallet.BlockchainID(), -// &recipientOwner, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { -// balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) -// }) -// }) +import ( + "math/big" + + ginkgo "github.com/onsi/ginkgo/v2" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/coreth/plugin/evm" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var _ = e2e.DescribeCChain("[Interchain Workflow]", func() { + require := require.New(ginkgo.GinkgoT()) + + const txAmount = 10 * units.Avax // Arbitrary amount to send and transfer + + ginkgo.It("should ensure that funds can be transferred from the C-Chain to the X-Chain and the P-Chain", func() { + ginkgo.By("initializing a new eth client") + // Select a random node URI to use for both the eth client and + // the wallet to avoid having to verify that all nodes are at + // the same height before initializing the wallet. + nodeURI := e2e.Env.GetRandomNodeURI() + ethClient := e2e.NewEthClient(nodeURI) + + ginkgo.By("allocating a pre-funded key to send from and a recipient key to deliver to") + senderKey := e2e.Env.AllocatePreFundedKey() + senderEthAddress := evm.GetEthAddress(senderKey) + recipientKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + recipientEthAddress := evm.GetEthAddress(recipientKey) + + ginkgo.By("sending funds from one address to another on the C-Chain", func() { + // Create transaction + acceptedNonce, err := ethClient.AcceptedNonceAt(e2e.DefaultContext(), senderEthAddress) + require.NoError(err) + gasPrice := e2e.SuggestGasPrice(ethClient) + tx := types.NewTransaction( + acceptedNonce, + recipientEthAddress, + big.NewInt(int64(txAmount)), + e2e.DefaultGasLimit, + gasPrice, + nil, + ) + + // Sign transaction + cChainID, err := ethClient.ChainID(e2e.DefaultContext()) + require.NoError(err) + signer := types.NewEIP155Signer(cChainID) + signedTx, err := types.SignTx(tx, signer, senderKey.ToECDSA()) + require.NoError(err) + + _ = e2e.SendEthTransaction(ethClient, signedTx) + + ginkgo.By("waiting for the C-Chain recipient address to have received the sent funds") + e2e.Eventually(func() bool { + balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) + require.NoError(err) + return balance.Cmp(big.NewInt(0)) > 0 + }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see funds delivered before timeout") + }) + + // Wallet must be initialized after sending funds on the + // C-Chain with the same node URI to ensure wallet state + // matches on-chain state. + ginkgo.By("initializing a keychain and associated wallet") + keychain := secp256k1fx.NewKeychain(senderKey, recipientKey) + baseWallet := e2e.NewWallet(keychain, nodeURI) + xWallet := baseWallet.X() + cWallet := baseWallet.C() + pWallet := baseWallet.P() + + ginkgo.By("defining common configuration") + avaxAssetID := xWallet.AVAXAssetID() + // Use the same owner for import funds to X-Chain and P-Chain + recipientOwner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + recipientKey.Address(), + }, + } + // Use the same outputs for both X-Chain and P-Chain exports + exportOutputs := []*secp256k1fx.TransferOutput{ + { + Amt: txAmount, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + keychain.Keys[0].Address(), + }, + }, + }, + } + + ginkgo.By("exporting AVAX from the C-Chain to the X-Chain", func() { + _, err := cWallet.IssueExportTx( + xWallet.BlockchainID(), + exportOutputs, + e2e.WithDefaultContext(), + e2e.WithSuggestedGasPrice(ethClient), + ) + require.NoError(err) + }) + + ginkgo.By("importing AVAX from the C-Chain to the X-Chain", func() { + _, err := xWallet.IssueImportTx( + cWallet.BlockchainID(), + &recipientOwner, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { + balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + ginkgo.By("exporting AVAX from the C-Chain to the P-Chain", func() { + _, err := cWallet.IssueExportTx( + constants.PlatformChainID, + exportOutputs, + e2e.WithDefaultContext(), + e2e.WithSuggestedGasPrice(ethClient), + ) + require.NoError(err) + }) + + ginkgo.By("importing AVAX from the C-Chain to the P-Chain", func() { + _, err = pWallet.IssueImportTx( + cWallet.BlockchainID(), + &recipientOwner, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { + balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) + }) +}) diff --git a/tests/e2e/p/interchain_workflow.go b/tests/e2e/p/interchain_workflow.go index b300ba4b2bd3..59e90198bed0 100644 --- a/tests/e2e/p/interchain_workflow.go +++ b/tests/e2e/p/interchain_workflow.go @@ -3,214 +3,214 @@ package p -// import ( -// "math/big" -// "time" - -// ginkgo "github.com/onsi/ginkgo/v2" - -// "github.com/spf13/cast" - -// "github.com/stretchr/testify/require" - -// "github.com/ava-labs/coreth/plugin/evm" - -// "github.com/ava-labs/avalanchego/api/info" -// "github.com/ava-labs/avalanchego/config" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/tests/e2e" -// "github.com/ava-labs/avalanchego/tests/fixture/testnet" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/platformvm/reward" -// "github.com/ava-labs/avalanchego/vms/platformvm/txs" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { -// require := require.New(ginkgo.GinkgoT()) - -// const ( -// transferAmount = 10 * units.Avax -// weight = 2_000 * units.Avax // Used for both validation and delegation -// ) - -// ginkgo.It("should ensure that funds can be transferred from the P-Chain to the X-Chain and the C-Chain", func() { -// network := e2e.Env.GetNetwork() - -// ginkgo.By("checking that the network has a compatible minimum stake duration", func() { -// minStakeDuration := cast.ToDuration(network.DefaultFlags[config.MinStakeDurationKey]) -// require.Equal(tmpnet.DefaultMinStakeDuration, minStakeDuration) -// }) - -// ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") -// recipientKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) -// keychain := e2e.Env.NewKeychain(1) -// keychain.Add(recipientKey) -// nodeURI := e2e.Env.GetRandomNodeURI() -// baseWallet := e2e.Env.NewWallet(keychain, nodeURI) -// xWallet := baseWallet.X() -// cWallet := baseWallet.C() -// pWallet := baseWallet.P() - -// ginkgo.By("defining common configuration") -// recipientEthAddress := evm.GetEthAddress(recipientKey) -// avaxAssetID := xWallet.AVAXAssetID() -// // Use the same owner for sending to X-Chain and importing funds to P-Chain -// recipientOwner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// recipientKey.Address(), -// }, -// } -// // Use the same outputs for both X-Chain and C-Chain exports -// exportOutputs := []*avax.TransferableOutput{ -// { -// Asset: avax.Asset{ -// ID: avaxAssetID, -// }, -// Out: &secp256k1fx.TransferOutput{ -// Amt: transferAmount, -// OutputOwners: secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// keychain.Keys[0].Address(), -// }, -// }, -// }, -// }, -// } - -// ginkgo.By("adding new node and waiting for it to report healthy") -// node := e2e.AddEphemeralNode(network, testnet.FlagsMap{}) -// e2e.WaitForHealthy(node) - -// ginkgo.By("retrieving new node's id and pop") -// infoClient := info.NewClient(node.URI) -// nodeID, nodePOP, err := infoClient.GetNodeID(e2e.DefaultContext()) -// require.NoError(err) - -// // Adding a validator should not break interchain transfer. -// endTime := time.Now().Add(30 * time.Second) -// ginkgo.By("adding the new node as a validator", func() { -// rewardKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) - -// const ( -// delegationPercent = 0.10 // 10% -// delegationShare = reward.PercentDenominator * delegationPercent -// ) - -// _, err = pWallet.IssueAddPermissionlessValidatorTx( -// &txs.SubnetValidator{ -// Validator: txs.Validator{ -// NodeID: nodeID, -// End: uint64(endTime.Unix()), -// Wght: weight, -// }, -// Subnet: constants.PrimaryNetworkID, -// }, -// nodePOP, -// pWallet.AVAXAssetID(), -// &secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{rewardKey.Address()}, -// }, -// &secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{rewardKey.Address()}, -// }, -// delegationShare, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// // Adding a delegator should not break interchain transfer. -// ginkgo.By("adding a delegator to the new node", func() { -// rewardKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) - -// _, err = pWallet.IssueAddPermissionlessDelegatorTx( -// &txs.SubnetValidator{ -// Validator: txs.Validator{ -// NodeID: nodeID, -// End: uint64(endTime.Unix()), -// Wght: weight, -// }, -// Subnet: constants.PrimaryNetworkID, -// }, -// pWallet.AVAXAssetID(), -// &secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{rewardKey.Address()}, -// }, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("exporting AVAX from the P-Chain to the X-Chain", func() { -// _, err := pWallet.IssueExportTx( -// xWallet.BlockchainID(), -// exportOutputs, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("importing AVAX from the P-Chain to the X-Chain", func() { -// _, err := xWallet.IssueImportTx( -// constants.PlatformChainID, -// &recipientOwner, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { -// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// ginkgo.By("exporting AVAX from the P-Chain to the C-Chain", func() { -// _, err := pWallet.IssueExportTx( -// cWallet.BlockchainID(), -// exportOutputs, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("initializing a new eth client") -// ethClient := e2e.NewEthClient(nodeURI) - -// ginkgo.By("importing AVAX from the P-Chain to the C-Chain", func() { -// _, err := cWallet.IssueImportTx( -// constants.PlatformChainID, -// recipientEthAddress, -// e2e.WithDefaultContext(), -// e2e.WithSuggestedGasPrice(ethClient), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") -// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) -// require.NoError(err) -// require.Positive(balance.Cmp(big.NewInt(0))) - -// ginkgo.By("stopping validator node to free up resources for a bootstrap check") -// require.NoError(node.Stop(e2e.DefaultContext())) - -// e2e.CheckBootstrapIsPossible(network) -// }) -// }) +import ( + "math/big" + "time" + + ginkgo "github.com/onsi/ginkgo/v2" + + "github.com/spf13/cast" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/coreth/plugin/evm" + + "github.com/ava-labs/avalanchego/api/info" + "github.com/ava-labs/avalanchego/config" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/platformvm/reward" + "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var _ = e2e.DescribePChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { + require := require.New(ginkgo.GinkgoT()) + + const ( + transferAmount = 10 * units.Avax + weight = 2_000 * units.Avax // Used for both validation and delegation + ) + + ginkgo.It("should ensure that funds can be transferred from the P-Chain to the X-Chain and the C-Chain", func() { + network := e2e.Env.GetNetwork() + + ginkgo.By("checking that the network has a compatible minimum stake duration", func() { + minStakeDuration := cast.ToDuration(network.DefaultFlags[config.MinStakeDurationKey]) + require.Equal(tmpnet.DefaultMinStakeDuration, minStakeDuration) + }) + + ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") + recipientKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + keychain := e2e.Env.NewKeychain(1) + keychain.Add(recipientKey) + nodeURI := e2e.Env.GetRandomNodeURI() + baseWallet := e2e.NewWallet(keychain, nodeURI) + xWallet := baseWallet.X() + cWallet := baseWallet.C() + pWallet := baseWallet.P() + + ginkgo.By("defining common configuration") + recipientEthAddress := evm.GetEthAddress(recipientKey) + avaxAssetID := xWallet.AVAXAssetID() + // Use the same owner for sending to X-Chain and importing funds to P-Chain + recipientOwner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + recipientKey.Address(), + }, + } + // Use the same outputs for both X-Chain and C-Chain exports + exportOutputs := []*avax.TransferableOutput{ + { + Asset: avax.Asset{ + ID: avaxAssetID, + }, + Out: &secp256k1fx.TransferOutput{ + Amt: transferAmount, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + keychain.Keys[0].Address(), + }, + }, + }, + }, + } + + ginkgo.By("adding new node and waiting for it to report healthy") + node := e2e.AddEphemeralNode(network, tmpnet.FlagsMap{}) + e2e.WaitForHealthy(node) + + ginkgo.By("retrieving new node's id and pop") + infoClient := info.NewClient(node.URI) + nodeID, nodePOP, err := infoClient.GetNodeID(e2e.DefaultContext()) + require.NoError(err) + + // Adding a validator should not break interchain transfer. + endTime := time.Now().Add(30 * time.Second) + ginkgo.By("adding the new node as a validator", func() { + rewardKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + + const ( + delegationPercent = 0.10 // 10% + delegationShare = reward.PercentDenominator * delegationPercent + ) + + _, err = pWallet.IssueAddPermissionlessValidatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + End: uint64(endTime.Unix()), + Wght: weight, + }, + Subnet: constants.PrimaryNetworkID, + }, + nodePOP, + pWallet.AVAXAssetID(), + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardKey.Address()}, + }, + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardKey.Address()}, + }, + delegationShare, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + // Adding a delegator should not break interchain transfer. + ginkgo.By("adding a delegator to the new node", func() { + rewardKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + + _, err = pWallet.IssueAddPermissionlessDelegatorTx( + &txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + End: uint64(endTime.Unix()), + Wght: weight, + }, + Subnet: constants.PrimaryNetworkID, + }, + pWallet.AVAXAssetID(), + &secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{rewardKey.Address()}, + }, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("exporting AVAX from the P-Chain to the X-Chain", func() { + _, err := pWallet.IssueExportTx( + xWallet.BlockchainID(), + exportOutputs, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("importing AVAX from the P-Chain to the X-Chain", func() { + _, err := xWallet.IssueImportTx( + constants.PlatformChainID, + &recipientOwner, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the X-Chain", func() { + balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + ginkgo.By("exporting AVAX from the P-Chain to the C-Chain", func() { + _, err := pWallet.IssueExportTx( + cWallet.BlockchainID(), + exportOutputs, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("initializing a new eth client") + ethClient := e2e.NewEthClient(nodeURI) + + ginkgo.By("importing AVAX from the P-Chain to the C-Chain", func() { + _, err := cWallet.IssueImportTx( + constants.PlatformChainID, + recipientEthAddress, + e2e.WithDefaultContext(), + e2e.WithSuggestedGasPrice(ethClient), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") + balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) + require.NoError(err) + require.Positive(balance.Cmp(big.NewInt(0))) + + ginkgo.By("stopping validator node to free up resources for a bootstrap check") + require.NoError(node.Stop(e2e.DefaultContext())) + + e2e.CheckBootstrapIsPossible(network) + }) +}) diff --git a/tests/e2e/x/interchain_workflow.go b/tests/e2e/x/interchain_workflow.go index d738e55a7f7a..f0c2951feb84 100644 --- a/tests/e2e/x/interchain_workflow.go +++ b/tests/e2e/x/interchain_workflow.go @@ -3,151 +3,151 @@ package x -// import ( -// "math/big" - -// ginkgo "github.com/onsi/ginkgo/v2" - -// "github.com/stretchr/testify/require" - -// "github.com/ava-labs/coreth/plugin/evm" - -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/tests/e2e" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var _ = e2e.DescribeXChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { -// require := require.New(ginkgo.GinkgoT()) - -// const transferAmount = 10 * units.Avax - -// ginkgo.It("should ensure that funds can be transferred from the X-Chain to the C-Chain and the P-Chain", func() { -// nodeURI := e2e.Env.GetRandomNodeURI() - -// ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") -// recipientKey, err := secp256k1.NewPrivateKey() -// require.NoError(err) -// keychain := e2e.Env.NewKeychain(1) -// keychain.Add(recipientKey) -// baseWallet := e2e.Env.NewWallet(keychain, nodeURI) -// xWallet := baseWallet.X() -// cWallet := baseWallet.C() -// pWallet := baseWallet.P() - -// ginkgo.By("defining common configuration") -// recipientEthAddress := evm.GetEthAddress(recipientKey) -// avaxAssetID := xWallet.AVAXAssetID() -// // Use the same owner for sending to X-Chain and importing funds to P-Chain -// recipientOwner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// recipientKey.Address(), -// }, -// } -// // Use the same outputs for both C-Chain and P-Chain exports -// exportOutputs := []*avax.TransferableOutput{ -// { -// Asset: avax.Asset{ -// ID: avaxAssetID, -// }, -// Out: &secp256k1fx.TransferOutput{ -// Amt: transferAmount, -// OutputOwners: secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// keychain.Keys[0].Address(), -// }, -// }, -// }, -// }, -// } - -// ginkgo.By("sending funds from one address to another on the X-Chain", func() { -// _, err = xWallet.IssueBaseTx( -// []*avax.TransferableOutput{{ -// Asset: avax.Asset{ -// ID: avaxAssetID, -// }, -// Out: &secp256k1fx.TransferOutput{ -// Amt: transferAmount, -// OutputOwners: recipientOwner, -// }, -// }}, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the X-Chain recipient address has received the sent funds", func() { -// balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// ginkgo.By("exporting AVAX from the X-Chain to the C-Chain", func() { -// _, err := xWallet.IssueExportTx( -// cWallet.BlockchainID(), -// exportOutputs, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("initializing a new eth client") -// ethClient := e2e.NewEthClient(nodeURI) - -// ginkgo.By("importing AVAX from the X-Chain to the C-Chain", func() { -// _, err := cWallet.IssueImportTx( -// xWallet.BlockchainID(), -// recipientEthAddress, -// e2e.WithDefaultContext(), -// e2e.WithSuggestedGasPrice(ethClient), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") -// e2e.Eventually(func() bool { -// balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) -// require.NoError(err) -// return balance.Cmp(big.NewInt(0)) > 0 -// }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see recipient address funded before timeout") - -// ginkgo.By("exporting AVAX from the X-Chain to the P-Chain", func() { -// _, err := xWallet.IssueExportTx( -// constants.PlatformChainID, -// exportOutputs, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("importing AVAX from the X-Chain to the P-Chain", func() { -// _, err := pWallet.IssueImportTx( -// xWallet.BlockchainID(), -// &recipientOwner, -// e2e.WithDefaultContext(), -// ) -// require.NoError(err) -// }) - -// ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { -// balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( -// recipientKey.Address(), -// ))) -// require.NoError(err) -// require.Positive(balances[avaxAssetID]) -// }) - -// e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) -// }) -// }) +import ( + "math/big" + + ginkgo "github.com/onsi/ginkgo/v2" + + "github.com/stretchr/testify/require" + + "github.com/ava-labs/coreth/plugin/evm" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/tests/fixture/e2e" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var _ = e2e.DescribeXChain("[Interchain Workflow]", ginkgo.Label(e2e.UsesCChainLabel), func() { + require := require.New(ginkgo.GinkgoT()) + + const transferAmount = 10 * units.Avax + + ginkgo.It("should ensure that funds can be transferred from the X-Chain to the C-Chain and the P-Chain", func() { + nodeURI := e2e.Env.GetRandomNodeURI() + + ginkgo.By("creating wallet with a funded key to send from and recipient key to deliver to") + recipientKey, err := secp256k1.NewPrivateKey() + require.NoError(err) + keychain := e2e.Env.NewKeychain(1) + keychain.Add(recipientKey) + baseWallet := e2e.NewWallet(keychain, nodeURI) + xWallet := baseWallet.X() + cWallet := baseWallet.C() + pWallet := baseWallet.P() + + ginkgo.By("defining common configuration") + recipientEthAddress := evm.GetEthAddress(recipientKey) + avaxAssetID := xWallet.AVAXAssetID() + // Use the same owner for sending to X-Chain and importing funds to P-Chain + recipientOwner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + recipientKey.Address(), + }, + } + // Use the same outputs for both C-Chain and P-Chain exports + exportOutputs := []*avax.TransferableOutput{ + { + Asset: avax.Asset{ + ID: avaxAssetID, + }, + Out: &secp256k1fx.TransferOutput{ + Amt: transferAmount, + OutputOwners: secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + keychain.Keys[0].Address(), + }, + }, + }, + }, + } + + ginkgo.By("sending funds from one address to another on the X-Chain", func() { + _, err = xWallet.IssueBaseTx( + []*avax.TransferableOutput{{ + Asset: avax.Asset{ + ID: avaxAssetID, + }, + Out: &secp256k1fx.TransferOutput{ + Amt: transferAmount, + OutputOwners: recipientOwner, + }, + }}, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the X-Chain recipient address has received the sent funds", func() { + balances, err := xWallet.Builder().GetFTBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + ginkgo.By("exporting AVAX from the X-Chain to the C-Chain", func() { + _, err := xWallet.IssueExportTx( + cWallet.BlockchainID(), + exportOutputs, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("initializing a new eth client") + ethClient := e2e.NewEthClient(nodeURI) + + ginkgo.By("importing AVAX from the X-Chain to the C-Chain", func() { + _, err := cWallet.IssueImportTx( + xWallet.BlockchainID(), + recipientEthAddress, + e2e.WithDefaultContext(), + e2e.WithSuggestedGasPrice(ethClient), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the C-Chain") + e2e.Eventually(func() bool { + balance, err := ethClient.BalanceAt(e2e.DefaultContext(), recipientEthAddress, nil) + require.NoError(err) + return balance.Cmp(big.NewInt(0)) > 0 + }, e2e.DefaultTimeout, e2e.DefaultPollingInterval, "failed to see recipient address funded before timeout") + + ginkgo.By("exporting AVAX from the X-Chain to the P-Chain", func() { + _, err := xWallet.IssueExportTx( + constants.PlatformChainID, + exportOutputs, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("importing AVAX from the X-Chain to the P-Chain", func() { + _, err := pWallet.IssueImportTx( + xWallet.BlockchainID(), + &recipientOwner, + e2e.WithDefaultContext(), + ) + require.NoError(err) + }) + + ginkgo.By("checking that the recipient address has received imported funds on the P-Chain", func() { + balances, err := pWallet.Builder().GetBalance(common.WithCustomAddresses(set.Of( + recipientKey.Address(), + ))) + require.NoError(err) + require.Positive(balances[avaxAssetID]) + }) + + e2e.CheckBootstrapIsPossible(e2e.Env.GetNetwork()) + }) +}) diff --git a/tests/fixture/e2e/helpers.go b/tests/fixture/e2e/helpers.go index 224263818156..ddebfbc8b81c 100644 --- a/tests/fixture/e2e/helpers.go +++ b/tests/fixture/e2e/helpers.go @@ -5,23 +5,20 @@ package e2e import ( "context" - - // "errors" - // "fmt" - // "math/big" - + "errors" + "fmt" + "math/big" "os" - - // "strings" + "strings" "time" ginkgo "github.com/onsi/ginkgo/v2" "github.com/stretchr/testify/require" - // "github.com/ava-labs/coreth/core/types" - // "github.com/ava-labs/coreth/ethclient" - // "github.com/ava-labs/coreth/interfaces" + "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/coreth/ethclient" + "github.com/ava-labs/coreth/interfaces" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/tests" @@ -63,7 +60,7 @@ func NewWallet(keychain *secp256k1fx.Keychain, nodeURI tmpnet.NodeURI) primary.W baseWallet, err := primary.MakeWallet(DefaultContext(), &primary.WalletConfig{ URI: nodeURI.URI, AVAXKeychain: keychain, - // EthKeychain: keychain, + EthKeychain: keychain, }) require.NoError(ginkgo.GinkgoT(), err) return primary.NewWalletWithOptions( @@ -76,15 +73,15 @@ func NewWallet(keychain *secp256k1fx.Keychain, nodeURI tmpnet.NodeURI) primary.W ) } -// // Create a new eth client targeting the specified node URI. -// func NewEthClient(nodeURI testnet.NodeURI) ethclient.Client { -// tests.Outf("{{blue}} initializing a new eth client for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) -// nodeAddress := strings.Split(nodeURI.URI, "//")[1] -// uri := fmt.Sprintf("ws://%s/ext/bc/C/ws", nodeAddress) -// client, err := ethclient.Dial(uri) -// require.NoError(ginkgo.GinkgoT(), err) -// return client -// } +// Create a new eth client targeting the specified node URI. +func NewEthClient(nodeURI tmpnet.NodeURI) ethclient.Client { + tests.Outf("{{blue}} initializing a new eth client for node %s with URI: %s {{/}}\n", nodeURI.NodeID, nodeURI.URI) + nodeAddress := strings.Split(nodeURI.URI, "//")[1] + uri := fmt.Sprintf("ws://%s/ext/bc/C/ws", nodeAddress) + client, err := ethclient.Dial(uri) + require.NoError(ginkgo.GinkgoT(), err) + return client +} // Helper simplifying use of a timed context by canceling the context on ginkgo teardown. func ContextWithTimeout(duration time.Duration) context.Context { @@ -147,49 +144,49 @@ func WaitForHealthy(node *tmpnet.Node) { require.NoError(ginkgo.GinkgoT(), tmpnet.WaitForHealthy(ctx, node)) } -// // Sends an eth transaction, waits for the transaction receipt to be issued -// // and checks that the receipt indicates success. -// func SendEthTransaction(ethClient ethclient.Client, signedTx *types.Transaction) *types.Receipt { -// require := require.New(ginkgo.GinkgoT()) - -// txID := signedTx.Hash() -// tests.Outf(" sending eth transaction with ID: %s\n", txID) - -// require.NoError(ethClient.SendTransaction(DefaultContext(), signedTx)) - -// // Wait for the receipt -// var receipt *types.Receipt -// Eventually(func() bool { -// var err error -// receipt, err = ethClient.TransactionReceipt(DefaultContext(), txID) -// if errors.Is(err, interfaces.NotFound) { -// return false // Transaction is still pending -// } -// require.NoError(err) -// return true -// }, DefaultTimeout, DefaultPollingInterval, "failed to see transaction acceptance before timeout") - -// require.Equal(receipt.Status, types.ReceiptStatusSuccessful) -// return receipt -// } - -// // Determines the suggested gas price for the configured client that will -// // maximize the chances of transaction acceptance. -// func SuggestGasPrice(ethClient ethclient.Client) *big.Int { -// gasPrice, err := ethClient.SuggestGasPrice(DefaultContext()) -// require.NoError(ginkgo.GinkgoT(), err) -// // Double the suggested gas price to maximize the chances of -// // acceptance. Maybe this can be revisited pending resolution of -// // https://github.com/ava-labs/coreth/issues/314. -// gasPrice.Add(gasPrice, gasPrice) -// return gasPrice -// } - -// // Helper simplifying use via an option of a gas price appropriate for testing. -// func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { -// baseFee := SuggestGasPrice(ethClient) -// return common.WithBaseFee(baseFee) -// } +// Sends an eth transaction, waits for the transaction receipt to be issued +// and checks that the receipt indicates success. +func SendEthTransaction(ethClient ethclient.Client, signedTx *types.Transaction) *types.Receipt { + require := require.New(ginkgo.GinkgoT()) + + txID := signedTx.Hash() + tests.Outf(" sending eth transaction with ID: %s\n", txID) + + require.NoError(ethClient.SendTransaction(DefaultContext(), signedTx)) + + // Wait for the receipt + var receipt *types.Receipt + Eventually(func() bool { + var err error + receipt, err = ethClient.TransactionReceipt(DefaultContext(), txID) + if errors.Is(err, interfaces.NotFound) { + return false // Transaction is still pending + } + require.NoError(err) + return true + }, DefaultTimeout, DefaultPollingInterval, "failed to see transaction acceptance before timeout") + + require.Equal(receipt.Status, types.ReceiptStatusSuccessful) + return receipt +} + +// Determines the suggested gas price for the configured client that will +// maximize the chances of transaction acceptance. +func SuggestGasPrice(ethClient ethclient.Client) *big.Int { + gasPrice, err := ethClient.SuggestGasPrice(DefaultContext()) + require.NoError(ginkgo.GinkgoT(), err) + // Double the suggested gas price to maximize the chances of + // acceptance. Maybe this can be revisited pending resolution of + // https://github.com/ava-labs/coreth/issues/314. + gasPrice.Add(gasPrice, gasPrice) + return gasPrice +} + +// Helper simplifying use via an option of a gas price appropriate for testing. +func WithSuggestedGasPrice(ethClient ethclient.Client) common.Option { + baseFee := SuggestGasPrice(ethClient) + return common.WithBaseFee(baseFee) +} // Verify that a new node can bootstrap into the network. func CheckBootstrapIsPossible(network *tmpnet.Network) { diff --git a/tests/fixture/tmpnet/genesis.go b/tests/fixture/tmpnet/genesis.go index db0462b3c0ce..5ee605702482 100644 --- a/tests/fixture/tmpnet/genesis.go +++ b/tests/fixture/tmpnet/genesis.go @@ -4,10 +4,16 @@ package tmpnet import ( + "encoding/json" "errors" "fmt" + "math/big" "time" + "github.com/ava-labs/coreth/core" + "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm" + "github.com/ava-labs/avalanchego/genesis" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/constants" @@ -21,12 +27,12 @@ const ( defaultGasLimit = uint64(100_000_000) // Gas limit is arbitrary // Arbitrarily large amount of AVAX to fund keys on the X-Chain for testing - // defaultFundedKeyXChainAmount = 30 * units.MegaAvax + defaultFundedKeyXChainAmount = 30 * units.MegaAvax ) var ( // Arbitrarily large amount of AVAX (10^12) to fund keys on the C-Chain for testing - // defaultFundedKeyCChainAmount = new(big.Int).Exp(big.NewInt(10), big.NewInt(30), nil) + defaultFundedKeyCChainAmount = new(big.Int).Exp(big.NewInt(10), big.NewInt(30), nil) errNoKeysForGenesis = errors.New("no keys to fund for genesis") errInvalidNetworkIDForGenesis = errors.New("network ID can't be mainnet, testnet or local network ID for genesis") @@ -107,13 +113,13 @@ func NewTestGenesis( // Ensure pre-funded keys have arbitrary large balances on both chains to support testing xChainBalances := make(XChainBalanceMap, len(keysToFund)) - // cChainBalances := make(core.GenesisAlloc, len(keysToFund)) - // for _, key := range keysToFund { - // xChainBalances[key.Address()] = defaultFundedKeyXChainAmount - // cChainBalances[evm.GetEthAddress(key)] = core.GenesisAccount{ - // Balance: defaultFundedKeyCChainAmount, - // } - // } + cChainBalances := make(core.GenesisAlloc, len(keysToFund)) + for _, key := range keysToFund { + xChainBalances[key.Address()] = defaultFundedKeyXChainAmount + cChainBalances[evm.GetEthAddress(key)] = core.GenesisAccount{ + Balance: defaultFundedKeyCChainAmount, + } + } // Set X-Chain balances for xChainAddress, balance := range xChainBalances { @@ -141,19 +147,19 @@ func NewTestGenesis( } // Define C-Chain genesis - // cChainGenesis := &core.Genesis{ - // Config: ¶ms.ChainConfig{ - // ChainID: big.NewInt(43112), // Arbitrary chain ID is arbitrary - // }, - // Difficulty: big.NewInt(0), // Difficulty is a mandatory field - // GasLimit: defaultGasLimit, - // Alloc: cChainBalances, - // } - // cChainGenesisBytes, err := json.Marshal(cChainGenesis) - // if err != nil { - // return nil, fmt.Errorf("failed to marshal C-Chain genesis: %w", err) - // } - // config.CChainGenesis = string(cChainGenesisBytes) + cChainGenesis := &core.Genesis{ + Config: ¶ms.ChainConfig{ + ChainID: big.NewInt(43112), // Arbitrary chain ID is arbitrary + }, + Difficulty: big.NewInt(0), // Difficulty is a mandatory field + GasLimit: defaultGasLimit, + Alloc: cChainBalances, + } + cChainGenesisBytes, err := json.Marshal(cChainGenesis) + if err != nil { + return nil, fmt.Errorf("failed to marshal C-Chain genesis: %w", err) + } + config.CChainGenesis = string(cChainGenesisBytes) return config, nil } diff --git a/vms/example/xsvm/cmd/chain/create/cmd.go b/vms/example/xsvm/cmd/chain/create/cmd.go index 56acfeaa703c..e562c8567b06 100644 --- a/vms/example/xsvm/cmd/chain/create/cmd.go +++ b/vms/example/xsvm/cmd/chain/create/cmd.go @@ -42,9 +42,9 @@ func createFunc(c *cobra.Command, args []string) error { // that [uri] is hosting. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: config.URI, - AVAXKeychain: kc, - // EthKeychain: kc, + URI: config.URI, + AVAXKeychain: kc, + EthKeychain: kc, PChainTxsToFetch: set.Of(config.SubnetID), }) if err != nil { diff --git a/wallet/chain/c/backend.go b/wallet/chain/c/backend.go index b88c8c643bc3..0a735116b646 100644 --- a/wallet/chain/c/backend.go +++ b/wallet/chain/c/backend.go @@ -3,153 +3,153 @@ package c -// import ( -// "errors" -// "fmt" -// "math/big" -// "sync" - -// stdcontext "context" - -// "github.com/ava-labs/coreth/plugin/evm" - -// ethcommon "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/avalanchego/database" -// "github.com/ava-labs/avalanchego/utils/math" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var ( -// _ Backend = (*backend)(nil) - -// errUnknownTxType = errors.New("unknown tx type") -// ) - -// // Backend defines the full interface required to support a C-chain wallet. -// type Backend interface { -// common.ChainUTXOs -// BuilderBackend -// SignerBackend - -// AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error -// } - -// type backend struct { -// Context -// common.ChainUTXOs - -// accountsLock sync.RWMutex -// accounts map[ethcommon.Address]*Account -// } - -// type Account struct { -// Balance *big.Int -// Nonce uint64 -// } - -// func NewBackend( -// ctx Context, -// utxos common.ChainUTXOs, -// accounts map[ethcommon.Address]*Account, -// ) Backend { -// return &backend{ -// Context: ctx, -// ChainUTXOs: utxos, -// accounts: accounts, -// } -// } - -// func (b *backend) AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error { -// switch tx := tx.UnsignedAtomicTx.(type) { -// case *evm.UnsignedImportTx: -// for _, input := range tx.ImportedInputs { -// utxoID := input.InputID() -// if err := b.RemoveUTXO(ctx, tx.SourceChain, utxoID); err != nil { -// return err -// } -// } - -// b.accountsLock.Lock() -// defer b.accountsLock.Unlock() - -// for _, output := range tx.Outs { -// account, ok := b.accounts[output.Address] -// if !ok { -// continue -// } - -// balance := new(big.Int).SetUint64(output.Amount) -// balance.Mul(balance, avaxConversionRate) -// account.Balance.Add(account.Balance, balance) -// } -// case *evm.UnsignedExportTx: -// txID := tx.ID() -// for i, out := range tx.ExportedOutputs { -// err := b.AddUTXO( -// ctx, -// tx.DestinationChain, -// &avax.UTXO{ -// UTXOID: avax.UTXOID{ -// TxID: txID, -// OutputIndex: uint32(i), -// }, -// Asset: avax.Asset{ID: out.AssetID()}, -// Out: out.Out, -// }, -// ) -// if err != nil { -// return err -// } -// } - -// b.accountsLock.Lock() -// defer b.accountsLock.Unlock() - -// for _, input := range tx.Ins { -// account, ok := b.accounts[input.Address] -// if !ok { -// continue -// } - -// balance := new(big.Int).SetUint64(input.Amount) -// balance.Mul(balance, avaxConversionRate) -// if account.Balance.Cmp(balance) == -1 { -// return errInsufficientFunds -// } -// account.Balance.Sub(account.Balance, balance) - -// newNonce, err := math.Add64(input.Nonce, 1) -// if err != nil { -// return err -// } -// account.Nonce = newNonce -// } -// default: -// return fmt.Errorf("%w: %T", errUnknownTxType, tx) -// } -// return nil -// } - -// func (b *backend) Balance(_ stdcontext.Context, addr ethcommon.Address) (*big.Int, error) { -// b.accountsLock.RLock() -// defer b.accountsLock.RUnlock() - -// account, exists := b.accounts[addr] -// if !exists { -// return nil, database.ErrNotFound -// } -// return account.Balance, nil -// } - -// func (b *backend) Nonce(_ stdcontext.Context, addr ethcommon.Address) (uint64, error) { -// b.accountsLock.RLock() -// defer b.accountsLock.RUnlock() - -// account, exists := b.accounts[addr] -// if !exists { -// return 0, database.ErrNotFound -// } -// return account.Nonce, nil -// } +import ( + "errors" + "fmt" + "math/big" + "sync" + + stdcontext "context" + + "github.com/ava-labs/coreth/plugin/evm" + + ethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/avalanchego/database" + "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var ( + _ Backend = (*backend)(nil) + + errUnknownTxType = errors.New("unknown tx type") +) + +// Backend defines the full interface required to support a C-chain wallet. +type Backend interface { + common.ChainUTXOs + BuilderBackend + SignerBackend + + AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error +} + +type backend struct { + Context + common.ChainUTXOs + + accountsLock sync.RWMutex + accounts map[ethcommon.Address]*Account +} + +type Account struct { + Balance *big.Int + Nonce uint64 +} + +func NewBackend( + ctx Context, + utxos common.ChainUTXOs, + accounts map[ethcommon.Address]*Account, +) Backend { + return &backend{ + Context: ctx, + ChainUTXOs: utxos, + accounts: accounts, + } +} + +func (b *backend) AcceptAtomicTx(ctx stdcontext.Context, tx *evm.Tx) error { + switch tx := tx.UnsignedAtomicTx.(type) { + case *evm.UnsignedImportTx: + for _, input := range tx.ImportedInputs { + utxoID := input.InputID() + if err := b.RemoveUTXO(ctx, tx.SourceChain, utxoID); err != nil { + return err + } + } + + b.accountsLock.Lock() + defer b.accountsLock.Unlock() + + for _, output := range tx.Outs { + account, ok := b.accounts[output.Address] + if !ok { + continue + } + + balance := new(big.Int).SetUint64(output.Amount) + balance.Mul(balance, avaxConversionRate) + account.Balance.Add(account.Balance, balance) + } + case *evm.UnsignedExportTx: + txID := tx.ID() + for i, out := range tx.ExportedOutputs { + err := b.AddUTXO( + ctx, + tx.DestinationChain, + &avax.UTXO{ + UTXOID: avax.UTXOID{ + TxID: txID, + OutputIndex: uint32(i), + }, + Asset: avax.Asset{ID: out.AssetID()}, + Out: out.Out, + }, + ) + if err != nil { + return err + } + } + + b.accountsLock.Lock() + defer b.accountsLock.Unlock() + + for _, input := range tx.Ins { + account, ok := b.accounts[input.Address] + if !ok { + continue + } + + balance := new(big.Int).SetUint64(input.Amount) + balance.Mul(balance, avaxConversionRate) + if account.Balance.Cmp(balance) == -1 { + return errInsufficientFunds + } + account.Balance.Sub(account.Balance, balance) + + newNonce, err := math.Add64(input.Nonce, 1) + if err != nil { + return err + } + account.Nonce = newNonce + } + default: + return fmt.Errorf("%w: %T", errUnknownTxType, tx) + } + return nil +} + +func (b *backend) Balance(_ stdcontext.Context, addr ethcommon.Address) (*big.Int, error) { + b.accountsLock.RLock() + defer b.accountsLock.RUnlock() + + account, exists := b.accounts[addr] + if !exists { + return nil, database.ErrNotFound + } + return account.Balance, nil +} + +func (b *backend) Nonce(_ stdcontext.Context, addr ethcommon.Address) (uint64, error) { + b.accountsLock.RLock() + defer b.accountsLock.RUnlock() + + account, exists := b.accounts[addr] + if !exists { + return 0, database.ErrNotFound + } + return account.Nonce, nil +} diff --git a/wallet/chain/c/builder.go b/wallet/chain/c/builder.go index 0e95a91e4fe4..81fcf3aa896a 100644 --- a/wallet/chain/c/builder.go +++ b/wallet/chain/c/builder.go @@ -3,409 +3,409 @@ package c -// import ( -// "errors" -// "math/big" - -// stdcontext "context" - -// "github.com/ava-labs/coreth/plugin/evm" - -// ethcommon "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/utils" -// "github.com/ava-labs/avalanchego/utils/math" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// const avaxConversionRateInt = 1_000_000_000 - -// var ( -// _ Builder = (*builder)(nil) - -// errInsufficientFunds = errors.New("insufficient funds") - -// // avaxConversionRate is the conversion rate between the smallest -// // denomination on the X-Chain and P-chain, 1 nAVAX, and the smallest -// // denomination on the C-Chain 1 wei. Where 1 nAVAX = 1 gWei. -// // -// // This is only required for AVAX because the denomination of 1 AVAX is 9 -// // decimal places on the X and P chains, but is 18 decimal places within the -// // EVM. -// avaxConversionRate = big.NewInt(avaxConversionRateInt) -// ) - -// // Builder provides a convenient interface for building unsigned C-chain -// // transactions. -// type Builder interface { -// // GetBalance calculates the amount of AVAX that this builder has control -// // over. -// GetBalance( -// options ...common.Option, -// ) (*big.Int, error) - -// // GetImportableBalance calculates the amount of AVAX that this builder -// // could import from the provided chain. -// // -// // - [chainID] specifies the chain the funds are from. -// GetImportableBalance( -// chainID ids.ID, -// options ...common.Option, -// ) (uint64, error) - -// // NewImportTx creates an import transaction that attempts to consume all -// // the available UTXOs and import the funds to [to]. -// // -// // - [chainID] specifies the chain to be importing funds from. -// // - [to] specifies where to send the imported funds to. -// // - [baseFee] specifies the fee price willing to be paid by this tx. -// NewImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedImportTx, error) - -// // NewExportTx creates an export transaction that attempts to send all the -// // provided [outputs] to the requested [chainID]. -// // -// // - [chainID] specifies the chain to be exporting the funds to. -// // - [outputs] specifies the outputs to send to the [chainID]. -// // - [baseFee] specifies the fee price willing to be paid by this tx. -// NewExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedExportTx, error) -// } - -// // BuilderBackend specifies the required information needed to build unsigned -// // C-chain transactions. -// type BuilderBackend interface { -// Context - -// UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) -// Balance(ctx stdcontext.Context, addr ethcommon.Address) (*big.Int, error) -// Nonce(ctx stdcontext.Context, addr ethcommon.Address) (uint64, error) -// } - -// type builder struct { -// avaxAddrs set.Set[ids.ShortID] -// ethAddrs set.Set[ethcommon.Address] -// backend BuilderBackend -// } - -// // NewBuilder returns a new transaction builder. -// // -// // - [avaxAddrs] is the set of addresses in the AVAX format that the builder -// // assumes can be used when signing the transactions in the future. -// // - [ethAddrs] is the set of addresses in the Eth format that the builder -// // assumes can be used when signing the transactions in the future. -// // - [backend] provides the required access to the chain's context and state -// // to build out the transactions. -// func NewBuilder( -// avaxAddrs set.Set[ids.ShortID], -// ethAddrs set.Set[ethcommon.Address], -// backend BuilderBackend, -// ) Builder { -// return &builder{ -// avaxAddrs: avaxAddrs, -// ethAddrs: ethAddrs, -// backend: backend, -// } -// } - -// func (b *builder) GetBalance( -// options ...common.Option, -// ) (*big.Int, error) { -// var ( -// ops = common.NewOptions(options) -// ctx = ops.Context() -// addrs = ops.EthAddresses(b.ethAddrs) -// totalBalance = new(big.Int) -// ) -// for addr := range addrs { -// balance, err := b.backend.Balance(ctx, addr) -// if err != nil { -// return nil, err -// } -// totalBalance.Add(totalBalance, balance) -// } - -// return totalBalance, nil -// } - -// func (b *builder) GetImportableBalance( -// chainID ids.ID, -// options ...common.Option, -// ) (uint64, error) { -// ops := common.NewOptions(options) -// utxos, err := b.backend.UTXOs(ops.Context(), chainID) -// if err != nil { -// return 0, err -// } - -// var ( -// addrs = ops.Addresses(b.avaxAddrs) -// minIssuanceTime = ops.MinIssuanceTime() -// avaxAssetID = b.backend.AVAXAssetID() -// balance uint64 -// ) -// for _, utxo := range utxos { -// amount, _, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) -// if !ok { -// continue -// } - -// newBalance, err := math.Add64(balance, amount) -// if err != nil { -// return 0, err -// } -// balance = newBalance -// } - -// return balance, nil -// } - -// func (b *builder) NewImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedImportTx, error) { -// ops := common.NewOptions(options) -// utxos, err := b.backend.UTXOs(ops.Context(), chainID) -// if err != nil { -// return nil, err -// } - -// var ( -// addrs = ops.Addresses(b.avaxAddrs) -// minIssuanceTime = ops.MinIssuanceTime() -// avaxAssetID = b.backend.AVAXAssetID() - -// importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) -// importedAmount uint64 -// ) -// for _, utxo := range utxos { -// amount, inputSigIndices, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) -// if !ok { -// continue -// } - -// importedInputs = append(importedInputs, &avax.TransferableInput{ -// UTXOID: utxo.UTXOID, -// Asset: utxo.Asset, -// FxID: secp256k1fx.ID, -// In: &secp256k1fx.TransferInput{ -// Amt: amount, -// Input: secp256k1fx.Input{ -// SigIndices: inputSigIndices, -// }, -// }, -// }) - -// newImportedAmount, err := math.Add64(importedAmount, amount) -// if err != nil { -// return nil, err -// } -// importedAmount = newImportedAmount -// } - -// utils.Sort(importedInputs) -// tx := &evm.UnsignedImportTx{ -// NetworkID: b.backend.NetworkID(), -// BlockchainID: b.backend.BlockchainID(), -// SourceChain: chainID, -// ImportedInputs: importedInputs, -// } - -// // We must initialize the bytes of the tx to calculate the initial cost -// wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} -// if err := wrappedTx.Sign(evm.Codec, nil); err != nil { -// return nil, err -// } - -// gasUsedWithoutOutput, err := tx.GasUsed(true /*=IsApricotPhase5*/) -// if err != nil { -// return nil, err -// } -// gasUsedWithOutput := gasUsedWithoutOutput + evm.EVMOutputGas - -// txFee, err := evm.CalculateDynamicFee(gasUsedWithOutput, baseFee) -// if err != nil { -// return nil, err -// } - -// if importedAmount <= txFee { -// return nil, errInsufficientFunds -// } - -// tx.Outs = []evm.EVMOutput{{ -// Address: to, -// Amount: importedAmount - txFee, -// AssetID: avaxAssetID, -// }} -// return tx, nil -// } - -// func (b *builder) NewExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedExportTx, error) { -// var ( -// avaxAssetID = b.backend.AVAXAssetID() -// exportedOutputs = make([]*avax.TransferableOutput, len(outputs)) -// exportedAmount uint64 -// ) -// for i, output := range outputs { -// exportedOutputs[i] = &avax.TransferableOutput{ -// Asset: avax.Asset{ID: avaxAssetID}, -// FxID: secp256k1fx.ID, -// Out: output, -// } - -// newExportedAmount, err := math.Add64(exportedAmount, output.Amt) -// if err != nil { -// return nil, err -// } -// exportedAmount = newExportedAmount -// } - -// avax.SortTransferableOutputs(exportedOutputs, evm.Codec) -// tx := &evm.UnsignedExportTx{ -// NetworkID: b.backend.NetworkID(), -// BlockchainID: b.backend.BlockchainID(), -// DestinationChain: chainID, -// ExportedOutputs: exportedOutputs, -// } - -// // We must initialize the bytes of the tx to calculate the initial cost -// wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} -// if err := wrappedTx.Sign(evm.Codec, nil); err != nil { -// return nil, err -// } - -// cost, err := tx.GasUsed(true /*=IsApricotPhase5*/) -// if err != nil { -// return nil, err -// } - -// initialFee, err := evm.CalculateDynamicFee(cost, baseFee) -// if err != nil { -// return nil, err -// } - -// amountToConsume, err := math.Add64(exportedAmount, initialFee) -// if err != nil { -// return nil, err -// } - -// var ( -// ops = common.NewOptions(options) -// ctx = ops.Context() -// addrs = ops.EthAddresses(b.ethAddrs) -// inputs = make([]evm.EVMInput, 0, addrs.Len()) -// ) -// for addr := range addrs { -// if amountToConsume == 0 { -// break -// } - -// prevFee, err := evm.CalculateDynamicFee(cost, baseFee) -// if err != nil { -// return nil, err -// } - -// newCost := cost + evm.EVMInputGas -// newFee, err := evm.CalculateDynamicFee(newCost, baseFee) -// if err != nil { -// return nil, err -// } - -// additionalFee := newFee - prevFee - -// balance, err := b.backend.Balance(ctx, addr) -// if err != nil { -// return nil, err -// } - -// // Since the asset is AVAX, we divide by the avaxConversionRate to -// // convert back to the correct denomination of AVAX that can be -// // exported. -// avaxBalance := new(big.Int).Div(balance, avaxConversionRate).Uint64() - -// // If the balance for [addr] is insufficient to cover the additional -// // cost of adding an input to the transaction, skip adding the input -// // altogether. -// if avaxBalance <= additionalFee { -// continue -// } - -// // Update the cost for the next iteration -// cost = newCost - -// amountToConsume, err = math.Add64(amountToConsume, additionalFee) -// if err != nil { -// return nil, err -// } - -// nonce, err := b.backend.Nonce(ctx, addr) -// if err != nil { -// return nil, err -// } - -// inputAmount := math.Min(amountToConsume, avaxBalance) -// inputs = append(inputs, evm.EVMInput{ -// Address: addr, -// Amount: inputAmount, -// AssetID: avaxAssetID, -// Nonce: nonce, -// }) -// amountToConsume -= inputAmount -// } - -// if amountToConsume > 0 { -// return nil, errInsufficientFunds -// } - -// utils.Sort(inputs) -// tx.Ins = inputs - -// snowCtx, err := newSnowContext(b.backend) -// if err != nil { -// return nil, err -// } -// for _, out := range tx.ExportedOutputs { -// out.InitCtx(snowCtx) -// } -// return tx, nil -// } - -// func getSpendableAmount( -// utxo *avax.UTXO, -// addrs set.Set[ids.ShortID], -// minIssuanceTime uint64, -// avaxAssetID ids.ID, -// ) (uint64, []uint32, bool) { -// if utxo.Asset.ID != avaxAssetID { -// // Only AVAX can be imported -// return 0, nil, false -// } - -// out, ok := utxo.Out.(*secp256k1fx.TransferOutput) -// if !ok { -// // Can't import an unknown transfer output type -// return 0, nil, false -// } - -// inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) -// return out.Amt, inputSigIndices, ok -// } +import ( + "errors" + "math/big" + + stdcontext "context" + + "github.com/ava-labs/coreth/plugin/evm" + + ethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils" + "github.com/ava-labs/avalanchego/utils/math" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +const avaxConversionRateInt = 1_000_000_000 + +var ( + _ Builder = (*builder)(nil) + + errInsufficientFunds = errors.New("insufficient funds") + + // avaxConversionRate is the conversion rate between the smallest + // denomination on the X-Chain and P-chain, 1 nAVAX, and the smallest + // denomination on the C-Chain 1 wei. Where 1 nAVAX = 1 gWei. + // + // This is only required for AVAX because the denomination of 1 AVAX is 9 + // decimal places on the X and P chains, but is 18 decimal places within the + // EVM. + avaxConversionRate = big.NewInt(avaxConversionRateInt) +) + +// Builder provides a convenient interface for building unsigned C-chain +// transactions. +type Builder interface { + // GetBalance calculates the amount of AVAX that this builder has control + // over. + GetBalance( + options ...common.Option, + ) (*big.Int, error) + + // GetImportableBalance calculates the amount of AVAX that this builder + // could import from the provided chain. + // + // - [chainID] specifies the chain the funds are from. + GetImportableBalance( + chainID ids.ID, + options ...common.Option, + ) (uint64, error) + + // NewImportTx creates an import transaction that attempts to consume all + // the available UTXOs and import the funds to [to]. + // + // - [chainID] specifies the chain to be importing funds from. + // - [to] specifies where to send the imported funds to. + // - [baseFee] specifies the fee price willing to be paid by this tx. + NewImportTx( + chainID ids.ID, + to ethcommon.Address, + baseFee *big.Int, + options ...common.Option, + ) (*evm.UnsignedImportTx, error) + + // NewExportTx creates an export transaction that attempts to send all the + // provided [outputs] to the requested [chainID]. + // + // - [chainID] specifies the chain to be exporting the funds to. + // - [outputs] specifies the outputs to send to the [chainID]. + // - [baseFee] specifies the fee price willing to be paid by this tx. + NewExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + baseFee *big.Int, + options ...common.Option, + ) (*evm.UnsignedExportTx, error) +} + +// BuilderBackend specifies the required information needed to build unsigned +// C-chain transactions. +type BuilderBackend interface { + Context + + UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) + Balance(ctx stdcontext.Context, addr ethcommon.Address) (*big.Int, error) + Nonce(ctx stdcontext.Context, addr ethcommon.Address) (uint64, error) +} + +type builder struct { + avaxAddrs set.Set[ids.ShortID] + ethAddrs set.Set[ethcommon.Address] + backend BuilderBackend +} + +// NewBuilder returns a new transaction builder. +// +// - [avaxAddrs] is the set of addresses in the AVAX format that the builder +// assumes can be used when signing the transactions in the future. +// - [ethAddrs] is the set of addresses in the Eth format that the builder +// assumes can be used when signing the transactions in the future. +// - [backend] provides the required access to the chain's context and state +// to build out the transactions. +func NewBuilder( + avaxAddrs set.Set[ids.ShortID], + ethAddrs set.Set[ethcommon.Address], + backend BuilderBackend, +) Builder { + return &builder{ + avaxAddrs: avaxAddrs, + ethAddrs: ethAddrs, + backend: backend, + } +} + +func (b *builder) GetBalance( + options ...common.Option, +) (*big.Int, error) { + var ( + ops = common.NewOptions(options) + ctx = ops.Context() + addrs = ops.EthAddresses(b.ethAddrs) + totalBalance = new(big.Int) + ) + for addr := range addrs { + balance, err := b.backend.Balance(ctx, addr) + if err != nil { + return nil, err + } + totalBalance.Add(totalBalance, balance) + } + + return totalBalance, nil +} + +func (b *builder) GetImportableBalance( + chainID ids.ID, + options ...common.Option, +) (uint64, error) { + ops := common.NewOptions(options) + utxos, err := b.backend.UTXOs(ops.Context(), chainID) + if err != nil { + return 0, err + } + + var ( + addrs = ops.Addresses(b.avaxAddrs) + minIssuanceTime = ops.MinIssuanceTime() + avaxAssetID = b.backend.AVAXAssetID() + balance uint64 + ) + for _, utxo := range utxos { + amount, _, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) + if !ok { + continue + } + + newBalance, err := math.Add64(balance, amount) + if err != nil { + return 0, err + } + balance = newBalance + } + + return balance, nil +} + +func (b *builder) NewImportTx( + chainID ids.ID, + to ethcommon.Address, + baseFee *big.Int, + options ...common.Option, +) (*evm.UnsignedImportTx, error) { + ops := common.NewOptions(options) + utxos, err := b.backend.UTXOs(ops.Context(), chainID) + if err != nil { + return nil, err + } + + var ( + addrs = ops.Addresses(b.avaxAddrs) + minIssuanceTime = ops.MinIssuanceTime() + avaxAssetID = b.backend.AVAXAssetID() + + importedInputs = make([]*avax.TransferableInput, 0, len(utxos)) + importedAmount uint64 + ) + for _, utxo := range utxos { + amount, inputSigIndices, ok := getSpendableAmount(utxo, addrs, minIssuanceTime, avaxAssetID) + if !ok { + continue + } + + importedInputs = append(importedInputs, &avax.TransferableInput{ + UTXOID: utxo.UTXOID, + Asset: utxo.Asset, + FxID: secp256k1fx.ID, + In: &secp256k1fx.TransferInput{ + Amt: amount, + Input: secp256k1fx.Input{ + SigIndices: inputSigIndices, + }, + }, + }) + + newImportedAmount, err := math.Add64(importedAmount, amount) + if err != nil { + return nil, err + } + importedAmount = newImportedAmount + } + + utils.Sort(importedInputs) + tx := &evm.UnsignedImportTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: b.backend.BlockchainID(), + SourceChain: chainID, + ImportedInputs: importedInputs, + } + + // We must initialize the bytes of the tx to calculate the initial cost + wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} + if err := wrappedTx.Sign(evm.Codec, nil); err != nil { + return nil, err + } + + gasUsedWithoutOutput, err := tx.GasUsed(true /*=IsApricotPhase5*/) + if err != nil { + return nil, err + } + gasUsedWithOutput := gasUsedWithoutOutput + evm.EVMOutputGas + + txFee, err := evm.CalculateDynamicFee(gasUsedWithOutput, baseFee) + if err != nil { + return nil, err + } + + if importedAmount <= txFee { + return nil, errInsufficientFunds + } + + tx.Outs = []evm.EVMOutput{{ + Address: to, + Amount: importedAmount - txFee, + AssetID: avaxAssetID, + }} + return tx, nil +} + +func (b *builder) NewExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + baseFee *big.Int, + options ...common.Option, +) (*evm.UnsignedExportTx, error) { + var ( + avaxAssetID = b.backend.AVAXAssetID() + exportedOutputs = make([]*avax.TransferableOutput, len(outputs)) + exportedAmount uint64 + ) + for i, output := range outputs { + exportedOutputs[i] = &avax.TransferableOutput{ + Asset: avax.Asset{ID: avaxAssetID}, + FxID: secp256k1fx.ID, + Out: output, + } + + newExportedAmount, err := math.Add64(exportedAmount, output.Amt) + if err != nil { + return nil, err + } + exportedAmount = newExportedAmount + } + + avax.SortTransferableOutputs(exportedOutputs, evm.Codec) + tx := &evm.UnsignedExportTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: b.backend.BlockchainID(), + DestinationChain: chainID, + ExportedOutputs: exportedOutputs, + } + + // We must initialize the bytes of the tx to calculate the initial cost + wrappedTx := &evm.Tx{UnsignedAtomicTx: tx} + if err := wrappedTx.Sign(evm.Codec, nil); err != nil { + return nil, err + } + + cost, err := tx.GasUsed(true /*=IsApricotPhase5*/) + if err != nil { + return nil, err + } + + initialFee, err := evm.CalculateDynamicFee(cost, baseFee) + if err != nil { + return nil, err + } + + amountToConsume, err := math.Add64(exportedAmount, initialFee) + if err != nil { + return nil, err + } + + var ( + ops = common.NewOptions(options) + ctx = ops.Context() + addrs = ops.EthAddresses(b.ethAddrs) + inputs = make([]evm.EVMInput, 0, addrs.Len()) + ) + for addr := range addrs { + if amountToConsume == 0 { + break + } + + prevFee, err := evm.CalculateDynamicFee(cost, baseFee) + if err != nil { + return nil, err + } + + newCost := cost + evm.EVMInputGas + newFee, err := evm.CalculateDynamicFee(newCost, baseFee) + if err != nil { + return nil, err + } + + additionalFee := newFee - prevFee + + balance, err := b.backend.Balance(ctx, addr) + if err != nil { + return nil, err + } + + // Since the asset is AVAX, we divide by the avaxConversionRate to + // convert back to the correct denomination of AVAX that can be + // exported. + avaxBalance := new(big.Int).Div(balance, avaxConversionRate).Uint64() + + // If the balance for [addr] is insufficient to cover the additional + // cost of adding an input to the transaction, skip adding the input + // altogether. + if avaxBalance <= additionalFee { + continue + } + + // Update the cost for the next iteration + cost = newCost + + amountToConsume, err = math.Add64(amountToConsume, additionalFee) + if err != nil { + return nil, err + } + + nonce, err := b.backend.Nonce(ctx, addr) + if err != nil { + return nil, err + } + + inputAmount := math.Min(amountToConsume, avaxBalance) + inputs = append(inputs, evm.EVMInput{ + Address: addr, + Amount: inputAmount, + AssetID: avaxAssetID, + Nonce: nonce, + }) + amountToConsume -= inputAmount + } + + if amountToConsume > 0 { + return nil, errInsufficientFunds + } + + utils.Sort(inputs) + tx.Ins = inputs + + snowCtx, err := newSnowContext(b.backend) + if err != nil { + return nil, err + } + for _, out := range tx.ExportedOutputs { + out.InitCtx(snowCtx) + } + return tx, nil +} + +func getSpendableAmount( + utxo *avax.UTXO, + addrs set.Set[ids.ShortID], + minIssuanceTime uint64, + avaxAssetID ids.ID, +) (uint64, []uint32, bool) { + if utxo.Asset.ID != avaxAssetID { + // Only AVAX can be imported + return 0, nil, false + } + + out, ok := utxo.Out.(*secp256k1fx.TransferOutput) + if !ok { + // Can't import an unknown transfer output type + return 0, nil, false + } + + inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime) + return out.Amt, inputSigIndices, ok +} diff --git a/wallet/chain/c/builder_with_options.go b/wallet/chain/c/builder_with_options.go index 9b7ab8399484..8416dddf9928 100644 --- a/wallet/chain/c/builder_with_options.go +++ b/wallet/chain/c/builder_with_options.go @@ -3,81 +3,81 @@ package c -// import ( -// "math/big" +import ( + "math/big" -// "github.com/ava-labs/coreth/plugin/evm" + "github.com/ava-labs/coreth/plugin/evm" -// ethcommon "github.com/ethereum/go-ethereum/common" + ethcommon "github.com/ethereum/go-ethereum/common" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) -// var _ Builder = (*builderWithOptions)(nil) +var _ Builder = (*builderWithOptions)(nil) -// type builderWithOptions struct { -// Builder -// options []common.Option -// } +type builderWithOptions struct { + Builder + options []common.Option +} -// // NewBuilderWithOptions returns a new transaction builder that will use the -// // given options by default. -// // -// // - [builder] is the builder that will be called to perform the underlying -// // operations. -// // - [options] will be provided to the builder in addition to the options -// // provided in the method calls. -// func NewBuilderWithOptions(builder Builder, options ...common.Option) Builder { -// return &builderWithOptions{ -// Builder: builder, -// options: options, -// } -// } +// NewBuilderWithOptions returns a new transaction builder that will use the +// given options by default. +// +// - [builder] is the builder that will be called to perform the underlying +// operations. +// - [options] will be provided to the builder in addition to the options +// provided in the method calls. +func NewBuilderWithOptions(builder Builder, options ...common.Option) Builder { + return &builderWithOptions{ + Builder: builder, + options: options, + } +} -// func (b *builderWithOptions) GetBalance( -// options ...common.Option, -// ) (*big.Int, error) { -// return b.Builder.GetBalance( -// common.UnionOptions(b.options, options)..., -// ) -// } +func (b *builderWithOptions) GetBalance( + options ...common.Option, +) (*big.Int, error) { + return b.Builder.GetBalance( + common.UnionOptions(b.options, options)..., + ) +} -// func (b *builderWithOptions) GetImportableBalance( -// chainID ids.ID, -// options ...common.Option, -// ) (uint64, error) { -// return b.Builder.GetImportableBalance( -// chainID, -// common.UnionOptions(b.options, options)..., -// ) -// } +func (b *builderWithOptions) GetImportableBalance( + chainID ids.ID, + options ...common.Option, +) (uint64, error) { + return b.Builder.GetImportableBalance( + chainID, + common.UnionOptions(b.options, options)..., + ) +} -// func (b *builderWithOptions) NewImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedImportTx, error) { -// return b.Builder.NewImportTx( -// chainID, -// to, -// baseFee, -// common.UnionOptions(b.options, options)..., -// ) -// } +func (b *builderWithOptions) NewImportTx( + chainID ids.ID, + to ethcommon.Address, + baseFee *big.Int, + options ...common.Option, +) (*evm.UnsignedImportTx, error) { + return b.Builder.NewImportTx( + chainID, + to, + baseFee, + common.UnionOptions(b.options, options)..., + ) +} -// func (b *builderWithOptions) NewExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// baseFee *big.Int, -// options ...common.Option, -// ) (*evm.UnsignedExportTx, error) { -// return b.Builder.NewExportTx( -// chainID, -// outputs, -// baseFee, -// common.UnionOptions(b.options, options)..., -// ) -// } +func (b *builderWithOptions) NewExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + baseFee *big.Int, + options ...common.Option, +) (*evm.UnsignedExportTx, error) { + return b.Builder.NewExportTx( + chainID, + outputs, + baseFee, + common.UnionOptions(b.options, options)..., + ) +} diff --git a/wallet/chain/c/context.go b/wallet/chain/c/context.go index c56a114a276e..b9cd41cb5667 100644 --- a/wallet/chain/c/context.go +++ b/wallet/chain/c/context.go @@ -3,100 +3,100 @@ package c -// import ( -// stdcontext "context" - -// "github.com/ava-labs/avalanchego/api/info" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/snow" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/logging" -// "github.com/ava-labs/avalanchego/vms/avm" -// ) - -// const Alias = "C" - -// var _ Context = (*context)(nil) - -// type Context interface { -// NetworkID() uint32 -// BlockchainID() ids.ID -// AVAXAssetID() ids.ID -// } - -// type context struct { -// networkID uint32 -// blockchainID ids.ID -// avaxAssetID ids.ID -// } - -// func NewContextFromURI(ctx stdcontext.Context, uri string) (Context, error) { -// infoClient := info.NewClient(uri) -// xChainClient := avm.NewClient(uri, "X") -// return NewContextFromClients(ctx, infoClient, xChainClient) -// } - -// func NewContextFromClients( -// ctx stdcontext.Context, -// infoClient info.Client, -// xChainClient avm.Client, -// ) (Context, error) { -// networkID, err := infoClient.GetNetworkID(ctx) -// if err != nil { -// return nil, err -// } - -// chainID, err := infoClient.GetBlockchainID(ctx, Alias) -// if err != nil { -// return nil, err -// } - -// asset, err := xChainClient.GetAssetDescription(ctx, "AVAX") -// if err != nil { -// return nil, err -// } - -// return NewContext( -// networkID, -// chainID, -// asset.AssetID, -// ), nil -// } - -// func NewContext( -// networkID uint32, -// blockchainID ids.ID, -// avaxAssetID ids.ID, -// ) Context { -// return &context{ -// networkID: networkID, -// blockchainID: blockchainID, -// avaxAssetID: avaxAssetID, -// } -// } - -// func (c *context) NetworkID() uint32 { -// return c.networkID -// } - -// func (c *context) BlockchainID() ids.ID { -// return c.blockchainID -// } - -// func (c *context) AVAXAssetID() ids.ID { -// return c.avaxAssetID -// } - -// func newSnowContext(c Context) (*snow.Context, error) { -// chainID := c.BlockchainID() -// lookup := ids.NewAliaser() -// return &snow.Context{ -// NetworkID: c.NetworkID(), -// SubnetID: constants.PrimaryNetworkID, -// ChainID: chainID, -// CChainID: chainID, -// AVAXAssetID: c.AVAXAssetID(), -// Log: logging.NoLog{}, -// BCLookup: lookup, -// }, lookup.Alias(chainID, Alias) -// } +import ( + stdcontext "context" + + "github.com/ava-labs/avalanchego/api/info" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/vms/avm" +) + +const Alias = "C" + +var _ Context = (*context)(nil) + +type Context interface { + NetworkID() uint32 + BlockchainID() ids.ID + AVAXAssetID() ids.ID +} + +type context struct { + networkID uint32 + blockchainID ids.ID + avaxAssetID ids.ID +} + +func NewContextFromURI(ctx stdcontext.Context, uri string) (Context, error) { + infoClient := info.NewClient(uri) + xChainClient := avm.NewClient(uri, "X") + return NewContextFromClients(ctx, infoClient, xChainClient) +} + +func NewContextFromClients( + ctx stdcontext.Context, + infoClient info.Client, + xChainClient avm.Client, +) (Context, error) { + networkID, err := infoClient.GetNetworkID(ctx) + if err != nil { + return nil, err + } + + chainID, err := infoClient.GetBlockchainID(ctx, Alias) + if err != nil { + return nil, err + } + + asset, err := xChainClient.GetAssetDescription(ctx, "AVAX") + if err != nil { + return nil, err + } + + return NewContext( + networkID, + chainID, + asset.AssetID, + ), nil +} + +func NewContext( + networkID uint32, + blockchainID ids.ID, + avaxAssetID ids.ID, +) Context { + return &context{ + networkID: networkID, + blockchainID: blockchainID, + avaxAssetID: avaxAssetID, + } +} + +func (c *context) NetworkID() uint32 { + return c.networkID +} + +func (c *context) BlockchainID() ids.ID { + return c.blockchainID +} + +func (c *context) AVAXAssetID() ids.ID { + return c.avaxAssetID +} + +func newSnowContext(c Context) (*snow.Context, error) { + chainID := c.BlockchainID() + lookup := ids.NewAliaser() + return &snow.Context{ + NetworkID: c.NetworkID(), + SubnetID: constants.PrimaryNetworkID, + ChainID: chainID, + CChainID: chainID, + AVAXAssetID: c.AVAXAssetID(), + Log: logging.NoLog{}, + BCLookup: lookup, + }, lookup.Alias(chainID, Alias) +} diff --git a/wallet/chain/c/signer.go b/wallet/chain/c/signer.go index 4bedc378234b..4fd85ed3b532 100644 --- a/wallet/chain/c/signer.go +++ b/wallet/chain/c/signer.go @@ -3,221 +3,221 @@ package c -// import ( -// "errors" -// "fmt" - -// stdcontext "context" - -// "github.com/ava-labs/coreth/plugin/evm" - -// ethcommon "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/avalanchego/database" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/utils/crypto/keychain" -// "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" -// "github.com/ava-labs/avalanchego/utils/hashing" -// "github.com/ava-labs/avalanchego/utils/set" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/components/verify" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// ) - -// const version = 0 - -// var ( -// _ Signer = (*txSigner)(nil) - -// errUnknownInputType = errors.New("unknown input type") -// errUnknownCredentialType = errors.New("unknown credential type") -// errUnknownOutputType = errors.New("unknown output type") -// errInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") - -// emptySig [secp256k1.SignatureLen]byte -// ) - -// type Signer interface { -// SignUnsignedAtomic(ctx stdcontext.Context, tx evm.UnsignedAtomicTx) (*evm.Tx, error) -// SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error -// } - -// type EthKeychain interface { -// // The returned Signer can provide a signature for [addr] -// GetEth(addr ethcommon.Address) (keychain.Signer, bool) -// // Returns the set of addresses for which the accessor keeps an associated -// // signer -// EthAddresses() set.Set[ethcommon.Address] -// } - -// type SignerBackend interface { -// GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) -// } - -// type txSigner struct { -// avaxKC keychain.Keychain -// ethKC EthKeychain -// backend SignerBackend -// } - -// func NewSigner(avaxKC keychain.Keychain, ethKC EthKeychain, backend SignerBackend) Signer { -// return &txSigner{ -// avaxKC: avaxKC, -// ethKC: ethKC, -// backend: backend, -// } -// } - -// func (s *txSigner) SignUnsignedAtomic(ctx stdcontext.Context, utx evm.UnsignedAtomicTx) (*evm.Tx, error) { -// tx := &evm.Tx{UnsignedAtomicTx: utx} -// return tx, s.SignAtomic(ctx, tx) -// } - -// func (s *txSigner) SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error { -// switch utx := tx.UnsignedAtomicTx.(type) { -// case *evm.UnsignedImportTx: -// signers, err := s.getImportSigners(ctx, utx.SourceChain, utx.ImportedInputs) -// if err != nil { -// return err -// } -// return sign(tx, true, signers) -// case *evm.UnsignedExportTx: -// signers := s.getExportSigners(utx.Ins) -// return sign(tx, true, signers) -// default: -// return fmt.Errorf("%w: %T", errUnknownTxType, tx) -// } -// } - -// func (s *txSigner) getImportSigners(ctx stdcontext.Context, sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { -// txSigners := make([][]keychain.Signer, len(ins)) -// for credIndex, transferInput := range ins { -// input, ok := transferInput.In.(*secp256k1fx.TransferInput) -// if !ok { -// return nil, errUnknownInputType -// } - -// inputSigners := make([]keychain.Signer, len(input.SigIndices)) -// txSigners[credIndex] = inputSigners - -// utxoID := transferInput.InputID() -// utxo, err := s.backend.GetUTXO(ctx, sourceChainID, utxoID) -// if err == database.ErrNotFound { -// // If we don't have access to the UTXO, then we can't sign this -// // transaction. However, we can attempt to partially sign it. -// continue -// } -// if err != nil { -// return nil, err -// } - -// out, ok := utxo.Out.(*secp256k1fx.TransferOutput) -// if !ok { -// return nil, errUnknownOutputType -// } - -// for sigIndex, addrIndex := range input.SigIndices { -// if addrIndex >= uint32(len(out.Addrs)) { -// return nil, errInvalidUTXOSigIndex -// } - -// addr := out.Addrs[addrIndex] -// key, ok := s.avaxKC.Get(addr) -// if !ok { -// // If we don't have access to the key, then we can't sign this -// // transaction. However, we can attempt to partially sign it. -// continue -// } -// inputSigners[sigIndex] = key -// } -// } -// return txSigners, nil -// } - -// func (s *txSigner) getExportSigners(ins []evm.EVMInput) [][]keychain.Signer { -// txSigners := make([][]keychain.Signer, len(ins)) -// for credIndex, input := range ins { -// inputSigners := make([]keychain.Signer, 1) -// txSigners[credIndex] = inputSigners - -// key, ok := s.ethKC.GetEth(input.Address) -// if !ok { -// // If we don't have access to the key, then we can't sign this -// // transaction. However, we can attempt to partially sign it. -// continue -// } -// inputSigners[0] = key -// } -// return txSigners -// } - -// // TODO: remove [signHash] after the ledger supports signing all transactions. -// func sign(tx *evm.Tx, signHash bool, txSigners [][]keychain.Signer) error { -// unsignedBytes, err := evm.Codec.Marshal(version, &tx.UnsignedAtomicTx) -// if err != nil { -// return fmt.Errorf("couldn't marshal unsigned tx: %w", err) -// } -// unsignedHash := hashing.ComputeHash256(unsignedBytes) - -// if expectedLen := len(txSigners); expectedLen != len(tx.Creds) { -// tx.Creds = make([]verify.Verifiable, expectedLen) -// } - -// sigCache := make(map[ids.ShortID][secp256k1.SignatureLen]byte) -// for credIndex, inputSigners := range txSigners { -// credIntf := tx.Creds[credIndex] -// if credIntf == nil { -// credIntf = &secp256k1fx.Credential{} -// tx.Creds[credIndex] = credIntf -// } - -// cred, ok := credIntf.(*secp256k1fx.Credential) -// if !ok { -// return errUnknownCredentialType -// } -// if expectedLen := len(inputSigners); expectedLen != len(cred.Sigs) { -// cred.Sigs = make([][secp256k1.SignatureLen]byte, expectedLen) -// } - -// for sigIndex, signer := range inputSigners { -// if signer == nil { -// // If we don't have access to the key, then we can't sign this -// // transaction. However, we can attempt to partially sign it. -// continue -// } -// addr := signer.Address() -// if sig := cred.Sigs[sigIndex]; sig != emptySig { -// // If this signature has already been populated, we can just -// // copy the needed signature for the future. -// sigCache[addr] = sig -// continue -// } - -// if sig, exists := sigCache[addr]; exists { -// // If this key has already produced a signature, we can just -// // copy the previous signature. -// cred.Sigs[sigIndex] = sig -// continue -// } - -// var sig []byte -// if signHash { -// sig, err = signer.SignHash(unsignedHash) -// } else { -// sig, err = signer.Sign(unsignedBytes) -// } -// if err != nil { -// return fmt.Errorf("problem signing tx: %w", err) -// } -// copy(cred.Sigs[sigIndex][:], sig) -// sigCache[addr] = cred.Sigs[sigIndex] -// } -// } - -// signedBytes, err := evm.Codec.Marshal(version, tx) -// if err != nil { -// return fmt.Errorf("couldn't marshal tx: %w", err) -// } -// tx.Initialize(unsignedBytes, signedBytes) -// return nil -// } +import ( + "errors" + "fmt" + + stdcontext "context" + + "github.com/ava-labs/coreth/plugin/evm" + + ethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/avalanchego/database" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/crypto/keychain" + "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" + "github.com/ava-labs/avalanchego/utils/hashing" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/components/verify" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" +) + +const version = 0 + +var ( + _ Signer = (*txSigner)(nil) + + errUnknownInputType = errors.New("unknown input type") + errUnknownCredentialType = errors.New("unknown credential type") + errUnknownOutputType = errors.New("unknown output type") + errInvalidUTXOSigIndex = errors.New("invalid UTXO signature index") + + emptySig [secp256k1.SignatureLen]byte +) + +type Signer interface { + SignUnsignedAtomic(ctx stdcontext.Context, tx evm.UnsignedAtomicTx) (*evm.Tx, error) + SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error +} + +type EthKeychain interface { + // The returned Signer can provide a signature for [addr] + GetEth(addr ethcommon.Address) (keychain.Signer, bool) + // Returns the set of addresses for which the accessor keeps an associated + // signer + EthAddresses() set.Set[ethcommon.Address] +} + +type SignerBackend interface { + GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) +} + +type txSigner struct { + avaxKC keychain.Keychain + ethKC EthKeychain + backend SignerBackend +} + +func NewSigner(avaxKC keychain.Keychain, ethKC EthKeychain, backend SignerBackend) Signer { + return &txSigner{ + avaxKC: avaxKC, + ethKC: ethKC, + backend: backend, + } +} + +func (s *txSigner) SignUnsignedAtomic(ctx stdcontext.Context, utx evm.UnsignedAtomicTx) (*evm.Tx, error) { + tx := &evm.Tx{UnsignedAtomicTx: utx} + return tx, s.SignAtomic(ctx, tx) +} + +func (s *txSigner) SignAtomic(ctx stdcontext.Context, tx *evm.Tx) error { + switch utx := tx.UnsignedAtomicTx.(type) { + case *evm.UnsignedImportTx: + signers, err := s.getImportSigners(ctx, utx.SourceChain, utx.ImportedInputs) + if err != nil { + return err + } + return sign(tx, true, signers) + case *evm.UnsignedExportTx: + signers := s.getExportSigners(utx.Ins) + return sign(tx, true, signers) + default: + return fmt.Errorf("%w: %T", errUnknownTxType, tx) + } +} + +func (s *txSigner) getImportSigners(ctx stdcontext.Context, sourceChainID ids.ID, ins []*avax.TransferableInput) ([][]keychain.Signer, error) { + txSigners := make([][]keychain.Signer, len(ins)) + for credIndex, transferInput := range ins { + input, ok := transferInput.In.(*secp256k1fx.TransferInput) + if !ok { + return nil, errUnknownInputType + } + + inputSigners := make([]keychain.Signer, len(input.SigIndices)) + txSigners[credIndex] = inputSigners + + utxoID := transferInput.InputID() + utxo, err := s.backend.GetUTXO(ctx, sourceChainID, utxoID) + if err == database.ErrNotFound { + // If we don't have access to the UTXO, then we can't sign this + // transaction. However, we can attempt to partially sign it. + continue + } + if err != nil { + return nil, err + } + + out, ok := utxo.Out.(*secp256k1fx.TransferOutput) + if !ok { + return nil, errUnknownOutputType + } + + for sigIndex, addrIndex := range input.SigIndices { + if addrIndex >= uint32(len(out.Addrs)) { + return nil, errInvalidUTXOSigIndex + } + + addr := out.Addrs[addrIndex] + key, ok := s.avaxKC.Get(addr) + if !ok { + // If we don't have access to the key, then we can't sign this + // transaction. However, we can attempt to partially sign it. + continue + } + inputSigners[sigIndex] = key + } + } + return txSigners, nil +} + +func (s *txSigner) getExportSigners(ins []evm.EVMInput) [][]keychain.Signer { + txSigners := make([][]keychain.Signer, len(ins)) + for credIndex, input := range ins { + inputSigners := make([]keychain.Signer, 1) + txSigners[credIndex] = inputSigners + + key, ok := s.ethKC.GetEth(input.Address) + if !ok { + // If we don't have access to the key, then we can't sign this + // transaction. However, we can attempt to partially sign it. + continue + } + inputSigners[0] = key + } + return txSigners +} + +// TODO: remove [signHash] after the ledger supports signing all transactions. +func sign(tx *evm.Tx, signHash bool, txSigners [][]keychain.Signer) error { + unsignedBytes, err := evm.Codec.Marshal(version, &tx.UnsignedAtomicTx) + if err != nil { + return fmt.Errorf("couldn't marshal unsigned tx: %w", err) + } + unsignedHash := hashing.ComputeHash256(unsignedBytes) + + if expectedLen := len(txSigners); expectedLen != len(tx.Creds) { + tx.Creds = make([]verify.Verifiable, expectedLen) + } + + sigCache := make(map[ids.ShortID][secp256k1.SignatureLen]byte) + for credIndex, inputSigners := range txSigners { + credIntf := tx.Creds[credIndex] + if credIntf == nil { + credIntf = &secp256k1fx.Credential{} + tx.Creds[credIndex] = credIntf + } + + cred, ok := credIntf.(*secp256k1fx.Credential) + if !ok { + return errUnknownCredentialType + } + if expectedLen := len(inputSigners); expectedLen != len(cred.Sigs) { + cred.Sigs = make([][secp256k1.SignatureLen]byte, expectedLen) + } + + for sigIndex, signer := range inputSigners { + if signer == nil { + // If we don't have access to the key, then we can't sign this + // transaction. However, we can attempt to partially sign it. + continue + } + addr := signer.Address() + if sig := cred.Sigs[sigIndex]; sig != emptySig { + // If this signature has already been populated, we can just + // copy the needed signature for the future. + sigCache[addr] = sig + continue + } + + if sig, exists := sigCache[addr]; exists { + // If this key has already produced a signature, we can just + // copy the previous signature. + cred.Sigs[sigIndex] = sig + continue + } + + var sig []byte + if signHash { + sig, err = signer.SignHash(unsignedHash) + } else { + sig, err = signer.Sign(unsignedBytes) + } + if err != nil { + return fmt.Errorf("problem signing tx: %w", err) + } + copy(cred.Sigs[sigIndex][:], sig) + sigCache[addr] = cred.Sigs[sigIndex] + } + } + + signedBytes, err := evm.Codec.Marshal(version, tx) + if err != nil { + return fmt.Errorf("couldn't marshal tx: %w", err) + } + tx.Initialize(unsignedBytes, signedBytes) + return nil +} diff --git a/wallet/chain/c/wallet.go b/wallet/chain/c/wallet.go index ebee50a9a958..fb1a83d53dad 100644 --- a/wallet/chain/c/wallet.go +++ b/wallet/chain/c/wallet.go @@ -3,204 +3,204 @@ package c -// import ( -// "errors" -// "math/big" -// "time" - -// "github.com/ava-labs/coreth/ethclient" -// "github.com/ava-labs/coreth/plugin/evm" - -// ethcommon "github.com/ethereum/go-ethereum/common" - -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) - -// var ( -// _ Wallet = (*wallet)(nil) - -// errNotCommitted = errors.New("not committed") -// ) - -// type Wallet interface { -// Context - -// // Builder returns the builder that will be used to create the transactions. -// Builder() Builder - -// // Signer returns the signer that will be used to sign the transactions. -// Signer() Signer - -// // IssueImportTx creates, signs, and issues an import transaction that -// // attempts to consume all the available UTXOs and import the funds to [to]. -// // -// // - [chainID] specifies the chain to be importing funds from. -// // - [to] specifies where to send the imported funds to. -// IssueImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// options ...common.Option, -// ) (*evm.Tx, error) - -// // IssueExportTx creates, signs, and issues an export transaction that -// // attempts to send all the provided [outputs] to the requested [chainID]. -// // -// // - [chainID] specifies the chain to be exporting the funds to. -// // - [outputs] specifies the outputs to send to the [chainID]. -// IssueExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// options ...common.Option, -// ) (*evm.Tx, error) - -// // IssueUnsignedTx signs and issues the unsigned tx. -// IssueUnsignedAtomicTx( -// utx evm.UnsignedAtomicTx, -// options ...common.Option, -// ) (*evm.Tx, error) - -// // IssueAtomicTx issues the signed tx. -// IssueAtomicTx( -// tx *evm.Tx, -// options ...common.Option, -// ) error -// } - -// func NewWallet( -// builder Builder, -// signer Signer, -// avaxClient evm.Client, -// ethClient ethclient.Client, -// backend Backend, -// ) Wallet { -// return &wallet{ -// Backend: backend, -// builder: builder, -// signer: signer, -// avaxClient: avaxClient, -// ethClient: ethClient, -// } -// } - -// type wallet struct { -// Backend -// builder Builder -// signer Signer -// avaxClient evm.Client -// ethClient ethclient.Client -// } - -// func (w *wallet) Builder() Builder { -// return w.builder -// } - -// func (w *wallet) Signer() Signer { -// return w.signer -// } - -// func (w *wallet) IssueImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// options ...common.Option, -// ) (*evm.Tx, error) { -// baseFee, err := w.baseFee(options) -// if err != nil { -// return nil, err -// } - -// utx, err := w.builder.NewImportTx(chainID, to, baseFee, options...) -// if err != nil { -// return nil, err -// } -// return w.IssueUnsignedAtomicTx(utx, options...) -// } - -// func (w *wallet) IssueExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// options ...common.Option, -// ) (*evm.Tx, error) { -// baseFee, err := w.baseFee(options) -// if err != nil { -// return nil, err -// } - -// utx, err := w.builder.NewExportTx(chainID, outputs, baseFee, options...) -// if err != nil { -// return nil, err -// } -// return w.IssueUnsignedAtomicTx(utx, options...) -// } - -// func (w *wallet) IssueUnsignedAtomicTx( -// utx evm.UnsignedAtomicTx, -// options ...common.Option, -// ) (*evm.Tx, error) { -// ops := common.NewOptions(options) -// ctx := ops.Context() -// tx, err := w.signer.SignUnsignedAtomic(ctx, utx) -// if err != nil { -// return nil, err -// } - -// return tx, w.IssueAtomicTx(tx, options...) -// } - -// func (w *wallet) IssueAtomicTx( -// tx *evm.Tx, -// options ...common.Option, -// ) error { -// ops := common.NewOptions(options) -// ctx := ops.Context() -// txID, err := w.avaxClient.IssueTx(ctx, tx.SignedBytes()) -// if err != nil { -// return err -// } - -// if f := ops.PostIssuanceFunc(); f != nil { -// f(txID) -// } - -// if ops.AssumeDecided() { -// return w.Backend.AcceptAtomicTx(ctx, tx) -// } - -// pollFrequency := ops.PollFrequency() -// ticker := time.NewTicker(pollFrequency) -// defer ticker.Stop() - -// for { -// status, err := w.avaxClient.GetAtomicTxStatus(ctx, txID) -// if err != nil { -// return err -// } - -// switch status { -// case evm.Accepted: -// return w.Backend.AcceptAtomicTx(ctx, tx) -// case evm.Dropped, evm.Unknown: -// return errNotCommitted -// } - -// // The tx is Processing. - -// select { -// case <-ticker.C: -// case <-ctx.Done(): -// return ctx.Err() -// } -// } -// } - -// func (w *wallet) baseFee(options []common.Option) (*big.Int, error) { -// ops := common.NewOptions(options) -// baseFee := ops.BaseFee(nil) -// if baseFee != nil { -// return baseFee, nil -// } - -// ctx := ops.Context() -// return w.ethClient.EstimateBaseFee(ctx) -// } +import ( + "errors" + "math/big" + "time" + + "github.com/ava-labs/coreth/ethclient" + "github.com/ava-labs/coreth/plugin/evm" + + ethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) + +var ( + _ Wallet = (*wallet)(nil) + + errNotCommitted = errors.New("not committed") +) + +type Wallet interface { + Context + + // Builder returns the builder that will be used to create the transactions. + Builder() Builder + + // Signer returns the signer that will be used to sign the transactions. + Signer() Signer + + // IssueImportTx creates, signs, and issues an import transaction that + // attempts to consume all the available UTXOs and import the funds to [to]. + // + // - [chainID] specifies the chain to be importing funds from. + // - [to] specifies where to send the imported funds to. + IssueImportTx( + chainID ids.ID, + to ethcommon.Address, + options ...common.Option, + ) (*evm.Tx, error) + + // IssueExportTx creates, signs, and issues an export transaction that + // attempts to send all the provided [outputs] to the requested [chainID]. + // + // - [chainID] specifies the chain to be exporting the funds to. + // - [outputs] specifies the outputs to send to the [chainID]. + IssueExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + options ...common.Option, + ) (*evm.Tx, error) + + // IssueUnsignedTx signs and issues the unsigned tx. + IssueUnsignedAtomicTx( + utx evm.UnsignedAtomicTx, + options ...common.Option, + ) (*evm.Tx, error) + + // IssueAtomicTx issues the signed tx. + IssueAtomicTx( + tx *evm.Tx, + options ...common.Option, + ) error +} + +func NewWallet( + builder Builder, + signer Signer, + avaxClient evm.Client, + ethClient ethclient.Client, + backend Backend, +) Wallet { + return &wallet{ + Backend: backend, + builder: builder, + signer: signer, + avaxClient: avaxClient, + ethClient: ethClient, + } +} + +type wallet struct { + Backend + builder Builder + signer Signer + avaxClient evm.Client + ethClient ethclient.Client +} + +func (w *wallet) Builder() Builder { + return w.builder +} + +func (w *wallet) Signer() Signer { + return w.signer +} + +func (w *wallet) IssueImportTx( + chainID ids.ID, + to ethcommon.Address, + options ...common.Option, +) (*evm.Tx, error) { + baseFee, err := w.baseFee(options) + if err != nil { + return nil, err + } + + utx, err := w.builder.NewImportTx(chainID, to, baseFee, options...) + if err != nil { + return nil, err + } + return w.IssueUnsignedAtomicTx(utx, options...) +} + +func (w *wallet) IssueExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + options ...common.Option, +) (*evm.Tx, error) { + baseFee, err := w.baseFee(options) + if err != nil { + return nil, err + } + + utx, err := w.builder.NewExportTx(chainID, outputs, baseFee, options...) + if err != nil { + return nil, err + } + return w.IssueUnsignedAtomicTx(utx, options...) +} + +func (w *wallet) IssueUnsignedAtomicTx( + utx evm.UnsignedAtomicTx, + options ...common.Option, +) (*evm.Tx, error) { + ops := common.NewOptions(options) + ctx := ops.Context() + tx, err := w.signer.SignUnsignedAtomic(ctx, utx) + if err != nil { + return nil, err + } + + return tx, w.IssueAtomicTx(tx, options...) +} + +func (w *wallet) IssueAtomicTx( + tx *evm.Tx, + options ...common.Option, +) error { + ops := common.NewOptions(options) + ctx := ops.Context() + txID, err := w.avaxClient.IssueTx(ctx, tx.SignedBytes()) + if err != nil { + return err + } + + if f := ops.PostIssuanceFunc(); f != nil { + f(txID) + } + + if ops.AssumeDecided() { + return w.Backend.AcceptAtomicTx(ctx, tx) + } + + pollFrequency := ops.PollFrequency() + ticker := time.NewTicker(pollFrequency) + defer ticker.Stop() + + for { + status, err := w.avaxClient.GetAtomicTxStatus(ctx, txID) + if err != nil { + return err + } + + switch status { + case evm.Accepted: + return w.Backend.AcceptAtomicTx(ctx, tx) + case evm.Dropped, evm.Unknown: + return errNotCommitted + } + + // The tx is Processing. + + select { + case <-ticker.C: + case <-ctx.Done(): + return ctx.Err() + } + } +} + +func (w *wallet) baseFee(options []common.Option) (*big.Int, error) { + ops := common.NewOptions(options) + baseFee := ops.BaseFee(nil) + if baseFee != nil { + return baseFee, nil + } + + ctx := ops.Context() + return w.ethClient.EstimateBaseFee(ctx) +} diff --git a/wallet/chain/c/wallet_with_options.go b/wallet/chain/c/wallet_with_options.go index fd69a6d4fd02..7d6193683d49 100644 --- a/wallet/chain/c/wallet_with_options.go +++ b/wallet/chain/c/wallet_with_options.go @@ -3,80 +3,80 @@ package c -// import ( -// "github.com/ava-labs/coreth/plugin/evm" +import ( + "github.com/ava-labs/coreth/plugin/evm" -// ethcommon "github.com/ethereum/go-ethereum/common" + ethcommon "github.com/ethereum/go-ethereum/common" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" -// ) + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" +) -// var _ Wallet = (*walletWithOptions)(nil) +var _ Wallet = (*walletWithOptions)(nil) -// func NewWalletWithOptions( -// wallet Wallet, -// options ...common.Option, -// ) Wallet { -// return &walletWithOptions{ -// Wallet: wallet, -// options: options, -// } -// } +func NewWalletWithOptions( + wallet Wallet, + options ...common.Option, +) Wallet { + return &walletWithOptions{ + Wallet: wallet, + options: options, + } +} -// type walletWithOptions struct { -// Wallet -// options []common.Option -// } +type walletWithOptions struct { + Wallet + options []common.Option +} -// func (w *walletWithOptions) Builder() Builder { -// return NewBuilderWithOptions( -// w.Wallet.Builder(), -// w.options..., -// ) -// } +func (w *walletWithOptions) Builder() Builder { + return NewBuilderWithOptions( + w.Wallet.Builder(), + w.options..., + ) +} -// func (w *walletWithOptions) IssueImportTx( -// chainID ids.ID, -// to ethcommon.Address, -// options ...common.Option, -// ) (*evm.Tx, error) { -// return w.Wallet.IssueImportTx( -// chainID, -// to, -// common.UnionOptions(w.options, options)..., -// ) -// } +func (w *walletWithOptions) IssueImportTx( + chainID ids.ID, + to ethcommon.Address, + options ...common.Option, +) (*evm.Tx, error) { + return w.Wallet.IssueImportTx( + chainID, + to, + common.UnionOptions(w.options, options)..., + ) +} -// func (w *walletWithOptions) IssueExportTx( -// chainID ids.ID, -// outputs []*secp256k1fx.TransferOutput, -// options ...common.Option, -// ) (*evm.Tx, error) { -// return w.Wallet.IssueExportTx( -// chainID, -// outputs, -// common.UnionOptions(w.options, options)..., -// ) -// } +func (w *walletWithOptions) IssueExportTx( + chainID ids.ID, + outputs []*secp256k1fx.TransferOutput, + options ...common.Option, +) (*evm.Tx, error) { + return w.Wallet.IssueExportTx( + chainID, + outputs, + common.UnionOptions(w.options, options)..., + ) +} -// func (w *walletWithOptions) IssueUnsignedAtomicTx( -// utx evm.UnsignedAtomicTx, -// options ...common.Option, -// ) (*evm.Tx, error) { -// return w.Wallet.IssueUnsignedAtomicTx( -// utx, -// common.UnionOptions(w.options, options)..., -// ) -// } +func (w *walletWithOptions) IssueUnsignedAtomicTx( + utx evm.UnsignedAtomicTx, + options ...common.Option, +) (*evm.Tx, error) { + return w.Wallet.IssueUnsignedAtomicTx( + utx, + common.UnionOptions(w.options, options)..., + ) +} -// func (w *walletWithOptions) IssueAtomicTx( -// tx *evm.Tx, -// options ...common.Option, -// ) error { -// return w.Wallet.IssueAtomicTx( -// tx, -// common.UnionOptions(w.options, options)..., -// ) -// } +func (w *walletWithOptions) IssueAtomicTx( + tx *evm.Tx, + options ...common.Option, +) error { + return w.Wallet.IssueAtomicTx( + tx, + common.UnionOptions(w.options, options)..., + ) +} diff --git a/wallet/subnet/primary/api.go b/wallet/subnet/primary/api.go index 00ebea6090fd..3ac72c217884 100644 --- a/wallet/subnet/primary/api.go +++ b/wallet/subnet/primary/api.go @@ -5,11 +5,12 @@ package primary import ( "context" - // "fmt" + "fmt" - // "github.com/ava-labs/coreth/ethclient" + "github.com/ava-labs/coreth/ethclient" + "github.com/ava-labs/coreth/plugin/evm" - // "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common" "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/codec" @@ -21,8 +22,7 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - - // "github.com/ava-labs/avalanchego/wallet/chain/c" + "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/x" ) @@ -59,9 +59,9 @@ type AVAXState struct { PCTX p.Context XClient avm.Client XCTX x.Context - // CClient evm.Client - // CCTX c.Context - UTXOs UTXOs + CClient evm.Client + CCTX c.Context + UTXOs UTXOs } func FetchState( @@ -75,7 +75,7 @@ func FetchState( infoClient := info.NewClient(uri) pClient := platformvm.NewClient(uri) xClient := avm.NewClient(uri, "X") - // cClient := evm.NewCChainClient(uri) + cClient := evm.NewCChainClient(uri) pCTX, err := p.NewContextFromClients(ctx, infoClient, xClient) if err != nil { @@ -87,10 +87,10 @@ func FetchState( return nil, err } - // cCTX, err := c.NewContextFromClients(ctx, infoClient, xClient) - // if err != nil { - // return nil, err - // } + cCTX, err := c.NewContextFromClients(ctx, infoClient, xClient) + if err != nil { + return nil, err + } utxos := NewUTXOs() addrList := addrs.List() @@ -109,11 +109,11 @@ func FetchState( client: xClient, codec: x.Parser.Codec(), }, - // { - // id: cCTX.BlockchainID(), - // client: cClient, - // codec: evm.Codec, - // }, + { + id: cCTX.BlockchainID(), + client: cClient, + codec: evm.Codec, + }, } for _, destinationChain := range chains { for _, sourceChain := range chains { @@ -136,52 +136,52 @@ func FetchState( PCTX: pCTX, XClient: xClient, XCTX: xCTX, - // CClient: cClient, - // CCTX: cCTX, - UTXOs: utxos, + CClient: cClient, + CCTX: cCTX, + UTXOs: utxos, }, nil } -// type EthState struct { -// Client ethclient.Client -// Accounts map[common.Address]*c.Account -// } - -// func FetchEthState( -// ctx context.Context, -// uri string, -// addrs set.Set[common.Address], -// ) (*EthState, error) { -// path := fmt.Sprintf( -// "%s/ext/%s/C/rpc", -// uri, -// constants.ChainAliasPrefix, -// ) -// client, err := ethclient.Dial(path) -// if err != nil { -// return nil, err -// } - -// accounts := make(map[common.Address]*c.Account, addrs.Len()) -// for addr := range addrs { -// balance, err := client.BalanceAt(ctx, addr, nil) -// if err != nil { -// return nil, err -// } -// nonce, err := client.NonceAt(ctx, addr, nil) -// if err != nil { -// return nil, err -// } -// accounts[addr] = &c.Account{ -// Balance: balance, -// Nonce: nonce, -// } -// } -// return &EthState{ -// Client: client, -// Accounts: accounts, -// }, nil -// } +type EthState struct { + Client ethclient.Client + Accounts map[common.Address]*c.Account +} + +func FetchEthState( + ctx context.Context, + uri string, + addrs set.Set[common.Address], +) (*EthState, error) { + path := fmt.Sprintf( + "%s/ext/%s/C/rpc", + uri, + constants.ChainAliasPrefix, + ) + client, err := ethclient.Dial(path) + if err != nil { + return nil, err + } + + accounts := make(map[common.Address]*c.Account, addrs.Len()) + for addr := range addrs { + balance, err := client.BalanceAt(ctx, addr, nil) + if err != nil { + return nil, err + } + nonce, err := client.NonceAt(ctx, addr, nil) + if err != nil { + return nil, err + } + accounts[addr] = &c.Account{ + Balance: balance, + Nonce: nonce, + } + } + return &EthState{ + Client: client, + Accounts: accounts, + }, nil +} // AddAllUTXOs fetches all the UTXOs referenced by [addresses] that were sent // from [sourceChainID] to [destinationChainID] from the [client]. It then uses diff --git a/wallet/subnet/primary/example_test.go b/wallet/subnet/primary/example_test.go index 4a73e8c070b2..483c049d4ac0 100644 --- a/wallet/subnet/primary/example_test.go +++ b/wallet/subnet/primary/example_test.go @@ -30,7 +30,7 @@ func ExampleWallet() { wallet, err := MakeWallet(ctx, &WalletConfig{ URI: LocalAPIURI, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet with: %s\n", err) diff --git a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go index 21c081d2982b..d5e8ce422307 100644 --- a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go +++ b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go @@ -46,9 +46,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - // EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/examples/add-primary-validator/main.go b/wallet/subnet/primary/examples/add-primary-validator/main.go index 13c28f995f63..a56dae23db3a 100644 --- a/wallet/subnet/primary/examples/add-primary-validator/main.go +++ b/wallet/subnet/primary/examples/add-primary-validator/main.go @@ -45,7 +45,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/c-chain-export/main.go b/wallet/subnet/primary/examples/c-chain-export/main.go index a6b9a0c810b8..fec55c899feb 100644 --- a/wallet/subnet/primary/examples/c-chain-export/main.go +++ b/wallet/subnet/primary/examples/c-chain-export/main.go @@ -3,70 +3,70 @@ package main -// import ( -// "context" -// "log" -// "time" +import ( + "context" + "log" + "time" -// "github.com/ava-labs/avalanchego/genesis" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary" -// ) + "github.com/ava-labs/avalanchego/genesis" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary" +) -// func main() { -// key := genesis.EWOQKey -// uri := primary.LocalAPIURI -// kc := secp256k1fx.NewKeychain(key) -// avaxAddr := key.Address() +func main() { + key := genesis.EWOQKey + uri := primary.LocalAPIURI + kc := secp256k1fx.NewKeychain(key) + avaxAddr := key.Address() -// ctx := context.Background() + ctx := context.Background() -// // MakeWallet fetches the available UTXOs owned by [kc] on the network that -// // [uri] is hosting. -// walletSyncStartTime := time.Now() -// wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ -// URI: uri, -// AVAXKeychain: kc, -// EthKeychain: kc, -// }) -// if err != nil { -// log.Fatalf("failed to initialize wallet: %s\n", err) -// } -// log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) + // MakeWallet fetches the available UTXOs owned by [kc] on the network that + // [uri] is hosting. + walletSyncStartTime := time.Now() + wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, + }) + if err != nil { + log.Fatalf("failed to initialize wallet: %s\n", err) + } + log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) -// // Get the P-chain wallet -// pWallet := wallet.P() -// cWallet := wallet.C() + // Get the P-chain wallet + pWallet := wallet.P() + cWallet := wallet.C() -// // Pull out useful constants to use when issuing transactions. -// cChainID := cWallet.BlockchainID() -// owner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// avaxAddr, -// }, -// } + // Pull out useful constants to use when issuing transactions. + cChainID := cWallet.BlockchainID() + owner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + avaxAddr, + }, + } -// exportStartTime := time.Now() -// exportTx, err := cWallet.IssueExportTx( -// constants.PlatformChainID, -// []*secp256k1fx.TransferOutput{{ -// Amt: units.Avax, -// OutputOwners: owner, -// }}, -// ) -// if err != nil { -// log.Fatalf("failed to issue export transaction: %s\n", err) -// } -// log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) + exportStartTime := time.Now() + exportTx, err := cWallet.IssueExportTx( + constants.PlatformChainID, + []*secp256k1fx.TransferOutput{{ + Amt: units.Avax, + OutputOwners: owner, + }}, + ) + if err != nil { + log.Fatalf("failed to issue export transaction: %s\n", err) + } + log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) -// importStartTime := time.Now() -// importTx, err := pWallet.IssueImportTx(cChainID, &owner) -// if err != nil { -// log.Fatalf("failed to issue import transaction: %s\n", err) -// } -// log.Printf("issued import %s in %s\n", importTx.ID(), time.Since(importStartTime)) -// } + importStartTime := time.Now() + importTx, err := pWallet.IssueImportTx(cChainID, &owner) + if err != nil { + log.Fatalf("failed to issue import transaction: %s\n", err) + } + log.Printf("issued import %s in %s\n", importTx.ID(), time.Since(importStartTime)) +} diff --git a/wallet/subnet/primary/examples/c-chain-import/main.go b/wallet/subnet/primary/examples/c-chain-import/main.go index 2d9b8a244cb0..b4dc4e603eb3 100644 --- a/wallet/subnet/primary/examples/c-chain-import/main.go +++ b/wallet/subnet/primary/examples/c-chain-import/main.go @@ -3,75 +3,75 @@ package main -// import ( -// "context" -// "log" -// "time" +import ( + "context" + "log" + "time" -// "github.com/ava-labs/coreth/plugin/evm" + "github.com/ava-labs/coreth/plugin/evm" -// "github.com/ava-labs/avalanchego/genesis" -// "github.com/ava-labs/avalanchego/ids" -// "github.com/ava-labs/avalanchego/utils/constants" -// "github.com/ava-labs/avalanchego/utils/units" -// "github.com/ava-labs/avalanchego/vms/components/avax" -// "github.com/ava-labs/avalanchego/vms/secp256k1fx" -// "github.com/ava-labs/avalanchego/wallet/subnet/primary" -// ) + "github.com/ava-labs/avalanchego/genesis" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/units" + "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" + "github.com/ava-labs/avalanchego/wallet/subnet/primary" +) -// func main() { -// key := genesis.EWOQKey -// uri := primary.LocalAPIURI -// kc := secp256k1fx.NewKeychain(key) -// avaxAddr := key.Address() -// ethAddr := evm.PublicKeyToEthAddress(key.PublicKey()) +func main() { + key := genesis.EWOQKey + uri := primary.LocalAPIURI + kc := secp256k1fx.NewKeychain(key) + avaxAddr := key.Address() + ethAddr := evm.PublicKeyToEthAddress(key.PublicKey()) -// ctx := context.Background() + ctx := context.Background() -// // MakeWallet fetches the available UTXOs owned by [kc] on the network that -// // [uri] is hosting. -// walletSyncStartTime := time.Now() -// wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ -// URI: uri, -// AVAXKeychain: kc, -// EthKeychain: kc, -// }) -// if err != nil { -// log.Fatalf("failed to initialize wallet: %s\n", err) -// } -// log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) + // MakeWallet fetches the available UTXOs owned by [kc] on the network that + // [uri] is hosting. + walletSyncStartTime := time.Now() + wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, + }) + if err != nil { + log.Fatalf("failed to initialize wallet: %s\n", err) + } + log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) -// // Get the P-chain wallet -// pWallet := wallet.P() -// cWallet := wallet.C() + // Get the P-chain wallet + pWallet := wallet.P() + cWallet := wallet.C() -// // Pull out useful constants to use when issuing transactions. -// cChainID := cWallet.BlockchainID() -// avaxAssetID := cWallet.AVAXAssetID() -// owner := secp256k1fx.OutputOwners{ -// Threshold: 1, -// Addrs: []ids.ShortID{ -// avaxAddr, -// }, -// } + // Pull out useful constants to use when issuing transactions. + cChainID := cWallet.BlockchainID() + avaxAssetID := cWallet.AVAXAssetID() + owner := secp256k1fx.OutputOwners{ + Threshold: 1, + Addrs: []ids.ShortID{ + avaxAddr, + }, + } -// exportStartTime := time.Now() -// exportTx, err := pWallet.IssueExportTx(cChainID, []*avax.TransferableOutput{{ -// Asset: avax.Asset{ID: avaxAssetID}, -// Out: &secp256k1fx.TransferOutput{ -// Amt: units.Avax, -// OutputOwners: owner, -// }, -// }}) -// if err != nil { -// log.Fatalf("failed to issue export transaction: %s\n", err) -// } -// log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) + exportStartTime := time.Now() + exportTx, err := pWallet.IssueExportTx(cChainID, []*avax.TransferableOutput{{ + Asset: avax.Asset{ID: avaxAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: units.Avax, + OutputOwners: owner, + }, + }}) + if err != nil { + log.Fatalf("failed to issue export transaction: %s\n", err) + } + log.Printf("issued export %s in %s\n", exportTx.ID(), time.Since(exportStartTime)) -// importStartTime := time.Now() -// importTx, err := cWallet.IssueImportTx(constants.PlatformChainID, ethAddr) -// if err != nil { -// log.Fatalf("failed to issue import transaction: %s\n", err) -// } -// log.Printf("issued import %s to %s in %s\n", importTx.ID(), ethAddr.Hex(), time.Since(importStartTime)) -// } + importStartTime := time.Now() + importTx, err := cWallet.IssueImportTx(constants.PlatformChainID, ethAddr) + if err != nil { + log.Fatalf("failed to issue import transaction: %s\n", err) + } + log.Printf("issued import %s to %s in %s\n", importTx.ID(), ethAddr.Hex(), time.Since(importStartTime)) +} diff --git a/wallet/subnet/primary/examples/create-asset/main.go b/wallet/subnet/primary/examples/create-asset/main.go index 0bccfbb5fc52..30804f083df6 100644 --- a/wallet/subnet/primary/examples/create-asset/main.go +++ b/wallet/subnet/primary/examples/create-asset/main.go @@ -30,7 +30,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/create-chain/main.go b/wallet/subnet/primary/examples/create-chain/main.go index 521a3cca53cf..5e6898a1b649 100644 --- a/wallet/subnet/primary/examples/create-chain/main.go +++ b/wallet/subnet/primary/examples/create-chain/main.go @@ -41,9 +41,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - // EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/examples/create-locked-stakeable/main.go b/wallet/subnet/primary/examples/create-locked-stakeable/main.go index 92f1b5cb0e1b..e688968e9e8a 100644 --- a/wallet/subnet/primary/examples/create-locked-stakeable/main.go +++ b/wallet/subnet/primary/examples/create-locked-stakeable/main.go @@ -39,7 +39,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/create-subnet/main.go b/wallet/subnet/primary/examples/create-subnet/main.go index 3e8d69bc016a..add98ea7931c 100644 --- a/wallet/subnet/primary/examples/create-subnet/main.go +++ b/wallet/subnet/primary/examples/create-subnet/main.go @@ -28,7 +28,7 @@ func main() { wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ URI: uri, AVAXKeychain: kc, - // EthKeychain: kc, + EthKeychain: kc, }) if err != nil { log.Fatalf("failed to initialize wallet: %s\n", err) diff --git a/wallet/subnet/primary/examples/remove-subnet-validator/main.go b/wallet/subnet/primary/examples/remove-subnet-validator/main.go index 46f4b85124db..2842c7c0a790 100644 --- a/wallet/subnet/primary/examples/remove-subnet-validator/main.go +++ b/wallet/subnet/primary/examples/remove-subnet-validator/main.go @@ -38,9 +38,9 @@ func main() { // [uri] is hosting and registers [subnetID]. walletSyncStartTime := time.Now() wallet, err := primary.MakeWallet(ctx, &primary.WalletConfig{ - URI: uri, - AVAXKeychain: kc, - // EthKeychain: kc, + URI: uri, + AVAXKeychain: kc, + EthKeychain: kc, PChainTxsToFetch: set.Of(subnetID), }) if err != nil { diff --git a/wallet/subnet/primary/wallet.go b/wallet/subnet/primary/wallet.go index ae5e4202a099..54de390d029c 100644 --- a/wallet/subnet/primary/wallet.go +++ b/wallet/subnet/primary/wallet.go @@ -11,8 +11,7 @@ import ( "github.com/ava-labs/avalanchego/utils/crypto/keychain" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - - // "github.com/ava-labs/avalanchego/wallet/chain/c" + "github.com/ava-labs/avalanchego/wallet/chain/c" "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/chain/x" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" @@ -24,13 +23,13 @@ var _ Wallet = (*wallet)(nil) type Wallet interface { P() p.Wallet X() x.Wallet - // C() c.Wallet + C() c.Wallet } type wallet struct { p p.Wallet x x.Wallet - // c c.Wallet + c c.Wallet } func (w *wallet) P() p.Wallet { @@ -41,16 +40,16 @@ func (w *wallet) X() x.Wallet { return w.x } -// func (w *wallet) C() c.Wallet { -// return w.c -// } +func (w *wallet) C() c.Wallet { + return w.c +} // Creates a new default wallet -func NewWallet(p p.Wallet, x x.Wallet /*, c c.Wallet*/) Wallet { +func NewWallet(p p.Wallet, x x.Wallet, c c.Wallet) Wallet { return &wallet{ p: p, x: x, - // c: c, + c: c, } } @@ -59,7 +58,7 @@ func NewWalletWithOptions(w Wallet, options ...common.Option) Wallet { return NewWallet( p.NewWalletWithOptions(w.P(), options...), x.NewWalletWithOptions(w.X(), options...), - // c.NewWalletWithOptions(w.C(), options...), + c.NewWalletWithOptions(w.C(), options...), ) } @@ -68,7 +67,7 @@ type WalletConfig struct { URI string // required // Keys to use for signing all transactions. AVAXKeychain keychain.Keychain // required - // EthKeychain c.EthKeychain // required + EthKeychain c.EthKeychain // required // Set of P-chain transactions that the wallet should know about to be able // to generate transactions. PChainTxs map[ids.ID]*txs.Tx // optional @@ -94,11 +93,11 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { return nil, err } - // ethAddrs := config.EthKeychain.EthAddresses() - // ethState, err := FetchEthState(ctx, config.URI, ethAddrs) - // if err != nil { - // return nil, err - // } + ethAddrs := config.EthKeychain.EthAddresses() + ethState, err := FetchEthState(ctx, config.URI, ethAddrs) + if err != nil { + return nil, err + } pChainTxs := config.PChainTxs if pChainTxs == nil { @@ -128,15 +127,15 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { xBuilder := x.NewBuilder(avaxAddrs, xBackend) xSigner := x.NewSigner(config.AVAXKeychain, xBackend) - // cChainID := avaxState.CCTX.BlockchainID() - // cUTXOs := NewChainUTXOs(cChainID, avaxState.UTXOs) - // cBackend := c.NewBackend(avaxState.CCTX, cUTXOs, ethState.Accounts) - // cBuilder := c.NewBuilder(avaxAddrs, ethAddrs, cBackend) - // cSigner := c.NewSigner(config.AVAXKeychain, config.EthKeychain, cBackend) + cChainID := avaxState.CCTX.BlockchainID() + cUTXOs := NewChainUTXOs(cChainID, avaxState.UTXOs) + cBackend := c.NewBackend(avaxState.CCTX, cUTXOs, ethState.Accounts) + cBuilder := c.NewBuilder(avaxAddrs, ethAddrs, cBackend) + cSigner := c.NewSigner(config.AVAXKeychain, config.EthKeychain, cBackend) return NewWallet( p.NewWallet(pBuilder, pSigner, avaxState.PClient, pBackend), x.NewWallet(xBuilder, xSigner, avaxState.XClient, xBackend), - // c.NewWallet(cBuilder, cSigner, avaxState.CClient, ethState.Client, cBackend), + c.NewWallet(cBuilder, cSigner, avaxState.CClient, ethState.Client, cBackend), ), nil } From ca3c6e940f93a1da1057d270c72fba7d14d21663 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 2 Jan 2024 10:49:14 +0100 Subject: [PATCH 13/13] regenerated mock --- snow/engine/snowman/block/mock_state_syncable_vm.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/snow/engine/snowman/block/mock_state_syncable_vm.go b/snow/engine/snowman/block/mock_state_syncable_vm.go index c4bcf7340d7c..7f07f3c447a3 100644 --- a/snow/engine/snowman/block/mock_state_syncable_vm.go +++ b/snow/engine/snowman/block/mock_state_syncable_vm.go @@ -8,9 +8,8 @@ import ( context "context" reflect "reflect" - gomock "go.uber.org/mock/gomock" - ids "github.com/ava-labs/avalanchego/ids" + gomock "go.uber.org/mock/gomock" ) // MockStateSyncableVM is a mock of StateSyncableVM interface.