Skip to content

Commit

Permalink
chore: upstream stf to main (#20286)
Browse files Browse the repository at this point in the history
Co-authored-by: testinginprod <98415576+testinginprod@users.noreply.github.com>
  • Loading branch information
tac0turtle and testinginprod authored May 8, 2024
1 parent 03d70aa commit 83c4b9b
Show file tree
Hide file tree
Showing 37 changed files with 3,117 additions and 10 deletions.
39 changes: 39 additions & 0 deletions .github/workflows/v2-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: v2 core Tests
on:
pull_request:
merge_group:
push:
branches:
- main

permissions:
contents: read

concurrency:
group: ci-${{ github.ref }}-v2-tests
cancel-in-progress: true

jobs:
stf:
runs-on: ubuntu-latest
strategy:
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.22"
check-latest: true
cache: true
cache-dependency-path: go.sum
- uses: technote-space/get-diff-action@v6.1.2
id: git_diff
with:
PATTERNS: |
server/v2/stf/**/*.go
server/v2/stf/go.mod
server/v2/stf/go.sum
- name: test & coverage report creation
if: env.GIT_DIFF
run: |
cd server/v2/stf && go test -mod=readonly -race -timeout 30m -covermode=atomic -tags='ledger test_ledger_mock'
66 changes: 66 additions & 0 deletions core/app/app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package app

import (
"time"

appmodulev2 "cosmossdk.io/core/appmodule/v2"
"cosmossdk.io/core/event"
"cosmossdk.io/core/transaction"
)

type QueryRequest struct {
Height int64
Path string
Data []byte
}

type QueryResponse struct {
Height int64
Value []byte
}

type BlockRequest[T any] struct {
Height uint64
Time time.Time
Hash []byte
ChainId string
AppHash []byte
Txs []T
ConsensusMessages []transaction.Type
}

type BlockResponse struct {
Apphash []byte
ConsensusMessagesResponse []transaction.Type
ValidatorUpdates []appmodulev2.ValidatorUpdate
PreBlockEvents []event.Event
BeginBlockEvents []event.Event
TxResults []TxResult
EndBlockEvents []event.Event
}

type RequestInitChain struct {
Time time.Time
ChainId string
Validators []appmodulev2.ValidatorUpdate
AppStateBytes []byte
InitialHeight int64
}

type ResponseInitChain struct {
Validators []appmodulev2.ValidatorUpdate
AppHash []byte
}

type TxResult struct {
Events []event.Event
Resp []transaction.Type
Error error
Code uint32
Data []byte
Log string
Info string
GasWanted uint64
GasUsed uint64
Codespace string
}
21 changes: 21 additions & 0 deletions core/app/codec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package app

import (
"github.com/cosmos/gogoproto/jsonpb"
gogoproto "github.com/cosmos/gogoproto/proto"
)

// MsgInterfaceProtoName defines the protobuf name of the cosmos Msg interface
const MsgInterfaceProtoName = "cosmos.base.v1beta1.Msg"

type ProtoCodec interface {
Marshal(v gogoproto.Message) ([]byte, error)
Unmarshal(data []byte, v gogoproto.Message) error
Name() string
}

type InterfaceRegistry interface {
jsonpb.AnyResolver
ListImplementations(ifaceTypeURL string) []string
ListAllInterfaces() []string
}
6 changes: 6 additions & 0 deletions core/app/identity.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package app

var (
RuntimeIdentity = []byte("runtime")
ConsensusIdentity = []byte("consensus")
)
16 changes: 16 additions & 0 deletions core/context/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package appmodule

// ExecMode defines the execution mode which can be set on a Context.
type ExecMode uint8

// All possible execution modes.
const (
ExecModeCheck ExecMode = iota
ExecModeReCheck
ExecModeSimulate
ExecModePrepareProposal
ExecModeProcessProposal
ExecModeVoteExtension
ExecModeVerifyVoteExtension
ExecModeFinalize
)
4 changes: 2 additions & 2 deletions core/gas/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ type Service interface {

// Meter represents a gas meter for modules consumption
type Meter interface {
Consume(amount Gas, descriptor string)
Refund(amount Gas, descriptor string)
Consume(amount Gas, descriptor string) error
Refund(amount Gas, descriptor string) error
Remaining() Gas
Limit() Gas
}
Expand Down
73 changes: 72 additions & 1 deletion core/header/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package header

import (
"context"
"crypto/sha256"
"encoding/binary"
"errors"
"time"
)

Expand All @@ -15,6 +18,74 @@ type Info struct {
Height int64 // Height returns the height of the block
Hash []byte // Hash returns the hash of the block header
Time time.Time // Time returns the time of the block
ChainID string // ChainId returns the chain ID of the block
AppHash []byte // AppHash used in the current block header
ChainID string // ChainId returns the chain ID of the block
}

const hashSize = sha256.Size

// Bytes encodes the Info struct into a byte slice using little-endian encoding
func (i *Info) Bytes() ([]byte, error) {
buf := make([]byte, 0)

// Encode Height
heightBytes := make([]byte, 8)
binary.LittleEndian.PutUint64(heightBytes, uint64(i.Height))
buf = append(buf, heightBytes...)

// Encode Hash
if len(i.Hash) != hashSize {
return nil, errors.New("invalid hash size")
}
buf = append(buf, i.Hash...)

// Encode Time
timeBytes := make([]byte, 8)
binary.LittleEndian.PutUint64(timeBytes, uint64(i.Time.Unix()))
buf = append(buf, timeBytes...)

// Encode AppHash
if len(i.Hash) != hashSize {
return nil, errors.New("invalid hash size")
}
buf = append(buf, i.AppHash...)

// Encode ChainID
chainIDLen := len(i.ChainID)
buf = append(buf, byte(chainIDLen))
buf = append(buf, []byte(i.ChainID)...)

return buf, nil
}

// FromBytes decodes the byte slice into an Info struct using little-endian encoding
func (i *Info) FromBytes(bytes []byte) error {
// Decode Height
i.Height = int64(binary.LittleEndian.Uint64(bytes[:8]))
bytes = bytes[8:]

// Decode Hash
i.Hash = make([]byte, hashSize)
copy(i.Hash, bytes[:hashSize])
bytes = bytes[hashSize:]

// Decode Time
unixTime := int64(binary.LittleEndian.Uint64(bytes[:8]))
i.Time = time.Unix(unixTime, 0).UTC()
bytes = bytes[8:]

// Decode AppHash
i.AppHash = make([]byte, hashSize)
copy(i.AppHash, bytes[:hashSize])
bytes = bytes[hashSize:]

// Decode ChainID
chainIDLen := int(bytes[0])
bytes = bytes[1:]
if len(bytes) < chainIDLen {
return errors.New("invalid byte slice length")
}
i.ChainID = string(bytes[:chainIDLen])

return nil
}
56 changes: 56 additions & 0 deletions core/header/service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package header

import (
"crypto/sha256"
"testing"
"time"

"github.com/stretchr/testify/require"
)

func TestInfo_Bytes(t *testing.T) {
sum := sha256.Sum256([]byte("test-chain"))
info := Info{
Height: 12345,
Hash: sum[:],
Time: time.Date(2024, time.January, 1, 0, 0, 0, 0, time.UTC),
AppHash: sum[:],
ChainID: "test-chain",
}

expectedBytes := []byte{
0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Height (little-endian)
0x26, 0xb0, 0xb8, 0x3e, 0x72, 0x81, 0xbe, 0x3b, 0x11, 0x76, 0x58, 0xb6, 0xf2, 0x63, 0x6d, 0x3, 0x68, 0xca, 0xd3, 0xd7, 0x4f, 0x22, 0x24, 0x34, 0x28, 0xf5, 0x40, 0x1a, 0x4b, 0x70, 0x89, 0x7e, // Hash
0x80, 0x0, 0x92, 0x65, 0x0, 0x0, 0x0, 0x0, // Time (little-endian)
0x26, 0xb0, 0xb8, 0x3e, 0x72, 0x81, 0xbe, 0x3b, 0x11, 0x76, 0x58, 0xb6, 0xf2, 0x63, 0x6d, 0x3, 0x68, 0xca, 0xd3, 0xd7, 0x4f, 0x22, 0x24, 0x34, 0x28, 0xf5, 0x40, 0x1a, 0x4b, 0x70, 0x89, 0x7e, // Apphash
0x0A, // ChainID length
0x74, 0x65, 0x73, 0x74, 0x2d, 0x63, 0x68, 0x61, 0x69, 0x6e, // ChainID
}

bytes, err := info.Bytes()
require.NoError(t, err)
require.Equal(t, expectedBytes, bytes)
}

func TestInfo_FromBytes(t *testing.T) {
info := Info{}

// Test case 1: Valid byte slice
bytes := []byte{
0x39, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Height (little-endian)
0x26, 0xb0, 0xb8, 0x3e, 0x72, 0x81, 0xbe, 0x3b, 0x11, 0x76, 0x58, 0xb6, 0xf2, 0x63, 0x6d, 0x3, 0x68, 0xca, 0xd3, 0xd7, 0x4f, 0x22, 0x24, 0x34, 0x28, 0xf5, 0x40, 0x1a, 0x4b, 0x70, 0x89, 0x7e, // Hash
0x80, 0x0, 0x92, 0x65, 0x0, 0x0, 0x0, 0x0, // Time (little-endian)
0x26, 0xb0, 0xb8, 0x3e, 0x72, 0x81, 0xbe, 0x3b, 0x11, 0x76, 0x58, 0xb6, 0xf2, 0x63, 0x6d, 0x3, 0x68, 0xca, 0xd3, 0xd7, 0x4f, 0x22, 0x24, 0x34, 0x28, 0xf5, 0x40, 0x1a, 0x4b, 0x70, 0x89, 0x7e, // Apphash
0x0A, // ChainID length
0x74, 0x65, 0x73, 0x74, 0x2d, 0x63, 0x68, 0x61, 0x69, 0x6e, // ChainID
}

err := info.FromBytes(bytes)
require.NoError(t, err)
require.Equal(t, int64(12345), info.Height)
require.Equal(t, []byte{0x26, 0xb0, 0xb8, 0x3e, 0x72, 0x81, 0xbe, 0x3b, 0x11, 0x76, 0x58, 0xb6, 0xf2, 0x63, 0x6d, 0x3, 0x68, 0xca, 0xd3, 0xd7, 0x4f, 0x22, 0x24, 0x34, 0x28, 0xf5, 0x40, 0x1a, 0x4b, 0x70, 0x89, 0x7e}, info.Hash)
require.Equal(t, time.Date(2024, time.January, 1, 0, 0, 0, 0, time.UTC), info.Time)
require.Equal(t, []byte{0x26, 0xb0, 0xb8, 0x3e, 0x72, 0x81, 0xbe, 0x3b, 0x11, 0x76, 0x58, 0xb6, 0xf2, 0x63, 0x6d, 0x3, 0x68, 0xca, 0xd3, 0xd7, 0x4f, 0x22, 0x24, 0x34, 0x28, 0xf5, 0x40, 0x1a, 0x4b, 0x70, 0x89, 0x7e}, info.AppHash)
require.Equal(t, "test-chain", info.ChainID)

}
6 changes: 3 additions & 3 deletions core/transaction/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ type Tx interface {
// Hash returns the unique identifier for the Tx.
Hash() [32]byte // TODO evaluate if 32 bytes is the right size & benchmark overhead of hashing instead of using identifier
// GetMessages returns the list of state transitions of the Tx.
GetMessages() []Type
GetMessages() ([]Type, error)
// GetSenders returns the tx state transition sender.
GetSenders() []Identity // TODO reduce this to a single identity if accepted
GetSenders() ([]Identity, error) // TODO reduce this to a single identity if accepted
// GetGasLimit returns the gas limit of the tx. Must return math.MaxUint64 for infinite gas
// txs.
GetGasLimit() uint64
GetGasLimit() (uint64, error)
// Bytes returns the encoded version of this tx. Note: this is ideally cached
// from the first instance of the decoding of the tx.
Bytes() []byte
Expand Down
1 change: 1 addition & 0 deletions go.work.example
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use (
./orm
./simapp
./tests
./server/v2/stf
./store
./store/v2
./tools/cosmovisor
Expand Down
14 changes: 10 additions & 4 deletions runtime/gas.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,15 @@ func (gm SDKGasMeter) Limit() storetypes.Gas {
}

func (gm SDKGasMeter) ConsumeGas(amount storetypes.Gas, descriptor string) {
gm.gm.Consume(amount, descriptor)
if err := gm.gm.Consume(amount, descriptor); err != nil {
panic(err)
}
}

func (gm SDKGasMeter) RefundGas(amount storetypes.Gas, descriptor string) {
gm.gm.Refund(amount, descriptor)
if err := gm.gm.Refund(amount, descriptor); err != nil {
panic(err)
}
}

func (gm SDKGasMeter) IsPastLimit() bool {
Expand All @@ -83,12 +87,14 @@ type CoreGasmeter struct {
gm storetypes.GasMeter
}

func (cgm CoreGasmeter) Consume(amount gas.Gas, descriptor string) {
func (cgm CoreGasmeter) Consume(amount gas.Gas, descriptor string) error {
cgm.gm.ConsumeGas(amount, descriptor)
return nil
}

func (cgm CoreGasmeter) Refund(amount gas.Gas, descriptor string) {
func (cgm CoreGasmeter) Refund(amount gas.Gas, descriptor string) error {
cgm.gm.RefundGas(amount, descriptor)
return nil
}

func (cgm CoreGasmeter) Remaining() gas.Gas {
Expand Down
Loading

0 comments on commit 83c4b9b

Please sign in to comment.