Skip to content

Instantly share code, notes, and snippets.

@evan-forbes
Created June 3, 2021 18:09
Show Gist options
  • Save evan-forbes/ad8fd510874f2a8c7d990ab080087da9 to your computer and use it in GitHub Desktop.
Save evan-forbes/ad8fd510874f2a8c7d990ab080087da9 to your computer and use it in GitHub Desktop.
test to figure out is we can use the online and offline api's interchangeably
func TestOnlineOfflineIPFSAPI(t *testing.T) {
ipfsNode, err := coremock.NewMockNode()
if err != nil {
t.Error(err)
}
ipfsAPI, err := coreapi.NewCoreAPI(ipfsNode)
if err != nil {
t.Fatal(err)
}
firstFakeBlock := &types.Block{Data: generateRandomMsgOnlyData(16)}
secondFakeBlock := &types.Block{Data: generateRandomMsgOnlyData(16)}
thirdFakeBlock := &types.Block{Data: generateRandomMsgOnlyData(16)}
blocks := []*types.Block{firstFakeBlock, secondFakeBlock, thirdFakeBlock}
// put the first block online using the normal online API
err = ipld.PutBlock(context.TODO(), ipfsAPI.Dag(), firstFakeBlock)
if err != nil {
t.Fatal(err)
}
// put the second block offline using the offline API
secondAPI, err := ipfsAPI.WithOptions(Offline())
err = ipld.PutBlock(context.TODO(), secondAPI.Dag(), secondFakeBlock)
if err != nil {
t.Fatal(err)
}
// put the third block online using the online API
err = ipld.PutBlock(context.TODO(), ipfsAPI.Dag(), thirdFakeBlock)
if err != nil {
t.Fatal(err)
}
// for each block try to access the data via both the online and offline API
for i := 0; i < 3; i++ {
// try to access the everyblock using the first api
ctx := context.Background()
timeoutCtx, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()
block := blocks[i]
block.Hash()
for _, rowRoot := range block.DataAvailabilityHeader.RowsRoots.Bytes() {
// recreate the cids using only the computed roots
cid, err := plugin.CidFromNamespacedSha256(rowRoot)
if err != nil {
t.Error(err)
}
// retrieve the data from IPFS
_, err = ipfsAPI.Dag().Get(timeoutCtx, cid)
if err != nil {
t.Errorf("Root not found: %s", cid.String())
}
}
}
// access all of the blocks using the second API
for i := 0; i < 3; i++ {
ctx := context.Background()
timeoutCtx, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()
block := blocks[i]
block.Hash()
for _, rowRoot := range block.DataAvailabilityHeader.RowsRoots.Bytes() {
// recreate the cids using only the computed roots
cid, err := plugin.CidFromNamespacedSha256(rowRoot)
if err != nil {
t.Error(err)
}
// retrieve the data from IPFS using second API
_, err = secondAPI.Dag().Get(timeoutCtx, cid)
if err != nil {
t.Errorf("Root not found: %s", cid.String())
}
}
}
}
func Offline() options.ApiOption {
return func(settings *options.ApiSettings) error {
settings.Offline = true
return nil
}
}
func generateRandomMsgOnlyData(msgCount int) types.Data {
out := make([]types.Message, msgCount)
for i, msg := range generateRandNamespacedRawData(msgCount, consts.NamespaceSize, consts.MsgShareSize-2) {
out[i] = types.Message{NamespaceID: msg[:consts.NamespaceSize], Data: msg[consts.NamespaceSize:]}
}
return types.Data{
Messages: types.Messages{MessagesList: out},
}
}
// this code is copy pasted from the plugin, and should likely be exported in the plugin instead
func generateRandNamespacedRawData(total int, nidSize int, leafSize int) [][]byte {
data := make([][]byte, total)
for i := 0; i < total; i++ {
nid := make([]byte, nidSize)
_, err := rand.Read(nid)
if err != nil {
panic(err)
}
data[i] = nid
}
sortByteArrays(data)
for i := 0; i < total; i++ {
d := make([]byte, leafSize)
_, err := rand.Read(d)
if err != nil {
panic(err)
}
data[i] = append(data[i], d...)
}
return data
}
func sortByteArrays(src [][]byte) {
sort.Slice(src, func(i, j int) bool { return bytes.Compare(src[i], src[j]) < 0 })
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment