Skip to content

Commit 9117d4d

Browse files
Stebalienarajasek
andauthored
fix: make flush match lotus as much as possible (#586)
* fix: make flush match lotus as much as possible 1. Reject anything we don't expect. 2. Properly handle identity cids. * fix: typos. Co-authored-by: Aayush Rajasekaran <arajasek94@gmail.com> Co-authored-by: Aayush Rajasekaran <arajasek94@gmail.com>
1 parent 788802e commit 9117d4d

File tree

1 file changed

+50
-21
lines changed

1 file changed

+50
-21
lines changed

fvm/src/blockstore/buffered.rs

Lines changed: 50 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use anyhow::{anyhow, Result};
55
use byteorder::{BigEndian, ByteOrder, ReadBytesExt};
66
use cid::Cid;
77
use fvm_ipld_blockstore::{Blockstore, Buffered};
8+
use fvm_shared::commcid::{FIL_COMMITMENT_SEALED, FIL_COMMITMENT_UNSEALED};
89

910
// TODO: figure out where to put this.
1011
const DAG_CBOR: u64 = 0x71;
@@ -171,31 +172,59 @@ fn copy_rec<'a>(
171172
root: Cid,
172173
buffer: &mut Vec<(Cid, &'a [u8])>,
173174
) -> Result<()> {
174-
// TODO: Make this non-recursive.
175-
// Skip identity and Filecoin commitment Cids
176-
if root.codec() != DAG_CBOR {
177-
return Ok(());
178-
}
179-
180-
let block = &*cache
181-
.get(&root)
182-
.ok_or_else(|| anyhow!("Invalid link ({}) in flushing buffered store", root))?;
183-
184-
scan_for_links(&mut Cursor::new(block), |link| {
185-
if link.codec() != DAG_CBOR {
186-
return Ok(());
175+
const DAG_RAW: u64 = 0x55;
176+
const BLAKE2B_256: u64 = 0xb220;
177+
const BLAKE2B_LEN: u8 = 32;
178+
const IDENTITY: u64 = 0x0;
179+
180+
// Differences from lotus (vm.Copy):
181+
// 1. We assume that if we don't have a block in our buffer, it must already be in the client.
182+
// don't check. This should only happen if the lotus node is missing state.
183+
// 2. We always write-back new blocks, even if lotus already has them. We haven't noticed a perf
184+
// impact.
185+
186+
match (root.codec(), root.hash().code(), root.hash().size()) {
187+
// Allow non-truncated blake2b-256 raw/cbor (code/state)
188+
(DAG_RAW | DAG_CBOR, BLAKE2B_256, BLAKE2B_LEN) => (),
189+
// Ignore raw identity cids (fake code cids)
190+
(DAG_RAW, IDENTITY, _) => return Ok(()),
191+
// Copy links from cbor identity cids.
192+
// We shouldn't be creating these at the moment, but lotus' vm.Copy supports them.
193+
(DAG_CBOR, IDENTITY, _) => {
194+
return scan_for_links(&mut Cursor::new(root.hash().digest()), |link| {
195+
copy_rec(cache, link, buffer)
196+
})
187197
}
188-
189-
// DB reads are expensive. So we check if it exists in the cache.
190-
// If it doesnt exist in the DB, which is likely, we proceed with using the cache.
191-
if !cache.contains_key(&link) {
192-
return Ok(());
198+
// Ignore commitments (not even going to check the hash function.
199+
(FIL_COMMITMENT_UNSEALED | FIL_COMMITMENT_SEALED, _, _) => return Ok(()),
200+
// Fail on anything else. We usually want to continue on error, but there's really no going
201+
// back from here.
202+
(codec, hash, length) => {
203+
return Err(anyhow!(
204+
"cid {root} has unexpected codec ({codec}), hash ({hash}), or length ({length})"
205+
))
193206
}
207+
}
194208

195-
// Recursively find more links under the links we're iterating over.
196-
copy_rec(cache, link, buffer)
197-
})?;
209+
// If we don't have the block, we assume it's already in the datastore.
210+
//
211+
// The alternative would be to check if it's in the datastore, but that's likely even more
212+
// expensive. And there wouldn't be much we could do at that point but abort the block.
213+
let block = match cache.get(&root) {
214+
Some(blk) => blk,
215+
None => return Ok(()),
216+
};
217+
218+
// At the moment, we only expect dag-cbor and raw.
219+
// In M2, we'll need to copy explicitly.
220+
if root.codec() == DAG_CBOR {
221+
// TODO: Make this non-recursive.
222+
scan_for_links(&mut Cursor::new(block), |link| {
223+
copy_rec(cache, link, buffer)
224+
})?;
225+
}
198226

227+
// Finally, push the block. We do this _last_ so that we always include write before parents.
199228
buffer.push((root, block));
200229

201230
Ok(())

0 commit comments

Comments
 (0)