Documentation ¶
Index ¶
- Constants
- func NewMemStorage() (storage *memoryStorage)
- func NewPaymentHandler(service PaymentChannelService, processor *blockchain.Processor, ...) handler.PaymentHandler
- type AtomicStorage
- type BlockchainChannelReader
- type ChannelPaymentValidator
- type ChannelUpdate
- type Claim
- type IncomeData
- type IncomeValidator
- type Lock
- type Locker
- type Payment
- type PaymentChannelData
- type PaymentChannelKey
- type PaymentChannelService
- type PaymentChannelState
- type PaymentChannelStateService
- type PaymentChannelStorage
- func (storage *PaymentChannelStorage) CompareAndSwap(key *PaymentChannelKey, prevState *PaymentChannelData, ...) (ok bool, err error)
- func (storage *PaymentChannelStorage) Get(key *PaymentChannelKey) (state *PaymentChannelData, ok bool, err error)
- func (storage *PaymentChannelStorage) GetAll() (states []*PaymentChannelData, err error)
- func (storage *PaymentChannelStorage) Put(key *PaymentChannelKey, state *PaymentChannelData) (err error)
- func (storage *PaymentChannelStorage) PutIfAbsent(key *PaymentChannelKey, state *PaymentChannelData) (ok bool, err error)
- type PaymentError
- type PaymentErrorCode
- type PaymentStorage
- type PaymentTransaction
- type PrefixedAtomicStorage
- func (storage *PrefixedAtomicStorage) CompareAndSwap(key string, prevValue string, newValue string) (ok bool, err error)
- func (storage *PrefixedAtomicStorage) Delete(key string) (err error)
- func (storage *PrefixedAtomicStorage) Get(key string) (value string, ok bool, err error)
- func (storage *PrefixedAtomicStorage) GetByKeyPrefix(prefix string) (values []string, err error)
- func (storage *PrefixedAtomicStorage) Put(key string, value string) (err error)
- func (storage *PrefixedAtomicStorage) PutIfAbsent(key string, value string) (ok bool, err error)
- type ProviderControlService
- func (service *ProviderControlService) GetListInProgress(ctx context.Context, request *GetPaymentsListRequest) (reply *PaymentsListReply, err error)
- func (service *ProviderControlService) GetListUnclaimed(ctx context.Context, request *GetPaymentsListRequest) (paymentReply *PaymentsListReply, err error)
- func (service *ProviderControlService) StartClaim(ctx context.Context, startClaim *StartClaimRequest) (paymentReply *PaymentReply, err error)
- type TypedAtomicStorage
- type TypedAtomicStorageImpl
- func (storage *TypedAtomicStorageImpl) CompareAndSwap(key interface{}, prevValue interface{}, newValue interface{}) (ok bool, err error)
- func (storage *TypedAtomicStorageImpl) Delete(key interface{}) (err error)
- func (storage *TypedAtomicStorageImpl) Get(key interface{}) (value interface{}, ok bool, err error)
- func (storage *TypedAtomicStorageImpl) GetAll() (array interface{}, err error)
- func (storage *TypedAtomicStorageImpl) Put(key interface{}, value interface{}) (err error)
- func (storage *TypedAtomicStorageImpl) PutIfAbsent(key interface{}, value interface{}) (ok bool, err error)
Constants ¶
const ( // PaymentChannelIDHeader is a MultiPartyEscrow contract payment channel // id. Value is a string containing a decimal number. PaymentChannelIDHeader = "snet-payment-channel-id" // PaymentChannelNonceHeader is a payment channel nonce value. Value is a // string containing a decimal number. PaymentChannelNonceHeader = "snet-payment-channel-nonce" // PaymentChannelAmountHeader is an amount of payment channel value // which server is authorized to withdraw after handling the RPC call. // Value is a string containing a decimal number. PaymentChannelAmountHeader = "snet-payment-channel-amount" // PaymentChannelSignatureHeader is a signature of the client to confirm // amount withdrawing authorization. Value is an array of bytes. PaymentChannelSignatureHeader = "snet-payment-channel-signature-bin" // EscrowPaymentType each call should have id and nonce of payment channel // in metadata. EscrowPaymentType = "escrow" )
Variables ¶
This section is empty.
Functions ¶
func NewMemStorage ¶
func NewMemStorage() (storage *memoryStorage)
NewMemStorage returns new in-memory atomic storage implementation
func NewPaymentHandler ¶
func NewPaymentHandler( service PaymentChannelService, processor *blockchain.Processor, incomeValidator IncomeValidator) handler.PaymentHandler
NewPaymentHandler retuns new MultiPartyEscrow contract payment handler.
Types ¶
type AtomicStorage ¶
type AtomicStorage interface { // Get returns value by key. ok value indicates whether passed key is // present in the storage. err indicates storage error. Get(key string) (value string, ok bool, err error) // GetByKeyPrefix returns list of values which keys has given prefix. GetByKeyPrefix(prefix string) (values []string, err error) // Put uncoditionally writes value by key in storage, err is not nil in // case of storage error. Put(key string, value string) (err error) // PutIfAbsent writes value if and only if key is absent in storage. ok is // true if key was absent and false otherwise. err indicates storage error. PutIfAbsent(key string, value string) (ok bool, err error) // CompareAndSwap atomically replaces prevValue by newValue. If ok flag is // true and err is nil then operation was successful. If err is nil and ok // is false then operation failed because prevValue is not equal to current // value. err indicates storage error. CompareAndSwap(key string, prevValue string, newValue string) (ok bool, err error) // Delete removes value by key Delete(key string) (err error) }
AtomicStorage is an interface to key-value storage with atomic operations.
type BlockchainChannelReader ¶
type BlockchainChannelReader struct {
// contains filtered or unexported fields
}
BlockchainChannelReader reads channel state from blockchain
func NewBlockchainChannelReader ¶
func NewBlockchainChannelReader(processor *blockchain.Processor, cfg *viper.Viper, metadata *blockchain.ServiceMetadata) *BlockchainChannelReader
NewBlockchainChannelReader returns new instance of blockchain channel reader
func (*BlockchainChannelReader) GetChannelStateFromBlockchain ¶
func (reader *BlockchainChannelReader) GetChannelStateFromBlockchain(key *PaymentChannelKey) (channel *PaymentChannelData, ok bool, err error)
GetChannelStateFromBlockchain returns channel state from Ethereum blockchain. ok is false if channel was not found.
type ChannelPaymentValidator ¶
type ChannelPaymentValidator struct {
// contains filtered or unexported fields
}
ChannelPaymentValidator validates payment using payment channel state.
func NewChannelPaymentValidator ¶
func NewChannelPaymentValidator(processor *blockchain.Processor, cfg *viper.Viper, metadata *blockchain.ServiceMetadata) *ChannelPaymentValidator
NewChannelPaymentValidator returns new payment validator instance
func (*ChannelPaymentValidator) Validate ¶
func (validator *ChannelPaymentValidator) Validate(payment *Payment, channel *PaymentChannelData) (err error)
Validate returns instance of PaymentError as error if validation fails, nil otherwise.
type ChannelUpdate ¶
type ChannelUpdate func(channel *PaymentChannelData)
ChannelUpdate is an type of channel update which should be applied when StartClaim() method is called.
var ( // CloseChannel is an update which zeroes full amount of the channel to // designate that channel sender should add funds to the channel before // continue working. CloseChannel ChannelUpdate = func(channel *PaymentChannelData) { channel.FullAmount = big.NewInt(0) } // IncrementChannelNonce is an update which increments channel nonce and // descreases full amount to allow channel sender continue working with // remaining amount. IncrementChannelNonce ChannelUpdate = func(channel *PaymentChannelData) { channel.Nonce = (&big.Int{}).Add(channel.Nonce, big.NewInt(1)) channel.FullAmount = (&big.Int{}).Sub(channel.FullAmount, channel.AuthorizedAmount) channel.AuthorizedAmount = big.NewInt(0) channel.Signature = nil } )
type Claim ¶
type Claim interface { // Payment returns the payment which is being claimed, caller uses details of // the payment to start blockchain transaction. Payment() *Payment // Finish to be called after blockchain transaction is finished successfully. // Updates repository state. Finish() error }
Claim is a handle of payment channel claim in progress. It is returned by StartClaim method and provides caller information about payment to call MultiPartyEscrow.channelClaim function. After transaction is written to blockchain caller should call Finish() method to update payment repository state.
type IncomeData ¶
type IncomeData struct { // Income is a difference between previous authorized amount and amount // which was received with current call. Income *big.Int // GrpcContext contains gRPC stream context information. For instance // metadata could be used to pass invoice id to check pricing. GrpcContext *handler.GrpcStreamContext }
IncomeData is used to pass information to the pricing validation system. This system can use information about call to calculate price and verify income received.
type IncomeValidator ¶
type IncomeValidator interface { // Validate returns nil if validation is successful or correct PaymentError // status to be sent to client in case of validation error. Validate(*IncomeData) (err error) }
IncomeValidator uses pricing information to check that call was payed correctly by channel sender. This interface can be implemented differently depending on pricing policy. For instance one can verify that call is payed according to invoice. Each RPC method can have different price and so on. To implement this strategies additional information from gRPC context can be required. In such case it should be added into handler.GrpcStreamContext.
func NewIncomeValidator ¶
func NewIncomeValidator(priceInCogs *big.Int) (validator IncomeValidator)
NewIncomeValidator returns new income validator instance
type Lock ¶
type Lock interface { // Unlock frees lock Unlock() (err error) }
Lock is an aquired lock.
type Locker ¶
type Locker interface { // Lock aquires and returns lock. ok is false if lock cannot be aquired. Lock(name string) (lock Lock, ok bool, err error) }
Locker is an interface to aquire lock
func NewEtcdLocker ¶
func NewEtcdLocker(storage AtomicStorage) Locker
NewEtcdLocker returns new lock which is based on etcd storage.
type Payment ¶
type Payment struct { // MpeContractAddress is an address of the MultiPartyEscrow contract which // were used to open the payment channel. MpeContractAddress common.Address // ChannelID is an id of the payment channel used. ChannelID *big.Int // ChannelNonce is a nonce of the payment channel. ChannelNonce *big.Int // Amount is an amount of the payment. Amount *big.Int // Signature is a signature of the payment. Signature []byte }
Payment contains MultiPartyEscrow payment details
type PaymentChannelData ¶
type PaymentChannelData struct { // ChannelID is an id of the channel ChannelID *big.Int // Nonce is a nonce of this channel state Nonce *big.Int // State is a payment channel state: Open or Closed. State PaymentChannelState // Sender is an Ethereum address of the client which created the channel. // It is and address to be charged for RPC call. Sender common.Address // Recipient is an address which can claim funds from channel using // signature. It is an address of service provider. Recipient common.Address // GroupID is an id of the group of service replicas which share the same // payment channel. GroupID [32]byte // FullAmount is an amount which is deposited in channel by Sender. FullAmount *big.Int // Expiration is a time at which channel will be expired. This time is // expressed in Ethereum block number. Since this block is added to // blockchain Sender can withdraw tokens from channel. Expiration *big.Int // Signer is and address to be used to sign the payments. Usually it is // equal to channel sender. Signer common.Address // service provider. This amount increments on price after each successful // RPC call. AuthorizedAmount *big.Int // Signature is a signature of last message containing Authorized amount. // It is required to claim tokens from channel. Signature []byte }
PaymentChannelData is to keep all channel related information.
func MergeStorageAndBlockchainChannelState ¶
func MergeStorageAndBlockchainChannelState(storage, blockchain *PaymentChannelData) (merged *PaymentChannelData)
MergeStorageAndBlockchainChannelState merges two instances of payment channel: one read from storage, one from blockchain.
func (*PaymentChannelData) String ¶
func (data *PaymentChannelData) String() string
type PaymentChannelKey ¶
PaymentChannelKey specifies the channel in MultiPartyEscrow contract. It consists of two parts: channel id and channel nonce. Channel nonce is incremented each time when amount of tokens in channel descreases. Nonce allows reusing channel id without risk of overexpenditure.
func (*PaymentChannelKey) String ¶
func (key *PaymentChannelKey) String() string
type PaymentChannelService ¶
type PaymentChannelService interface { // PaymentChannel returns latest payment channel state. This method uses // shared storage and blockchain to construct and return latest channel // state. PaymentChannel(key *PaymentChannelKey) (channel *PaymentChannelData, ok bool, err error) // ListChannels returns list of payment channels from payment channel // storage. ListChannels() (channels []*PaymentChannelData, err error) // StartClaim gets channel from storage, applies update on it and adds // payment for claiming into the storage. StartClaim(key *PaymentChannelKey, update ChannelUpdate) (claim Claim, err error) // ListClaims returns list of payment claims in progress ListClaims() (claim []Claim, err error) // StartPaymentTransaction validates payment and starts payment transaction StartPaymentTransaction(payment *Payment) (transaction PaymentTransaction, err error) //Get Channel from BlockChain PaymentChannelFromBlockChain(key *PaymentChannelKey) (channel *PaymentChannelData, ok bool, err error) }
PaymentChannelService interface is API for payment channel functionality.
func NewPaymentChannelService ¶
func NewPaymentChannelService( storage *PaymentChannelStorage, paymentStorage *PaymentStorage, blockchainReader *BlockchainChannelReader, locker Locker, channelPaymentValidator *ChannelPaymentValidator, groupIdReader func() ([32]byte, error)) PaymentChannelService
NewPaymentChannelService returns instance of PaymentChannelService to work with payments via MultiPartyEscrow contract.
type PaymentChannelState ¶
type PaymentChannelState int
PaymentChannelState is a current state of a payment channel. Payment channel may be in Open or Closed state.
const ( // Open means that channel is open and can be used to pay for calls. Open PaymentChannelState = 0 // Closed means that channel is closed cannot be used to pay for calls. Closed PaymentChannelState = 1 )
func (PaymentChannelState) String ¶
func (state PaymentChannelState) String() string
type PaymentChannelStateService ¶
type PaymentChannelStateService struct {
// contains filtered or unexported fields
}
PaymentChannelStateService is an implementation of PaymentChannelStateServiceServer gRPC interface
func NewPaymentChannelStateService ¶
func NewPaymentChannelStateService(channelService PaymentChannelService) *PaymentChannelStateService
NewPaymentChannelStateService returns new instance of PaymentChannelStateService
func (*PaymentChannelStateService) GetChannelState ¶
func (service *PaymentChannelStateService) GetChannelState(context context.Context, request *ChannelStateRequest) (reply *ChannelStateReply, err error)
GetChannelState returns the latest state of the channel which id is passed in request. To authenticate sender request should also contain correct signature of the channel id.
type PaymentChannelStorage ¶
type PaymentChannelStorage struct {
// contains filtered or unexported fields
}
PaymentChannelStorage is a storage for PaymentChannelData by PaymentChannelKey based on TypedAtomicStorage implementation
func NewPaymentChannelStorage ¶
func NewPaymentChannelStorage(atomicStorage AtomicStorage) *PaymentChannelStorage
NewPaymentChannelStorage returns new instance of PaymentChannelStorage implementation
func (*PaymentChannelStorage) CompareAndSwap ¶
func (storage *PaymentChannelStorage) CompareAndSwap(key *PaymentChannelKey, prevState *PaymentChannelData, newState *PaymentChannelData) (ok bool, err error)
CompareAndSwap compares previous storage value and set new value by key
func (*PaymentChannelStorage) Get ¶
func (storage *PaymentChannelStorage) Get(key *PaymentChannelKey) (state *PaymentChannelData, ok bool, err error)
Get returns payment channel by key
func (*PaymentChannelStorage) GetAll ¶
func (storage *PaymentChannelStorage) GetAll() (states []*PaymentChannelData, err error)
GetAll returns all channels from the storage
func (*PaymentChannelStorage) Put ¶
func (storage *PaymentChannelStorage) Put(key *PaymentChannelKey, state *PaymentChannelData) (err error)
Put stores payment channel by key
func (*PaymentChannelStorage) PutIfAbsent ¶
func (storage *PaymentChannelStorage) PutIfAbsent(key *PaymentChannelKey, state *PaymentChannelData) (ok bool, err error)
PutIfAbsent storage payment channel by key if key is absent
type PaymentError ¶
type PaymentError struct { // Code is error code Code PaymentErrorCode // Message is message Message string }
PaymentError contains error code and message and implements Error interface.
func NewPaymentError ¶
func NewPaymentError(code PaymentErrorCode, format string, msg ...interface{}) *PaymentError
NewPaymentError constructs new PaymentError instance with given error code and message.
func (*PaymentError) Error ¶
func (err *PaymentError) Error() string
type PaymentErrorCode ¶
type PaymentErrorCode int
PaymentErrorCode contains all types of errors which we need to handle on the client side.
const ( // Internal error code means that error is caused by improper daemon // configuration or functioning. Client cannot do anything with it. Internal PaymentErrorCode = 1 // Unauthenticated error code means that client sent payment which cannot // be applied to the channel. Unauthenticated PaymentErrorCode = 2 // FailedPrecondition means that request cannot be handled because system // is not in appropriate state. FailedPrecondition PaymentErrorCode = 3 // IncorrectNonce is returned when nonce value sent by client is incorrect. IncorrectNonce PaymentErrorCode = 4 )
type PaymentStorage ¶
type PaymentStorage struct {
// contains filtered or unexported fields
}
PaymentStorage is a storage for PaymentChannelData by PaymentChannelKey based on TypedAtomicStorage implementation
func NewPaymentStorage ¶
func NewPaymentStorage(atomicStorage AtomicStorage) *PaymentStorage
NewPaymentStorage returns new instance of PaymentStorage implementation
func (*PaymentStorage) Delete ¶
func (storage *PaymentStorage) Delete(payment *Payment) (err error)
func (*PaymentStorage) GetAll ¶
func (storage *PaymentStorage) GetAll() (states []*Payment, err error)
func (*PaymentStorage) Put ¶
func (storage *PaymentStorage) Put(payment *Payment) (err error)
type PaymentTransaction ¶
type PaymentTransaction interface { // Channel returns the channel which is used to apply the payment Channel() *PaymentChannelData // Commit finishes transaction and applies payment. Commit() error // Rollback rolls transaction back. Rollback() error }
PaymentTransaction is a payment transaction in progress.
type PrefixedAtomicStorage ¶
type PrefixedAtomicStorage struct {
// contains filtered or unexported fields
}
PrefixedAtomicStorage is decorator for atomic storage which adds a prefix to the storage keys.
func NewLockerStorage ¶
func NewLockerStorage(storage AtomicStorage) *PrefixedAtomicStorage
returns new prefixed storage
func (*PrefixedAtomicStorage) CompareAndSwap ¶
func (storage *PrefixedAtomicStorage) CompareAndSwap(key string, prevValue string, newValue string) (ok bool, err error)
CompareAndSwap is implementation of AtomicStorage.CompareAndSwap
func (*PrefixedAtomicStorage) Delete ¶
func (storage *PrefixedAtomicStorage) Delete(key string) (err error)
func (*PrefixedAtomicStorage) Get ¶
func (storage *PrefixedAtomicStorage) Get(key string) (value string, ok bool, err error)
Get is implementation of AtomicStorage.Get
func (*PrefixedAtomicStorage) GetByKeyPrefix ¶
func (storage *PrefixedAtomicStorage) GetByKeyPrefix(prefix string) (values []string, err error)
func (*PrefixedAtomicStorage) Put ¶
func (storage *PrefixedAtomicStorage) Put(key string, value string) (err error)
Put is implementation of AtomicStorage.Put
func (*PrefixedAtomicStorage) PutIfAbsent ¶
func (storage *PrefixedAtomicStorage) PutIfAbsent(key string, value string) (ok bool, err error)
PutIfAbsent is implementation of AtomicStorage.PutIfAbsent
type ProviderControlService ¶
type ProviderControlService struct {
// contains filtered or unexported fields
}
func NewProviderControlService ¶
func NewProviderControlService(channelService PaymentChannelService, metaData *blockchain.ServiceMetadata) *ProviderControlService
func (*ProviderControlService) GetListInProgress ¶
func (service *ProviderControlService) GetListInProgress(ctx context.Context, request *GetPaymentsListRequest) (reply *PaymentsListReply, err error)
Get the list of all claims that have been initiated but not completed yet. Verify that mpe_address is correct Verify that actual block_number is not very different (+-5 blocks) from the current_block_number from the signature Verify that message was signed by the service provider (“payment_address” in metadata should match to the signer). Check for any claims already done on block chain but have not been reflected in the storage yet, update the storage status by calling the Finish() method on such claims.
func (*ProviderControlService) GetListUnclaimed ¶
func (service *ProviderControlService) GetListUnclaimed(ctx context.Context, request *GetPaymentsListRequest) (paymentReply *PaymentsListReply, err error)
Get list of unclaimed payments, we do this by getting the list of channels in progress which have some amount to be claimed. Verify that mpe_address is correct Verify that actual block_number is not very different (+-5 blocks) from the current_block_number from the signature Verify that message was signed by the service provider (“payment_address” in metadata should match to the signer). Send list of unclaimed payments
func (*ProviderControlService) StartClaim ¶
func (service *ProviderControlService) StartClaim(ctx context.Context, startClaim *StartClaimRequest) (paymentReply *PaymentReply, err error)
Initialize the claim for specific channel Verify that the “payment_address” in meta data matches to that of the signer. Increase nonce and send last payment with old nonce to the caller. Begin the claim process on the current channel and Increment the channel nonce and decrease the full amount to allow channel sender to continue working with remaining amount. Check for any claims already done on block chain but have not been reflected in the storage yet, update the storage status by calling the Finish() method on such claims
type TypedAtomicStorage ¶
type TypedAtomicStorage interface { // Get returns value by key Get(key interface{}) (value interface{}, ok bool, err error) // GetAll returns an array which contains all values from storage GetAll() (array interface{}, err error) // Put puts value by key unconditionally Put(key interface{}, value interface{}) (err error) // PutIfAbsent puts value by key if and only if key is absent in storage PutIfAbsent(key interface{}, value interface{}) (ok bool, err error) // CompareAndSwap puts newValue by key if and only if previous value is equal // to prevValue CompareAndSwap(key interface{}, prevValue interface{}, newValue interface{}) (ok bool, err error) // Delete removes value by key Delete(key interface{}) (err error) }
TypedAtomicStorage is an atomic storage which automatically serializes/deserializes values and keys
type TypedAtomicStorageImpl ¶
type TypedAtomicStorageImpl struct {
// contains filtered or unexported fields
}
TypedAtomicStorageImpl is an implementation of TypedAtomicStorage interface
func (*TypedAtomicStorageImpl) CompareAndSwap ¶
func (storage *TypedAtomicStorageImpl) CompareAndSwap(key interface{}, prevValue interface{}, newValue interface{}) (ok bool, err error)
CompareAndSwap implements TypedAtomicStorage.CompareAndSwap
func (*TypedAtomicStorageImpl) Delete ¶
func (storage *TypedAtomicStorageImpl) Delete(key interface{}) (err error)
func (*TypedAtomicStorageImpl) Get ¶
func (storage *TypedAtomicStorageImpl) Get(key interface{}) (value interface{}, ok bool, err error)
Get implements TypedAtomicStorage.Get
func (*TypedAtomicStorageImpl) GetAll ¶
func (storage *TypedAtomicStorageImpl) GetAll() (array interface{}, err error)
func (*TypedAtomicStorageImpl) Put ¶
func (storage *TypedAtomicStorageImpl) Put(key interface{}, value interface{}) (err error)
Put implementor TypedAtomicStorage.Put
func (*TypedAtomicStorageImpl) PutIfAbsent ¶
func (storage *TypedAtomicStorageImpl) PutIfAbsent(key interface{}, value interface{}) (ok bool, err error)
PutIfAbsent implements TypedAtomicStorage.PutIfAbsent