From 252a416827b5e9d110435024e9959442917baa99 Mon Sep 17 00:00:00 2001 From: JT Olio Date: Mon, 1 Jul 2024 15:54:03 -0400 Subject: [PATCH] relative images --- app/(blog)/blog/a-tale-of-two-copies/page.md | 10 +++--- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 4 +-- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 10 +++--- .../blog/demystifying-technical-debt/page.md | 36 +++++++++---------- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 4 +-- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../blog/february-2022-product-update/page.md | 2 +- .../page.md | 2 +- .../finding-goroutine-leaks-in-tests/page.md | 2 +- .../page.md | 8 ++--- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 10 +++--- .../page.md | 26 +++++++------- .../page.md | 4 +-- .../page.md | 2 +- .../blog/january-2021-product-update/page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../blog/june-2021-development-update/page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 2 +- .../blog/production-concurrency/page.md | 2 +- .../page.md | 14 ++++---- .../september-2021-development-update/page.md | 2 +- .../page.md | 6 ++-- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 4 +-- .../page.md | 2 +- .../page.md | 2 +- .../page.md | 14 ++++---- .../page.md | 10 +++--- .../page.md | 4 +-- .../page.md | 4 +-- .../what-is-end-to-end-encryption/page.md | 2 +- .../page.md | 4 +-- utils/import-blogs.py | 2 +- 86 files changed, 155 insertions(+), 155 deletions(-) diff --git a/app/(blog)/blog/a-tale-of-two-copies/page.md b/app/(blog)/blog/a-tale-of-two-copies/page.md index fe7165467..285052bf5 100644 --- a/app/(blog)/blog/a-tale-of-two-copies/page.md +++ b/app/(blog)/blog/a-tale-of-two-copies/page.md @@ -8,7 +8,7 @@ metadata: hit a performance mystery that sent me down a multi-day rabbit hole of adventure. I was writing some code to take some entries, append them into a fixed size in-memory buffer, and then flush that buffer to disk when it was full. - heroimage: /blog/a-tale-of-two-copies/a5d148aee871d9eb.png + heroimage: ./a5d148aee871d9eb.png title: A Tale of Two Copies title: A Tale of Two Copies @@ -92,7 +92,7 @@ BenchmarkBuffer/32 436220 ns/op 196.0 flushes 4.362 ns/key That's right, a nearly 2x difference in performance where the benchmark writing to disk MORE is FASTER! -![](/blog/a-tale-of-two-copies/51fb41f548601419.png) +![](./51fb41f548601419.png) *Me too, Nick Young. Me, too.* @@ -241,7 +241,7 @@ So that's saying that in the 32 byte version, the SHLQ ran on port 2 half the ti And for a while, this is what I thought was happening. In fact, a first draft of this very blog post had that as the conclusion, but the more I thought about it, the less good of an explanation it seemed. -![](/blog/a-tale-of-two-copies/eb4b808e55daa547.png) +![](./eb4b808e55daa547.png) *My first draft attempt* @@ -266,7 +266,7 @@ If this were a movie, this would be the part where the main character is shown t A quick estimate shows that perf knows how to read over 700 different counters on my machine, and I feel like I looked at most of them. Take a look at [this huge table](https://perfmon-events.intel.com/skylake.html) if you're interested. I couldn't find any counters that could seem to explain the large difference in speed, and I was starting to get desparate. -![](/blog/a-tale-of-two-copies/9b285294e5712e47.jpeg) +![](./9b285294e5712e47.jpeg) *A picture of me wading through all of the perf counters* @@ -439,7 +439,7 @@ Remember how CPUs are complex beasts? Well it gets even better. An optimization So now it has this write buffer buffering all of the writes. What happens if a read comes in for one of those writes? It would slow everything down if had to wait for that write to actually happen before reading it back out, so instead it tries to service the read from the write buffer directly if possible, and no one is the wiser. You clever little CPU. This optimization is called [store forwarding](https://easyperf.net/blog/2018/03/09/Store-forwarding). -![](/blog/a-tale-of-two-copies/07035c56befc8dc1.png) +![](./07035c56befc8dc1.png) *My CPU buffering and reorganizing all of the writes* diff --git a/app/(blog)/blog/announcing-beacon-alpha-file-sharing-ip-filtering-and-increased-performance/page.md b/app/(blog)/blog/announcing-beacon-alpha-file-sharing-ip-filtering-and-increased-performance/page.md index f45c13137..4a70a64b5 100644 --- a/app/(blog)/blog/announcing-beacon-alpha-file-sharing-ip-filtering-and-increased-performance/page.md +++ b/app/(blog)/blog/announcing-beacon-alpha-file-sharing-ip-filtering-and-increased-performance/page.md @@ -9,7 +9,7 @@ metadata: \ last update ahead of our Pioneer 1 (Beta), which we\u2019re planning to release\ \ mid-July.\_Beacon is a huge milestone for several reasons. In addition to general\ \ i..." - heroimage: /blog/announcing-beacon-alpha-file-sharing-ip-filtering-and-increased-performance/71dd92bdd263bc4c.jpeg + heroimage: ./71dd92bdd263bc4c.jpeg title: Announcing Beacon Alpha - File sharing, IP filtering, and increased performance title: Announcing Beacon Alpha - File sharing, IP filtering, and increased performance diff --git a/app/(blog)/blog/announcing-beta-pioneer-1-v3-and-tardigrade-are-here/page.md b/app/(blog)/blog/announcing-beta-pioneer-1-v3-and-tardigrade-are-here/page.md index 37e048c24..7e74713e3 100644 --- a/app/(blog)/blog/announcing-beta-pioneer-1-v3-and-tardigrade-are-here/page.md +++ b/app/(blog)/blog/announcing-beta-pioneer-1-v3-and-tardigrade-are-here/page.md @@ -8,7 +8,7 @@ metadata: \ that Pioneer Beta for the V3 network has arrived. Now that V3 is here, we\u2019\ re also ready to launch the beta for Tardigrade decentralized cloud object storage.\ \ So, what changes are coming with the V3 network? V3 is more scalable, performa..." - heroimage: /blog/announcing-beta-pioneer-1-v3-and-tardigrade-are-here/48d94812c2adfd37.png + heroimage: ./48d94812c2adfd37.png title: 'Announcing Beta: Pioneer 1 V3 and Tardigrade Are Here' title: 'Announcing Beta: Pioneer 1 V3 and Tardigrade Are Here' diff --git a/app/(blog)/blog/announcing-pioneer-2-and-tardigrade-io-pricing/page.md b/app/(blog)/blog/announcing-pioneer-2-and-tardigrade-io-pricing/page.md index cf717b042..755f09ebd 100644 --- a/app/(blog)/blog/announcing-pioneer-2-and-tardigrade-io-pricing/page.md +++ b/app/(blog)/blog/announcing-pioneer-2-and-tardigrade-io-pricing/page.md @@ -9,7 +9,7 @@ metadata: \ Tardigrade Decentralized Cloud Storage Service. Since our founding, our goal\ \ has been to achieve pricing that is half the price of centralized cloud storage\ \ providers,..." - heroimage: /blog/announcing-pioneer-2-and-tardigrade-io-pricing/050b4597b2f44ed5.png + heroimage: ./050b4597b2f44ed5.png title: Announcing Pioneer 2 and Tardigrade.io Pricing title: Announcing Pioneer 2 and Tardigrade.io Pricing diff --git a/app/(blog)/blog/announcing-the-storj-v3-explorer-release/page.md b/app/(blog)/blog/announcing-the-storj-v3-explorer-release/page.md index 7c85b3e14..9f2859581 100644 --- a/app/(blog)/blog/announcing-the-storj-v3-explorer-release/page.md +++ b/app/(blog)/blog/announcing-the-storj-v3-explorer-release/page.md @@ -8,7 +8,7 @@ metadata: network V3 Explorer release, which is the alpha that allows storage node operators to join the network! We know many of you have been waiting to join the V3 network as storage node operators to start earning STORJ tokens by s... - heroimage: /blog/announcing-the-storj-v3-explorer-release/c12f0143a9f81c8c.png + heroimage: ./c12f0143a9f81c8c.png title: Announcing The Storj V3 Explorer Release title: Announcing The Storj V3 Explorer Release diff --git a/app/(blog)/blog/august-2021-development-update-from-storj/page.md b/app/(blog)/blog/august-2021-development-update-from-storj/page.md index 241f7a2b2..f15ebced1 100644 --- a/app/(blog)/blog/august-2021-development-update-from-storj/page.md +++ b/app/(blog)/blog/august-2021-development-update-from-storj/page.md @@ -9,7 +9,7 @@ metadata: We want to thank everyone who participated in the surveys we recently sent out. Your responses and insights were very helpful as we continue to make our product better for our users. - heroimage: /blog/august-2021-development-update-from-storj/b42ec40b7e3c447d.png + heroimage: ./b42ec40b7e3c447d.png title: August 2021 Development Update from Storj title: August 2021 Development Update from Storj diff --git a/app/(blog)/blog/automatically-store-your-tesla-sentry-mode-and-dashcam-videos-on-the-decentralized-cloud/page.md b/app/(blog)/blog/automatically-store-your-tesla-sentry-mode-and-dashcam-videos-on-the-decentralized-cloud/page.md index a71436b61..b4a10b9db 100644 --- a/app/(blog)/blog/automatically-store-your-tesla-sentry-mode-and-dashcam-videos-on-the-decentralized-cloud/page.md +++ b/app/(blog)/blog/automatically-store-your-tesla-sentry-mode-and-dashcam-videos-on-the-decentralized-cloud/page.md @@ -13,7 +13,7 @@ metadata: use the next day. This will also work for videos recorded in Track Mode if you have one of the performance models, making it easy to share any of the videos with your friends. - heroimage: /blog/automatically-store-your-tesla-sentry-mode-and-dashcam-videos-on-the-decentralized-cloud/94ca9aa0a874a87b.png + heroimage: ./94ca9aa0a874a87b.png title: Automatically Store Your Tesla Sentry Mode and Dashcam Videos on the Decentralized Cloud title: Automatically Store Your Tesla Sentry Mode and Dashcam Videos on the Decentralized diff --git a/app/(blog)/blog/choosing-cockroach-db-for-horizontal-scalability/page.md b/app/(blog)/blog/choosing-cockroach-db-for-horizontal-scalability/page.md index 54c00efb2..1ae39015d 100644 --- a/app/(blog)/blog/choosing-cockroach-db-for-horizontal-scalability/page.md +++ b/app/(blog)/blog/choosing-cockroach-db-for-horizontal-scalability/page.md @@ -8,7 +8,7 @@ metadata: \ PostgreSQL to CockroachDB. We want to share why we did this and what our experience\ \ was.TL;DR Our experience has convinced us that CockroachDB is the best horizontally\ \ scalable database choice in 2020.\_Why use a horizontally scalab..." - heroimage: /blog/choosing-cockroach-db-for-horizontal-scalability/1f4faa49217ba74e.png + heroimage: ./1f4faa49217ba74e.png title: Choosing Cockroach DB for Horizontal Scalability title: Choosing Cockroach DB for Horizontal Scalability diff --git a/app/(blog)/blog/cloud-based-mutlimedia-library-transformation/page.md b/app/(blog)/blog/cloud-based-mutlimedia-library-transformation/page.md index 8b0c5f158..e1e5137c7 100644 --- a/app/(blog)/blog/cloud-based-mutlimedia-library-transformation/page.md +++ b/app/(blog)/blog/cloud-based-mutlimedia-library-transformation/page.md @@ -8,7 +8,7 @@ metadata: things to watch. Besides extensive lists of classic movies and TV shows, growing studios have contributed to a recent explosion in new popular series. These can't-miss titles have amassed viewerships in the millions and critical ... - heroimage: /blog/cloud-based-mutlimedia-library-transformation/1bb0baa6b3e5f63c.png + heroimage: ./1bb0baa6b3e5f63c.png title: Use the Decentralized Cloud to Transform Your Multimedia Library Into Your Personal Netflix title: Use the Decentralized Cloud to Transform Your Multimedia Library Into Your diff --git a/app/(blog)/blog/coordination-avoidance-on-the-storj-network/page.md b/app/(blog)/blog/coordination-avoidance-on-the-storj-network/page.md index a2f460266..747de3962 100644 --- a/app/(blog)/blog/coordination-avoidance-on-the-storj-network/page.md +++ b/app/(blog)/blog/coordination-avoidance-on-the-storj-network/page.md @@ -8,7 +8,7 @@ metadata: \ and consumers are storing unprecedented amounts of data. IDC predicts worldwide\ \ data will grow to 175 zettabytes by 2025, with as much data stored in the cloud\ \ as in data centers\xB9.The Storj network introduces an economy around s..." - heroimage: /blog/coordination-avoidance-on-the-storj-network/a7e04c245b685755.jpeg + heroimage: ./a7e04c245b685755.jpeg title: Coordination Avoidance On The Storj Network title: Coordination Avoidance On The Storj Network @@ -33,7 +33,7 @@ We recently announced Tardigrade [[5](https://storj.io/blog/2019/04/introducing- -![](/blog/coordination-avoidance-on-the-storj-network/0d31ccd75012f9a8.png)*Figure 1. Storj network architecture.* +![](./0d31ccd75012f9a8.png)*Figure 1. Storj network architecture.* As shown in *Figure 1,* storage nodes and Satellites in the Storj network architecture are both capable of being decentralized. The Storj network can leverage the decentralized nature of storage nodes and Satellites to create partitions in the network to isolate users and file transfers from each other, which helps minimize coordination across the Storj network. For extremely high throughput demands, organizations can run their own Satellite. This avoids coordination overhead with the rest of the Tardigrade network and allows users to make their own decisions about what database infrastructure their Satellite will use and relax consistency guarantees if they wish. diff --git a/app/(blog)/blog/december-2020-development-update-from-storj-labs/page.md b/app/(blog)/blog/december-2020-development-update-from-storj-labs/page.md index 4e8a43ede..15ca45ec9 100644 --- a/app/(blog)/blog/december-2020-development-update-from-storj-labs/page.md +++ b/app/(blog)/blog/december-2020-development-update-from-storj-labs/page.md @@ -9,7 +9,7 @@ metadata: \ 2021. We just want to take a moment to thank our team, our users, and our community\ \ for supporting us and still being excited about what we're doing. Here's to\ \ a be..." - heroimage: /blog/december-2020-development-update-from-storj-labs/909ca9dc52fc563a.png + heroimage: ./909ca9dc52fc563a.png title: December 2020 Development Update from Storj Labs title: December 2020 Development Update from Storj Labs diff --git a/app/(blog)/blog/december-2021-storj-product-update/page.md b/app/(blog)/blog/december-2021-storj-product-update/page.md index 682cea17e..f4cf98b3c 100644 --- a/app/(blog)/blog/december-2021-storj-product-update/page.md +++ b/app/(blog)/blog/december-2021-storj-product-update/page.md @@ -6,7 +6,7 @@ layout: blog metadata: description: A brief look into what our development team at Storj has been working on this month. - heroimage: /blog/december-2021-storj-product-update/0b09f63c3c0fb3f7.png + heroimage: ./0b09f63c3c0fb3f7.png title: December 2021 Storj Product Update title: December 2021 Storj Product Update diff --git a/app/(blog)/blog/decentralized-auditing-and-repair-the-low-key-life-of-data-resurrection/page.md b/app/(blog)/blog/decentralized-auditing-and-repair-the-low-key-life-of-data-resurrection/page.md index ffc9dee0b..c6d9ab1a4 100644 --- a/app/(blog)/blog/decentralized-auditing-and-repair-the-low-key-life-of-data-resurrection/page.md +++ b/app/(blog)/blog/decentralized-auditing-and-repair-the-low-key-life-of-data-resurrection/page.md @@ -9,7 +9,7 @@ metadata: \ don\u2019t! Yes it\u2019s true that auditing does the sort of drudge work of\ \ the storage system, in that it\u2019s a continuously running process, randomly\ \ trying to downlo..." - heroimage: /blog/decentralized-auditing-and-repair-the-low-key-life-of-data-resurrection/3a7cf88738fc1956.png + heroimage: ./3a7cf88738fc1956.png title: Decentralized Auditing and Repair! The Low-key Life of Data Resurrection title: Decentralized Auditing and Repair! The Low-key Life of Data Resurrection @@ -27,7 +27,7 @@ To better understand how the auditing process works, let’s first break down th **Satellites** function as a collection of services that perform duties such as node discovery, caching node addresses, storing object metadata, recording storage node reputation, securing billing data, paying storage nodes, auditing, repairing, and managing user accounts. -![Figure 4.1 from our white paper](/blog/decentralized-auditing-and-repair-the-low-key-life-of-data-resurrection/46d5d20f2cc7cf1f.png)Figure 4.1 from our white paper. +![Figure 4.1 from our white paper](./46d5d20f2cc7cf1f.png)Figure 4.1 from our white paper. **Storage nodes** store data for others and are paid each month for the bandwidth they provide to the network and for the amount of (correct and untampered!) data they store. This creates a built-in incentive for storage nodes to behave “rationally” and not delete data upon receiving it or something, uh, unthinkable like that. Obviously we’re not naive to the fact that wild little animals do exist out there who would do such a thing. This is why we have audits and repairs. However, we do rely on the fact that majority of storage nodes are honest, upstanding nodes. @@ -45,13 +45,13 @@ We also consider **data durability**, referring to the probability of data remai It’s also important to know that when your secret garage band MP3s are first uploaded into our network, those files are first sectioned into data **segments** of a certain length. Those segments are encrypted, and then further divided into **stripes**, which are small ranges of bytes. The Uplinks use erasure encoding on stripes, which generates something called **erasure shares**. Erasure shares are the output of erasure encoding that can be processed to later reconstruct the original file. -![Animation by Moby von Briesen](/blog/decentralized-auditing-and-repair-the-low-key-life-of-data-resurrection/666fd702bcf215bb.gif)Animation by Moby von Briesen. +![Animation by Moby von Briesen](./666fd702bcf215bb.gif)Animation by Moby von Briesen. Erasure codes are also often described by two numbers, *k* and *n*. In the context of our network, *n* total erasure shares are generated for every stripe of data, and *k* number of erasure shares are required to reconstruct that stripe. For example, if we used a 20/40 scheme, encoding would generate 40 erasure shares. However it would be okay if we lose any 20 of those erasure shares to the ether because we only need any 20 to recover the original stripe. *N.B. I’ll admit right now that my title is a bit misleading, since data resurrection implies that the data was wholly dead, while the truth is that we can only re-animate data that’s 50% dead. Or other percentages of deadness depending on the erasure scheme used.* -![There's a big difference between mostly dead and all dead.](/blog/decentralized-auditing-and-repair-the-low-key-life-of-data-resurrection/c2454b1f929e0852.png)Also, the durability of a (k = 20, n = 40) erasure code is better than a (k = 10, n = 20) erasure code, even though the expansion factor is the same. This is because the risk is spread across more nodes in the (k = 20, n = 40) case. This also means that erasure coding allows us to increase data durability without increasing the cost for the end user. Check out sections 3.4 and 7.3 of our white paper for further reading about erasure code values related to data durability. +![There's a big difference between mostly dead and all dead.](./c2454b1f929e0852.png)Also, the durability of a (k = 20, n = 40) erasure code is better than a (k = 10, n = 20) erasure code, even though the expansion factor is the same. This is because the risk is spread across more nodes in the (k = 20, n = 40) case. This also means that erasure coding allows us to increase data durability without increasing the cost for the end user. Check out sections 3.4 and 7.3 of our white paper for further reading about erasure code values related to data durability. After erasure shares are generated, they’re streamed and concatenated together onto a storage node, forming something that we call a **piece**. Storage nodes can see only pieces, which look like opaque blobs to them. This is because storage nodes have no knowledge about the erasure scheme, the original files used to generate the piece, or where other pieces are stored. @@ -65,7 +65,7 @@ Zooming out a bit, this auditing process occurs as a continuous job, running at When files are uploaded and divided into segments, the Satellite creates something called a **pointer** that correlates to each segment. The pointer is a data type that contains information such as a list of pieces and their corresponding node IDs. The pointer also contains indices where erasure shares are located within a piece. Pointers are saved in the metadata database that is also located on the Satellite. The audit system’s cursor selects a random pointer. Then it selects a random stripe from this pointer and hands it off to the verifier to verify the data. -![Figure 4.2 from our white paper](/blog/decentralized-auditing-and-repair-the-low-key-life-of-data-resurrection/e3a90fac8486b39b.png)Figure 4.2 from our white paper. +![Figure 4.2 from our white paper](./e3a90fac8486b39b.png)Figure 4.2 from our white paper. While every byte stored has an equal probability of being audited, we don’t require that audits are performed on every byte or every file. We also used probabilistic testing to ensure that we’re auditing storage nodes frequently enough to have the statistical basis in determining how well-behaved they are. diff --git a/app/(blog)/blog/demystifying-technical-debt/page.md b/app/(blog)/blog/demystifying-technical-debt/page.md index f54adec7f..57aa52f8a 100644 --- a/app/(blog)/blog/demystifying-technical-debt/page.md +++ b/app/(blog)/blog/demystifying-technical-debt/page.md @@ -9,7 +9,7 @@ metadata: \ different design mistakes, code worsening over time, legacy codebases, and intentional\ \ design mistakes due to time constraints. You can take a look at the list of\ \ caus..." - heroimage: /blog/demystifying-technical-debt/dea5acde0e869ea5.png + heroimage: ./dea5acde0e869ea5.png title: Demystifying Technical Debt title: Demystifying Technical Debt @@ -17,19 +17,19 @@ title: Demystifying Technical Debt ‍ -![](/blog/demystifying-technical-debt/91daf91929515361.png) +![](./91daf91929515361.png) “Technical debt” has been bothering me for a while. It looks like a scary monster in the closet. It seems somehow a catchall for different design mistakes, code worsening over time, legacy codebases, and intentional design mistakes due to time constraints. You can take a look at the list of causes in [Wikipedia](https://en.wikipedia.org/wiki/Technical_debt#Causes) if you don’t believe me. It makes you feel like the code is collecting dust when it’s not being maintained, but clearly, that cannot be correct since the code might be unchanged. Let’s take this piece of code from "Software Tools" by Kernighan and Plauger. It has been unchanged since 1976. Has the technical debt risen for this code? When we talk about things collecting dust, the book example would have more chance of being dusty than code stored digitally. -![](/blog/demystifying-technical-debt/75c7c37ca0dd4c23.jpeg) +![](./75c7c37ca0dd4c23.jpeg) To push the metaphor to the breaking point, how do you measure technical debt, and how large is the interest? How much code would I need to write to pay off all the debt? If I have a lot of code, can I give a technical loan to other people? -![](/blog/demystifying-technical-debt/132d3b12bc22594e.png)But I digress; this unclear “technical debt” metaphor has caused bad decisions in codebases that don’t need fixing. On the other hand, not understanding it has caused people to overlook actual problems. +![](./132d3b12bc22594e.png)But I digress; this unclear “technical debt” metaphor has caused bad decisions in codebases that don’t need fixing. On the other hand, not understanding it has caused people to overlook actual problems. Before we get to tackle ***technical debt***, we need to take a slight detour. @@ -47,9 +47,9 @@ The first problem we need to tackle is ***quality***. When we are talking about * Efficiency - how many trees we need to burn to run an operation * Maintainability - how many hours and lines of code do we need to modify to add, fix or remove a feature. -![](/blog/demystifying-technical-debt/fc01c0ee8ce96871.png)When we talk about technical debt, usually, we are concerned about maintainability. There definitely are hints of the other aspects in there, but maintainability seems to be dominant. +![](./fc01c0ee8ce96871.png)When we talk about technical debt, usually, we are concerned about maintainability. There definitely are hints of the other aspects in there, but maintainability seems to be dominant. -![](/blog/demystifying-technical-debt/927230183b2dd4ce.png)One way to summarize ***maintainability*** is to treat it as “***effort needed to make a change***.” We can dissect this effort into several pieces or, in other words, places where we use up our energy: +![](./927230183b2dd4ce.png)One way to summarize ***maintainability*** is to treat it as “***effort needed to make a change***.” We can dissect this effort into several pieces or, in other words, places where we use up our energy: The most visible part is "***effort in code modification***." We can modify many different aspects of the code: @@ -88,25 +88,25 @@ It’s an obvious statement that this ***effort*** changes over time. The questi * the user interface is larger -> more things that can interact, hence more complexity; * features accumulate more cases -> which means more complex and more code. -![](/blog/demystifying-technical-debt/4fc027a938f4b0a5.png)***Understanding effort*** roughly depends on the complexity of the mental model, project, and user needs. It also depends on how much we know the system already. We can similarly estimate that it increases over time: +![](./4fc027a938f4b0a5.png)***Understanding effort*** roughly depends on the complexity of the mental model, project, and user needs. It also depends on how much we know the system already. We can similarly estimate that it increases over time: * larger number of features interact -> more complex mental model and cases to consider; * more business rules and concerns -> because we want to solve the user problems better; * knowledge of code, that isn’t being modified is forgotten -> it’s going to be harder to work with a system that you don’t know; * people come and go -> tacit knowledge is lost when a person leaves. -![](/blog/demystifying-technical-debt/fed657d8659dbc29.png)***Communication effort*** roughly depends on the number of people you need to communicate with and clarity on organization structure. Here it’s harder to pinpoint clear tendencies, but we can estimate that: +![](./fed657d8659dbc29.png)***Communication effort*** roughly depends on the number of people you need to communicate with and clarity on organization structure. Here it’s harder to pinpoint clear tendencies, but we can estimate that: * communication effort increases when a company grows * communication effort decreases when processes and company structure is clarified -![](/blog/demystifying-technical-debt/7635f7e95616d794.png)Overall, we can estimate that: +![](./7635f7e95616d794.png)Overall, we can estimate that: ***The effort to maintain a project increases without activities that actively reduce it.*** -![](/blog/demystifying-technical-debt/b06a6c08163bb49f.png)It would be easy to conclude that this “***increase in the effort***” is the “***technical debt***.” However, when we look back at the initial question about old code. +![](./b06a6c08163bb49f.png)It would be easy to conclude that this “***increase in the effort***” is the “***technical debt***.” However, when we look back at the initial question about old code. -![](/blog/demystifying-technical-debt/75c7c37ca0dd4c23.jpeg)This code has been years in a book without any new additions and no one communicating about it, but some still consider it technical debt. +![](./75c7c37ca0dd4c23.jpeg)This code has been years in a book without any new additions and no one communicating about it, but some still consider it technical debt. There must be things that we don’t take into account when thinking about technical debt. @@ -114,7 +114,7 @@ There must be things that we don’t take into account when thinking about techn One of the fundamental laws of software development is that you make mistakes. Technical debt is often associated with bad decisions in the past. Let’s get philosophical – how do we recognize mistakes? -![](/blog/demystifying-technical-debt/e2acd2ec17692723.png) +![](./e2acd2ec17692723.png) When we look at this equation, we have two parts in our head: @@ -126,17 +126,17 @@ Or in other words, there’s something that we ***perceive*** and realize that i We can apply the same line of thinking to ***effort*** and ***maintainability***. -![](/blog/demystifying-technical-debt/09f5df2707586cc9.png)Our ***ideal effort to modify*** decreases when we learn how things could be better. So, there’s a “potential improvement” that we evaluate. We could simplify this into an equation: +![](./09f5df2707586cc9.png)Our ***ideal effort to modify*** decreases when we learn how things could be better. So, there’s a “potential improvement” that we evaluate. We could simplify this into an equation: **Technical Debt ~ Perceived Effort - Ideal Effort** -![](/blog/demystifying-technical-debt/928390a574b36827.png)There are several interesting observations here. +![](./928390a574b36827.png)There are several interesting observations here. When there’s a breakthrough in technology, people realize that there’s a much better way to do something. Hence, they feel that their project has technical debt and they should fix it. Although, the effort to maintain the project hasn’t changed. Only the expectation has changed. In principle, the technical debt is higher because people learned something new. *Note, that our "ideal" may have many problems that are being overlooked*. -![](/blog/demystifying-technical-debt/afc5ffad22ef3dfa.png)Borrowing technical debt is also nicely explained with this way of thinking. Instead of perceived effort and ideal effort changing separately, they are changed together. Or in other words, we increase perceived effort while knowing that ideal effort would increase it less. +![](./afc5ffad22ef3dfa.png)Borrowing technical debt is also nicely explained with this way of thinking. Instead of perceived effort and ideal effort changing separately, they are changed together. Or in other words, we increase perceived effort while knowing that ideal effort would increase it less. -![](/blog/demystifying-technical-debt/4e80d123d00106b7.png) +![](./4e80d123d00106b7.png) This model does seem to explain technical debt quite well and gives us a nice intuition about different situations. @@ -153,7 +153,7 @@ The second question is, which changes? Is it about an arbitrary change in the co Finally, we need to consider the person evaluating because every person has some biases. Especially when dealing with “***perceived effort***” and “***ideal effort***.” -![](/blog/demystifying-technical-debt/eafa151edb719f5b.png) +![](./eafa151edb719f5b.png) For example, if the person is hyped about a language, framework, or works with a system they know well, they can easily underestimate the average effort. This is due to knowing how to solve common problems and knowing how to avoid the issues in the first place. @@ -253,7 +253,7 @@ Technical debt is not “dust” that accumulates on your code, but rather it’ **It’s just the realization that you could do better.** -![](/blog/demystifying-technical-debt/adbf52a20f1b6129.png) +![](./adbf52a20f1b6129.png) diff --git a/app/(blog)/blog/developers-and-v3-network-make-first-contact-with-vanguard-alpha/page.md b/app/(blog)/blog/developers-and-v3-network-make-first-contact-with-vanguard-alpha/page.md index d17b8e241..08790f113 100644 --- a/app/(blog)/blog/developers-and-v3-network-make-first-contact-with-vanguard-alpha/page.md +++ b/app/(blog)/blog/developers-and-v3-network-make-first-contact-with-vanguard-alpha/page.md @@ -8,7 +8,7 @@ metadata: than any other man-made object. Launched by NASA in 1958, the satellite is expected to remain in orbit for more than 200 years into the future. Its durability and resilience has been the inspiration behind our Vanguard release. J... - heroimage: /blog/developers-and-v3-network-make-first-contact-with-vanguard-alpha/ca5800089403555a.png + heroimage: ./ca5800089403555a.png title: Developers and V3 Network Make First Contact with Vanguard Alpha title: Developers and V3 Network Make First Contact with Vanguard Alpha diff --git a/app/(blog)/blog/development-update-17-from-storj-labs/page.md b/app/(blog)/blog/development-update-17-from-storj-labs/page.md index ef89c8643..3b8c049f8 100644 --- a/app/(blog)/blog/development-update-17-from-storj-labs/page.md +++ b/app/(blog)/blog/development-update-17-from-storj-labs/page.md @@ -8,7 +8,7 @@ metadata: continues to grow every day! If you haven't received an invitation to become a V3 storage node operator, and you joined the waitlist, please be patient. We currently have about 10,000 people on the list. With so many new storage n... - heroimage: /blog/development-update-17-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Development Update 17 from Storj Labs title: Development Update 17 from Storj Labs diff --git a/app/(blog)/blog/development-update-18-from-storj-labs/page.md b/app/(blog)/blog/development-update-18-from-storj-labs/page.md index 465e4b9af..e3b7e9de5 100644 --- a/app/(blog)/blog/development-update-18-from-storj-labs/page.md +++ b/app/(blog)/blog/development-update-18-from-storj-labs/page.md @@ -9,7 +9,7 @@ metadata: \ soon be releasing payments for the month of February and will send communication\ \ directly to the SNOs when they have been completed. If you are a V3 SNO and\ \ ..." - heroimage: /blog/development-update-18-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Development Update 18 from Storj Labs title: Development Update 18 from Storj Labs diff --git a/app/(blog)/blog/development-update-19-from-storj-labs/page.md b/app/(blog)/blog/development-update-19-from-storj-labs/page.md index 91464a209..3f66adc2d 100644 --- a/app/(blog)/blog/development-update-19-from-storj-labs/page.md +++ b/app/(blog)/blog/development-update-19-from-storj-labs/page.md @@ -8,7 +8,7 @@ metadata: \ getting ready for the hottest summer we've ever had! Our team is on fire and\ \ making great progress on our release roadmap. The Vanguard release is next,\ \ so be on the lookout for more information about it. If you would like to participat..." - heroimage: /blog/development-update-19-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Development Update 19 from Storj Labs title: Development Update 19 from Storj Labs diff --git a/app/(blog)/blog/development-update-20-from-storj-labs/page.md b/app/(blog)/blog/development-update-20-from-storj-labs/page.md index b7f0ae21e..10e47d328 100644 --- a/app/(blog)/blog/development-update-20-from-storj-labs/page.md +++ b/app/(blog)/blog/development-update-20-from-storj-labs/page.md @@ -8,7 +8,7 @@ metadata: Q1 of this year. Make sure to register for the event to reserve your spot! We are eager to share a synopsis of what we have accomplished this year and an overview of our 2019 plans. Our team has been burning the midnight oil to fi... - heroimage: /blog/development-update-20-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Development Update 20 from Storj Labs title: Development Update 20 from Storj Labs diff --git a/app/(blog)/blog/development-update-21-from-storj-labs/page.md b/app/(blog)/blog/development-update-21-from-storj-labs/page.md index 1b9675308..6b9109a88 100644 --- a/app/(blog)/blog/development-update-21-from-storj-labs/page.md +++ b/app/(blog)/blog/development-update-21-from-storj-labs/page.md @@ -8,7 +8,7 @@ metadata: by community members and partners uploading and downloading data on our network! If you want to get access to the Vanguard release, make sure to sign up on the waitlist. If you were unable to tune into the Q1 town hall last... - heroimage: /blog/development-update-21-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Development Update 21 from Storj Labs title: Development Update 21 from Storj Labs diff --git a/app/(blog)/blog/development-update-22-from-storj-labs/page.md b/app/(blog)/blog/development-update-22-from-storj-labs/page.md index 816f9a959..eef1e889c 100644 --- a/app/(blog)/blog/development-update-22-from-storj-labs/page.md +++ b/app/(blog)/blog/development-update-22-from-storj-labs/page.md @@ -8,7 +8,7 @@ metadata: and continue to be listed as one of the top Ethereum projects by developer activity! The Beacon release will enable clients to share objects with others, and we have a hand full of features we need to implement to make that happen... - heroimage: /blog/development-update-22-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Development Update 22 from Storj Labs title: Development Update 22 from Storj Labs diff --git a/app/(blog)/blog/development-update-23-from-storj-labs/page.md b/app/(blog)/blog/development-update-23-from-storj-labs/page.md index 8edb0ae1d..93951e1f6 100644 --- a/app/(blog)/blog/development-update-23-from-storj-labs/page.md +++ b/app/(blog)/blog/development-update-23-from-storj-labs/page.md @@ -8,7 +8,7 @@ metadata: \ the functionality needed for our next release, bacon\u2026 I mean Beacon. The\ \ functionality in this release will allow clients to share encrypted files via\ \ a cool technique called macaroons. As part of the Vanguard release, we are still..." - heroimage: /blog/development-update-23-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Development Update 23 from Storj Labs title: Development Update 23 from Storj Labs diff --git a/app/(blog)/blog/development-update-24-from-storj-labs/page.md b/app/(blog)/blog/development-update-24-from-storj-labs/page.md index 8b7775818..ab7425c77 100644 --- a/app/(blog)/blog/development-update-24-from-storj-labs/page.md +++ b/app/(blog)/blog/development-update-24-from-storj-labs/page.md @@ -9,7 +9,7 @@ metadata: \ in on our next major release Beacon, which will give our clients the ability\ \ to share files with each other, among other things. As part of the Vanguard\ \ re..." - heroimage: /blog/development-update-24-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Development Update 24 from Storj Labs title: Development Update 24 from Storj Labs diff --git a/app/(blog)/blog/development-update-25-from-storj-labs/page.md b/app/(blog)/blog/development-update-25-from-storj-labs/page.md index a6c3176be..d25122ed3 100644 --- a/app/(blog)/blog/development-update-25-from-storj-labs/page.md +++ b/app/(blog)/blog/development-update-25-from-storj-labs/page.md @@ -8,7 +8,7 @@ metadata: \ so strap in, this is a long one. Since our last update, we\u2019ve merged over\ \ 250 PRs, which equates to about 30,000 lines of code added and 10,000 lines\ \ deleted. This code is for the functionality we\u2019re building into the network..." - heroimage: /blog/development-update-25-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Development Update 25 from Storj Labs title: Development Update 25 from Storj Labs @@ -16,7 +16,7 @@ title: Development Update 25 from Storj Labs It has been almost a month since we posted our last development update, so strap in, this is a long one. Since our last update, we’ve merged over 250 PRs, which equates to about 30,000 lines of code added and 10,000 lines deleted. This code is for the functionality we’re building into the network for our Beacon and Pioneer releases. Part of our team has been focused on finishing out the last bits of functionality for Beacon, while the rest of our team has been focused on Pioneer. -![null](/blog/development-update-25-from-storj-labs/ef6762a0cfb87e44.jpeg)**Recent development accomplishments:** +![null](./ef6762a0cfb87e44.jpeg)**Recent development accomplishments:** * We finished the libuplink C library bindings. This means anyone who wants to use V3 as their data storage layer on a C application can integrate easily. * We added the ability to determine how much storage and egress (value attribution) is referred to the V3 network by our partners for our Open Source Partner Program. We are particularly proud of this because it reinforces our commitment to open source and is one way we’re trying to give back to the open source community we love. diff --git a/app/(blog)/blog/development-update-26-from-storj-labs/page.md b/app/(blog)/blog/development-update-26-from-storj-labs/page.md index 2e77ec6f8..2e256ea88 100644 --- a/app/(blog)/blog/development-update-26-from-storj-labs/page.md +++ b/app/(blog)/blog/development-update-26-from-storj-labs/page.md @@ -9,7 +9,7 @@ metadata: \ We expect we\u2019ll be launching this release in the next few weeks, so be\ \ on the lookout. From V0.14.3 to V0.15.3 releases we had over 200 PRs get merged\ \ into ..." - heroimage: /blog/development-update-26-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Development Update 26 from Storj Labs title: Development Update 26 from Storj Labs diff --git a/app/(blog)/blog/development-update-27-from-storj-labs/page.md b/app/(blog)/blog/development-update-27-from-storj-labs/page.md index ef05a6edc..5d04a2f9a 100644 --- a/app/(blog)/blog/development-update-27-from-storj-labs/page.md +++ b/app/(blog)/blog/development-update-27-from-storj-labs/page.md @@ -8,7 +8,7 @@ metadata: \ heating up here at Storj Labs! We\u2019ve been on fire adding the final features\ \ and improvements ahead of our Pioneer 1 beta launch in the next few weeks, and\ \ iced coffee and nitro cold brew are the only two things keeping us cool.Rece..." - heroimage: /blog/development-update-27-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Development Update 27 from Storj Labs title: Development Update 27 from Storj Labs diff --git a/app/(blog)/blog/development-update-28-from-storj-labs/page.md b/app/(blog)/blog/development-update-28-from-storj-labs/page.md index d283d3fd0..4f71de768 100644 --- a/app/(blog)/blog/development-update-28-from-storj-labs/page.md +++ b/app/(blog)/blog/development-update-28-from-storj-labs/page.md @@ -8,7 +8,7 @@ metadata: \ our first beta release last week while we were at Open Source Summit in San\ \ Diego. Open Source Summit has a special place in our hard drives because we\ \ love being a part of the incredibly talented, and diverse open source comm..." - heroimage: /blog/development-update-28-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Development Update 28 from Storj Labs title: Development Update 28 from Storj Labs diff --git a/app/(blog)/blog/development-update-29-from-storj-labs/page.md b/app/(blog)/blog/development-update-29-from-storj-labs/page.md index d9785240b..01fb47226 100644 --- a/app/(blog)/blog/development-update-29-from-storj-labs/page.md +++ b/app/(blog)/blog/development-update-29-from-storj-labs/page.md @@ -8,7 +8,7 @@ metadata: \ hard on functionality for our next release, Pioneer 2. Pioneer 2 will contain\ \ all of the functionality we need to launch our production service, so it\u2019\ s a major milestone. Our town hall this quarter will be held on Wednesday, Sep..." - heroimage: /blog/development-update-29-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Development Update 29 from Storj Labs title: Development Update 29 from Storj Labs diff --git a/app/(blog)/blog/development-update-30-from-storj-labs/page.md b/app/(blog)/blog/development-update-30-from-storj-labs/page.md index c3bfd4d43..ccab3bdf0 100644 --- a/app/(blog)/blog/development-update-30-from-storj-labs/page.md +++ b/app/(blog)/blog/development-update-30-from-storj-labs/page.md @@ -8,7 +8,7 @@ metadata: \ update, so strap in, we've got a lot to share! If you missed our September quarterly\ \ town hall, don't worry, we recorded it for your viewing pleasure. We also just\ \ announced a Storj IPFS integration that allows you to upl..." - heroimage: /blog/development-update-30-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Development Update 30 from Storj Labs title: Development Update 30 from Storj Labs diff --git a/app/(blog)/blog/development-update-31-from-storj-labs/page.md b/app/(blog)/blog/development-update-31-from-storj-labs/page.md index 6be111aa1..7601fbc3b 100644 --- a/app/(blog)/blog/development-update-31-from-storj-labs/page.md +++ b/app/(blog)/blog/development-update-31-from-storj-labs/page.md @@ -8,7 +8,7 @@ metadata: \ only heating up as we get closer to our Pioneer 2 and Voyager launches. Over\ \ the past couple of weeks, we\u2019ve been focused on finishing the final remaining\ \ items before our Pioneer 2 release. Pioneer 2 is a major milestone because..." - heroimage: /blog/development-update-31-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Development Update 31 from Storj Labs title: Development Update 31 from Storj Labs diff --git a/app/(blog)/blog/development-update-32-from-storj-labs/page.md b/app/(blog)/blog/development-update-32-from-storj-labs/page.md index 956be9b00..151791715 100644 --- a/app/(blog)/blog/development-update-32-from-storj-labs/page.md +++ b/app/(blog)/blog/development-update-32-from-storj-labs/page.md @@ -8,7 +8,7 @@ metadata: \ arrived. We were ranked #2 on Consensys Top 20 blockchain - Developer Activity\ \ for October. Our team has been laser-focused and its showing as we finish features\ \ for our Pioneer 2 release. The network is more stable, performant, a..." - heroimage: /blog/development-update-32-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Development Update 32 from Storj Labs title: Development Update 32 from Storj Labs diff --git a/app/(blog)/blog/development-update-33-from-storj-labs/page.md b/app/(blog)/blog/development-update-33-from-storj-labs/page.md index 4d979c5a4..2bb89575d 100644 --- a/app/(blog)/blog/development-update-33-from-storj-labs/page.md +++ b/app/(blog)/blog/development-update-33-from-storj-labs/page.md @@ -9,7 +9,7 @@ metadata: \ release and we\u2019re more excited about it than the holidays. We\u2019re still\ \ looking for more Nodes to join ahead of our Voyager release, please sign up\ \ o..." - heroimage: /blog/development-update-33-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Development Update 33 from Storj Labs title: Development Update 33 from Storj Labs diff --git a/app/(blog)/blog/development-update-34-from-storj-labs/page.md b/app/(blog)/blog/development-update-34-from-storj-labs/page.md index f469aaec7..2319ef4a4 100644 --- a/app/(blog)/blog/development-update-34-from-storj-labs/page.md +++ b/app/(blog)/blog/development-update-34-from-storj-labs/page.md @@ -8,7 +8,7 @@ metadata: for 2020 we could cry and scream at the same time. Our focus during the holiday season was finishing the final bits of functionality needed on the network ahead of the Tardigrade production launch. Our team has been onboarding our... - heroimage: /blog/development-update-34-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Development Update 34 from Storj Labs title: Development Update 34 from Storj Labs diff --git a/app/(blog)/blog/development-update-35-from-storj-labs/page.md b/app/(blog)/blog/development-update-35-from-storj-labs/page.md index 9fade33c4..33e1a7348 100644 --- a/app/(blog)/blog/development-update-35-from-storj-labs/page.md +++ b/app/(blog)/blog/development-update-35-from-storj-labs/page.md @@ -8,7 +8,7 @@ metadata: bi-weekly development updates, but during that time we did a few small things. We launched Tardigrade into GA production! Ok, it was a BIG thing. What this means is that anyone can start utilizing our decentralized cloud st... - heroimage: /blog/development-update-35-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Development Update 35 from Storj Labs title: Development Update 35 from Storj Labs diff --git a/app/(blog)/blog/development-update-36-from-storj-labs/page.md b/app/(blog)/blog/development-update-36-from-storj-labs/page.md index e821a5f98..f7965ca3d 100644 --- a/app/(blog)/blog/development-update-36-from-storj-labs/page.md +++ b/app/(blog)/blog/development-update-36-from-storj-labs/page.md @@ -8,7 +8,7 @@ metadata: attend, you can watch the video on YouTube. As with every town hall, we provided some great updates and this one included a live (well, it was live when it was recorded) demo using our Go library bindings for Tardigrade.Beyond the... - heroimage: /blog/development-update-36-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Development Update 36 from Storj Labs title: Development Update 36 from Storj Labs diff --git a/app/(blog)/blog/development-update-37-from-storj-labs/page.md b/app/(blog)/blog/development-update-37-from-storj-labs/page.md index 9de75d565..d64abfd62 100644 --- a/app/(blog)/blog/development-update-37-from-storj-labs/page.md +++ b/app/(blog)/blog/development-update-37-from-storj-labs/page.md @@ -8,7 +8,7 @@ metadata: \ As a company, we typically meet in person every quarter to fully immerse ourselves\ \ into a specific topic or goal. Last week we had a virtual all company week where\ \ we all participated in an internal hackathon. The theme was, \u201C..." - heroimage: /blog/development-update-37-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Development Update 37 from Storj Labs title: Development Update 37 from Storj Labs diff --git a/app/(blog)/blog/february-2022-product-update/page.md b/app/(blog)/blog/february-2022-product-update/page.md index e7c26af91..24717b67e 100644 --- a/app/(blog)/blog/february-2022-product-update/page.md +++ b/app/(blog)/blog/february-2022-product-update/page.md @@ -8,7 +8,7 @@ metadata: \ working hard to create new resources and communications to further elevate our\ \ transparency with you. Part of these initiatives was creating a product roadmap\ \ to give you and our community more insight into what our development team wi..." - heroimage: /blog/february-2022-product-update/3a44980925b05d58.png + heroimage: ./3a44980925b05d58.png title: February 2022 Product Update title: February 2022 Product Update diff --git a/app/(blog)/blog/finding-and-tracking-resource-leaks-in-go/page.md b/app/(blog)/blog/finding-and-tracking-resource-leaks-in-go/page.md index d63957cdd..9f778d6b2 100644 --- a/app/(blog)/blog/finding-and-tracking-resource-leaks-in-go/page.md +++ b/app/(blog)/blog/finding-and-tracking-resource-leaks-in-go/page.md @@ -8,7 +8,7 @@ metadata: a rather common issue in Go. Usually you can spot them with good code review practices, but what if you wanted to automate it and you don't have a suitable linter at hand? - heroimage: /blog/finding-and-tracking-resource-leaks-in-go/d2d97753e00bbc80.png + heroimage: ./d2d97753e00bbc80.png title: Finding and Tracking Resource Leaks in Go title: Finding and Tracking Resource Leaks in Go diff --git a/app/(blog)/blog/finding-goroutine-leaks-in-tests/page.md b/app/(blog)/blog/finding-goroutine-leaks-in-tests/page.md index 083ea589c..31b7d21fc 100644 --- a/app/(blog)/blog/finding-goroutine-leaks-in-tests/page.md +++ b/app/(blog)/blog/finding-goroutine-leaks-in-tests/page.md @@ -8,7 +8,7 @@ metadata: test can indicate several problems. Let''s first, take a look at the most common ones before tackling an approach to finding them.Problem: DeadlockFirst, we can have a goroutine that is blocked. As an example:func LeakySumSquares(c...' - heroimage: /blog/finding-goroutine-leaks-in-tests/c1245dac8cff160d.jpeg + heroimage: ./c1245dac8cff160d.jpeg title: Finding Goroutine Leaks in Tests title: Finding Goroutine Leaks in Tests diff --git a/app/(blog)/blog/flexible-file-sharing-with-macaroons/page.md b/app/(blog)/blog/flexible-file-sharing-with-macaroons/page.md index b21d3de09..c6e419600 100644 --- a/app/(blog)/blog/flexible-file-sharing-with-macaroons/page.md +++ b/app/(blog)/blog/flexible-file-sharing-with-macaroons/page.md @@ -8,7 +8,7 @@ metadata: precise, access control is a vital piece of such systems. When you store a file, you need to be able to designate whether other people or automated agents are allowed to retrieve the data, delete it, or put something else in it... - heroimage: /blog/flexible-file-sharing-with-macaroons/71499072b0db295f.jpeg + heroimage: ./71499072b0db295f.jpeg title: Flexible File Sharing With Macaroons title: Flexible File Sharing With Macaroons @@ -24,15 +24,15 @@ Let’s see how they work! Suppose you create a new project instance on the Storj network called “OlioFamilyPhotos”. The Satellite you are using gives you a token that will govern access to that project. We can think of it looking like a certificate like this: -![Macaroons are tasty!](/blog/flexible-file-sharing-with-macaroons/441ae738c61703c8.png)Any time you ask your computer to read or write files in OlioFamilyPhotos, it can send that special certificate to the Storj Satellite to prove that it’s allowed to do so. The Satellite will verify the digital signature and grant access if appropriate. You could make a copy of the certificate and share it with your spouse, if you trust them with full, unrestricted access to the project. +![Macaroons are tasty!](./441ae738c61703c8.png)Any time you ask your computer to read or write files in OlioFamilyPhotos, it can send that special certificate to the Storj Satellite to prove that it’s allowed to do so. The Satellite will verify the digital signature and grant access if appropriate. You could make a copy of the certificate and share it with your spouse, if you trust them with full, unrestricted access to the project. But you may want to allow other family members to see these photos, without being able to reorganize or delete anything (they really are busybodies sometimes). Rather than making API calls to the Storj Satellite to ask for a new token, you³ can make a copy of your existing token, cut off the signature, paste it into a bigger certificate, and add on a proviso, like this: -![But while they are good,](/blog/flexible-file-sharing-with-macaroons/79fa81cab0393039.png)You can hand out copies of this bigger certificate to family members at the next family reunion. If they want to see your photos, their computers will send this bigger certificate to the Satellite. The Satellite can still verify the digital signature—through the wonders of digital cryptography⁴—and thereby verify that the added proviso is satisfied. If your second cousin-in-law turns out to be nefarious and wants to make changes to your photos, they can’t just cut out the smaller certificate from the big one and use that, because its signature is gone. They could try to make a new bigger certificate with a weaker proviso, but they would not be able to make a valid signature because they don’t know what the original signature looked like. +![But while they are good,](./79fa81cab0393039.png)You can hand out copies of this bigger certificate to family members at the next family reunion. If they want to see your photos, their computers will send this bigger certificate to the Satellite. The Satellite can still verify the digital signature—through the wonders of digital cryptography⁴—and thereby verify that the added proviso is satisfied. If your second cousin-in-law turns out to be nefarious and wants to make changes to your photos, they can’t just cut out the smaller certificate from the big one and use that, because its signature is gone. They could try to make a new bigger certificate with a weaker proviso, but they would not be able to make a valid signature because they don’t know what the original signature looked like. Now, imagine Aunt Alice wants to share a specific one of your photos with her friend Beth. Alice values your privacy and does not want to share everything with Beth, and she also does not want Beth to be able to share the photo with anyone else. Just like what we did earlier, Alice can make a copy of her certificate, cut off the signature, paste it into a bigger certificate, and add on some provisos: -![Macaroons are not as good as macarons!](/blog/flexible-file-sharing-with-macaroons/1597845bc69c4f76.png) +![Macaroons are not as good as macarons!](./1597845bc69c4f76.png) Again, the Satellite will be able to verify this digital signature, verify that the signer knew what the signature on the intermediate certificate looked like, verify that the intermediate signature was also valid, and check that all the provisos there are satisfied before granting access. There won’t be any way for Beth to use the original root project token or the intermediate family-sharing token on their own; she will only be able to use this certificate to fetch that one specific file, and nothing else. She also won’t be able to pass on her access to anyone else, because of the “only if the bearer is Beth” proviso that has been indelibly added. diff --git a/app/(blog)/blog/go-integration-tests-with-postgres/page.md b/app/(blog)/blog/go-integration-tests-with-postgres/page.md index db7e59a75..3b62f5cae 100644 --- a/app/(blog)/blog/go-integration-tests-with-postgres/page.md +++ b/app/(blog)/blog/go-integration-tests-with-postgres/page.md @@ -8,7 +8,7 @@ metadata: need to test against a database. Let's take a look at different ways of using Postgres with different performance characteristics. The final approach shows how you can set up a clean database in 20ms (there are a few caveats). - heroimage: /blog/go-integration-tests-with-postgres/2aaa5a3adcf49612.jpeg + heroimage: ./2aaa5a3adcf49612.jpeg title: Go Integration Tests with Postgres title: Go Integration Tests with Postgres diff --git a/app/(blog)/blog/how-developers-can-easily-connect-storj-to-compute-for-presigned-urls/page.md b/app/(blog)/blog/how-developers-can-easily-connect-storj-to-compute-for-presigned-urls/page.md index c00d43fd7..f76cb9cfd 100644 --- a/app/(blog)/blog/how-developers-can-easily-connect-storj-to-compute-for-presigned-urls/page.md +++ b/app/(blog)/blog/how-developers-can-easily-connect-storj-to-compute-for-presigned-urls/page.md @@ -10,7 +10,7 @@ metadata: \ that security model to support public sharing files via the web in our Link\ \ Sharing service. Additionally, we offer S3-compatible services, including support\ \ for S3-style presigned URLs." - heroimage: /blog/how-developers-can-easily-connect-storj-to-compute-for-presigned-urls/5197073b00a85cfc.jpeg + heroimage: ./5197073b00a85cfc.jpeg title: How developers can easily connect Storj to compute for presigned URLs title: How developers can easily connect Storj to compute for presigned URLs diff --git a/app/(blog)/blog/how-to-generate-presigned-urls-for-temporary-object-access/page.md b/app/(blog)/blog/how-to-generate-presigned-urls-for-temporary-object-access/page.md index 4dbd81af8..bfb7c8778 100644 --- a/app/(blog)/blog/how-to-generate-presigned-urls-for-temporary-object-access/page.md +++ b/app/(blog)/blog/how-to-generate-presigned-urls-for-temporary-object-access/page.md @@ -5,7 +5,7 @@ date: '2022-08-02 00:00:00' layout: blog metadata: description: A tutorial on how to generate presigned urls using Storj - heroimage: /blog/how-to-generate-presigned-urls-for-temporary-object-access/a3e14220ca97c1cf.jpeg + heroimage: ./a3e14220ca97c1cf.jpeg title: How to Generate Presigned URLs for Temporary Object Access title: How to Generate Presigned URLs for Temporary Object Access @@ -35,7 +35,7 @@ Have you ever shared a photo from Google photos and inspected the link? -![](/blog/how-to-generate-presigned-urls-for-temporary-object-access/a527a3c96bbd79f9.png)You’ll notice a series of seemingly random characters. Those are what make up the special key to the data. Anyone with the key is able to view it, and since it has plenty of random characters, it would be nearly impossible for someone to guess it. +![](./a527a3c96bbd79f9.png)You’ll notice a series of seemingly random characters. Those are what make up the special key to the data. Anyone with the key is able to view it, and since it has plenty of random characters, it would be nearly impossible for someone to guess it. ‍ @@ -70,7 +70,7 @@ Here’s how to get started: * Click “Access” on the left navigation * Click “Create S3 Credentials” on the access management page -![](/blog/how-to-generate-presigned-urls-for-temporary-object-access/97fa7f494b48be83.png)* Give the credentials a name, permissions, and generate a passphrase for your data. +![](./97fa7f494b48be83.png)* Give the credentials a name, permissions, and generate a passphrase for your data. @@ -82,11 +82,11 @@ In your terminal run: Copy the “Access Key” to “AWS Access Key ID” -![](/blog/how-to-generate-presigned-urls-for-temporary-object-access/973a4592863af763.png) +![](./973a4592863af763.png) Copy the “Secret Key” to “AWS Secret Access Key” -![](/blog/how-to-generate-presigned-urls-for-temporary-object-access/9a75a2197ee11b52.png) +![](./9a75a2197ee11b52.png) Finish the configuration by entering a region name and output format (default of “None” is okay). ## Upload a file to share diff --git a/app/(blog)/blog/integrating-decentralized-cloud-storage-with-duplicati/page.md b/app/(blog)/blog/integrating-decentralized-cloud-storage-with-duplicati/page.md index d67f29442..0459354d9 100644 --- a/app/(blog)/blog/integrating-decentralized-cloud-storage-with-duplicati/page.md +++ b/app/(blog)/blog/integrating-decentralized-cloud-storage-with-duplicati/page.md @@ -9,7 +9,7 @@ metadata: \ to build a new back end for Duplicati\u2014although I do not know why there\ \ should be the need for another back end next to Tardigrade. \U0001F60AFor those\ \ who do n..." - heroimage: /blog/integrating-decentralized-cloud-storage-with-duplicati/75e382c46a1d2f4e.jpeg + heroimage: ./75e382c46a1d2f4e.jpeg title: Integrating Decentralized Cloud Storage with Duplicati title: Integrating Decentralized Cloud Storage with Duplicati @@ -27,14 +27,14 @@ Getting cold feet and fearing of data-loss? Go and start your backup to Tardigra Duplicati itself is available on GitHub for anyone to clone, fork, extend and fix. So, in order to start developing for it, clone the actual Duplicati-repository locally. I am doing this on Windows, but Linux and Mac are supported, too. Just click the "Code" Button on the GitHub-Repo [here](https://github.com/duplicati/duplicati) and choose the option that fits your developer setup. Personally I'm working with GitHub Desktop, which I find very helpful with the daily git-tasks. -![](/blog/integrating-decentralized-cloud-storage-with-duplicati/1c972875bfa093ef.png)Next, open the Duplicati solution with Visual Studio. You will find plenty of projects included. First, try to build and run Duplicati to see if something is missing. Right-click the "Duplicati.GUI.TryIcon" project and set it as start project. Hit F5 and if everything is ok the tray icon should launch from where you can enter the frontend in your browser. Further info on setting up your Duplicati development can be found [here](https://github.com/duplicati/duplicati/wiki/How-to-build-from-source). +![](./1c972875bfa093ef.png)Next, open the Duplicati solution with Visual Studio. You will find plenty of projects included. First, try to build and run Duplicati to see if something is missing. Right-click the "Duplicati.GUI.TryIcon" project and set it as start project. Hit F5 and if everything is ok the tray icon should launch from where you can enter the frontend in your browser. Further info on setting up your Duplicati development can be found [here](https://github.com/duplicati/duplicati/wiki/How-to-build-from-source). ### Let's do this If you want to create a new back end, you would have to create a new project within the solution and place it in the namespace (and path) such as “Duplicati.Library.Backend.XXX“. This newly created project then has to be added as reference to “Duplicati.GUI.TrayIcon“, “Duplicati.CommandLine“, “Duplicati.CommandLine.BackendTester“ and “Duplicati.Server“. This assures your project can be used from all relevant parts of Duplicati. Going forward, we’ll focus on the Tardigrade-Backend which—following the convention—can be found under “Duplicati.Library.Backend.Tardigrade“: -![](/blog/integrating-decentralized-cloud-storage-with-duplicati/cb021f50a47bf350.png)The first file created and the most important one is “TardigradeBackend.cs“. It contains the main logic of the back end. To get a valid back end, a class has to implement either the "IBackend“ or the "IStreamingBackend“-interface. As Storj supports async streams the Tardigrade back end implements the latter. +![](./cb021f50a47bf350.png)The first file created and the most important one is “TardigradeBackend.cs“. It contains the main logic of the back end. To get a valid back end, a class has to implement either the "IBackend“ or the "IStreamingBackend“-interface. As Storj supports async streams the Tardigrade back end implements the latter. The most important methods you have to implement for a back end to work correctly are "Put“, "Get“, "List“ and "Delete“. But by simply adding one of the two interfaces to the class makes your back end already visible to Duplicati. It then already gets added to the list of possible backup-targets, but to be really useful you would have to return values for the properties "DisplayName“ and "ProtocolKey“. The former gives your back end a name, the latter is a prefix used by Duplicati to know which configuration belongs to which back end. You might also want to provide a Description for your back end by returning a value within the "Description“ property, as the name suggests. @@ -42,7 +42,7 @@ The most important methods you have to implement for a back end to work correctl A word about localization: Duplicati is available in 43 languages currently. This is done by extracting the strings to Transifex for translation by the community. The translated texts then get automatically fetched for the current user-language. All you must do is to make sure that all your strings are routed through Duplicati.Library.Localization.Short.LC.L(). Recommended approach is to extract those strings into a static class named like the back end as seen here: -![](/blog/integrating-decentralized-cloud-storage-with-duplicati/8cec12d26906229c.png)Then use those static strings whenever you need to return a translatable string to the user. +![](./8cec12d26906229c.png)Then use those static strings whenever you need to return a translatable string to the user. ### Connect to Storj @@ -50,17 +50,17 @@ The native integration of Storj and the Tardigrade-network is done with the upli Let us have a look at the Put-Method, which uploads a file to the back end. It provides us with a stream to a temporary file and where it should be placed at the remote location. We simply handle that Stream over to UploadObjectAsync() of the ObjectService from the uplink.NET-Library: -![](/blog/integrating-decentralized-cloud-storage-with-duplicati/8e24a910b91ea921.png)Additionally we are setting some custom metadata for the LastAccess and the LastModification. This metadata is later retrieved again from the file during listing and helps Duplicati verify and handle the files. +![](./8e24a910b91ea921.png)Additionally we are setting some custom metadata for the LastAccess and the LastModification. This metadata is later retrieved again from the file during listing and helps Duplicati verify and handle the files. Downloading a file is done in a similar way–we get a stream where the file-data should be written to and the filename on the remote location. Here we are using the DownloadOperationProgressChanged-event to fill the stream with the newly received data: -![](/blog/integrating-decentralized-cloud-storage-with-duplicati/904ae59e5fa7e9f4.png)Listing files on the remote location is necessary for Duplicati to verify if an expected file is available and to successfully restore data without having any knowledge about the backup. We list all files within the bucket (and possibly within a folder) recursively and include the CustomMetadata ("Custom = true“). +![](./904ae59e5fa7e9f4.png)Listing files on the remote location is necessary for Duplicati to verify if an expected file is available and to successfully restore data without having any knowledge about the backup. We list all files within the bucket (and possibly within a folder) recursively and include the CustomMetadata ("Custom = true“). -![](/blog/integrating-decentralized-cloud-storage-with-duplicati/bc7a64c4af5a8d43.png)For that method we needed an IFileEntry-Implementation – therefore I created a "Tardigrade file“ which fetches its properties (size, name, etc.) from the underlying Storj-object (see TardigradeFile.cs). +![](./bc7a64c4af5a8d43.png)For that method we needed an IFileEntry-Implementation – therefore I created a "Tardigrade file“ which fetches its properties (size, name, etc.) from the underlying Storj-object (see TardigradeFile.cs). Finally let’s have a look at the Delete-Method, that’s really straight-forward: -![](/blog/integrating-decentralized-cloud-storage-with-duplicati/a09533201ef64080.png)To have valid access to a Storj-bucket and the included objects, we need some information from the user. Without defining the user-interface for a back end, Duplicati defaults to some generic fields. To really be useful, we need a more Tardigrade-specific UI. I will come to that in a second – let’s just quickly see how we handle those options within our Tardigrade back end. We get them within the constructor of our back end as a collection of KeyValue-Pairs, so all we must do is read and use them. +![](./a09533201ef64080.png)To have valid access to a Storj-bucket and the included objects, we need some information from the user. Without defining the user-interface for a back end, Duplicati defaults to some generic fields. To really be useful, we need a more Tardigrade-specific UI. I will come to that in a second – let’s just quickly see how we handle those options within our Tardigrade back end. We get them within the constructor of our back end as a collection of KeyValue-Pairs, so all we must do is read and use them. With Tardigrade, the user has multiple ways to get access: @@ -71,21 +71,21 @@ Besides the rough connection settings, the user has to provide a bucket name to With all that information coming from the user-interface it is quite simple—though a little verbose—to create the necessary uplink.NET-objects in the TardigradeBackend-constructor: -![](/blog/integrating-decentralized-cloud-storage-with-duplicati/b0bfc07431233b78.png)### Facing the user +![](./b0bfc07431233b78.png)### Facing the user To implement a Tardigrade-specific user interface, we must leave Visual Studio and create some additional files. In the subfolder "Duplicati/Server/webroot/ngax/templates/backends/“ I created a new file called "tardigrade.html“. To let Duplicati actually use that file, we need to supply that template-file to a JavaScript-list. This happens in the file "Duplicati/Server/webroot/ngax/scripts/services/EditUriBuiltins.js“: -![](/blog/integrating-decentralized-cloud-storage-with-duplicati/389e5f7c1c9b0d34.png)In the template-file we can now define the view shown when the user selects our back end from the list of available back ends. +![](./389e5f7c1c9b0d34.png)In the template-file we can now define the view shown when the user selects our back end from the list of available back ends. This is the view I’ve created for the Tardigrade-back end: -![](/blog/integrating-decentralized-cloud-storage-with-duplicati/c9ff56c697006e5a.png)I will not go into the details on how to create this. But I want to emphasize some things around it that help in generating nice and productive back end-views. E.g. the available Satellites in the dropdown can be provided by your back end. For this to work you must provide a class that implements the IWebModule-Interface. The Execute-Method can then be called by some JavaScript on the UI. This may happen on loading the UI like this (also in the “EditUriBuiltins.js“): +![](./c9ff56c697006e5a.png)I will not go into the details on how to create this. But I want to emphasize some things around it that help in generating nice and productive back end-views. E.g. the available Satellites in the dropdown can be provided by your back end. For this to work you must provide a class that implements the IWebModule-Interface. The Execute-Method can then be called by some JavaScript on the UI. This may happen on loading the UI like this (also in the “EditUriBuiltins.js“): -![](/blog/integrating-decentralized-cloud-storage-with-duplicati/bec4fb180016851d.png)In line 162 you can see the call into the WebModule for Tardigrade asking for all the available Satellites. Following that we also set the default values to use if they are not yet set. +![](./bec4fb180016851d.png)In line 162 you can see the call into the WebModule for Tardigrade asking for all the available Satellites. Following that we also set the default values to use if they are not yet set. To get our options from the UI into the options that Duplicati sends to our back end, we need to map the values like this: -![](/blog/integrating-decentralized-cloud-storage-with-duplicati/4f13029531e11867.png)Now we have a clean and easy to use UI for the users of our back end, that fetches some values from the WebModule and provides all selected options to our back end. +![](./4f13029531e11867.png)Now we have a clean and easy to use UI for the users of our back end, that fetches some values from the WebModule and provides all selected options to our back end. ### Summary diff --git a/app/(blog)/blog/introducing-drpc-our-replacement-for-grpc/page.md b/app/(blog)/blog/introducing-drpc-our-replacement-for-grpc/page.md index d064a7a05..1c989a611 100644 --- a/app/(blog)/blog/introducing-drpc-our-replacement-for-grpc/page.md +++ b/app/(blog)/blog/introducing-drpc-our-replacement-for-grpc/page.md @@ -17,7 +17,7 @@ metadata: we needed from gRPC (and most likely, everything you need) in under 3000 lines of Go. It now powers our full network of tens of thousands of servers and countless clients. - heroimage: /blog/introducing-drpc-our-replacement-for-grpc/e2c929baac38fe20.png + heroimage: ./e2c929baac38fe20.png title: 'Introducing DRPC: Our Replacement for gRPC' title: 'Introducing DRPC: Our Replacement for gRPC' @@ -61,7 +61,7 @@ On the other hand, DRPC’s core is under 3000 lines! It’s a reasonable task t -![](/blog/introducing-drpc-our-replacement-for-grpc/26c69fe77df6e712.png)‍ +![](./26c69fe77df6e712.png)‍ This tweet is from 2019, and as of today, in 2021, WithDefaultServiceConfig is still experimental, and WithBalancerName is still deprecated. diff --git a/app/(blog)/blog/introducing-the-storj-v3-white-paper/page.md b/app/(blog)/blog/introducing-the-storj-v3-white-paper/page.md index 541c6e35d..3f34369d5 100644 --- a/app/(blog)/blog/introducing-the-storj-v3-white-paper/page.md +++ b/app/(blog)/blog/introducing-the-storj-v3-white-paper/page.md @@ -19,7 +19,7 @@ Since Storj’s humble inception at the Texas Bitcoin Hackathon four years ago - This white paper is the culmination of a big team effort. Our hefty V2 paper weighed in at 37 pages, but our new V3 paper is even more detailed - to the tune of over 90 pages! I’ve personally read it at least 20 different times, and it’s come a long way! This paper represents the combined efforts of no fewer than 36 people, not counting additional reviewers and supporters who contributed time and effort to make this what it is. I want to extend an especially big thanks to all contributors for all of the effort they invested to make this paper a success. -![Storj White Paper Citations By Publish Date](/blog/introducing-the-storj-v3-white-paper/a04714c1c7d54b64.png)Based on decades of academic research and experience, this paper ultimately ended with nine pages of citations, the oldest of which comes all the way from 1946! Among the many lessons we learned and research we gathered, we realized that the experience that we gleaned from working with our previous network was among the most valuable. At over 150 PB of data stored, we learned what did and did not work well in designing a fault tolerant storage system. Ultimately, we are proud of the engineering effort that went into designing this paper, and are immensely grateful for the shoulders on which we stand. +![Storj White Paper Citations By Publish Date](./a04714c1c7d54b64.png)Based on decades of academic research and experience, this paper ultimately ended with nine pages of citations, the oldest of which comes all the way from 1946! Among the many lessons we learned and research we gathered, we realized that the experience that we gleaned from working with our previous network was among the most valuable. At over 150 PB of data stored, we learned what did and did not work well in designing a fault tolerant storage system. Ultimately, we are proud of the engineering effort that went into designing this paper, and are immensely grateful for the shoulders on which we stand. You’ll notice we do things a bit differently in Storj V3 than we did before and what you may have seen in other systems, so I’d like to take a minute and call out the important areas. diff --git a/app/(blog)/blog/january-2021-product-update/page.md b/app/(blog)/blog/january-2021-product-update/page.md index f7695411d..2060dae08 100644 --- a/app/(blog)/blog/january-2021-product-update/page.md +++ b/app/(blog)/blog/january-2021-product-update/page.md @@ -8,7 +8,7 @@ metadata: \ downtime during the holiday season. 2021 was a big year for Storj as we launched\ \ a brand new solution to store, stream and share data on the decentralized cloud\ \ - \_Storj DCS! Over the year, we\u2019ve added lots of customer-requested fu..." - heroimage: /blog/january-2021-product-update/3a44980925b05d58.png + heroimage: ./3a44980925b05d58.png title: January 2021 Product Update title: January 2021 Product Update diff --git a/app/(blog)/blog/july-2020-development-update-from-storj-labs/page.md b/app/(blog)/blog/july-2020-development-update-from-storj-labs/page.md index 5ca9a2532..45b242a3b 100644 --- a/app/(blog)/blog/july-2020-development-update-from-storj-labs/page.md +++ b/app/(blog)/blog/july-2020-development-update-from-storj-labs/page.md @@ -8,7 +8,7 @@ metadata: \ Storj Labs, we have been heating up just as much as the weather!\_ During the\ \ month of July, our team spent a lot of time planning for the future. We want\ \ to make our goals and roadmap are aligned with the features Storage Node Ope..." - heroimage: /blog/july-2020-development-update-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: July 2020 Development Update from Storj Labs title: July 2020 Development Update from Storj Labs diff --git a/app/(blog)/blog/july-2021-development-update-from-storj/page.md b/app/(blog)/blog/july-2021-development-update-from-storj/page.md index 15bf68520..01aa84e53 100644 --- a/app/(blog)/blog/july-2021-development-update-from-storj/page.md +++ b/app/(blog)/blog/july-2021-development-update-from-storj/page.md @@ -6,7 +6,7 @@ layout: blog metadata: description: Read about what our engineering team worked on during the month of July and what we have planned for the coming month. - heroimage: /blog/july-2021-development-update-from-storj/71d8a35b9b3f6042.png + heroimage: ./71d8a35b9b3f6042.png title: July 2021 Development Update from Storj title: July 2021 Development Update from Storj diff --git a/app/(blog)/blog/june-2021-development-update/page.md b/app/(blog)/blog/june-2021-development-update/page.md index f4b25535d..ce11a57cd 100644 --- a/app/(blog)/blog/june-2021-development-update/page.md +++ b/app/(blog)/blog/june-2021-development-update/page.md @@ -6,7 +6,7 @@ layout: blog metadata: description: Read our June 2021 Development Update to learn what we've been up to here at Storj. - heroimage: /blog/june-2021-development-update/71d8a35b9b3f6042.png + heroimage: ./71d8a35b9b3f6042.png title: June 2021 Development Update title: June 2021 Development Update diff --git a/app/(blog)/blog/may-2021-development-update-from-storj/page.md b/app/(blog)/blog/may-2021-development-update-from-storj/page.md index 451d9c8cc..59db0c076 100644 --- a/app/(blog)/blog/may-2021-development-update-from-storj/page.md +++ b/app/(blog)/blog/may-2021-development-update-from-storj/page.md @@ -8,7 +8,7 @@ metadata: \ our customers and on April 20th, 2021 we officially launched Storj DCS; Decentralized\ \ Cloud Storage for Developers. With this launch came a bunch of new features\ \ you can start utilizing to build onto Storj DCS!" - heroimage: /blog/may-2021-development-update-from-storj/71d8a35b9b3f6042.png + heroimage: ./71d8a35b9b3f6042.png title: May 2021 Development Update from Storj title: May 2021 Development Update from Storj diff --git a/app/(blog)/blog/november-2020-development-update-from-storj-labs/page.md b/app/(blog)/blog/november-2020-development-update-from-storj-labs/page.md index cd53c8d97..4062f5f86 100644 --- a/app/(blog)/blog/november-2020-development-update-from-storj-labs/page.md +++ b/app/(blog)/blog/november-2020-development-update-from-storj-labs/page.md @@ -8,7 +8,7 @@ metadata: \ hard to finish building some special features for you. The product team also\ \ wants to thank everyone who signed up for usertesting.com to help us test and\ \ validate features we\u2019re building into the product and network. The num..." - heroimage: /blog/november-2020-development-update-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: November 2020 Development Update from Storj Labs title: November 2020 Development Update from Storj Labs diff --git a/app/(blog)/blog/november-2021-storj-product-update/page.md b/app/(blog)/blog/november-2021-storj-product-update/page.md index 7922cb453..d0c0a9124 100644 --- a/app/(blog)/blog/november-2021-storj-product-update/page.md +++ b/app/(blog)/blog/november-2021-storj-product-update/page.md @@ -5,7 +5,7 @@ date: '2021-11-04 00:00:00' layout: blog metadata: description: "November 2021 Product Update,\_By the Product Team @Storj" - heroimage: /blog/november-2021-storj-product-update/3a44980925b05d58.png + heroimage: ./3a44980925b05d58.png title: November 2021 Storj Product Update title: November 2021 Storj Product Update diff --git a/app/(blog)/blog/october-2020-development-update-from-storj-labs/page.md b/app/(blog)/blog/october-2020-development-update-from-storj-labs/page.md index dea11ab6c..1d4edf9f2 100644 --- a/app/(blog)/blog/october-2020-development-update-from-storj-labs/page.md +++ b/app/(blog)/blog/october-2020-development-update-from-storj-labs/page.md @@ -8,7 +8,7 @@ metadata: from our product team so we have a lot to share with you! The global pandemic has lasted longer than many of us thought and even under these circumstances it's amazing how much our team has been able to accomplish. We've also ... - heroimage: /blog/october-2020-development-update-from-storj-labs/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: October 2020 Development Update from Storj Labs title: October 2020 Development Update from Storj Labs diff --git a/app/(blog)/blog/open-source-and-open-data-storj-dcs-network-statistics/page.md b/app/(blog)/blog/open-source-and-open-data-storj-dcs-network-statistics/page.md index e64746bcf..0bfddc960 100644 --- a/app/(blog)/blog/open-source-and-open-data-storj-dcs-network-statistics/page.md +++ b/app/(blog)/blog/open-source-and-open-data-storj-dcs-network-statistics/page.md @@ -10,7 +10,7 @@ metadata: \ on our new Storj DCS Public Network Statistics page. Now, if you\u2019re a non-technical\ \ person, this may not be what you expected. Here\u2019s an explanation of why\ \ we took this approach." - heroimage: /blog/open-source-and-open-data-storj-dcs-network-statistics/20487c1035ee937f.jpeg + heroimage: ./20487c1035ee937f.jpeg title: 'Open Source and Open Data: Storj DCS Network Statistics' title: 'Open Source and Open Data: Storj DCS Network Statistics' diff --git a/app/(blog)/blog/our-3-step-interview-process-for-engineering-candidates/page.md b/app/(blog)/blog/our-3-step-interview-process-for-engineering-candidates/page.md index f56054404..245942286 100644 --- a/app/(blog)/blog/our-3-step-interview-process-for-engineering-candidates/page.md +++ b/app/(blog)/blog/our-3-step-interview-process-for-engineering-candidates/page.md @@ -8,7 +8,7 @@ metadata: object storage service. Why would we do such a challenging thing? At a basic level, it's because we believe the internet can be better than it currently is and we see how to improve it. We believe your data is worse off being ... - heroimage: /blog/our-3-step-interview-process-for-engineering-candidates/14f72bac7573e10c.png + heroimage: ./14f72bac7573e10c.png title: Our 3-Step Interview Process for Engineering Candidates title: Our 3-Step Interview Process for Engineering Candidates diff --git a/app/(blog)/blog/product-development-update-april-2021/page.md b/app/(blog)/blog/product-development-update-april-2021/page.md index 60f748f87..7d931b4bb 100644 --- a/app/(blog)/blog/product-development-update-april-2021/page.md +++ b/app/(blog)/blog/product-development-update-april-2021/page.md @@ -6,7 +6,7 @@ layout: blog metadata: description: Read all about the latest features our engineering team has been working on. - heroimage: /blog/product-development-update-april-2021/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Product Development Update - April 2021 title: Product Development Update - April 2021 diff --git a/app/(blog)/blog/product-manager-development-update-10/page.md b/app/(blog)/blog/product-manager-development-update-10/page.md index 3f39bb267..002ea25de 100644 --- a/app/(blog)/blog/product-manager-development-update-10/page.md +++ b/app/(blog)/blog/product-manager-development-update-10/page.md @@ -9,7 +9,7 @@ metadata: \ what we are building and how it works. Most of our time has been dedicated\ \ to writing and publishing the white paper during the last several weeks, but\ \ he..." - heroimage: /blog/product-manager-development-update-10/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Product Manager Development Update 10 title: Product Manager Development Update 10 diff --git a/app/(blog)/blog/product-manager-development-update-11/page.md b/app/(blog)/blog/product-manager-development-update-11/page.md index f6b0d7110..e26ad737d 100644 --- a/app/(blog)/blog/product-manager-development-update-11/page.md +++ b/app/(blog)/blog/product-manager-development-update-11/page.md @@ -8,7 +8,7 @@ metadata: for developers), and our white paper has been published, we would love for the community to start contributing to the project. We have opened a number of GitHub issues for open source developers within the community to tackle, i... - heroimage: /blog/product-manager-development-update-11/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Product Manager Development Update 11 title: Product Manager Development Update 11 diff --git a/app/(blog)/blog/product-manager-development-update-12/page.md b/app/(blog)/blog/product-manager-development-update-12/page.md index 40c66e02b..5ef1974e7 100644 --- a/app/(blog)/blog/product-manager-development-update-12/page.md +++ b/app/(blog)/blog/product-manager-development-update-12/page.md @@ -8,7 +8,7 @@ metadata: have been busy making huge amounts of progress on the V3 network. Our next major milestone is the Explorer release, which will allow storage nodes to start joining the V3 alpha network. Most of our efforts have been focused aroun... - heroimage: /blog/product-manager-development-update-12/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Product Manager Development Update 12 title: Product Manager Development Update 12 diff --git a/app/(blog)/blog/product-manager-development-update-13/page.md b/app/(blog)/blog/product-manager-development-update-13/page.md index 0eaaa8673..d6d14d82b 100644 --- a/app/(blog)/blog/product-manager-development-update-13/page.md +++ b/app/(blog)/blog/product-manager-development-update-13/page.md @@ -8,7 +8,7 @@ metadata: \ and that's not something you can find on Amazon so we are working hard to make\ \ that happen! Our next major milestone is the Explorer release, which is scheduled\ \ to be released in Q1 of 2019, so we have shifted our focus around e..." - heroimage: /blog/product-manager-development-update-13/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Product Manager Development Update 13 title: Product Manager Development Update 13 diff --git a/app/(blog)/blog/product-manager-development-update-14/page.md b/app/(blog)/blog/product-manager-development-update-14/page.md index 28818b76d..b69f7e127 100644 --- a/app/(blog)/blog/product-manager-development-update-14/page.md +++ b/app/(blog)/blog/product-manager-development-update-14/page.md @@ -8,7 +8,7 @@ metadata: are continuing to focus our efforts around the Explorer release, which is scheduled to be released in Q1 of 2019. We want to make sure all of our storage node operators are pleasantly surprised when they join the V3 network, so ... - heroimage: /blog/product-manager-development-update-14/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Product Manager Development Update 14 title: Product Manager Development Update 14 diff --git a/app/(blog)/blog/product-manager-development-update-15/page.md b/app/(blog)/blog/product-manager-development-update-15/page.md index 72976156e..a03525c0b 100644 --- a/app/(blog)/blog/product-manager-development-update-15/page.md +++ b/app/(blog)/blog/product-manager-development-update-15/page.md @@ -8,7 +8,7 @@ metadata: accomplished so much in just the past couple of weeks! We are still focusing the majority of our time and effort on the Explorer release, the public alpha for storage node operators. This release will be very important to the ne... - heroimage: /blog/product-manager-development-update-15/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Product Manager Development Update 15 title: Product Manager Development Update 15 diff --git a/app/(blog)/blog/product-manager-development-update-16/page.md b/app/(blog)/blog/product-manager-development-update-16/page.md index e4f23daeb..2fc03b742 100644 --- a/app/(blog)/blog/product-manager-development-update-16/page.md +++ b/app/(blog)/blog/product-manager-development-update-16/page.md @@ -8,7 +8,7 @@ metadata: are sending invitations out every day to our waitlist participants, so if you joined the list be on the lookout. We had an all company meeting in Atlanta mid-January where the entire team focused its efforts on completing the rele... - heroimage: /blog/product-manager-development-update-16/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Product Manager Development Update 16 title: Product Manager Development Update 16 diff --git a/app/(blog)/blog/product-manager-development-update-4/page.md b/app/(blog)/blog/product-manager-development-update-4/page.md index df3374735..75d541728 100644 --- a/app/(blog)/blog/product-manager-development-update-4/page.md +++ b/app/(blog)/blog/product-manager-development-update-4/page.md @@ -8,7 +8,7 @@ metadata: \ Labs. Two of our leaders, Ben Golub and Shawn Wilkinson, will be giving a keynote\ \ at The Linux Foundation\u2019s Open Source Summit in Vancouver on August 29th-31st.\ \ We have been spending a lot of time getting ready for some major ann..." - heroimage: /blog/product-manager-development-update-4/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Product Manager Development Update 4 title: Product Manager Development Update 4 diff --git a/app/(blog)/blog/product-manager-development-update-5/page.md b/app/(blog)/blog/product-manager-development-update-5/page.md index 48dbac73e..82fd21156 100644 --- a/app/(blog)/blog/product-manager-development-update-5/page.md +++ b/app/(blog)/blog/product-manager-development-update-5/page.md @@ -8,7 +8,7 @@ metadata: \ Summit where Ben Golub and Shawn Wilkinson will be giving a keynote! They will\ \ make some major announcements on stage so our team has been focusing on finishing\ \ everything they need. The V3 network has made tremendous progress sinc..." - heroimage: /blog/product-manager-development-update-5/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Product Manager Development Update 5 title: Product Manager Development Update 5 diff --git a/app/(blog)/blog/product-manager-development-update-6/page.md b/app/(blog)/blog/product-manager-development-update-6/page.md index 6c40db0c8..ebb98d841 100644 --- a/app/(blog)/blog/product-manager-development-update-6/page.md +++ b/app/(blog)/blog/product-manager-development-update-6/page.md @@ -8,7 +8,7 @@ metadata: s keynote presentation at The Linux Foundation's Open Source Summit last week.\ \ At the conference, we announced our new Open Source Partner Program! Through\ \ this program, open-source projects can generate revenue when their..." - heroimage: /blog/product-manager-development-update-6/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Product Manager Development Update 6 title: Product Manager Development Update 6 diff --git a/app/(blog)/blog/product-manager-development-update-7/page.md b/app/(blog)/blog/product-manager-development-update-7/page.md index be1d16273..5e89d58f5 100644 --- a/app/(blog)/blog/product-manager-development-update-7/page.md +++ b/app/(blog)/blog/product-manager-development-update-7/page.md @@ -9,7 +9,7 @@ metadata: \ Labs and the energy of our team was through the roof. The theme for the week\ \ was \u201CThe White Paper is Coming\u201D so we spent a lot of our time writing\ \ and fi..." - heroimage: /blog/product-manager-development-update-7/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Product Manager Development Update 7 title: Product Manager Development Update 7 diff --git a/app/(blog)/blog/product-manager-development-update-8/page.md b/app/(blog)/blog/product-manager-development-update-8/page.md index 70b50bf2b..05afcdd41 100644 --- a/app/(blog)/blog/product-manager-development-update-8/page.md +++ b/app/(blog)/blog/product-manager-development-update-8/page.md @@ -8,7 +8,7 @@ metadata: had a great summer. Even though summer has come to an end, the Storj team is still running HOT and making tons of progress on the V3 network. Below is a quick update from our engineering team.Recent development accomplishments:W... - heroimage: /blog/product-manager-development-update-8/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Product Manager Development Update 8 title: Product Manager Development Update 8 diff --git a/app/(blog)/blog/product-manager-development-update-9/page.md b/app/(blog)/blog/product-manager-development-update-9/page.md index 953d8be22..a168d525d 100644 --- a/app/(blog)/blog/product-manager-development-update-9/page.md +++ b/app/(blog)/blog/product-manager-development-update-9/page.md @@ -8,7 +8,7 @@ metadata: V3 network and wanted to share a quick update. Our new white paper has also been sent out to a number of external people for peer review. Once we gather and incorporate their feedback, the next step is public release, so stay t... - heroimage: /blog/product-manager-development-update-9/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: Product Manager Development Update 9 title: Product Manager Development Update 9 diff --git a/app/(blog)/blog/production-concurrency/page.md b/app/(blog)/blog/production-concurrency/page.md index 1e08d3c0d..b2db128fd 100644 --- a/app/(blog)/blog/production-concurrency/page.md +++ b/app/(blog)/blog/production-concurrency/page.md @@ -7,7 +7,7 @@ metadata: description: Concurrency is one of those things that's easy to get wrong, even with Go concurrency features. Let's review things you should consider while writing a concurrency production code. - heroimage: /blog/production-concurrency/df0a3a1834547b61.jpeg + heroimage: ./df0a3a1834547b61.jpeg title: Production Ready Go Concurrency title: Production Ready Go Concurrency diff --git a/app/(blog)/blog/replication-is-bad-for-decentralized-storage-part-1-erasure-codes-for-fun-and-profit/page.md b/app/(blog)/blog/replication-is-bad-for-decentralized-storage-part-1-erasure-codes-for-fun-and-profit/page.md index d87d0544f..2284e6098 100644 --- a/app/(blog)/blog/replication-is-bad-for-decentralized-storage-part-1-erasure-codes-for-fun-and-profit/page.md +++ b/app/(blog)/blog/replication-is-bad-for-decentralized-storage-part-1-erasure-codes-for-fun-and-profit/page.md @@ -9,7 +9,7 @@ metadata: \ and are now working on for our near-term roadmap, and it\u2019s wonderful to\ \ finally have it out!I would have loved to go into this amount of detail during\ \ my conver..." - heroimage: /blog/replication-is-bad-for-decentralized-storage-part-1-erasure-codes-for-fun-and-profit/2990137796909c31.png + heroimage: ./2990137796909c31.png title: 'Replication is bad for decentralized storage, part 1: Erasure codes for fun and profit' title: 'Replication is bad for decentralized storage, part 1: Erasure codes for fun @@ -27,7 +27,7 @@ There are a number of potentially controversial claims our paper makes, and the In a decentralized storage network, any storage node could go offline permanently at any time. A storage network’s redundancy strategy must store data in a way that provides access with high probability, even though any given number of individual nodes may be in anoffline state. To achieve a specific level of *durability* (defined as the probability that data remains available in the face of failures), many products in this space (Filecoin, MaidSafe, Siacoin, GFS, Ceph, IPFS, etc.) by default use replication, which means simply having multiple copies of the data stored on different nodes. -![](/blog/replication-is-bad-for-decentralized-storage-part-1-erasure-codes-for-fun-and-profit/7c30dc9476d94f1a.png)Unfortunately, replication anchors durability to the network *expansion factor*, which is the storage overhead for reliably storing data. If you want more durability, you need more copies. For every increase of durability you desire, you must spend another multiple of the data size in bandwidth when storing or repairing the data, as nodes churn in and out of the network. +![](./7c30dc9476d94f1a.png)Unfortunately, replication anchors durability to the network *expansion factor*, which is the storage overhead for reliably storing data. If you want more durability, you need more copies. For every increase of durability you desire, you must spend another multiple of the data size in bandwidth when storing or repairing the data, as nodes churn in and out of the network. For example, suppose your desired durability level requires a replication strategy that makes eight copies of the data. This yields an expansion factor of 8x, or 800%. This data then needs to be stored on the network, using bandwidth in the process. Thus, more replication results in more bandwidth usage for a fixed amount of data. @@ -35,7 +35,7 @@ On the one hand, replication does make network maintenance simpler. If a node go ## Erasure Codes ? -![](/blog/replication-is-bad-for-decentralized-storage-part-1-erasure-codes-for-fun-and-profit/7dc9788a4f752cd5.png)Erasure codes are another redundancy approach, and importantly, they do not tie durability to the expansion factor. You can tune your durability without increasing the overall network traffic! +![](./7dc9788a4f752cd5.png)Erasure codes are another redundancy approach, and importantly, they do not tie durability to the expansion factor. You can tune your durability without increasing the overall network traffic! Erasure codes are widely used in both distributed and peer-to-peer storage systems. While they are more complicated and possess trade-offs of their own, the scheme we adopt, Reed-Solomon, has been around since 1960 and is used everywhere from CDs, deep space communication, barcodes, advanced RAID-like applications--you name it. @@ -45,13 +45,13 @@ If a block of data is *s* bytes large, each of the *n* erasure shares are roughl Interestingly, the durability of a *k* = 20, *n* = 40 erasure code is better than a *k* = 10, *n* = 20 erasure code, even though the expansion factor (2x) is the same for both. This is because the risk is spread across more nodes in the *k* = 20, *n* = 40 case. To help drive this point home, we calculated the durability for various erasure code configuration choices in a network with a churn of 10%. We talked more about the math behind this table in section 3.4 of [our paper](https://storj.io/storjv3.pdf), and we’ll discuss more about churn in an upcoming blog post, but suffice it to say, we hope these calculated values are illustrative: -![](/blog/replication-is-bad-for-decentralized-storage-part-1-erasure-codes-for-fun-and-profit/748c8849fba01372.png)Notice how increasing the amount of storage nodes involved increases the amount of durability significantly (each new 9 is 10x more durable), without a change in the expansion factor. We also put this data together in a graph: +![](./748c8849fba01372.png)Notice how increasing the amount of storage nodes involved increases the amount of durability significantly (each new 9 is 10x more durable), without a change in the expansion factor. We also put this data together in a graph: -![](/blog/replication-is-bad-for-decentralized-storage-part-1-erasure-codes-for-fun-and-profit/e463fccc00512f4d.png)Admittedly, this graph is a little disingenuous: the chances of you caring about having thirty-two 9s of durability is… low, to say the least. The National Weather Service [estimates](https://www.weather.gov/safety/lightning-odds) the likelihood of you not getting hit by lightning this year at only six 9s after all. But you should still be able to see that a *k* = 2, *n* = 4 is less durable than a *k* = 16, *n* = 32 configuration. +![](./e463fccc00512f4d.png)Admittedly, this graph is a little disingenuous: the chances of you caring about having thirty-two 9s of durability is… low, to say the least. The National Weather Service [estimates](https://www.weather.gov/safety/lightning-odds) the likelihood of you not getting hit by lightning this year at only six 9s after all. But you should still be able to see that a *k* = 2, *n* = 4 is less durable than a *k* = 16, *n* = 32 configuration. In contrast, replication requires significantly higher expansion factors for the same durability. The following table shows durability with a replication scheme: -![](/blog/replication-is-bad-for-decentralized-storage-part-1-erasure-codes-for-fun-and-profit/a50e169436e41d7e.png)Comparing the two tables, notice that replicating data at 10x can’t beat erasure codes with *k* = 16, *n* = 32, which is an expansion factor of only two. For durable storage, erasure codes simply require ridiculously less disk space than replication. +![](./a50e169436e41d7e.png)Comparing the two tables, notice that replicating data at 10x can’t beat erasure codes with *k* = 16, *n* = 32, which is an expansion factor of only two. For durable storage, erasure codes simply require ridiculously less disk space than replication. If you want to learn more about how erasure codes work, you can read [this introductory tutorial I co-wrote last year.](https://innovation.vivint.com/introduction-to-reed-solomon-bc264d0794f8) @@ -71,7 +71,7 @@ Erasure coding did require more CPU time, that’s true. Still, a reasonable era Erasure coding also required a designated node to do the repair. While this complicates architectures in untrusted environments, it is not an unsolvable problem. It simply requires the addition of hashes, signatures, and retries in a few new places. This is something we’ll talk about more down the road. We have a lot of blog posts to write! -![](/blog/replication-is-bad-for-decentralized-storage-part-1-erasure-codes-for-fun-and-profit/c79081350d8d6e70.png)Notably, erasure coding does *not* complicate streaming. Remember how I said erasure codes are used for satellite communication and CDs? As long as erasure coding is batched into small operations, streaming continues to work just fine. See Figure 4.2 and sections 4.1.2 and 4.8 in [our white paper](https://storj.io/storjv3.pdf) for more details about how we can pull native video streaming off. +![](./c79081350d8d6e70.png)Notably, erasure coding does *not* complicate streaming. Remember how I said erasure codes are used for satellite communication and CDs? As long as erasure coding is batched into small operations, streaming continues to work just fine. See Figure 4.2 and sections 4.1.2 and 4.8 in [our white paper](https://storj.io/storjv3.pdf) for more details about how we can pull native video streaming off. ## Upsides? diff --git a/app/(blog)/blog/september-2021-development-update/page.md b/app/(blog)/blog/september-2021-development-update/page.md index 2617888cb..5102349b2 100644 --- a/app/(blog)/blog/september-2021-development-update/page.md +++ b/app/(blog)/blog/september-2021-development-update/page.md @@ -9,7 +9,7 @@ metadata: \ Currently, we\u2019re hyper focused on the user experience for our Storj DCS\ \ customers and we\u2019re continuing to focus on the performance, security, and\ \ reliabil..." - heroimage: /blog/september-2021-development-update/8855fa2f80969623.png + heroimage: ./8855fa2f80969623.png title: September 2021 Development Update title: September 2021 Development Update diff --git a/app/(blog)/blog/so-youre-ready-for-your-first-payday-as-a-storage-node-operator/page.md b/app/(blog)/blog/so-youre-ready-for-your-first-payday-as-a-storage-node-operator/page.md index 0b570ece4..556104aae 100644 --- a/app/(blog)/blog/so-youre-ready-for-your-first-payday-as-a-storage-node-operator/page.md +++ b/app/(blog)/blog/so-youre-ready-for-your-first-payday-as-a-storage-node-operator/page.md @@ -9,7 +9,7 @@ metadata: \ you get paid! \U0001F4B8\U0001F4B8\U0001F4B8By the time this blog post is published,\ \ it will have been one month since we launched the V3 network Explorer release,\ \ the public alpha for S..." - heroimage: /blog/so-youre-ready-for-your-first-payday-as-a-storage-node-operator/f597592e440fac90.png + heroimage: ./f597592e440fac90.png title: "So You\u2019re Ready for Your First Payday as a Storage Node Operator" title: "So You\u2019re Ready for Your First Payday as a Storage Node Operator" @@ -39,11 +39,11 @@ Next, we look at the rollup service. Every 24 hours, rollup service sums the pre Every month, we generate a payment report that includes each NodeID, rollup data, operator wallet address, node creation date, and audit information. We use the node creation date to calculate [escrow withholdings](https://storj.io/blog/2019/01/sharing-storage-space-for-fun-and-profit/) and audit information to determine any disqualifications. In our example, our report for your node would show 1130.64TBh static data, 100GB\*28 days = 2.8TB egress and 10GB\*28 days = 0.28TB repair bandwidth for the month of February. Converting our static storage to TBM, we get 1130.64TBh/(24h\*28days) = 1.6825TBM. The chart below shows the data added to your node every hour, the total data on your node at the beginning of the hour, and the resulting gigabyte hours. Hour 0 represents midnight Feb 1. You can recreate the calculations in the last column using the [equation](https://bit.ly/2EtUjVk): -![](/blog/so-youre-ready-for-your-first-payday-as-a-storage-node-operator/b6b8386771375187.png)where *b* = 5 and *n* = total hours. +![](./b6b8386771375187.png)where *b* = 5 and *n* = total hours. \*\*Storage Node Static Data\*\* -![Storage Node Static Data](/blog/so-youre-ready-for-your-first-payday-as-a-storage-node-operator/2319262679a9c69e.png)Finally, it’s payday! Within 2 weeks after the end of each month, we will send STORJ tokens valued in USD to the wallet addresses provided by storage node operators. Make sure yours is correct, as there’s no way to re-send payments to an incorrect address after the fact. In our example, if you’ve been well behaved, you could expect the following payout for the month of Feb (before withholdings): +![Storage Node Static Data](./2319262679a9c69e.png)Finally, it’s payday! Within 2 weeks after the end of each month, we will send STORJ tokens valued in USD to the wallet addresses provided by storage node operators. Make sure yours is correct, as there’s no way to re-send payments to an incorrect address after the fact. In our example, if you’ve been well behaved, you could expect the following payout for the month of Feb (before withholdings): * Static: 1.6825TBM \* $1.5 = $2.52 * Egress: 2.8TB \* $20 = $56 diff --git a/app/(blog)/blog/storage-nodes-are-now-supported-on-windows-home/page.md b/app/(blog)/blog/storage-nodes-are-now-supported-on-windows-home/page.md index ee93b9d79..b718de3b5 100644 --- a/app/(blog)/blog/storage-nodes-are-now-supported-on-windows-home/page.md +++ b/app/(blog)/blog/storage-nodes-are-now-supported-on-windows-home/page.md @@ -8,7 +8,7 @@ metadata: \ Node using our native Windows installer. The new installer includes an auto-updater\ \ so you never have to worry about whether or not your Node is up to date and\ \ it also includes our brand new Node Dashboard. The Node Dashboard can..." - heroimage: /blog/storage-nodes-are-now-supported-on-windows-home/f732d96575e78699.jpeg + heroimage: ./f732d96575e78699.jpeg title: Storage Nodes Are Now Supported on Windows Home title: Storage Nodes Are Now Supported on Windows Home diff --git a/app/(blog)/blog/storj-open-development-announcement/page.md b/app/(blog)/blog/storj-open-development-announcement/page.md index 779bc1317..ba7637053 100644 --- a/app/(blog)/blog/storj-open-development-announcement/page.md +++ b/app/(blog)/blog/storj-open-development-announcement/page.md @@ -5,7 +5,7 @@ date: '2021-10-01 00:00:00' layout: blog metadata: description: Storj Open Development Announcement - heroimage: /blog/storj-open-development-announcement/10fb6f750e522e1c.png + heroimage: ./10fb6f750e522e1c.png title: Storj Open Development Announcement title: Storj Open Development Announcement diff --git a/app/(blog)/blog/storj-open-development-part-2-whats-new/page.md b/app/(blog)/blog/storj-open-development-part-2-whats-new/page.md index 91502d6e3..77f86cc6b 100644 --- a/app/(blog)/blog/storj-open-development-part-2-whats-new/page.md +++ b/app/(blog)/blog/storj-open-development-part-2-whats-new/page.md @@ -8,7 +8,7 @@ metadata: \ strategy for the storage node development efforts. The goal was to enable our\ \ community\u2014and the wider open source community\u2014to contribute to the\ \ development of the network. We started this effort by moving all node issues..." - heroimage: /blog/storj-open-development-part-2-whats-new/69c628262ae22ee5.png + heroimage: ./69c628262ae22ee5.png title: Storj Open Development -Part 2 title: Storj Open Development -Part 2 @@ -30,7 +30,7 @@ As a part of this open development initiative, before starting development the p ‍ -![](/blog/storj-open-development-part-2-whats-new/75072fcbffc78ed1.png)‍ +![](./75072fcbffc78ed1.png)‍ Team boards diff --git a/app/(blog)/blog/the-10-most-common-questions-about-decentralized-cloud-storage/page.md b/app/(blog)/blog/the-10-most-common-questions-about-decentralized-cloud-storage/page.md index dde6c0623..fe6f560f5 100644 --- a/app/(blog)/blog/the-10-most-common-questions-about-decentralized-cloud-storage/page.md +++ b/app/(blog)/blog/the-10-most-common-questions-about-decentralized-cloud-storage/page.md @@ -8,7 +8,7 @@ metadata: \ have questions about how it works and what benefits it can provide. In this\ \ post, I\u2019ll answer some of these frequently asked questions regarding Storj\u2019\ s Decentralized Cloud Storage (DCS) offering." - heroimage: /blog/the-10-most-common-questions-about-decentralized-cloud-storage/2c8582edba5fac76.png + heroimage: ./2c8582edba5fac76.png title: The 10 most common questions about decentralized cloud storage title: The 10 most common questions about decentralized cloud storage diff --git a/app/(blog)/blog/the-complexity-of-amazon-s3-and-the-simplicity-of-decentralization/page.md b/app/(blog)/blog/the-complexity-of-amazon-s3-and-the-simplicity-of-decentralization/page.md index b97e10a6c..fadaa86e6 100644 --- a/app/(blog)/blog/the-complexity-of-amazon-s3-and-the-simplicity-of-decentralization/page.md +++ b/app/(blog)/blog/the-complexity-of-amazon-s3-and-the-simplicity-of-decentralization/page.md @@ -8,7 +8,7 @@ metadata: \ dimensions. Along the way, we\u2019ll touch on the performance and security\ \ benefits distributed storage has by design, as well as the difference between\ \ Amazon S3 and the storage tiers of Storj DCS." - heroimage: /blog/the-complexity-of-amazon-s3-and-the-simplicity-of-decentralization/a3d28c91951b5f80.png + heroimage: ./a3d28c91951b5f80.png title: The Complexity of Amazon S3 and the Simplicity of Decentralization title: The Complexity of Amazon S3 and the Simplicity of Decentralization diff --git a/app/(blog)/blog/use-storj-dcs-from-cloud-native-environments-using-sidecar-pattern/page.md b/app/(blog)/blog/use-storj-dcs-from-cloud-native-environments-using-sidecar-pattern/page.md index 8bb06fa4f..a5f25ce65 100644 --- a/app/(blog)/blog/use-storj-dcs-from-cloud-native-environments-using-sidecar-pattern/page.md +++ b/app/(blog)/blog/use-storj-dcs-from-cloud-native-environments-using-sidecar-pattern/page.md @@ -9,7 +9,7 @@ metadata: \ to the nodes where the data is storedWith using S3 compatible REST API, using\ \ an S3 gateway:Either the hosted S3 gateway, operated by Storj LabsOr with running\ \ ..." - heroimage: /blog/use-storj-dcs-from-cloud-native-environments-using-sidecar-pattern/344a9e476aa2b1ea.png + heroimage: ./344a9e476aa2b1ea.png title: Use Storj DCS from Cloud-native Environments Using the Sidecar Pattern title: Use Storj DCS from Cloud-native Environments Using the Sidecar Pattern @@ -40,19 +40,19 @@ The smallest deployable unit in Kubernetes is a pod. Pod is the definition of on As the network namespace is shared inside the pod the main container can access the features of the sidecar container. -![](/blog/use-storj-dcs-from-cloud-native-environments-using-sidecar-pattern/6de1c07a519802ed.png)To follow this pattern, we should deploy a sidecar container to each of our application pods. +![](./6de1c07a519802ed.png)To follow this pattern, we should deploy a sidecar container to each of our application pods. Instead of using the hosted, multi-tenant version of the S3 gateway: -![](/blog/use-storj-dcs-from-cloud-native-environments-using-sidecar-pattern/06a4d2d7af413c6a.png) +![](./06a4d2d7af413c6a.png) We will start a single-tenant S3 gateway with each of the services: -![](/blog/use-storj-dcs-from-cloud-native-environments-using-sidecar-pattern/943dcd25f919a98b.png)## Getting Started +![](./943dcd25f919a98b.png)## Getting Started Let’s start with a simple example: we will create a Jupyter notebook which reads data from a Storj bucket for following data science calculations. @@ -76,7 +76,7 @@ To open the Jupyter web application we need the secret token which is printed ou And now we can create a new notebook where we use the Storj data: -![](/blog/use-storj-dcs-from-cloud-native-environments-using-sidecar-pattern/4b79f2e770056a31.png)To read data via S3 protocol, we need *boto*, the python S3 library, which can be added to the docker image or installed as a first step in the notebook: +![](./4b79f2e770056a31.png)To read data via S3 protocol, we need *boto*, the python S3 library, which can be added to the docker image or installed as a first step in the notebook: ‍ Next, we can read/use files directly from Storj: @@ -92,7 +92,7 @@ Let’s improve the previous example by using the sidecar pattern. First, we nee -![](/blog/use-storj-dcs-from-cloud-native-environments-using-sidecar-pattern/c911680feffbe653.png) +![](./c911680feffbe653.png) Let’s create a Kubernetes secret with all of these: @@ -118,7 +118,7 @@ Note: http://localhost:7777 is the address of the single-tenant Storj gateway wh Sidecar pattern is an easy way to access our data from Storj Decentralized Cloud Storage using the power of the native protocol, even if our application is compatible only with the S3 Rest API. -![](/blog/use-storj-dcs-from-cloud-native-environments-using-sidecar-pattern/e76c6da3bc2247e7.png) +![](./e76c6da3bc2247e7.png) diff --git a/app/(blog)/blog/using-storj-dcs-with-github-actions/page.md b/app/(blog)/blog/using-storj-dcs-with-github-actions/page.md index 8ce34589f..c02979b09 100644 --- a/app/(blog)/blog/using-storj-dcs-with-github-actions/page.md +++ b/app/(blog)/blog/using-storj-dcs-with-github-actions/page.md @@ -8,7 +8,7 @@ metadata: software development workflows in the GitHub repository. This article will inform you how to upload files to a Storj DCS bucket from a GitHub Actions workflow.The Storj DCS Public Network Stats is one of the projects at Storj wher... - heroimage: /blog/using-storj-dcs-with-github-actions/9ccdc75d22b6993e.png + heroimage: ./9ccdc75d22b6993e.png title: Using Storj DCS with GitHub Actions title: Using Storj DCS with GitHub Actions @@ -133,7 +133,7 @@ The destination bucket and the S3 credentials for s3-sync-action are configured Encrypted secrets can be configured in the “Secrets” section of the repository settings.  -![](/blog/using-storj-dcs-with-github-actions/9fae43e73a66cba0.png)All these secrets can be created via the Storj Satellite web interface. After logging in to the web interface, we make sure that the target bucket is already created. If not, the easiest way to create it is using the [Object Browser](https://docs.storj.io/dcs/getting-started/quickstart-objectbrowser). Then we set the name of the bucket as the AWS\_S3\_BUCKET secret in the Github repository. +![](./9fae43e73a66cba0.png)All these secrets can be created via the Storj Satellite web interface. After logging in to the web interface, we make sure that the target bucket is already created. If not, the easiest way to create it is using the [Object Browser](https://docs.storj.io/dcs/getting-started/quickstart-objectbrowser). Then we set the name of the bucket as the AWS\_S3\_BUCKET secret in the Github repository. Having the bucket created, next, we create S3 credentials that grant access to that bucket. This is done by [creating a new access grant from the web interface](https://docs.storj.io/dcs/getting-started/gateway-mt#generate-credentials-to-the-gateway-mt). @@ -144,13 +144,13 @@ In the Permissions dialog, we make sure to limit the access only to the target b -![](/blog/using-storj-dcs-with-github-actions/87361ca4a0a843f4.png)In the Access Grant dialog, we click on the Generate S3 Gateway Credentials button. +![](./87361ca4a0a843f4.png)In the Access Grant dialog, we click on the Generate S3 Gateway Credentials button. -![](/blog/using-storj-dcs-with-github-actions/334785fee7e124be.png)This generates the S3 credentials for the access grant that can be used with Gateway-MT. +![](./334785fee7e124be.png)This generates the S3 credentials for the access grant that can be used with Gateway-MT. -![](/blog/using-storj-dcs-with-github-actions/1da95eeb5ef706b6.png)We use these credentials to set the remaining secrets in the Github repository: +![](./1da95eeb5ef706b6.png)We use these credentials to set the remaining secrets in the Github repository: * AWS\_ACCESS\_KEY\_ID is set to the Access Key value * AWS\_SECRET\_ACCESS\_KEY is set to the Secret Key value diff --git a/app/(blog)/blog/visualizing-decentralized-data-distribution-with-the-linkshare-object-map/page.md b/app/(blog)/blog/visualizing-decentralized-data-distribution-with-the-linkshare-object-map/page.md index 48c78c2f7..0455c4878 100644 --- a/app/(blog)/blog/visualizing-decentralized-data-distribution-with-the-linkshare-object-map/page.md +++ b/app/(blog)/blog/visualizing-decentralized-data-distribution-with-the-linkshare-object-map/page.md @@ -8,7 +8,7 @@ metadata: distributed, ridiculously resilient software. The Storj Network is currently spread across over 10,000 uncorrelated endpoints, and that number is growing fast.The global substrate of diverse, uncorrelated endpoints across wh... - heroimage: /blog/visualizing-decentralized-data-distribution-with-the-linkshare-object-map/6371747a59800613.jpeg + heroimage: ./6371747a59800613.jpeg title: Visualizing Decentralized Data Distribution with the Linkshare Object Map title: Visualizing Decentralized Data Distribution with the Linkshare Object Map @@ -28,7 +28,7 @@ Through this tool—which is called the Linkshare Object Map—our team and our We set out to build the Linkshare Object Map Dashboard at the start of the two-day Storj Labs employee hackathon and quickly productized and completed the project. -![](/blog/visualizing-decentralized-data-distribution-with-the-linkshare-object-map/29e62398803ba277.png)![](/blog/visualizing-decentralized-data-distribution-with-the-linkshare-object-map/47f263c59b58c3b7.jpeg)Try it out yourself by generating access for an object, and creating a link share for the URL, [like outlined in our documentation](https://documentation.tardigrade.io/getting-started/uploading-your-first-object/view-distribution-of-an-object). This process will generate a link with a macaroon (embedded, [hash-based logic](https://storj.io/blog/2019/12/secure-access-control-in-the-decentralized-cloud/)) that controls how the object can be accessed. +![](./29e62398803ba277.png)![](./47f263c59b58c3b7.jpeg)Try it out yourself by generating access for an object, and creating a link share for the URL, [like outlined in our documentation](https://documentation.tardigrade.io/getting-started/uploading-your-first-object/view-distribution-of-an-object). This process will generate a link with a macaroon (embedded, [hash-based logic](https://storj.io/blog/2019/12/secure-access-control-in-the-decentralized-cloud/)) that controls how the object can be accessed. See an example of the Node map yourself, here: [Link share Object Map](https://bit.ly/31qVdyc) diff --git a/app/(blog)/blog/what-happens-when-you-upload-a-file-to-a-decentralized-network/page.md b/app/(blog)/blog/what-happens-when-you-upload-a-file-to-a-decentralized-network/page.md index c0a041882..33bb6dda3 100644 --- a/app/(blog)/blog/what-happens-when-you-upload-a-file-to-a-decentralized-network/page.md +++ b/app/(blog)/blog/what-happens-when-you-upload-a-file-to-a-decentralized-network/page.md @@ -9,7 +9,7 @@ metadata: \ store data on random computers around the world?\u201D \u201CThat doesn't sound\ \ secure\u2026. Is it?!?\u201D \u201CIs this a real thing?\u201D Let me tell\ \ you, it\u2019s real and it\u2019s specta..." - heroimage: /blog/what-happens-when-you-upload-a-file-to-a-decentralized-network/0b83672fb222f6ad.jpeg + heroimage: ./0b83672fb222f6ad.jpeg title: What Happens When You Upload a File to a Decentralized Network title: What Happens When You Upload a File to a Decentralized Network @@ -25,7 +25,7 @@ Let me tell you, it’s real and it’s spectacular! #### The Lifecycle of a File -![](/blog/what-happens-when-you-upload-a-file-to-a-decentralized-network/666fd702bcf215bb.gif)When files are uploaded to the Storj network, the first thing that happens is the Uplink, which runs on the local machine uploading the files to the network, determines if the file is small enough to be stored as an inline segment. I will discuss the difference between inline and remote segments later in this post but for the rest of this section assume we are referring to a remote segment. The Uplink then sends an upload request to the Satellite, which includes the Uplink’s API key so that the Satellite can validate if that Uplink is authorized to upload data to the project and bucket that it requested. If there are no issues with the authorization, the Satellite then compiles some information to send back to the Uplink. +![](./666fd702bcf215bb.gif)When files are uploaded to the Storj network, the first thing that happens is the Uplink, which runs on the local machine uploading the files to the network, determines if the file is small enough to be stored as an inline segment. I will discuss the difference between inline and remote segments later in this post but for the rest of this section assume we are referring to a remote segment. The Uplink then sends an upload request to the Satellite, which includes the Uplink’s API key so that the Satellite can validate if that Uplink is authorized to upload data to the project and bucket that it requested. If there are no issues with the authorization, the Satellite then compiles some information to send back to the Uplink. This information includes a list of storage nodes (where the data can be stored) and an order limit for the Uplink. The list of storage nodes will include nodes with varying levels of reputation, as well as the information that the Uplink needs in order to establish a connection with them such as IP/port. Check out [our blog about reputation](https://storj.io/blog/2019/01/reputation-matters-when-it-comes-to-storage-nodes/) to read more about what type of criteria determines whether a node is reliable or not, and how the network disqualifies poorly behaved nodes. The Uplink will use the order limit as proof that the Satellite authorized its uploads when the Uplink establishes connections with storage nodes. Order limits are like an empty tank that the Satellite gives the Uplink. As the Uplink uploads more data over time, that empty tank will begin to fill. Once it reaches its limit, the Uplink won't be able to upload any more, because it has reached the amount that was agreed upon with the Satellite. While this seems like a lot of back and forth, this all happens in microseconds. diff --git a/app/(blog)/blog/what-is-end-to-end-encryption/page.md b/app/(blog)/blog/what-is-end-to-end-encryption/page.md index 3e745b456..eff0fd8f0 100644 --- a/app/(blog)/blog/what-is-end-to-end-encryption/page.md +++ b/app/(blog)/blog/what-is-end-to-end-encryption/page.md @@ -7,7 +7,7 @@ metadata: description: We care deeply about security and privacy, so it's no surprise that the official Storj "uplink" client has always supported end-to-end encryption (E2E). Learn what end-to-end encryption means to us. - heroimage: /blog/what-is-end-to-end-encryption/7d93123c73021515.jpeg + heroimage: ./7d93123c73021515.jpeg title: What is End-to-End Encryption? title: What is End-to-End Encryption? diff --git a/app/(blog)/blog/what-storage-node-operators-need-to-know-about-satellites/page.md b/app/(blog)/blog/what-storage-node-operators-need-to-know-about-satellites/page.md index 040b0646c..34cc613e5 100644 --- a/app/(blog)/blog/what-storage-node-operators-need-to-know-about-satellites/page.md +++ b/app/(blog)/blog/what-storage-node-operators-need-to-know-about-satellites/page.md @@ -8,7 +8,7 @@ metadata: \ the Satellite, and the Uplink.The storage node\u2019s role is to store and return\ \ data. The Uplink is the software or service that puts and gets data onto and\ \ from the network. The role of Satellites is to act as the mediator between ..." - heroimage: /blog/what-storage-node-operators-need-to-know-about-satellites/0a307b9d9d2384d3.jpeg + heroimage: ./0a307b9d9d2384d3.jpeg title: What Storage Node Operators Need to Know About Satellites title: What Storage Node Operators Need to Know About Satellites @@ -18,7 +18,7 @@ The Storj network includes three main components: the storage node, the Satellit The storage node’s role is to store and return data. The Uplink is the software or service that puts and gets data onto and from the network. The role of Satellites is to act as the mediator between Uplinks and storage nodes, facilitating the storage interaction, and deciding which storage nodes will store what files. -![The Circle of Life on a decentralized cloud storage network](/blog/what-storage-node-operators-need-to-know-about-satellites/46d5d20f2cc7cf1f.png)The Satellite’s relationship with the storage node is an important one. The Satellite is responsible for paying the storage node for the storage and bandwidth utilized by the network. The storage node wants to store the most data it can for the network so it can make the most money and it’s heavily dependent on the Satellite for that. +![The Circle of Life on a decentralized cloud storage network](./46d5d20f2cc7cf1f.png)The Satellite’s relationship with the storage node is an important one. The Satellite is responsible for paying the storage node for the storage and bandwidth utilized by the network. The storage node wants to store the most data it can for the network so it can make the most money and it’s heavily dependent on the Satellite for that. At beta launch, Storj will be operating all the Satellites on the network, but because the software we create is open source and the network is decentralized, in the future, anyone will be able to operate a Satellite. diff --git a/utils/import-blogs.py b/utils/import-blogs.py index 4a48d8d40..b70de4e04 100644 --- a/utils/import-blogs.py +++ b/utils/import-blogs.py @@ -157,7 +157,7 @@ def persist_image(url): os.path.basename(url).split(".")[-1]) with open(os.path.join("output", slug, filename), "wb") as fh: fh.write(image_data) - return "/blog/" + slug + "/" + filename + return "./" + filename date = dateparse(parsed.find_all("div", class_="blog-details")[0].string or "1970-01-01") author = parsed.find_all("div", class_="blog-author")[0].string or "No Author"