You want a running sum of values in Column D based on a conditional value in each row of Column B.
Your scenario is VERY similar to this Webapps precedent ArrayFormula to compute running average for groups of rows. In that case, the desired result was a running average. I have modified the accepted answer by @AdamL. I have also added an alternative found on infoinspired
Assuming all entries in Column B are in sequence (grouped)
Use this formula:
Assuming all entries in Column B are NOT in sequence (grouped)
Solution from infoinspired Array Formula for Conditional Running Total in Google Sheets
MMULT function (Doc ref) is often avoided because it can slow down recalculation. It is generally accepted that it is slow with an open ended range (such as B2:B) but faster over a smaller number of rows where the range can be capped (such as B2:B8). AdamL's answer should also be read for his discussion of the pros and cons of the "MMULT" vs "non-MMULT" alternatives, including their limitations and effect of processing speed.