Skip to content
Snippets Groups Projects
Commit fd48a6cc authored by Gomez Goiri, Aitor's avatar Gomez Goiri, Aitor
Browse files

Implementing bid operation

parent 0f688689
Branches
No related tags found
No related merge requests found
// acl.go
// COPYRIGHT: FUNDACIÓN TECNALIA RESEARCH & INNOVATION, 2021.
// acl.go is part of the Computer file TRACEBLOCK. Copyrighted under U.S. Copyright Office Registration Number TXu002105160, registered on 2018-06-25 by FUNDACIÓN TECNALIA RESEARCH & INNOVATION.
// This license is effective worldwide.
package bid
import (
"errors"
"git.code.tecnalia.com/ledgerbuilder/sdk/core/api"
"git.code.tecnalia.com/ledgerbuilder/sdk/core/fabric/protos"
"git.code.tecnalia.com/ledgerbuilder/sdk/shared"
)
var (
errNotSidenorMSP = errors.New("the asset does not belong to Sidenor")
)
func (c BidController) OwnedBySidenor(trigger shared.TriggerFunction) shared.TriggerFunction {
return func(stub shared.LedgerBuildrStubInterface, requestAsset shared.LedgerBuildrAsset) protos.Response {
const fnName = "ACL:OwnedBySidenor"
storedAsset, err := c.readAsset(stub, requestAsset)
if err != nil {
return api.NewApiResponsePtr(fnName, err, nil).SendResponse()
}
if storedAsset.Owner.MspId != "sidenor-com" {
return api.NewApiResponsePtr(fnName, errNotSidenorMSP, nil).SendResponse()
}
return trigger(stub, requestAsset)
}
}
\ No newline at end of file
// controller.go
// COPYRIGHT: FUNDACIÓN TECNALIA RESEARCH & INNOVATION, 2018.
// controller.go is part of the Computer file TRACEBLOCK. Copyrighted under U.S. Copyright Office Registration Number TXu002105160, registered on 2018-06-25 by FUNDACIÓN TECNALIA RESEARCH & INNOVATION.
// This license is effective worldwide.
package bid
import (
"errors"
"git.code.tecnalia.com/ledgerbuilder/sdk/core/api"
"git.code.tecnalia.com/ledgerbuilder/sdk/core/controller"
"git.code.tecnalia.com/ledgerbuilder/sdk/core/fabric/protos"
"git.code.tecnalia.com/ledgerbuilder/sdk/core/util/logging"
"git.code.tecnalia.com/ledgerbuilder/sdk/shared"
"github.com/mitchellh/mapstructure"
errs "git.code.tecnalia.com/traceblock/sdk/constants"
"git.code.tecnalia.com/traceblock/sdk/controller/base"
"git.code.tecnalia.com/traceblock/sdk/model"
)
type BidController struct {
base.TraceblockBaseController
}
type Bid struct {
// Not renaming any of these fields in json to make mapstructure.decode work
Quantity uint32 `json:"quantity"`
Price float32 `json:"price"`
Bidder string `json:"bidder"`
}
var (
log = logging.NewGoLogger("controller/transfer")
errInvalidInputData = errors.New("failed to read model")
errParamsMissing = errors.New("missing split params. assetId and splitParams config must be send in split request")
errChildrenMissmatch = errors.New("number of requested childs and proposed id count mismatch")
errBidirectionalLink = errors.New("failed to bidirectonally link base asset on current transaction")
errInvalidBidQuantity = errors.New("bid quantity is greater than the available quantity")
)
// constructor like function
func NewBidController() *BidController {
ctl := new(BidController)
ctl.LowLevelController = controller.NewLowLevelController()
ctl.SetDataModelClosure(ctl.modelClosure)
return ctl
}
// model closure function maps an specific model against current controller so that
// all IO interaction are decoded using the closure defined model.
func (c BidController) modelClosure(stub shared.LedgerBuildrStubInterface) shared.LedgerBuildrAsset {
return NewBidParams()
}
func (c BidController) readAsset(stub shared.LedgerBuildrStubInterface, requestAsset shared.LedgerBuildrAsset) (*model.TraceableAsset, error) {
readedModel, err := c.ReadAbstractAssetAndReturn(stub, requestAsset.GetID(), model.NewTraceableAsset())
if err != nil {
return nil, err
}
// asset data successfully readed
asset, ok := readedModel.(*model.TraceableAsset)
if !ok {
return nil, errs.NotExistingAsset
}
return asset, nil
}
// SplitSingle generates as many assets as requested
// all of those new assets are linked to the previous one
func (c BidController) BidAsset(stub shared.LedgerBuildrStubInterface, params shared.LedgerBuildrAsset) protos.Response {
const fnName = "BidController:BidAsset"
bidParams, ok := params.(*BidParams) // already checked
if bidParams == nil || !ok {
//failed when casting/fetching input data
return api.NewApiResponsePtr(fnName, errInvalidInputData, nil).SendResponse()
}
biddableAsset, err := c.readAsset(stub, bidParams)
if err != nil {
return api.NewApiResponsePtr(fnName, err, nil).SendResponse()
}
if biddableAsset.Quantity < bidParams.Bid.Quantity {
return api.NewApiResponsePtr(fnName, errInvalidBidQuantity, nil).SendResponse()
}
auxArr := []Bid{}
if _, ok := biddableAsset.ArbitraryDataFields["bids"]; ok {
// to avoid interface conversion errors ([]interface {} is not []bid.Bid)
err := mapstructure.Decode(biddableAsset.ArbitraryDataFields["bids"], &auxArr)
log.Warning("Editing %+v", auxArr[0])
if err != nil {
return api.NewApiResponsePtr(fnName, err, nil).SendResponse()
panic(err)
}
}
newBid := Bid{
Quantity: bidParams.Bid.Quantity,
Price: bidParams.Bid.Price,
Bidder: stub.GetUniqueUserId(),
}
alreadyExists := false
for i, bid := range auxArr {
if bid.Bidder == newBid.Bidder {
auxArr[i] = newBid
alreadyExists = true
break
}
}
if !alreadyExists {
auxArr = append(auxArr, newBid)
}
biddableAsset.Add("bids", auxArr)
biddableAsset.MarkModification(stub)
return c.SaveAbstractAsset(stub, biddableAsset)
}
\ No newline at end of file
// input.go
// COPYRIGHT: FUNDACIÓN TECNALIA RESEARCH & INNOVATION, 2018.
// input.go is part of the Computer file TRACEBLOCK. Copyrighted under U.S. Copyright Office Registration Number TXu002105160, registered on 2018-06-25 by FUNDACIÓN TECNALIA RESEARCH & INNOVATION.
// This license is effective worldwide.
package bid
import (
"git.code.tecnalia.com/ledgerbuilder/sdk/core/model/io"
"git.code.tecnalia.com/ledgerbuilder/sdk/shared"
errs "git.code.tecnalia.com/traceblock/sdk/constants"
)
type BidParams struct {
shared.LedgerBuildrAsset
AssetId string `json:"id"`
Bid struct {
Quantity uint32 `json:"quantity"`
Price float32 `json:"price"`
} `json:"bid"`
}
func (p *BidParams) GetID() string {
return p.AssetId
}
func (p *BidParams) Get(key string) (interface{}, bool) {
return nil, false
}
func (p *BidParams) SetID(id string) {
p.AssetId = id
}
func (p *BidParams) StubBytes() []byte {
return []byte{}
}
func (p *BidParams) LedgerBytes() []byte {
return nil
}
func (p *BidParams) ReadValidation() bool {
return false
}
// set write validations to false to avoid ledger persistency
func (p *BidParams) WriteValidation() bool {
return false
}
func (p *BidParams) StubReader(stub shared.LedgerBuildrStubInterface) (shared.LedgerBuildrAsset, error) {
if stub != nil {
parseErr := io.NewJSONSerializer().LoadFromByteArray(&p, stub.GetPayload())
return p, parseErr
}
return nil, errs.StubReader
}
func (p *BidParams) LedgerReader(data []byte) (shared.LedgerBuildrAsset, error) {
if data != nil {
parseErr := io.NewJSONSerializer().LoadFromByteArray(&p, data)
return p, parseErr
}
return nil, errs.LedgerReader
}
func NewBidParams() shared.LedgerBuildrAsset {
return new(BidParams)
}
...@@ -20,6 +20,7 @@ import ( ...@@ -20,6 +20,7 @@ import (
"git.code.tecnalia.com/traceblock/sdk/controller/transfer" "git.code.tecnalia.com/traceblock/sdk/controller/transfer"
"git.code.tecnalia.com/traceblock/sdk/middleware" "git.code.tecnalia.com/traceblock/sdk/middleware"
"git.code.tecnalia.com/blockchain/hypercog/controller/bid"
m2 "git.code.tecnalia.com/blockchain/hypercog/middleware" m2 "git.code.tecnalia.com/blockchain/hypercog/middleware"
) )
...@@ -35,6 +36,8 @@ var ( ...@@ -35,6 +36,8 @@ var (
joinController *join.JoinController joinController *join.JoinController
qrController *qr.QRController qrController *qr.QRController
barcodeController *barcode.BarcodeController barcodeController *barcode.BarcodeController
// bid controller
bidController *bid.BidController
) )
func init() { func init() {
...@@ -53,6 +56,8 @@ func init() { ...@@ -53,6 +56,8 @@ func init() {
qrController = qr.NewQRController() qrController = qr.NewQRController()
// barcode controller // barcode controller
barcodeController = barcode.NewBarcodeController() barcodeController = barcode.NewBarcodeController()
// bid controller
bidController = bid.NewBidController()
} }
// Implementation of chaincode business logic operations // Implementation of chaincode business logic operations
...@@ -184,7 +189,7 @@ func ContextOperations(m shared.AbstractChaincodeOperationManager) error { ...@@ -184,7 +189,7 @@ func ContextOperations(m shared.AbstractChaincodeOperationManager) error {
AddBasicReadOperation("random-string", testController.DistributedPrngString). AddBasicReadOperation("random-string", testController.DistributedPrngString).
// HyperCOG operations // HyperCOG operations
AddOperation( AddOperation(
"hypercog-bid-asset-list", "hypercog-list-bid-assets",
shared.READ_OP, shared.READ_OP,
[]shared.MiddlewareInterface{ []shared.MiddlewareInterface{
m2.RejectIfNotCementCompany, m2.RejectIfNotCementCompany,
...@@ -194,6 +199,18 @@ func ContextOperations(m shared.AbstractChaincodeOperationManager) error { ...@@ -194,6 +199,18 @@ func ContextOperations(m shared.AbstractChaincodeOperationManager) error {
nil, nil,
assetController.RichQuery, // Actually implemented in LowLevelController assetController.RichQuery, // Actually implemented in LowLevelController
). ).
AddOperationWithoutDefaults(
"hypercog-bid-asset",
shared.WRITE_OP,
&assetController,
bidController.StubReader,
bidController.LedgerReader,
[]shared.MiddlewareInterface{
m2.RejectIfNotCementCompany,
},
nil,
bidController.OwnedBySidenor(bidController.BidAsset),
).
Build(m) Build(m)
return nil return nil
......
...@@ -5,5 +5,6 @@ go 1.15 ...@@ -5,5 +5,6 @@ go 1.15
require ( require (
git.code.tecnalia.com/ledgerbuilder/sdk v1.4.1 git.code.tecnalia.com/ledgerbuilder/sdk v1.4.1
git.code.tecnalia.com/traceblock/sdk v1.0.1-0.20211110143004-41d906ebb98e git.code.tecnalia.com/traceblock/sdk v1.0.1-0.20211110143004-41d906ebb98e
github.com/mitchellh/mapstructure v1.4.2
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
) )
...@@ -80,8 +80,9 @@ github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/Qd ...@@ -80,8 +80,9 @@ github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/Qd
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 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.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8=
github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo=
github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg=
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw= github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8= github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment