use crate::chain::linked_list::{ListIndex, ListWrapper, PruneableListIndex, RewindableListIndex};
use crate::chain::store::{self, ChainStore};
use crate::chain::types::CommitPos;
use crate::core::global;
use crate::util::secp::pedersen::Commitment;
use grin_chain as chain;
use grin_core as core;
use grin_store;
use grin_util as util;
mod chain_test_helper;
use self::chain_test_helper::clean_output_dir;
use crate::grin_store::Error;
fn setup_test() {
util::init_test_logger();
global::set_local_chain_type(global::ChainTypes::AutomatedTesting);
}
#[test]
fn test_store_kernel_idx() {
setup_test();
let chain_dir = ".grin_idx_1";
clean_output_dir(chain_dir);
let commit = Commitment::from_vec(vec![]);
let store = ChainStore::new(chain_dir, None).unwrap();
let mut batch = store.batch().unwrap();
let index = store::nrd_recent_kernel_index();
assert_eq!(index.peek_pos(&batch, commit), Ok(None));
assert_eq!(index.get_list(&batch, commit), Ok(None));
assert_eq!(
index.push_pos(&mut batch, commit, CommitPos { pos: 1, height: 1 }),
Ok(()),
);
assert_eq!(
index.peek_pos(&batch, commit),
Ok(Some(CommitPos { pos: 1, height: 1 })),
);
assert_eq!(
index.get_list(&batch, commit),
Ok(Some(ListWrapper::Single {
pos: CommitPos { pos: 1, height: 1 }
})),
);
assert_eq!(
index.push_pos(&mut batch, commit, CommitPos { pos: 2, height: 2 }),
Ok(()),
);
assert_eq!(
index.peek_pos(&batch, commit),
Ok(Some(CommitPos { pos: 2, height: 2 })),
);
assert_eq!(
index.get_list(&batch, commit),
Ok(Some(ListWrapper::Multi { head: 2, tail: 1 })),
);
assert_eq!(
index.push_pos(&mut batch, commit, CommitPos { pos: 1, height: 1 }),
Err(Error::OtherErr("pos must be increasing".into())),
);
assert_eq!(
index.push_pos(&mut batch, commit, CommitPos { pos: 2, height: 2 }),
Err(Error::OtherErr("pos must be increasing".into())),
);
assert_eq!(
index.push_pos(&mut batch, commit, CommitPos { pos: 3, height: 3 }),
Ok(()),
);
assert_eq!(
index.peek_pos(&batch, commit),
Ok(Some(CommitPos { pos: 3, height: 3 })),
);
assert_eq!(
index.get_list(&batch, commit),
Ok(Some(ListWrapper::Multi { head: 3, tail: 1 })),
);
assert_eq!(
index.pop_pos(&mut batch, commit),
Ok(Some(CommitPos { pos: 3, height: 3 })),
);
assert_eq!(
index.peek_pos(&batch, commit),
Ok(Some(CommitPos { pos: 2, height: 2 })),
);
assert_eq!(
index.get_list(&batch, commit),
Ok(Some(ListWrapper::Multi { head: 2, tail: 1 })),
);
assert_eq!(
index.push_pos(&mut batch, commit, CommitPos { pos: 3, height: 3 }),
Ok(()),
);
assert_eq!(
index.peek_pos(&batch, commit),
Ok(Some(CommitPos { pos: 3, height: 3 })),
);
assert_eq!(
index.get_list(&batch, commit),
Ok(Some(ListWrapper::Multi { head: 3, tail: 1 })),
);
assert_eq!(
index.pop_pos(&mut batch, commit),
Ok(Some(CommitPos { pos: 3, height: 3 })),
);
assert_eq!(
index.peek_pos(&batch, commit),
Ok(Some(CommitPos { pos: 2, height: 2 })),
);
assert_eq!(
index.get_list(&batch, commit),
Ok(Some(ListWrapper::Multi { head: 2, tail: 1 })),
);
assert_eq!(
index.pop_pos(&mut batch, commit),
Ok(Some(CommitPos { pos: 2, height: 2 })),
);
assert_eq!(
index.peek_pos(&batch, commit),
Ok(Some(CommitPos { pos: 1, height: 1 })),
);
assert_eq!(
index.get_list(&batch, commit),
Ok(Some(ListWrapper::Single {
pos: CommitPos { pos: 1, height: 1 }
})),
);
assert_eq!(
index.pop_pos(&mut batch, commit),
Ok(Some(CommitPos { pos: 1, height: 1 })),
);
assert_eq!(index.peek_pos(&batch, commit), Ok(None));
assert_eq!(index.get_list(&batch, commit), Ok(None));
clean_output_dir(chain_dir);
}
#[test]
fn test_store_kernel_idx_pop_back() {
setup_test();
let chain_dir = ".grin_idx_2";
clean_output_dir(chain_dir);
let commit = Commitment::from_vec(vec![]);
let store = ChainStore::new(chain_dir, None).unwrap();
let mut batch = store.batch().unwrap();
let index = store::nrd_recent_kernel_index();
assert_eq!(index.peek_pos(&batch, commit), Ok(None));
assert_eq!(index.get_list(&batch, commit), Ok(None));
assert_eq!(
index.push_pos(&mut batch, commit, CommitPos { pos: 1, height: 1 }),
Ok(()),
);
assert_eq!(
index.peek_pos(&batch, commit),
Ok(Some(CommitPos { pos: 1, height: 1 })),
);
assert_eq!(
index.get_list(&batch, commit),
Ok(Some(ListWrapper::Single {
pos: CommitPos { pos: 1, height: 1 }
})),
);
assert_eq!(
index.pop_pos_back(&mut batch, commit),
Ok(Some(CommitPos { pos: 1, height: 1 })),
);
assert_eq!(index.peek_pos(&batch, commit), Ok(None));
assert_eq!(index.get_list(&batch, commit), Ok(None));
assert_eq!(
index.push_pos(&mut batch, commit, CommitPos { pos: 1, height: 1 }),
Ok(()),
);
assert_eq!(
index.push_pos(&mut batch, commit, CommitPos { pos: 2, height: 2 }),
Ok(()),
);
assert_eq!(
index.push_pos(&mut batch, commit, CommitPos { pos: 3, height: 3 }),
Ok(()),
);
assert_eq!(
index.peek_pos(&mut batch, commit),
Ok(Some(CommitPos { pos: 3, height: 3 })),
);
assert_eq!(
index.get_list(&mut batch, commit),
Ok(Some(ListWrapper::Multi { head: 3, tail: 1 })),
);
assert_eq!(
index.pop_pos_back(&mut batch, commit),
Ok(Some(CommitPos { pos: 1, height: 1 })),
);
assert_eq!(
index.peek_pos(&batch, commit),
Ok(Some(CommitPos { pos: 3, height: 3 })),
);
assert_eq!(
index.get_list(&batch, commit),
Ok(Some(ListWrapper::Multi { head: 3, tail: 2 })),
);
assert_eq!(
index.pop_pos_back(&mut batch, commit),
Ok(Some(CommitPos { pos: 2, height: 2 })),
);
assert_eq!(
index.peek_pos(&batch, commit),
Ok(Some(CommitPos { pos: 3, height: 3 })),
);
assert_eq!(
index.get_list(&batch, commit),
Ok(Some(ListWrapper::Single {
pos: CommitPos { pos: 3, height: 3 }
})),
);
assert_eq!(
index.pop_pos_back(&mut batch, commit),
Ok(Some(CommitPos { pos: 3, height: 3 })),
);
assert_eq!(index.peek_pos(&batch, commit), Ok(None));
assert_eq!(index.get_list(&batch, commit), Ok(None));
clean_output_dir(chain_dir);
}
#[test]
fn test_store_kernel_idx_rewind() {
setup_test();
let chain_dir = ".grin_idx_3";
clean_output_dir(chain_dir);
let commit = Commitment::from_vec(vec![]);
let store = ChainStore::new(chain_dir, None).unwrap();
let mut batch = store.batch().unwrap();
let index = store::nrd_recent_kernel_index();
assert_eq!(
index.push_pos(&mut batch, commit, CommitPos { pos: 1, height: 1 }),
Ok(()),
);
assert_eq!(
index.push_pos(&mut batch, commit, CommitPos { pos: 2, height: 2 }),
Ok(()),
);
assert_eq!(
index.push_pos(&mut batch, commit, CommitPos { pos: 3, height: 3 }),
Ok(()),
);
assert_eq!(
index.get_list(&batch, commit),
Ok(Some(ListWrapper::Multi { head: 3, tail: 1 })),
);
assert_eq!(index.rewind(&mut batch, commit, 1), Ok(()),);
assert_eq!(
index.get_list(&batch, commit),
Ok(Some(ListWrapper::Single {
pos: CommitPos { pos: 1, height: 1 }
})),
);
assert_eq!(index.rewind(&mut batch, commit, 2), Ok(()),);
assert_eq!(
index.get_list(&batch, commit),
Ok(Some(ListWrapper::Single {
pos: CommitPos { pos: 1, height: 1 }
})),
);
assert_eq!(index.rewind(&mut batch, commit, 1), Ok(()),);
assert_eq!(
index.get_list(&batch, commit),
Ok(Some(ListWrapper::Single {
pos: CommitPos { pos: 1, height: 1 }
})),
);
assert_eq!(index.rewind(&mut batch, commit, 0), Ok(()),);
assert_eq!(index.get_list(&batch, commit), Ok(None),);
assert_eq!(index.rewind(&mut batch, commit, 0), Ok(()),);
assert_eq!(
index.push_pos(&mut batch, commit, CommitPos { pos: 1, height: 1 }),
Ok(()),
);
assert_eq!(
index.push_pos(&mut batch, commit, CommitPos { pos: 2, height: 2 }),
Ok(()),
);
assert_eq!(
index.push_pos(&mut batch, commit, CommitPos { pos: 3, height: 3 }),
Ok(()),
);
assert_eq!(
index.pop_pos_back(&mut batch, commit),
Ok(Some(CommitPos { pos: 1, height: 1 })),
);
assert_eq!(
index.get_list(&mut batch, commit),
Ok(Some(ListWrapper::Multi { head: 3, tail: 2 })),
);
assert_eq!(index.rewind(&mut batch, commit, 1), Ok(()),);
assert_eq!(index.get_list(&mut batch, commit), Ok(None),);
clean_output_dir(chain_dir);
}
#[test]
fn test_store_kernel_idx_multiple_commits() {
setup_test();
let chain_dir = ".grin_idx_4";
clean_output_dir(chain_dir);
let commit = Commitment::from_vec(vec![]);
let commit2 = Commitment::from_vec(vec![1]);
let store = ChainStore::new(chain_dir, None).unwrap();
let mut batch = store.batch().unwrap();
let index = store::nrd_recent_kernel_index();
assert_eq!(index.get_list(&batch, commit), Ok(None));
assert_eq!(index.get_list(&batch, commit2), Ok(None));
assert_eq!(
index.push_pos(&mut batch, commit, CommitPos { pos: 1, height: 1 }),
Ok(()),
);
assert_eq!(
index.get_list(&batch, commit),
Ok(Some(ListWrapper::Single {
pos: CommitPos { pos: 1, height: 1 }
})),
);
assert_eq!(index.get_list(&batch, commit2), Ok(None));
assert_eq!(
index.push_pos(&mut batch, commit2, CommitPos { pos: 2, height: 2 }),
Ok(()),
);
assert_eq!(
index.get_list(&batch, commit),
Ok(Some(ListWrapper::Single {
pos: CommitPos { pos: 1, height: 1 }
})),
);
assert_eq!(
index.get_list(&batch, commit2),
Ok(Some(ListWrapper::Single {
pos: CommitPos { pos: 2, height: 2 }
})),
);
assert_eq!(
index.push_pos(&mut batch, commit, CommitPos { pos: 3, height: 3 }),
Ok(()),
);
assert_eq!(
index.get_list(&batch, commit),
Ok(Some(ListWrapper::Multi { head: 3, tail: 1 })),
);
assert_eq!(
index.get_list(&batch, commit2),
Ok(Some(ListWrapper::Single {
pos: CommitPos { pos: 2, height: 2 }
})),
);
assert_eq!(
index.pop_pos(&mut batch, commit),
Ok(Some(CommitPos { pos: 3, height: 3 })),
);
assert_eq!(
index.get_list(&batch, commit),
Ok(Some(ListWrapper::Single {
pos: CommitPos { pos: 1, height: 1 }
})),
);
assert_eq!(
index.get_list(&batch, commit2),
Ok(Some(ListWrapper::Single {
pos: CommitPos { pos: 2, height: 2 }
})),
);
clean_output_dir(chain_dir);
}
#[test]
fn test_store_kernel_idx_clear() -> Result<(), Error> {
setup_test();
let chain_dir = ".grin_idx_clear";
clean_output_dir(chain_dir);
let commit = Commitment::from_vec(vec![]);
let commit2 = Commitment::from_vec(vec![1]);
let store = ChainStore::new(chain_dir, None)?;
let index = store::nrd_recent_kernel_index();
{
let mut batch = store.batch()?;
assert_eq!(index.peek_pos(&batch, commit), Ok(None));
assert_eq!(index.get_list(&batch, commit), Ok(None));
assert_eq!(
index.push_pos(&mut batch, commit, CommitPos { pos: 1, height: 1 }),
Ok(()),
);
assert_eq!(
index.push_pos(
&mut batch,
commit2,
CommitPos {
pos: 10,
height: 10
}
),
Ok(()),
);
assert_eq!(
index.peek_pos(&batch, commit),
Ok(Some(CommitPos { pos: 1, height: 1 })),
);
assert_eq!(
index.get_list(&batch, commit),
Ok(Some(ListWrapper::Single {
pos: CommitPos { pos: 1, height: 1 }
})),
);
assert_eq!(
index.peek_pos(&batch, commit2),
Ok(Some(CommitPos {
pos: 10,
height: 10
})),
);
assert_eq!(
index.get_list(&batch, commit2),
Ok(Some(ListWrapper::Single {
pos: CommitPos {
pos: 10,
height: 10
}
})),
);
batch.commit()?;
}
{
let mut batch = store.batch()?;
assert_eq!(index.clear(&mut batch), Ok(()));
assert_eq!(index.peek_pos(&batch, commit), Ok(None));
assert_eq!(index.get_list(&batch, commit), Ok(None));
assert_eq!(index.peek_pos(&batch, commit2), Ok(None));
assert_eq!(index.get_list(&batch, commit2), Ok(None));
batch.commit()?;
}
{
let mut batch = store.batch()?;
assert_eq!(
index.push_pos(&mut batch, commit, CommitPos { pos: 1, height: 1 }),
Ok(()),
);
assert_eq!(
index.push_pos(&mut batch, commit, CommitPos { pos: 2, height: 2 }),
Ok(()),
);
assert_eq!(
index.peek_pos(&batch, commit),
Ok(Some(CommitPos { pos: 2, height: 2 })),
);
assert_eq!(
index.get_list(&batch, commit),
Ok(Some(ListWrapper::Multi { head: 2, tail: 1 })),
);
batch.commit()?;
}
{
let mut batch = store.batch()?;
assert_eq!(index.clear(&mut batch), Ok(()));
assert_eq!(index.peek_pos(&batch, commit), Ok(None));
assert_eq!(index.get_list(&batch, commit), Ok(None));
batch.commit()?;
}
clean_output_dir(chain_dir);
Ok(())
}