Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions simapp/Dockerfile.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM ghcr.io/cosmos/proto-builder:0.14.0



WORKDIR /workspace

56 changes: 56 additions & 0 deletions simapp/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Proto build helpers for the astro module

SHELL := /bin/bash

PWD := $(shell pwd)
DOCKER ?= docker
WORKDIR ?= /workspace

# Use the published Cosmos SDK proto-builder image (has protoc, buf, plugins)
PROTO_IMAGE ?= ghcr.io/cosmos/proto-builder:0.14.0

# Local image tag if you want to build the wrapper Dockerfile in this repo
PROTO_IMAGE_LOCAL ?= astro-proto-builder:local

# Convenience for running inside the container with current UID/GID so files are writable
UID_GID := $(shell id -u):$(shell id -g)

.PHONY: proto-image proto-image-local proto-lint proto-format proto-gen proto-clean

proto-image:
$(DOCKER) pull $(PROTO_IMAGE)

# Build a local image from Dockerfile.proto (optional)
proto-image-local:
$(DOCKER) build -f Dockerfile.proto -t $(PROTO_IMAGE_LOCAL) .

proto-format:
mkdir -p .cache
$(DOCKER) run --rm \
-v $(PWD):$(WORKDIR) -w $(WORKDIR) \
-e HOME=$(WORKDIR) \
-e XDG_CACHE_HOME=$(WORKDIR)/.cache \
-e BUF_CACHE_DIR=$(WORKDIR)/.cache \
$(PROTO_IMAGE) buf format -w

proto-lint:
mkdir -p .cache
$(DOCKER) run --rm \
-v $(PWD):$(WORKDIR) -w $(WORKDIR) \
-e HOME=$(WORKDIR) \
-e XDG_CACHE_HOME=$(WORKDIR)/.cache \
-e BUF_CACHE_DIR=$(WORKDIR)/.cache \
$(PROTO_IMAGE) buf lint

proto-gen:
mkdir -p .cache
$(DOCKER) run --rm -u $(UID_GID) \
-v $(PWD):$(WORKDIR) -w $(WORKDIR) \
-e HOME=$(WORKDIR) \
-e XDG_CACHE_HOME=$(WORKDIR)/.cache \
-e BUF_CACHE_DIR=$(WORKDIR)/.cache \
$(PROTO_IMAGE) buf generate --template buf.gen.yaml

# Remove any previously generated code under gen/ or other temp dirs if you use them
proto-clean:
rm -rf gen 2>/dev/null || true
84 changes: 84 additions & 0 deletions simapp/app/abci.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package simapp

import (
"bytes"
"crypto/rand"
"encoding/json"
"fmt"

abci "github.com/cometbft/cometbft/abci/types"

"github.com/cosmos/cosmos-sdk/baseapp"
sdk "github.com/cosmos/cosmos-sdk/types"
)

type (
// VoteExtensionHandler defines a dummy vote extension handler for SimApp.
//
// NOTE: This implementation is solely used for testing purposes. DO NOT use
// in a production application!
VoteExtensionHandler struct{}

// VoteExtension defines the structure used to create a dummy vote extension.
VoteExtension struct {
Hash []byte
Height int64
Data []byte
}
)

func NewVoteExtensionHandler() *VoteExtensionHandler {
return &VoteExtensionHandler{}
}

func (h *VoteExtensionHandler) SetHandlers(bApp *baseapp.BaseApp) {
bApp.SetExtendVoteHandler(h.ExtendVote())
bApp.SetVerifyVoteExtensionHandler(h.VerifyVoteExtension())
}

func (h *VoteExtensionHandler) ExtendVote() sdk.ExtendVoteHandler {
return func(_ sdk.Context, req *abci.RequestExtendVote) (*abci.ResponseExtendVote, error) {
buf := make([]byte, 1024)

_, err := rand.Read(buf)
if err != nil {
return nil, fmt.Errorf("failed to generate random vote extension data: %w", err)
}

ve := VoteExtension{
Hash: req.Hash,
Height: req.Height,
Data: buf,
}

bz, err := json.Marshal(ve)
if err != nil {
return nil, fmt.Errorf("failed to encode vote extension: %w", err)
}

return &abci.ResponseExtendVote{VoteExtension: bz}, nil
}
}

func (h *VoteExtensionHandler) VerifyVoteExtension() sdk.VerifyVoteExtensionHandler {
return func(ctx sdk.Context, req *abci.RequestVerifyVoteExtension) (*abci.ResponseVerifyVoteExtension, error) {
var ve VoteExtension

if err := json.Unmarshal(req.VoteExtension, &ve); err != nil {
return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil
}

switch {
case req.Height != ve.Height:
return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil

case !bytes.Equal(req.Hash, ve.Hash):
return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil

case len(ve.Data) != 1024:
return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_REJECT}, nil
}

return &abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_ACCEPT}, nil
}
}
51 changes: 51 additions & 0 deletions simapp/app/ante.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package simapp

import (
"errors"

circuitante "cosmossdk.io/x/circuit/ante"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
)

// HandlerOptions are the options required for constructing a default SDK AnteHandler.
type HandlerOptions struct {
ante.HandlerOptions
CircuitKeeper circuitante.CircuitBreaker
}

// NewAnteHandler returns an AnteHandler that checks and increments sequence
// numbers, checks signatures & account numbers, and deducts fees from the first
// signer.
func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) {
if options.AccountKeeper == nil {
return nil, errors.New("account keeper is required for ante builder")
}

if options.BankKeeper == nil {
return nil, errors.New("bank keeper is required for ante builder")
}

if options.SignModeHandler == nil {
return nil, errors.New("sign mode handler is required for ante builder")
}

anteDecorators := []sdk.AnteDecorator{
ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first
circuitante.NewCircuitBreakerDecorator(options.CircuitKeeper),
ante.NewExtensionOptionsDecorator(options.ExtensionOptionChecker),
ante.NewValidateBasicDecorator(),
ante.NewTxTimeoutHeightDecorator(),
ante.NewValidateMemoDecorator(options.AccountKeeper),
ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper),
ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.TxFeeChecker),
ante.NewSetPubKeyDecorator(options.AccountKeeper), // SetPubKeyDecorator must be called before all signature verification decorators
ante.NewValidateSigCountDecorator(options.AccountKeeper),
ante.NewSigGasConsumeDecorator(options.AccountKeeper, options.SigGasConsumer),
ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler, options.SigVerifyOptions...),
ante.NewIncrementSequenceDecorator(options.AccountKeeper),
}

return sdk.ChainAnteDecorators(anteDecorators...), nil
}
Loading
Loading