Add service provider auctions #59

Merged
nabarun merged 29 commits from deep-stack/laconicd:iv-service-provider-auction into main 2024-09-25 12:38:50 +00:00
5 changed files with 129 additions and 27 deletions
Showing only changes of commit 01bc492371 - Show all commits

View File

@ -4,6 +4,7 @@ const (
EventTypeCreateAuction = "create-auction" EventTypeCreateAuction = "create-auction"
EventTypeCommitBid = "commit-bid" EventTypeCommitBid = "commit-bid"
EventTypeRevealBid = "reveal-bid" EventTypeRevealBid = "reveal-bid"
EventTypeReleaseFunds = "release-funds"
AttributeKeyCommitsDuration = "commits-duration" AttributeKeyCommitsDuration = "commits-duration"
AttributeKeyRevealsDuration = "reveals-duration" AttributeKeyRevealsDuration = "reveals-duration"

View File

@ -886,24 +886,6 @@ func (k Keeper) pickProviderAuctionWinners(ctx sdk.Context, auction *auctiontype
} }
} }
// Process winner accounts (if nobody bids, there won't be a winner).
if len(winnerBids) > 0 {
for _, bid := range winnerBids {
winnerAddress, err := sdk.AccAddressFromBech32(bid.BidderAddress)
if err != nil {
k.Logger(ctx).Error(fmt.Sprintf("Invalid winner address. %v", err))
panic("Invalid winner address.")
}
// Send winning price to bidders
sdkErr := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, auctiontypes.ModuleName, winnerAddress, sdk.NewCoins(auction.WinningPrice))
if sdkErr != nil {
k.Logger(ctx).Error(fmt.Sprintf("Auction error sending funds to winner: %v", sdkErr))
panic(sdkErr)
}
}
}
// Send back any leftover locked amount to auction creator // Send back any leftover locked amount to auction creator
// All of it in case of no winners // All of it in case of no winners
totalLockedAmount := auction.MaxPrice.Amount.Mul(math.NewInt(int64(auction.NumProviders))) totalLockedAmount := auction.MaxPrice.Amount.Mul(math.NewInt(int64(auction.NumProviders)))
@ -936,3 +918,61 @@ func (k Keeper) pickProviderAuctionWinners(ctx sdk.Context, auction *auctiontype
return nil return nil
} }
func (k Keeper) ReleaseFunds(ctx sdk.Context, msg auctiontypes.MsgReleaseFunds) (*auctiontypes.Auction, error) {
if has, err := k.HasAuction(ctx, msg.AuctionId); !has {
if err != nil {
return nil, err
}
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Auction not found.")
}
auction, err := k.GetAuctionById(ctx, msg.AuctionId)
if err != nil {
return nil, err
}
if auction.Kind != auctiontypes.AuctionKindProvider {
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Auction kind must be provider.")
}
if auction.Status != auctiontypes.AuctionStatusCompleted {
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Auction is not completed.")
}
if auction.Status == auctiontypes.AuctionStatusFundsReleased {
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Funds have already been released.")
}
// Only the auction owner can release funds.
if msg.Signer != auction.OwnerAddress {
return nil, errorsmod.Wrap(sdkerrors.ErrUnauthorized, "Auction owner mismatch.")
}
// Process winner accounts (if nobody bids, there won't be a winner).
if len(auction.WinnerAddresses) > 0 {
for _, winnerAddress := range auction.WinnerAddresses {
winnerAccAddress, err := sdk.AccAddressFromBech32(winnerAddress)
if err != nil {
k.Logger(ctx).Error(fmt.Sprintf("Invalid winner address. %v", err))
panic("Invalid winner address.")
}
// Send winning price to bidders
sdkErr := k.bankKeeper.SendCoinsFromModuleToAccount(
ctx,
auctiontypes.ModuleName,
winnerAccAddress,
sdk.NewCoins(auction.WinningPrice),
)
if sdkErr != nil {
k.Logger(ctx).Error(fmt.Sprintf("Auction error sending funds to winner: %v", sdkErr))
panic(sdkErr)
}
}
}
auction.FundsReleased = true
return &auction, err
}

View File

@ -149,3 +149,40 @@ func (ms msgServer) UpdateParams(c context.Context, msg *auctiontypes.MsgUpdateP
return &auctiontypes.MsgUpdateParamsResponse{}, nil return &auctiontypes.MsgUpdateParamsResponse{}, nil
} }
// ReleaseFunds is the command to pay the winning amounts to provider auction winners
// nolint: all
func (ms msgServer) ReleaseFunds(c context.Context, msg *auctiontypes.MsgReleaseFunds) (*auctiontypes.MsgReleaseFundsResponse, error) {
if err := msg.ValidateBasic(); err != nil {
return nil, err
}
ctx := sdk.UnwrapSDKContext(c)
ctx = *utils.CtxWithCustomKVGasConfig(&ctx)
signerAddress, err := sdk.AccAddressFromBech32(msg.Signer)
if err != nil {
return nil, err
}
resp, err := ms.k.ReleaseFunds(ctx, *msg)
if err != nil {
return nil, err
}
ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
auctiontypes.EventTypeReleaseFunds,
sdk.NewAttribute(auctiontypes.AttributeKeyAuctionId, msg.AuctionId),
),
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, auctiontypes.AttributeValueCategory),
sdk.NewAttribute(auctiontypes.AttributeKeySigner, signerAddress.String()),
),
})
utils.LogTxGasConsumed(ctx, ms.k.Logger(ctx), "ReleaseFunds")
return &auctiontypes.MsgReleaseFundsResponse{Auction: resp}, nil
}

View File

@ -49,6 +49,23 @@ func NewMsgCommitBid(auctionId string, commitHash string, signer sdk.AccAddress)
} }
} }
// NewMsgRevealBid is the constructor function for MsgRevealBid.
func NewMsgRevealBid(auctionId string, reveal string, signer sdk.AccAddress) MsgRevealBid {
return MsgRevealBid{
AuctionId: auctionId,
Reveal: reveal,
Signer: signer.String(),
}
}
// NewMsgReleaseFunds is the constructor function for MsgReleaseFunds.
func NewMsgReleaseFunds(auctionId string, signer sdk.AccAddress) MsgReleaseFunds {
return MsgReleaseFunds{
AuctionId: auctionId,
Signer: signer.String(),
}
}
// ValidateBasic Implements Msg. // ValidateBasic Implements Msg.
func (msg MsgCreateAuction) ValidateBasic() error { func (msg MsgCreateAuction) ValidateBasic() error {
if msg.Signer == "" { if msg.Signer == "" {
@ -101,15 +118,6 @@ func (msg MsgCommitBid) ValidateBasic() error {
return nil return nil
} }
// NewMsgRevealBid is the constructor function for MsgRevealBid.
func NewMsgRevealBid(auctionId string, reveal string, signer sdk.AccAddress) MsgRevealBid {
return MsgRevealBid{
AuctionId: auctionId,
Reveal: reveal,
Signer: signer.String(),
}
}
// ValidateBasic Implements Msg. // ValidateBasic Implements Msg.
func (msg MsgRevealBid) ValidateBasic() error { func (msg MsgRevealBid) ValidateBasic() error {
if msg.Signer == "" { if msg.Signer == "" {
@ -126,3 +134,16 @@ func (msg MsgRevealBid) ValidateBasic() error {
return nil return nil
} }
// ValidateBasic Implements Msg.
func (msg MsgReleaseFunds) ValidateBasic() error {
if msg.Signer == "" {
return errorsmod.Wrap(sdkerrors.ErrInvalidAddress, "invalid signer address")
}
if msg.AuctionId == "" {
return errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "invalid auction id")
}
return nil
}

View File

@ -21,6 +21,9 @@ const (
// Auction has completed (winner selected). // Auction has completed (winner selected).
AuctionStatusCompleted = "completed" AuctionStatusCompleted = "completed"
// Auction has completed (winner selected).
AuctionStatusFundsReleased = "funds_released"
) )
// Bid status values. // Bid status values.