forked from filecoin-project/lotus
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add tests to sanity-check embedded built-in actors metadata (filecoin…
…-project#11684) Add tests that assert the embedded built-in actors metadata is correct: * the corresponding CAR file is present in built-in actors released assets as a CAR file. * manifest CID is the only root CID in the corresponding CAR file. * actor CIDs are present in the corresponding CAR file. Fixes filecoin-project#11683
- Loading branch information
Showing
2 changed files
with
125 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
name: Built-in Actors | ||
on: | ||
push: | ||
paths: | ||
- build/actors | ||
- build/builtin_actors_gen.go | ||
branches: | ||
- release/* | ||
jobs: | ||
release: | ||
name: Release Tests | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: actions/setup-go@v3 | ||
with: | ||
go-version: 1.21 | ||
- run: go test -tags=release ./build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
//go:build release | ||
// +build release | ||
|
||
package build_test | ||
|
||
import ( | ||
"archive/tar" | ||
"crypto/sha256" | ||
"encoding/hex" | ||
"errors" | ||
"fmt" | ||
"io" | ||
"net/http" | ||
"os" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/DataDog/zstd" | ||
"github.com/ipfs/go-cid" | ||
"github.com/ipld/go-car/v2" | ||
"github.com/stretchr/testify/require" | ||
|
||
actorstypes "github.com/filecoin-project/go-state-types/actors" | ||
|
||
"github.com/filecoin-project/lotus/build" | ||
) | ||
|
||
func TestEmbeddedBuiltinActorsMetadata(t *testing.T) { | ||
subjectsByVersionByNetworks := make(map[actorstypes.Version]map[string]*build.BuiltinActorsMetadata) | ||
for _, subject := range build.EmbeddedBuiltinActorsMetadata { | ||
if subject.BundleGitTag == "" { | ||
// BundleGitTag is required to verify the SHA-256 checksum. | ||
// The pack script only includes this for the latest network version, and it is good enough to only | ||
// check the latest network version metadata. Hence the skip. | ||
continue | ||
} | ||
v, ok := subjectsByVersionByNetworks[subject.Version] | ||
if !ok { | ||
v = make(map[string]*build.BuiltinActorsMetadata) | ||
} | ||
v[subject.Network] = subject | ||
subjectsByVersionByNetworks[subject.Version] = v | ||
} | ||
|
||
for version, networks := range subjectsByVersionByNetworks { | ||
cachedCar, err := os.Open(fmt.Sprintf("./actors/v%v.tar.zst", version)) | ||
require.NoError(t, err) | ||
t.Cleanup(func() { require.NoError(t, cachedCar.Close()) }) | ||
tarReader := tar.NewReader(zstd.NewReader(cachedCar)) | ||
for { | ||
header, err := tarReader.Next() | ||
if errors.Is(err, io.EOF) { | ||
break | ||
} | ||
require.NoError(t, err) | ||
|
||
network := strings.TrimSuffix(strings.TrimPrefix(header.Name, "builtin-actors-"), ".car") | ||
subject, found := networks[network] | ||
if !found { | ||
continue | ||
} | ||
|
||
shaURL := fmt.Sprintf("https://github.com/filecoin-project/builtin-actors/releases/download/%s/builtin-actors-%s.sha256", subject.BundleGitTag, subject.Network) | ||
resp, err := http.Get(shaURL) | ||
require.NoError(t, err, "failed to retrieve CAR SHA") | ||
require.Equal(t, http.StatusOK, resp.StatusCode, "unexpected response status code while retrieving CAR SHA") | ||
|
||
respBody, err := io.ReadAll(resp.Body) | ||
require.NoError(t, resp.Body.Close()) | ||
require.NoError(t, err) | ||
fields := strings.Fields(string(respBody)) | ||
require.Len(t, fields, 2) | ||
wantShaHex := fields[0] | ||
|
||
hasher := sha256.New() | ||
reader, err := car.NewBlockReader(io.TeeReader(tarReader, hasher)) | ||
require.NoError(t, err) | ||
|
||
require.EqualValues(t, 1, reader.Version) | ||
require.Len(t, reader.Roots, 1, "expected exactly one root CID for builtin actors bundle network %s, version %v", subject.Network, subject.Version) | ||
require.True(t, reader.Roots[0].Equals(subject.ManifestCid), "manifest CID does not match") | ||
|
||
subjectActorsByCid := make(map[cid.Cid]string) | ||
for name, c := range subject.Actors { | ||
subjectActorsByCid[c] = name | ||
} | ||
for { | ||
next, err := reader.Next() | ||
if errors.Is(err, io.EOF) { | ||
break | ||
} | ||
require.NoError(t, err) | ||
name, found := subjectActorsByCid[next.Cid()] | ||
if found { | ||
t.Logf("OK: %sv%v/%s -> %s", subject.Network, subject.Version, name, next.Cid()) | ||
delete(subjectActorsByCid, next.Cid()) | ||
} | ||
} | ||
require.Empty(t, subjectActorsByCid, "ZST CAR bundle did not contain CIDs for all actors; missing: %v", subjectActorsByCid) | ||
|
||
gotShaHex := hex.EncodeToString(hasher.Sum(nil)) | ||
require.Equal(t, wantShaHex, gotShaHex, "SHA-256 digest of ZST CAR bundle does not match builtin-actors release") | ||
delete(networks, network) | ||
} | ||
require.Empty(t, networks, "CAR bundle did not contain CIDs for network; missing: %v", networks) | ||
} | ||
} |