Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update contracts-compatibility-checker #3631

Merged
merged 4 commits into from
Oct 22, 2024
Merged
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
4 changes: 2 additions & 2 deletions .github/workflows/compatibility-check-template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ jobs:
run: |
GOPROXY=direct go mod edit -replace github.com/onflow/cadence=github.com/${{ inputs.repo }}@${{ inputs.current-branch }}
go mod tidy
go run ./cmd/check_contracts/main.go ../../tmp/contracts.csv ../../tmp/output-new.txt
go run ./cmd/check_contracts/main.go flow-${{ inputs.chain }} ../../tmp/contracts.csv ../../tmp/output-new.txt

# Check contracts using base branch

Expand All @@ -97,7 +97,7 @@ jobs:
run: |
GOPROXY=direct go mod edit -replace github.com/onflow/cadence=github.com/${{ inputs.repo }}@`git rev-parse origin/${{ inputs.base-branch }}`
go mod tidy
go run ./cmd/check_contracts/main.go ../../tmp/contracts.csv ../../tmp/output-old.txt
go run ./cmd/check_contracts/main.go flow-${{ inputs.chain }} ../../tmp/contracts.csv ../../tmp/output-old.txt

# Upload checking results for later use

Expand Down
21 changes: 17 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ build: build-tools ./cmd/parse/parse ./cmd/parse/parse.wasm ./cmd/check/check ./
go build -o $@ ./cmd/main

.PHONY: build-tools
build-tools: build-analysis build-get-contracts
build-tools: build-analysis build-get-contracts build-compatibility-check

.PHONY: build-analysis
build-analysis:
Expand All @@ -55,6 +55,10 @@ build-analysis:
build-get-contracts:
(cd ./tools/get-contracts && go build .)

.PHONY: build-compatibility-check
build-compatibility-check:
(cd ./tools/compatibility-check && go build .)

.PHONY: ci
ci:
# test all packages
Expand All @@ -65,9 +69,18 @@ ci:
sed -i -e 's/^.* 0 0$$//' coverage.txt

.PHONY: test
test:
# test all packages
go test -parallel 8 ./...
test: test-all-packages test-tools

.PHONY: test-all-packages
test-all-packages:
(go test -parallel 8 ./...)

.PHONY: test-tools
test-tools:
(cd ./tools/analysis && go test -parallel 8 ./)
(cd ./tools/compatibility-check && go test -parallel 8 ./)
(cd ./tools/constructorcheck && go test -parallel 8 ./)
(cd ./tools/maprange && go test -parallel 8 ./)

.PHONY: lint-github-actions
lint-github-actions: build-linter
Expand Down
23 changes: 23 additions & 0 deletions tools/analysis/programs.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
package analysis

import (
"fmt"

"github.com/onflow/cadence/ast"
"github.com/onflow/cadence/common"
"github.com/onflow/cadence/parser"
Expand All @@ -29,6 +31,7 @@ import (
type Programs struct {
Programs map[common.Location]*Program
CryptoContractElaboration *sema.Elaboration
CryptoContractLocation func() common.Location
}

type importResolutionResults map[common.Location]bool
Expand Down Expand Up @@ -157,8 +160,28 @@ func (programs *Programs) check(

switch importedLocation {
case stdlib.CryptoContractLocation:
// If the elaboration for the crypto contract is available, take it.
elaboration = programs.CryptoContractElaboration
if elaboration != nil {
break
}

// Otherwise, if the location for the Crypto contract is provided,
// then resolve the source code from that location and continue as
// any other contract.
cryptoLocation := programs.CryptoContractLocation
if cryptoLocation == nil {
return nil, fmt.Errorf("cannot find crypto contract")
}

importedLocation = cryptoLocation()

// Memoize the crypto contract's elaboration, for subsequent uses.
defer func() {
programs.CryptoContractElaboration = elaboration
}()

fallthrough
default:
if seenImports[importedLocation] {
return nil, &sema.CyclicImportsError{
Expand Down
15 changes: 10 additions & 5 deletions tools/compatibility-check/cmd/check_contracts/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,21 @@ import (
"github.com/rs/zerolog/log"

"github.com/onflow/cadence/tools/compatibility_check"

"github.com/onflow/flow-go/model/flow"
)

func main() {
if len(os.Args) < 2 {
log.Error().Msg("not enough arguments. Usage: csv_path output_path")
if len(os.Args) < 3 {
log.Error().Msg("not enough arguments. Usage: <chain_name> <csv_path> <output_path>")
return
}

csvPath := os.Args[1]
outputPath := os.Args[2]
chainName := os.Args[1]
csvPath := os.Args[2]
outputPath := os.Args[3]

chain := flow.ChainID(chainName).Chain()

csvFile, err := os.Open(csvPath)
if err != nil {
Expand All @@ -53,6 +58,6 @@ func main() {
_ = outputFile.Close()
}()

checker := compatibility_check.NewContractChecker(outputFile)
checker := compatibility_check.NewContractChecker(chain, outputFile)
checker.CheckCSV(csvFile)
}
28 changes: 26 additions & 2 deletions tools/compatibility-check/contracts_checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,28 @@ import (
"github.com/onflow/cadence/common"
"github.com/onflow/cadence/parser"
"github.com/onflow/cadence/sema"
"github.com/onflow/cadence/stdlib"
"github.com/onflow/cadence/tools/analysis"

"github.com/onflow/flow-go/fvm/systemcontracts"
"github.com/onflow/flow-go/model/flow"

"github.com/onflow/flow-core-contracts/lib/go/contracts"
)

const LoadMode = analysis.NeedTypes

type ContractsChecker struct {
chain flow.Chain
Codes map[common.Location][]byte
outputWriter io.StringWriter
}

func NewContractChecker(outputWriter io.StringWriter) *ContractsChecker {
func NewContractChecker(chain flow.Chain, outputWriter io.StringWriter) *ContractsChecker {
checker := &ContractsChecker{
Codes: map[common.Location][]byte{},
outputWriter: outputWriter,
chain: chain,
}

return checker
Expand Down Expand Up @@ -117,7 +125,23 @@ func (c *ContractsChecker) analyze(
config *analysis.Config,
locations []common.Location,
) {
programs := make(analysis.Programs, len(locations))

sc := systemcontracts.SystemContractsForChain(c.chain.ChainID())

cryptoContractLocation := common.AddressLocation{
Address: common.Address(sc.Crypto.Address),
Name: string(stdlib.CryptoContractLocation),
}

// TODO: Remove once the Crypto contract is available on-chain.
c.Codes[cryptoContractLocation] = contracts.Crypto()

programs := analysis.Programs{
Programs: make(map[common.Location]*analysis.Program, len(locations)),
CryptoContractLocation: func() common.Location {
return cryptoContractLocation
},
}

log.Println("Checking contracts ...")

Expand Down
35 changes: 34 additions & 1 deletion tools/compatibility-check/contracts_checker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,20 @@ import (
"testing"

"github.com/stretchr/testify/assert"

"github.com/onflow/flow-go/model/flow"
)

func TestCyclicImport(t *testing.T) {

t.Parallel()

var output bytes.Buffer
var input bytes.Buffer

checker := NewContractChecker(&output)
chain := flow.Testnet.Chain()

checker := NewContractChecker(chain, &output)

input.Write([]byte(`location,code
A.0000000000000001.Foo,"import Bar from 0x0000000000000001
Expand All @@ -49,3 +55,30 @@ access(all) contract Foo {}"
assert.Contains(t, outputStr, "Bar:16(1:16):*sema.ImportedProgramError")
assert.Contains(t, outputStr, "Baz:16(1:16):*sema.ImportedProgramError")
}

func TestCryptoImport(t *testing.T) {

t.Parallel()

var output bytes.Buffer
var input bytes.Buffer

chainID := flow.Testnet

checker := NewContractChecker(chainID.Chain(), &output)

contractsCSV := `location,code
A.0000000000000001.Foo,"import Crypto
access(all) contract Foo {}"
A.0000000000000001.Bar,"import Crypto
access(all) contract Bar {}"
`

input.Write([]byte(contractsCSV))

checker.CheckCSV(&input)

outputStr := output.String()

assert.Empty(t, outputStr)
}
75 changes: 63 additions & 12 deletions tools/compatibility-check/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,89 @@ module github.com/onflow/cadence/tools/compatibility_check
go 1.22

require (
github.com/onflow/cadence v1.0.1-0.20241017195911-152088fcbb15
github.com/rs/zerolog v1.26.1
github.com/onflow/cadence v1.1.1-0.20241018202510-7f1b6fbc57c2
github.com/rs/zerolog v1.29.0
github.com/stretchr/testify v1.9.0
)

require (
github.com/SaveTheRbtz/mph v0.1.1-0.20240117162131-4166ec7869bc // indirect
github.com/bits-and-blooms/bitset v1.5.0 // indirect
github.com/bits-and-blooms/bitset v1.10.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
github.com/coreos/go-semver v0.3.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
github.com/ethereum/go-ethereum v1.13.10 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/fxamacker/cbor/v2 v2.4.1-0.20230228173756-c0c9f774e40c // indirect
github.com/fxamacker/circlehash v0.3.0 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/holiman/uint256 v1.3.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/ipfs/go-cid v0.4.1 // indirect
github.com/k0kubun/pp v3.0.1+incompatible // indirect
github.com/klauspost/cpuid/v2 v2.2.0 // indirect
github.com/kevinburke/go-bindata v3.24.0+incompatible // indirect
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 // indirect
github.com/logrusorgru/aurora/v4 v4.0.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/minio/sha256-simd v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/multiformats/go-base32 v0.1.0 // indirect
github.com/multiformats/go-base36 v0.2.0 // indirect
github.com/multiformats/go-multibase v0.2.0 // indirect
github.com/multiformats/go-multihash v0.2.3 // indirect
github.com/multiformats/go-varint v0.0.7 // indirect
github.com/onflow/atree v0.8.0 // indirect
github.com/onflow/crypto v0.25.2 // indirect
github.com/onflow/flow-core-contracts/lib/go/contracts v1.4.0 // indirect
github.com/onflow/flow-core-contracts/lib/go/templates v1.3.3-0.20241017220455-79fdc6c8ba53 // indirect
github.com/onflow/flow-ft/lib/go/contracts v1.0.1 // indirect
github.com/onflow/flow-ft/lib/go/templates v1.0.1 // indirect
github.com/onflow/flow-go v0.38.0-preview.0.0.20241018215103-774056466e36 // indirect
github.com/onflow/flow-go-sdk v1.1.0 // indirect
github.com/onflow/flow-nft/lib/go/contracts v1.2.2 // indirect
github.com/onflow/flow-nft/lib/go/templates v1.2.1 // indirect
github.com/onflow/flow/protobuf/go/flow v0.4.7 // indirect
github.com/onflow/go-ethereum v1.14.7 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/psiemens/sconfig v0.1.0 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/rogpeppe/go-internal v1.9.0 // indirect
github.com/rogpeppe/go-internal v1.10.0 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/spf13/afero v1.10.0 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/cobra v1.8.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.15.0 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
github.com/texttheater/golang-levenshtein/levenshtein v0.0.0-20200805054039-cae8b0eaed6c // indirect
github.com/turbolent/prettier v0.0.0-20220320183459-661cc755135d // indirect
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
github.com/vmihailenco/msgpack/v4 v4.3.11 // indirect
github.com/vmihailenco/tagparser v0.1.1 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/zeebo/blake3 v0.2.3 // indirect
go.opentelemetry.io/otel v1.8.0 // indirect
golang.org/x/crypto v0.1.0 // indirect
golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.4.0 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
go.opentelemetry.io/otel v1.24.0 // indirect
golang.org/x/crypto v0.26.0 // indirect
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect
golang.org/x/sys v0.23.0 // indirect
golang.org/x/text v0.17.0 // indirect
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
gonum.org/v1/gonum v0.14.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
lukechampine.com/blake3 v1.3.0 // indirect
)

replace github.com/onflow/cadence => ../../
Loading
Loading