github.com/MetalBlockchain/metalgo@v1.11.9/vms/rpcchainvm/ghttp/gconn/conn_client.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package gconn
     5  
     6  import (
     7  	"context"
     8  	"errors"
     9  	"io"
    10  	"net"
    11  	"time"
    12  
    13  	"google.golang.org/protobuf/types/known/emptypb"
    14  
    15  	"github.com/MetalBlockchain/metalgo/utils/wrappers"
    16  
    17  	connpb "github.com/MetalBlockchain/metalgo/proto/pb/net/conn"
    18  )
    19  
    20  var _ net.Conn = (*Client)(nil)
    21  
    22  // Client is an implementation of a connection that talks over RPC.
    23  type Client struct {
    24  	client  connpb.ConnClient
    25  	local   net.Addr
    26  	remote  net.Addr
    27  	toClose []io.Closer
    28  }
    29  
    30  // NewClient returns a connection connected to a remote connection
    31  func NewClient(client connpb.ConnClient, local, remote net.Addr, toClose ...io.Closer) *Client {
    32  	return &Client{
    33  		client:  client,
    34  		local:   local,
    35  		remote:  remote,
    36  		toClose: toClose,
    37  	}
    38  }
    39  
    40  func (c *Client) Read(p []byte) (int, error) {
    41  	resp, err := c.client.Read(context.Background(), &connpb.ReadRequest{
    42  		Length: int32(len(p)),
    43  	})
    44  	if err != nil {
    45  		return 0, err
    46  	}
    47  
    48  	copy(p, resp.Read)
    49  
    50  	if resp.Error != nil {
    51  		err = errors.New(*resp.Error)
    52  	}
    53  	return len(resp.Read), err
    54  }
    55  
    56  func (c *Client) Write(b []byte) (int, error) {
    57  	resp, err := c.client.Write(context.Background(), &connpb.WriteRequest{
    58  		Payload: b,
    59  	})
    60  	if err != nil {
    61  		return 0, err
    62  	}
    63  
    64  	if resp.Error != nil {
    65  		err = errors.New(*resp.Error)
    66  	}
    67  	return int(resp.Length), err
    68  }
    69  
    70  func (c *Client) Close() error {
    71  	_, err := c.client.Close(context.Background(), &emptypb.Empty{})
    72  	errs := wrappers.Errs{}
    73  	errs.Add(err)
    74  	for _, toClose := range c.toClose {
    75  		errs.Add(toClose.Close())
    76  	}
    77  	return errs.Err
    78  }
    79  
    80  func (c *Client) LocalAddr() net.Addr {
    81  	return c.local
    82  }
    83  
    84  func (c *Client) RemoteAddr() net.Addr {
    85  	return c.remote
    86  }
    87  
    88  func (c *Client) SetDeadline(t time.Time) error {
    89  	bytes, err := t.MarshalBinary()
    90  	if err != nil {
    91  		return err
    92  	}
    93  	_, err = c.client.SetDeadline(context.Background(), &connpb.SetDeadlineRequest{
    94  		Time: bytes,
    95  	})
    96  	return err
    97  }
    98  
    99  func (c *Client) SetReadDeadline(t time.Time) error {
   100  	bytes, err := t.MarshalBinary()
   101  	if err != nil {
   102  		return err
   103  	}
   104  	_, err = c.client.SetReadDeadline(context.Background(), &connpb.SetDeadlineRequest{
   105  		Time: bytes,
   106  	})
   107  	return err
   108  }
   109  
   110  func (c *Client) SetWriteDeadline(t time.Time) error {
   111  	bytes, err := t.MarshalBinary()
   112  	if err != nil {
   113  		return err
   114  	}
   115  	_, err = c.client.SetWriteDeadline(context.Background(), &connpb.SetDeadlineRequest{
   116  		Time: bytes,
   117  	})
   118  	return err
   119  }