Skip to content

Commit

Permalink
Merge pull request #3631 from onflow/supun/update-contracts-checker
Browse files Browse the repository at this point in the history
Update contracts-compatibility-checker
  • Loading branch information
SupunS authored Oct 22, 2024
2 parents 9b853da + 237ddb7 commit 8b27276
Show file tree
Hide file tree
Showing 8 changed files with 836 additions and 55 deletions.
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

0 comments on commit 8b27276

Please sign in to comment.