|
5 | 5 | "crypto/rand"
|
6 | 6 | "encoding/hex"
|
7 | 7 | "errors"
|
| 8 | + "fmt" |
8 | 9 | "math"
|
9 | 10 | "math/big"
|
10 | 11 | "strings"
|
@@ -79,6 +80,28 @@ func checkDispersalsDesc(t *testing.T, items []*corev2.DispersalRequest) {
|
79 | 80 | }
|
80 | 81 | }
|
81 | 82 |
|
| 83 | +func checkBlobsAsc(t *testing.T, items []*v2.BlobMetadata) { |
| 84 | + if len(items) > 1 { |
| 85 | + for i := 1; i < len(items); i++ { |
| 86 | + assert.Less(t, |
| 87 | + items[i-1].RequestedAt, // previous should be less |
| 88 | + items[i].RequestedAt, // than current |
| 89 | + "blobs should be in ascending order", |
| 90 | + ) |
| 91 | + } |
| 92 | + } |
| 93 | +} |
| 94 | + |
| 95 | +func checkBlobsDesc(t *testing.T, items []*v2.BlobMetadata) { |
| 96 | + for i := 1; i < len(items); i++ { |
| 97 | + assert.Greater(t, |
| 98 | + items[i-1].RequestedAt, // previous should be greater |
| 99 | + items[i].RequestedAt, // than current |
| 100 | + "blobs should be in descending order", |
| 101 | + ) |
| 102 | + } |
| 103 | +} |
| 104 | + |
82 | 105 | func TestBlobFeedCursor_Equal(t *testing.T) {
|
83 | 106 | bk1 := corev2.BlobKey([32]byte{1, 2, 3})
|
84 | 107 | bk2 := corev2.BlobKey([32]byte{2, 3, 4})
|
@@ -832,6 +855,171 @@ func TestBlobMetadataStoreGetBlobMetadataByRequestedAtBackward(t *testing.T) {
|
832 | 855 | })
|
833 | 856 | }
|
834 | 857 |
|
| 858 | +func TestBlobMetadataStoreGetBlobMetadataByAccountID(t *testing.T) { |
| 859 | + ctx := context.Background() |
| 860 | + |
| 861 | + // Make all blobs happen in 12s |
| 862 | + numBlobs := 120 |
| 863 | + nanoSecsPerBlob := uint64(1e8) // 10 blobs per second |
| 864 | + |
| 865 | + now := uint64(time.Now().UnixNano()) |
| 866 | + firstBlobTime := now - uint64(10*time.Minute.Nanoseconds()) |
| 867 | + |
| 868 | + accountId := gethcommon.HexToAddress(fmt.Sprintf("0x000000000000000000000000000000000000000%d", 5)) |
| 869 | + |
| 870 | + // Create blobs for testing |
| 871 | + keys := make([]corev2.BlobKey, numBlobs) |
| 872 | + requestedAt := make([]uint64, numBlobs) |
| 873 | + dynamoKeys := make([]commondynamodb.Key, numBlobs) |
| 874 | + for i := 0; i < numBlobs; i++ { |
| 875 | + _, blobHeader := newBlob(t) |
| 876 | + blobHeader.PaymentMetadata.AccountID = accountId |
| 877 | + blobKey, err := blobHeader.BlobKey() |
| 878 | + require.NoError(t, err) |
| 879 | + requestedAt[i] = firstBlobTime + nanoSecsPerBlob*uint64(i) |
| 880 | + now := time.Now() |
| 881 | + metadata := &v2.BlobMetadata{ |
| 882 | + BlobHeader: blobHeader, |
| 883 | + Signature: []byte{1, 2, 3}, |
| 884 | + BlobStatus: v2.Encoded, |
| 885 | + Expiry: uint64(now.Add(time.Hour).Unix()), |
| 886 | + NumRetries: 0, |
| 887 | + UpdatedAt: uint64(now.UnixNano()), |
| 888 | + RequestedAt: requestedAt[i], |
| 889 | + } |
| 890 | + err = blobMetadataStore.PutBlobMetadata(ctx, metadata) |
| 891 | + require.NoError(t, err) |
| 892 | + keys[i] = blobKey |
| 893 | + dynamoKeys[i] = commondynamodb.Key{ |
| 894 | + "PK": &types.AttributeValueMemberS{Value: "BlobKey#" + blobKey.Hex()}, |
| 895 | + "SK": &types.AttributeValueMemberS{Value: "BlobMetadata"}, |
| 896 | + } |
| 897 | + } |
| 898 | + defer deleteItems(t, dynamoKeys) |
| 899 | + |
| 900 | + // Test empty range |
| 901 | + t.Run("empty range", func(t *testing.T) { |
| 902 | + // Test invalid time range |
| 903 | + _, err := blobMetadataStore.GetBlobMetadataByAccountID(ctx, accountId, 1, 1, 0, true) |
| 904 | + require.Error(t, err) |
| 905 | + assert.Equal(t, "no time point in exclusive time range (1, 1)", err.Error()) |
| 906 | + |
| 907 | + _, err = blobMetadataStore.GetBlobMetadataByAccountID(ctx, accountId, 1, 2, 0, true) |
| 908 | + require.Error(t, err) |
| 909 | + assert.Equal(t, "no time point in exclusive time range (1, 2)", err.Error()) |
| 910 | + |
| 911 | + // Test empty range |
| 912 | + blobs, err := blobMetadataStore.GetBlobMetadataByAccountID(ctx, accountId, now, now+1024, 0, true) |
| 913 | + require.NoError(t, err) |
| 914 | + assert.Equal(t, 0, len(blobs)) |
| 915 | + }) |
| 916 | + |
| 917 | + // Test full range query |
| 918 | + t.Run("ascending full range", func(t *testing.T) { |
| 919 | + // Test without limit |
| 920 | + blobs, err := blobMetadataStore.GetBlobMetadataByAccountID(ctx, accountId, firstBlobTime-1, now, 0, true) |
| 921 | + require.NoError(t, err) |
| 922 | + require.Equal(t, numBlobs, len(blobs)) |
| 923 | + checkBlobsAsc(t, blobs) |
| 924 | + |
| 925 | + // Test with limit |
| 926 | + blobs, err = blobMetadataStore.GetBlobMetadataByAccountID(ctx, accountId, firstBlobTime-1, now, 10, true) |
| 927 | + require.NoError(t, err) |
| 928 | + require.Equal(t, 10, len(blobs)) |
| 929 | + checkBlobsAsc(t, blobs) |
| 930 | + |
| 931 | + // Test min/max timestamp range |
| 932 | + blobs, err = blobMetadataStore.GetBlobMetadataByAccountID(ctx, accountId, 0, now, 0, true) |
| 933 | + require.NoError(t, err) |
| 934 | + require.Equal(t, numBlobs, len(blobs)) |
| 935 | + checkBlobsAsc(t, blobs) |
| 936 | + blobs, err = blobMetadataStore.GetBlobMetadataByAccountID(ctx, accountId, firstBlobTime-1, math.MaxInt64, 0, true) |
| 937 | + require.NoError(t, err) |
| 938 | + require.Equal(t, numBlobs, len(blobs)) |
| 939 | + checkBlobsAsc(t, blobs) |
| 940 | + }) |
| 941 | + |
| 942 | + // Test full range query |
| 943 | + t.Run("descending full range", func(t *testing.T) { |
| 944 | + // Test without limit |
| 945 | + blobs, err := blobMetadataStore.GetBlobMetadataByAccountID(ctx, accountId, firstBlobTime-1, now, 0, false) |
| 946 | + require.NoError(t, err) |
| 947 | + require.Equal(t, numBlobs, len(blobs)) |
| 948 | + checkBlobsDesc(t, blobs) |
| 949 | + |
| 950 | + // Test with limit |
| 951 | + blobs, err = blobMetadataStore.GetBlobMetadataByAccountID(ctx, accountId, firstBlobTime-1, now, 10, false) |
| 952 | + require.NoError(t, err) |
| 953 | + require.Equal(t, 10, len(blobs)) |
| 954 | + checkBlobsDesc(t, blobs) |
| 955 | + |
| 956 | + // Test min/max timestamp range |
| 957 | + blobs, err = blobMetadataStore.GetBlobMetadataByAccountID(ctx, accountId, 0, now, 0, false) |
| 958 | + require.NoError(t, err) |
| 959 | + require.Equal(t, numBlobs, len(blobs)) |
| 960 | + checkBlobsDesc(t, blobs) |
| 961 | + blobs, err = blobMetadataStore.GetBlobMetadataByAccountID(ctx, accountId, firstBlobTime-1, math.MaxInt64, 0, false) |
| 962 | + require.NoError(t, err) |
| 963 | + require.Equal(t, numBlobs, len(blobs)) |
| 964 | + checkBlobsDesc(t, blobs) |
| 965 | + }) |
| 966 | + |
| 967 | + // Test range boundaries |
| 968 | + t.Run("ascending range boundaries", func(t *testing.T) { |
| 969 | + // Test exclusive start |
| 970 | + blobs, err := blobMetadataStore.GetBlobMetadataByAccountID(ctx, accountId, firstBlobTime, now, 0, true) |
| 971 | + require.NoError(t, err) |
| 972 | + require.Equal(t, numBlobs-1, len(blobs)) |
| 973 | + assert.Equal(t, requestedAt[1], blobs[0].RequestedAt) |
| 974 | + assert.Equal(t, requestedAt[numBlobs-1], blobs[numBlobs-2].RequestedAt) |
| 975 | + checkBlobsAsc(t, blobs) |
| 976 | + |
| 977 | + // Test exclusive end |
| 978 | + blobs, err = blobMetadataStore.GetBlobMetadataByAccountID(ctx, accountId, firstBlobTime-1, requestedAt[4], 0, true) |
| 979 | + require.NoError(t, err) |
| 980 | + require.Equal(t, 4, len(blobs)) |
| 981 | + assert.Equal(t, requestedAt[0], blobs[0].RequestedAt) |
| 982 | + assert.Equal(t, requestedAt[3], blobs[3].RequestedAt) |
| 983 | + checkBlobsAsc(t, blobs) |
| 984 | + }) |
| 985 | + |
| 986 | + // Test range boundaries |
| 987 | + t.Run("descending range boundaries", func(t *testing.T) { |
| 988 | + // Test exclusive start |
| 989 | + blobs, err := blobMetadataStore.GetBlobMetadataByAccountID(ctx, accountId, firstBlobTime, now, 0, false) |
| 990 | + require.NoError(t, err) |
| 991 | + require.Equal(t, numBlobs-1, len(blobs)) |
| 992 | + assert.Equal(t, requestedAt[numBlobs-1], blobs[0].RequestedAt) |
| 993 | + assert.Equal(t, requestedAt[1], blobs[numBlobs-2].RequestedAt) |
| 994 | + checkBlobsDesc(t, blobs) |
| 995 | + |
| 996 | + // Test exclusive end |
| 997 | + blobs, err = blobMetadataStore.GetBlobMetadataByAccountID(ctx, accountId, firstBlobTime-1, requestedAt[4], 0, false) |
| 998 | + require.NoError(t, err) |
| 999 | + require.Equal(t, 4, len(blobs)) |
| 1000 | + assert.Equal(t, requestedAt[3], blobs[0].RequestedAt) |
| 1001 | + assert.Equal(t, requestedAt[0], blobs[3].RequestedAt) |
| 1002 | + checkBlobsDesc(t, blobs) |
| 1003 | + }) |
| 1004 | + |
| 1005 | + // Test pagination |
| 1006 | + t.Run("pagination", func(t *testing.T) { |
| 1007 | + for i := 1; i < numBlobs; i++ { |
| 1008 | + blobs, err := blobMetadataStore.GetBlobMetadataByAccountID(ctx, accountId, requestedAt[i-1], requestedAt[i]+1, 0, true) |
| 1009 | + require.NoError(t, err) |
| 1010 | + require.Equal(t, 1, len(blobs)) |
| 1011 | + assert.Equal(t, requestedAt[i], blobs[0].RequestedAt) |
| 1012 | + } |
| 1013 | + |
| 1014 | + for i := 1; i < numBlobs; i++ { |
| 1015 | + blobs, err := blobMetadataStore.GetBlobMetadataByAccountID(ctx, accountId, requestedAt[i-1], requestedAt[i]+1, 0, false) |
| 1016 | + require.NoError(t, err) |
| 1017 | + require.Equal(t, 1, len(blobs)) |
| 1018 | + assert.Equal(t, requestedAt[i], blobs[0].RequestedAt) |
| 1019 | + } |
| 1020 | + }) |
| 1021 | +} |
| 1022 | + |
835 | 1023 | func TestBlobMetadataStoreGetAttestationByAttestedAtForward(t *testing.T) {
|
836 | 1024 | ctx := context.Background()
|
837 | 1025 | numBatches := 72
|
|
0 commit comments