Categorygithub.com/filecoin-project/go-data-transfer
modulepackage
1.15.4-boost
Repository: https://github.com/filecoin-project/go-data-transfer.git
Documentation: pkg.go.dev

# README

go-data-transfer

CircleCI codecov

A go module to perform data transfers over ipfs/go-graphsync

Description

This module encapsulates protocols for exchanging piece data between storage clients and miners, both when consummating a storage deal and when retrieving the piece later.

Table of Contents

Usage

Requires go 1.13

Install the module in your package or app with go get "github.com/filecoin-project/go-data-transfer/datatransfer"

Initialize a data transfer module

  1. Set up imports. You need, minimally, the following imports:

    package mypackage
    
    import (
        gsimpl "github.com/filecoin-project/boost-graphsync/impl"
        datatransfer "github.com/filecoin-project/go-data-transfer/impl"
        gstransport "github.com/filecoin-project/go-data-transfer/transport/graphsync"
        "github.com/libp2p/go-libp2p/core/host"
    )
            
    
  2. Provide or create a libp2p host.Host

  3. You will need a transport protocol. The current default transport is graphsync. go-graphsync GraphExchange

  4. Create a data transfer by building a transport interface and then initializing a new data transfer instance

    func NewGraphsyncDataTransfer(h host.Host, gs graphsync.GraphExchange) {
        tp := gstransport.NewTransport(h.ID(), gs)
        dt := impl.NewDataTransfer(h, tp)
    }
    
  5. If needed, build out your voucher struct and its validator.

    A push or pull request must include a voucher. The voucher's type must have been registered with the node receiving the request before it's sent, otherwise the request will be rejected.

    datatransfer.Voucher and datatransfer.Validator are the interfaces used for validation of graphsync datatransfer messages. Voucher types plus a Validator for them must be registered with the peer to whom requests will be sent.

Example Toy Voucher and Validator

type myVoucher struct {
	data string
}

func (v *myVoucher) ToBytes() ([]byte, error) {
	return []byte(v.data), nil
}

func (v *myVoucher) FromBytes(data []byte) error {
	v.data = string(data)
	return nil
}

func (v *myVoucher) Type() string {
	return "FakeDTType"
}

type myValidator struct {
	ctx                 context.Context
	ValidationsReceived chan receivedValidation
}

func (vl *myValidator) ValidatePush(
	sender peer.ID,
	voucher datatransfer.Voucher,
	baseCid cid.Cid,
	selector ipld.Node) error {
    
    v := voucher.(*myVoucher)
    if v.data == "" || v.data != "validpush" {
        return errors.New("invalid")
    }   

	return nil
}

func (vl *myValidator) ValidatePull(
	receiver peer.ID,
	voucher datatransfer.Voucher,
	baseCid cid.Cid,
	selector ipld.Node) error {

    v := voucher.(*myVoucher)
    if v.data == "" || v.data != "validpull" {
        return errors.New("invalid")
    }   

	return nil
}

Please see go-data-transfer/blob/master/types.go for more detail.

Register a validator

Before sending push or pull requests, you must register a datatransfer.Voucher by its reflect.Type and dataTransfer.RequestValidator for vouchers that must be sent with the request. Using the trivial examples above:

    func NewGraphsyncDatatransfer(h host.Host, gs graphsync.GraphExchange) {
        tp := gstransport.NewTransport(h.ID(), gs)
        dt := impl.NewDataTransfer(h, tp)

        vouch := &myVoucher{}
        mv := &myValidator{} 
        dt.RegisterVoucherType(reflect.TypeOf(vouch), mv)
    }

For more detail, please see the unit tests.

Open a Push or Pull Request

For a push or pull request, provide a context, a datatransfer.Voucher, a host recipient peer.ID, a baseCID cid.CID and a selector ipld.Node. These calls return a datatransfer.ChannelID and any error:

    channelID, err := dtm.OpenPullDataChannel(ctx, recipient, voucher, baseCid, selector)
    // OR
    channelID, err := dtm.OpenPushDataChannel(ctx, recipient, voucher, baseCid, selector)

Subscribe to Events

The module allows the consumer to be notified when a graphsync Request is sent or a datatransfer push or pull request response is received:

    func ToySubscriberFunc (event Event, channelState ChannelState) {
        if event.Code == datatransfer.Error {
            // log error, flail about helplessly
            return
        }
        // 
        if channelState.Recipient() == our.PeerID && channelState.Received() > 0 {
            // log some stuff, update some state somewhere, send data to a channel, etc.
        }
    }

    dtm := SetupDataTransferManager(ctx, h, gs, baseCid, snode)
    unsubFunc := dtm.SubscribeToEvents(ToySubscriberFunc)

    // . . . later, when you don't need to know about events any more:
    unsubFunc()

Contributing

PRs are welcome! Please first read the design docs and look over the current code. PRs against master require approval of at least two maintainers. For the rest, please see our CONTRIBUTING guide.

License

This repository is dual-licensed under Apache 2.0 and MIT terms.

Copyright 2019. Protocol Labs, Inc.

# Packages

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Constants

Accept is an event that emits when the data transfer is first accepted.
BeginFinalizing emits when the responder completes its operations but awaits a response from the initiator.
BothPaused means both sender and receiver have paused the channel seperately (both must unpause).
Cancel indicates one side has cancelled the transfer.
Cancelled means the data transfer ended prematurely.
Cancelling just means we have some final cleanup for a cancelled request.
ChannelNotFoundError means the searched for data transfer does not exist.
CleanupComplete emits when a request is cleaned up.
Complete is emitted when a data transfer is complete.
CompleteCleanupOnRestart is emitted when a data transfer channel is restarted to signal that channels that were cleaning up should finish cleanup.
Completed means the data transfer is completed successfully.
Completing just means we have some final cleanup for a completed request.
DataQueued is emitted when data is read and queued for sending to the remote peer.
DataQueuedProgress is emitted when a block is queued for sending to the remote peer.
DataReceived is emitted when data is received on the channel from a remote peer.
DataReceivedProgress is emitted the first time a block is received from the remote peer.
DataSent is emitted when data is sent on the channel to the remote peer.
DataSentProgress is emitted when a block is sent to the remote peer.
Disconnected emits when we are not able to connect to the other party.
EmptyTypeIdentifier means there is no voucher present.
ErrChannelNotFound means the channel this command was issued for does not exist.
ErrHandlerAlreadySet means an event handler was already set for this instance of hooks.
ErrHandlerNotSet means you cannot issue commands to this interface because the handler has not been set.
Error is an event that emits when an error occurs in a data transfer.
ErrPause is a special error that the DataReceived / DataSent hooks can use to pause the channel.
ErrRejected indicates a request was not accepted.
ErrResume is a special error that the RequestReceived / ResponseReceived hooks can use to resume the channel.
ErrUnsupported indicates an operation is not supported by the transport protocol.
Failed means the data transfer failed.
Failing just means we have some final cleanup for a failed request.
Finalizing means the responder is awaiting a final message from the initator to consider the transfer done.
FinishTransfer emits when the initiator has completed sending/receiving data.
InitiatorPaused means the data sender has paused the channel (only the sender can unpause this).
NewVoucher means we have a new voucher on this channel.
NewVoucherResult means we have a new voucher result on this channel.
Ongoing means the data transfer is in progress.
Open is an event occurs when a channel is first opened.
Opened is fired when a request for data is sent from this node to a peer.
PauseInitiator emits when the data sender pauses transfer.
PauseResponder emits when the data receiver pauses transfer.
ReceiveDataError indicates that the transport layer had an error receiving data from the remote peer.
RequestCancelled indicates that a transport layer request was cancelled by the request opener.
Requested means a data transfer was requested by has not yet been approved.
Deprecated in favour of RequestCancelled.
ResponderBeginsFinalization emits when the initiator receives a message that the responder is finilizing.
ResponderCompleted indicates the initiator received a message from the responder that it's completed.
ResponderCompletes emits when the initiator receives a message that the responder is finished.
ResponderFinalizing is a unique state where the responder is awaiting a final voucher.
ResponderFinalizingTransferFinished is a unique state where the responder is awaiting a final voucher and we have received all data.
ResponderPaused means the data receiver has paused the channel (only the receiver can unpause this).
Restart is an event that emits when the data transfer is restarted.
ResumeInitiator emits when the data sender resumes transfer.
ResumeResponder emits when the data receiver resumes transfer.
SendDataError indicates that the transport layer had an error trying to send data to the remote peer.
TransferFinished indicates the initiator is done sending/receiving data but is awaiting confirmation from the responder.
TransferRequestQueued indicates that a new data transfer request has been queued in the transport layer.

# Variables

Events are human readable names for data transfer events.
ProtocolDataTransfer1_2 is the protocol identifier for the latest version of data-transfer (supports do-not-send-first-blocks extension).
Statuses are human readable names for data transfer states.

# Structs

ChannelID is a unique identifier for a channel, distinct by both the other party's peer ID + the transfer ID.
ChannelStage traces the execution of a data transfer channel stage.
ChannelStages captures a timeline of the progress of a data transfer channel, grouped by stages.
Event is a struct containing information about a data transfer event.
Log represents a point-in-time event that occurred inside a channel stage.

# Interfaces

Channel represents all the parameters for a single data transfer.
ChannelState is channel parameters plus it's current state.
EventsHandler are semantic data transfer events that happen as a result of graphsync hooks.
Manager is the core interface presented by all implementations of of the data transfer sub system.
Message is a message for the data transfer protocol (either request or response) that can serialize to a protobuf.
PauseableTransport is a transport that can also pause and resume channels.
Registerable is a type of object in a registry.
Request is a response message for the data transfer protocol.
RequestValidator is an interface implemented by the client of the data transfer module to validate requests.
Response is a response message for the data transfer protocol.
Revalidator is a request validator revalidates in progress requests by requesting request additional vouchers, and resuming when it receives them.
Transport defines the interface for a transport layer for data transfer.

# Type aliases

EventCode is a name for an event that occurs on a data transfer channel.
ReadyFunc is function that gets called once when the data transfer module is ready.
Status is the status of transfer for a given channel.
Subscriber is a callback that is called when events are emitted.
TransferID is an identifier for a data transfer, shared between request/responder and unique to the requester.
TransportConfigurer provides a mechanism to provide transport specific configuration for a given voucher type.
TypeIdentifier is a unique string identifier for a type of encodable object in a registry.
Unsubscribe is a function that gets called to unsubscribe from data transfer events.
Voucher is used to validate a data transfer request against the underlying storage or retrieval deal that precipitated it.
VoucherResult is used to provide option additional information about a voucher being rejected or accepted.