110 lines
3.6 KiB
Go
110 lines
3.6 KiB
Go
//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/ipfs/go-cid"
|
|
"github.com/ipld/go-car/v2"
|
|
"github.com/klauspost/compress/zstd"
|
|
"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()) })
|
|
zstReader, err := zstd.NewReader(cachedCar)
|
|
require.NoError(t, err)
|
|
tarReader := tar.NewReader(zstReader)
|
|
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)
|
|
}
|
|
}
|