Documentation ¶
Index ¶
- Constants
- func AllowedUserPaymentHandler() handler.PaymentHandler
- func FreeCallPaymentHandler(freeCallService FreeCallUserService, processor *blockchain.Processor, ...) handler.PaymentHandler
- func NewMemStorage() (storage *memoryStorage)
- func NewPaymentHandler(service PaymentChannelService, processor *blockchain.Processor, ...) handler.PaymentHandler
- func NewPrePaidPaymentHandler(PrePaidService PrePaidService, metadata *blockchain.OrganizationMetaData, ...) handler.PaymentHandler
- func PaymentID(channelID *big.Int, channelNonce *big.Int) string
- func PublishChannelStats(payment handler.Payment) (err *handler.GrpcError)
- type AllowedUserPaymentValidator
- type AtomicStorage
- type BlockChainDisabledFreeCallStateService
- type BlockChainDisabledProviderControlService
- func (service *BlockChainDisabledProviderControlService) GetListInProgress(ctx context.Context, request *GetPaymentsListRequest) (reply *PaymentsListReply, err error)
- func (service *BlockChainDisabledProviderControlService) GetListUnclaimed(ctx context.Context, request *GetPaymentsListRequest) (paymentReply *PaymentsListReply, err error)
- func (service *BlockChainDisabledProviderControlService) StartClaim(ctx context.Context, startClaim *StartClaimRequest) (paymentReply *PaymentReply, err error)
- func (service *BlockChainDisabledProviderControlService) StartClaimForMultipleChannels(ctx context.Context, request *StartMultipleClaimRequest) (reply *PaymentsListReply, err error)
- type BlockChainDisabledStateService
- type BlockChainDisabledTokenService
- type BlockchainChannelReader
- type CASRequest
- type ChannelPaymentValidator
- type ChannelUpdate
- type Claim
- type ConditionFunc
- type FreeCallPayment
- type FreeCallPaymentValidator
- type FreeCallStateService
- type FreeCallTransaction
- type FreeCallUserData
- type FreeCallUserKey
- type FreeCallUserService
- type FreeCallUserStorage
- func (storage *FreeCallUserStorage) CompareAndSwap(key *FreeCallUserKey, prevState *FreeCallUserData, newState *FreeCallUserData) (ok bool, err error)
- func (storage *FreeCallUserStorage) Get(key *FreeCallUserKey) (state *FreeCallUserData, ok bool, err error)
- func (storage *FreeCallUserStorage) GetAll() (states []*FreeCallUserData, err error)
- func (storage *FreeCallUserStorage) Put(key *FreeCallUserKey, state *FreeCallUserData) (err error)
- func (storage *FreeCallUserStorage) PutIfAbsent(key *FreeCallUserKey, state *FreeCallUserData) (ok bool, err error)
- type FreeCallUserUpdate
- type IncomeData
- type IncomeValidator
- type KeyValueData
- 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 PrePaidData
- type PrePaidDataKey
- type PrePaidPayment
- type PrePaidPaymentHandler
- func (h *PrePaidPaymentHandler) Complete(payment handler.Payment) (err *handler.GrpcError)
- func (h *PrePaidPaymentHandler) CompleteAfterError(payment handler.Payment, result error) (err *handler.GrpcError)
- func (h *PrePaidPaymentHandler) Payment(context *handler.GrpcStreamContext) (transaction handler.Payment, err *handler.GrpcError)
- func (h *PrePaidPaymentHandler) Type() (typ string)
- type PrePaidPaymentValidator
- type PrePaidService
- type PrePaidTransaction
- type PrePaidUsageData
- type PrefixedAtomicStorage
- func (storage *PrefixedAtomicStorage) CompareAndSwap(key string, prevValue string, newValue string) (ok bool, err error)
- func (storage *PrefixedAtomicStorage) CompleteTransaction(transaction Transaction, update []KeyValueData) (ok bool, err error)
- func (storage *PrefixedAtomicStorage) Delete(key string) (err error)
- func (storage *PrefixedAtomicStorage) ExecuteTransaction(request CASRequest) (ok bool, 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)
- func (storage *PrefixedAtomicStorage) StartTransaction(conditionKeys []string) (transaction Transaction, 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)
- func (service *ProviderControlService) StartClaimForMultipleChannels(ctx context.Context, request *StartMultipleClaimRequest) (reply *PaymentsListReply, err error)
- type TokenService
- type Transaction
- 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) ExecuteTransaction(request TypedCASRequest) (ok bool, 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)
- type TypedCASRequest
- type TypedKeyValueData
- type TypedTransaction
- type TypedUpdateFunc
- type UpdateFunc
Constants ¶
const ( USED_AMOUNT string = "U" PLANNED_AMOUNT string = "P" REFUND_AMOUNT string = "R" )
const ( PrefixInSignature = "__MPE_claim_message" //Agreed constant value FreeCallPrefixSignature = "__prefix_free_trial" //Agreed constant value AllowedUserPrefixSignature = "__authorized_user" )
const ( // EscrowPaymentType each call should have id and nonce of payment channel // in metadata. EscrowPaymentType = "escrow" )
const ( // EscrowPaymentType each call should have id and nonce of payment channel // in metadata. FreeCallPaymentType = "free-call" )
const (
PrePaidPaymentType = "prepaid-call"
)
Variables ¶
This section is empty.
Functions ¶
func AllowedUserPaymentHandler ¶
func AllowedUserPaymentHandler() handler.PaymentHandler
func FreeCallPaymentHandler ¶ added in v1.1.1
func FreeCallPaymentHandler( freeCallService FreeCallUserService, processor *blockchain.Processor, metadata *blockchain.OrganizationMetaData, pServiceMetaData *blockchain.ServiceMetadata) handler.PaymentHandler
NewPaymentHandler returns new MultiPartyEscrow contract payment handler.
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.
func NewPrePaidPaymentHandler ¶
func NewPrePaidPaymentHandler( PrePaidService PrePaidService, metadata *blockchain.OrganizationMetaData, pServiceMetaData *blockchain.ServiceMetadata, pricing *pricing.PricingStrategy, manager token.Manager) handler.PaymentHandler
NewPaymentHandler returns new MultiPartyEscrow contract payment handler.
Types ¶
type AllowedUserPaymentValidator ¶
type AllowedUserPaymentValidator struct { }
func (*AllowedUserPaymentValidator) Validate ¶
func (validator *AllowedUserPaymentValidator) Validate(payment *Payment) (err error)
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) StartTransaction(conditionKeys []string) (transaction Transaction, err error) CompleteTransaction(transaction Transaction, update []KeyValueData) (ok bool, err error) ExecuteTransaction(request CASRequest) (ok bool, err error) }
AtomicStorage is an interface to key-value storage with atomic operations.
type BlockChainDisabledFreeCallStateService ¶
type BlockChainDisabledFreeCallStateService struct { }
func (*BlockChainDisabledFreeCallStateService) GetFreeCallsAvailable ¶
func (service *BlockChainDisabledFreeCallStateService) GetFreeCallsAvailable(context.Context, *FreeCallStateRequest) (*FreeCallStateReply, error)
type BlockChainDisabledProviderControlService ¶ added in v1.1.1
type BlockChainDisabledProviderControlService struct { }
func (*BlockChainDisabledProviderControlService) GetListInProgress ¶ added in v1.1.1
func (service *BlockChainDisabledProviderControlService) GetListInProgress(ctx context.Context, request *GetPaymentsListRequest) (reply *PaymentsListReply, err error)
func (*BlockChainDisabledProviderControlService) GetListUnclaimed ¶ added in v1.1.1
func (service *BlockChainDisabledProviderControlService) GetListUnclaimed(ctx context.Context, request *GetPaymentsListRequest) (paymentReply *PaymentsListReply, err error)
func (*BlockChainDisabledProviderControlService) StartClaim ¶ added in v1.1.1
func (service *BlockChainDisabledProviderControlService) StartClaim(ctx context.Context, startClaim *StartClaimRequest) (paymentReply *PaymentReply, err error)
func (*BlockChainDisabledProviderControlService) StartClaimForMultipleChannels ¶
func (service *BlockChainDisabledProviderControlService) StartClaimForMultipleChannels(ctx context.Context, request *StartMultipleClaimRequest) (reply *PaymentsListReply, err error)
type BlockChainDisabledStateService ¶ added in v1.1.1
type BlockChainDisabledStateService struct { }
func (*BlockChainDisabledStateService) GetChannelState ¶ added in v1.1.1
func (service *BlockChainDisabledStateService) GetChannelState(context context.Context, request *ChannelStateRequest) (reply *ChannelStateReply, err error)
type BlockChainDisabledTokenService ¶
type BlockChainDisabledTokenService struct { }
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, orgMetadata *blockchain.OrganizationMetaData) *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 CASRequest ¶
type CASRequest struct { RetryTillSuccessOrError bool Update UpdateFunc ConditionKeys []string }
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.OrganizationMetaData) *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 // decreases 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 ConditionFunc ¶
type ConditionFunc func(conditionValues []TypedKeyValueData, revisedAmount *big.Int, channelId *big.Int) ([]TypedKeyValueData, error)
Defines the condition that needs to be met, it generates the respective typed Data when conditions are satisfied, you define your own validations in here It takes in the latest typed values read.
var ( IncrementUsedAmount ConditionFunc = func(conditionValues []TypedKeyValueData, revisedAmount *big.Int, channelId *big.Int) (newValues []TypedKeyValueData, err error) { oldState, err := convertTypedDataToPrePaidUsage(conditionValues) if err != nil { return nil, err } oldState.ChannelID = channelId newState := oldState.Clone() usageKey := PrePaidDataKey{UsageType: USED_AMOUNT, ChannelID: oldState.ChannelID} updateDetails(newState, usageKey, revisedAmount) if newState.UsedAmount.Cmp(oldState.PlannedAmount.Add(oldState.PlannedAmount, oldState.RefundAmount)) > 0 { return nil, fmt.Errorf("Usage Exceeded on channel Id %v", oldState.ChannelID) } return BuildOldAndNewValuesForCAS(newState) } //Make sure you update the planned amount ONLY when the new value is greater than what was last persisted IncrementPlannedAmount ConditionFunc = func(conditionValues []TypedKeyValueData, revisedAmount *big.Int, channelId *big.Int) (newValues []TypedKeyValueData, err error) { oldState, err := convertTypedDataToPrePaidUsage(conditionValues) if err != nil { return nil, err } oldState.ChannelID = channelId newState := oldState.Clone() usageKey := PrePaidDataKey{UsageType: PLANNED_AMOUNT, ChannelID: oldState.ChannelID} updateDetails(newState, usageKey, revisedAmount) return BuildOldAndNewValuesForCAS(newState) } //If there is no refund amount yet, put it , else add latest value in DB with the additional refund to be done IncrementRefundAmount ConditionFunc = func(conditionValues []TypedKeyValueData, revisedAmount *big.Int, channelId *big.Int) (newValues []TypedKeyValueData, err error) { newState, err := convertTypedDataToPrePaidUsage(conditionValues) if err != nil { return nil, err } newState.ChannelID = channelId usageKey := PrePaidDataKey{UsageType: REFUND_AMOUNT, ChannelID: newState.ChannelID} updateDetails(newState, usageKey, revisedAmount) return BuildOldAndNewValuesForCAS(newState) } )
type FreeCallPayment ¶ added in v1.1.1
type FreeCallPayment struct { //Has the Id of the user making the call UserId string //Service Id . ServiceId string //Organization Id OrganizationId string //Current block number CurrentBlockNumber *big.Int // Signature passed Signature []byte //Group ID GroupId string //Auth Token Passed AuthToken []byte //Token expiration date in blocks AuthTokenExpiryBlockNumber *big.Int }
To Support Free calls
func (*FreeCallPayment) String ¶
func (key *FreeCallPayment) String() string
type FreeCallPaymentValidator ¶ added in v1.1.1
type FreeCallPaymentValidator struct {
// contains filtered or unexported fields
}
func NewFreeCallPaymentValidator ¶ added in v1.1.1
func (*FreeCallPaymentValidator) Validate ¶ added in v1.1.1
func (validator *FreeCallPaymentValidator) Validate(payment *FreeCallPayment) (err error)
type FreeCallStateService ¶
type FreeCallStateService struct {
// contains filtered or unexported fields
}
func NewFreeCallStateService ¶
func NewFreeCallStateService(orgMetadata *blockchain.OrganizationMetaData, srvMetaData *blockchain.ServiceMetadata, service FreeCallUserService, validator *FreeCallPaymentValidator) *FreeCallStateService
func (*FreeCallStateService) GetFreeCallsAvailable ¶
func (service *FreeCallStateService) GetFreeCallsAvailable(context context.Context, request *FreeCallStateRequest) (reply *FreeCallStateReply, err error)
type FreeCallTransaction ¶
type FreeCallTransaction interface { FreeCallUser() *FreeCallUserData Commit() error Rollback() error }
type FreeCallUserData ¶
type FreeCallUserData struct { UserId string FreeCallsMade int OrganizationId string ServiceId string GroupID string }
func (*FreeCallUserData) String ¶
func (data *FreeCallUserData) String() string
type FreeCallUserKey ¶
func (*FreeCallUserKey) String ¶
func (key *FreeCallUserKey) String() string
type FreeCallUserService ¶
type FreeCallUserService interface { GetFreeCallUserKey(payment *FreeCallPayment) (userKey *FreeCallUserKey, err error) //if the user details are not found, send back a new entry to be persisted FreeCallUser(key *FreeCallUserKey) (freeCallUser *FreeCallUserData, ok bool, err error) ListFreeCallUsers() (freeCallUsers []*FreeCallUserData, err error) StartFreeCallUserTransaction(payment *FreeCallPayment) (transaction FreeCallTransaction, err error) }
func NewFreeCallUserService ¶
func NewFreeCallUserService( storage *FreeCallUserStorage, locker Locker, groupIdReader func() ([32]byte, error), metadata *blockchain.ServiceMetadata) FreeCallUserService
type FreeCallUserStorage ¶
type FreeCallUserStorage struct {
// contains filtered or unexported fields
}
func NewFreeCallUserStorage ¶
func NewFreeCallUserStorage(atomicStorage AtomicStorage) *FreeCallUserStorage
func (*FreeCallUserStorage) CompareAndSwap ¶
func (storage *FreeCallUserStorage) CompareAndSwap(key *FreeCallUserKey, prevState *FreeCallUserData, newState *FreeCallUserData) (ok bool, err error)
func (*FreeCallUserStorage) Get ¶
func (storage *FreeCallUserStorage) Get(key *FreeCallUserKey) (state *FreeCallUserData, ok bool, err error)
func (*FreeCallUserStorage) GetAll ¶
func (storage *FreeCallUserStorage) GetAll() (states []*FreeCallUserData, err error)
func (*FreeCallUserStorage) Put ¶
func (storage *FreeCallUserStorage) Put(key *FreeCallUserKey, state *FreeCallUserData) (err error)
func (*FreeCallUserStorage) PutIfAbsent ¶
func (storage *FreeCallUserStorage) PutIfAbsent(key *FreeCallUserKey, state *FreeCallUserData) (ok bool, err error)
type FreeCallUserUpdate ¶
type FreeCallUserUpdate func(user *FreeCallUserData)
var (
IncrementFreeCallCount FreeCallUserUpdate = func(user *FreeCallUserData) {
user.FreeCallsMade = user.FreeCallsMade + 1
}
)
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(pricing *pricing.PricingStrategy) (validator IncomeValidator)
NewIncomeValidator returns new income validator instance
type KeyValueData ¶
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, paymentStorage *PaymentStorage, metaData *blockchain.ServiceMetadata) *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. Simple case current_nonce == blockchain_nonce unspent_amount = blockchain_value - current_signed_amount Complex case current_nonce != blockchain_nonce Taking into account our assumptions, we know that current_nonce = blockchain_nonce + 1.
unspent_amount = blockchain_value - oldnonce_signed_amount - current_signed_amount It should be noted that in this case the server could send us smaller old nonce_signed_amount (not the actually last one which was used for channelClaim). In this case, the server can only make us believe that we have more money in the channel then we actually have. That means that one possible attack via unspent_amount is to make us believe that we have less tokens than we truly have, and therefore reject future calls (or force us to call channelAddFunds).
func (*PaymentChannelStateService) StorageNonceMatchesWithBlockchainNonce ¶ added in v1.0.0
func (service *PaymentChannelStateService) StorageNonceMatchesWithBlockchainNonce(storageChannel *PaymentChannelData) (equal bool, err error)
verifies whether storage channel nonce is equal to blockchain nonce or not
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) Get ¶ added in v1.0.0
func (storage *PaymentStorage) Get(paymentID string) (payment *Payment, ok bool, 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 PrePaidData ¶
Kept the bare minimum here , other details like group and sender address of this channel can always be retrieved from BlockChain
func (*PrePaidData) String ¶
func (data *PrePaidData) String() string
type PrePaidDataKey ¶
func (*PrePaidDataKey) String ¶
func (key *PrePaidDataKey) String() string
type PrePaidPayment ¶
type PrePaidPayment struct { ChannelID *big.Int OrganizationId string GroupId string AuthToken string }
To Support PrePaid calls and also concurrency
func (*PrePaidPayment) String ¶
func (payment *PrePaidPayment) String() string
Used when the Request comes in
type PrePaidPaymentHandler ¶
type PrePaidPaymentHandler struct { PrePaidPaymentValidator *PrePaidPaymentValidator // contains filtered or unexported fields }
func (*PrePaidPaymentHandler) Complete ¶
func (h *PrePaidPaymentHandler) Complete(payment handler.Payment) (err *handler.GrpcError)
Just logging , as we increase the usage before calling the service assuming the service call will be successful
func (*PrePaidPaymentHandler) CompleteAfterError ¶
func (*PrePaidPaymentHandler) Payment ¶
func (h *PrePaidPaymentHandler) Payment(context *handler.GrpcStreamContext) (transaction handler.Payment, err *handler.GrpcError)
func (*PrePaidPaymentHandler) Type ¶
func (h *PrePaidPaymentHandler) Type() (typ string)
type PrePaidPaymentValidator ¶
type PrePaidPaymentValidator struct {
// contains filtered or unexported fields
}
func NewPrePaidPaymentValidator ¶
func NewPrePaidPaymentValidator(pricing *pricing.PricingStrategy, manager token.Manager) *PrePaidPaymentValidator
func (*PrePaidPaymentValidator) Validate ¶
func (validator *PrePaidPaymentValidator) Validate(payment *PrePaidPayment) (err error)
type PrePaidService ¶
type PrePaidService interface { GetUsage(key PrePaidDataKey) (*PrePaidData, bool, error) UpdateUsage(channelId *big.Int, revisedAmount *big.Int, updateUsageType string) error }
func NewPrePaidService ¶
func NewPrePaidService( storage TypedAtomicStorage, prepaidValidator *PrePaidPaymentValidator, groupIdReader func() ([32]byte, error)) PrePaidService
type PrePaidTransaction ¶
type PrePaidUsageData ¶
type PrePaidUsageData struct { ChannelID *big.Int PlannedAmount *big.Int UsedAmount *big.Int RefundAmount *big.Int UpdateUsageType string }
This will ony be used for doing any business checks
func (PrePaidUsageData) Clone ¶
func (data PrePaidUsageData) Clone() *PrePaidUsageData
func (*PrePaidUsageData) GetAmountForUsageType ¶
func (data *PrePaidUsageData) GetAmountForUsageType() (*big.Int, error)
func (*PrePaidUsageData) String ¶
func (data *PrePaidUsageData) String() string
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 NewPrefixedAtomicStorage ¶
func NewPrefixedAtomicStorage(atomicStorage AtomicStorage, prefix string) *PrefixedAtomicStorage
It is recommended to use this function to create a PrefixedAtomicStorage
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) CompleteTransaction ¶
func (storage *PrefixedAtomicStorage) CompleteTransaction(transaction Transaction, update []KeyValueData) (ok bool, err error)
func (*PrefixedAtomicStorage) Delete ¶
func (storage *PrefixedAtomicStorage) Delete(key string) (err error)
func (*PrefixedAtomicStorage) ExecuteTransaction ¶
func (storage *PrefixedAtomicStorage) ExecuteTransaction(request CASRequest) (ok bool, 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
func (*PrefixedAtomicStorage) StartTransaction ¶
func (storage *PrefixedAtomicStorage) StartTransaction(conditionKeys []string) (transaction Transaction, err error)
type ProviderControlService ¶ added in v0.1.5
type ProviderControlService struct {
// contains filtered or unexported fields
}
func NewProviderControlService ¶ added in v0.1.5
func NewProviderControlService(channelService PaymentChannelService, serMetaData *blockchain.ServiceMetadata, orgMetadata *blockchain.OrganizationMetaData) *ProviderControlService
func (*ProviderControlService) GetListInProgress ¶ added in v0.1.5
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 ¶ added in v0.1.5
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 ¶ added in v0.1.5
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
func (*ProviderControlService) StartClaimForMultipleChannels ¶
func (service *ProviderControlService) StartClaimForMultipleChannels(ctx context.Context, request *StartMultipleClaimRequest) (reply *PaymentsListReply, err error)
We need to have an ability to StartClaims for multiple channels too! The User makes a Daemon call to the get all the pending claims The user then needs to call the start claim for every channel that he intends to claim ( thus a new signature again ) for every invocation of StartClaim ! PS You can make Multiple Claims in BlockChain in a single call multiChannelClaim You can now initiate multiple claims using this function StartClaimsOnMultipleChannels that takes a list of ChannelIds , What Daemon will do is invoke the StartClaim internally for every channel Id passed If an error is encountered , then we return back whatever was successful and stop with the channel ID that had an issue and return the error that was encountered.
type TokenService ¶
type TokenService struct {
// contains filtered or unexported fields
}
func NewTokenService ¶
func NewTokenService(paymentChannelService PaymentChannelService, usageService PrePaidService, tokenManager token.Manager, validator *ChannelPaymentValidator, metadata *blockchain.ServiceMetadata) *TokenService
type Transaction ¶
type Transaction interface {
GetConditionValues() ([]KeyValueData, error)
}
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) ExecuteTransaction(request TypedCASRequest) (ok bool, err error) }
TypedAtomicStorage is an atomic storage which automatically serializes/deserializes values and keys
func NewPrepaidStorage ¶
func NewPrepaidStorage(atomicStorage AtomicStorage) TypedAtomicStorage
NewPrepaidStorage returns new instance of TypedAtomicStorage
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) ExecuteTransaction ¶
func (storage *TypedAtomicStorageImpl) ExecuteTransaction(request TypedCASRequest) (ok bool, 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
type TypedCASRequest ¶
type TypedCASRequest struct { RetryTillSuccessOrError bool Update TypedUpdateFunc ConditionKeys []interface{} //Typed Keys }
type TypedKeyValueData ¶
type TypedKeyValueData struct { Key interface{} Value interface{} Present bool }
func BuildOldAndNewValuesForCAS ¶
func BuildOldAndNewValuesForCAS(data *PrePaidUsageData) (newValues []TypedKeyValueData, err error)
type TypedTransaction ¶
type TypedTransaction interface {
GetConditionValues() ([]TypedKeyValueData, error)
}
type TypedUpdateFunc ¶
type TypedUpdateFunc func(conditionValues []TypedKeyValueData) (update []TypedKeyValueData, ok bool, err error)
Best to change this to KeyValueData , will do this in the next commit
type UpdateFunc ¶
type UpdateFunc func(conditionValues []KeyValueData) (update []KeyValueData, ok bool, err error)
Best to change this to KeyValueData , will do this in the next commit
Source Files ¶
- allowed_user_payment_handler.go
- atomic_storage.go
- control_service.go
- escrow.go
- free_call.go
- free_call_api.go
- free_call_payment_handler.go
- free_call_state_service.go
- free_call_storage.go
- income.go
- lock.go
- memory_storage.go
- payment_channel_api.go
- payment_channel_storage.go
- payment_handler.go
- payment_storage.go
- prepaid_api.go
- prepaid_handler.go
- prepaid_service.go
- prepaid_storage.go
- state_service.go
- token_service.go
- validation.go