blockchain.rs 79.8 KiB
Newer Older
			logs: vec![
				LogEntry { address: Default::default(), topics: vec![], data: vec![3], },
			],
		}]);
		insert_block(&db, &bc, &b2, vec![
			Receipt {
				state_root: Some(H256::default()),
				gas_used: 10_000.into(),
				log_bloom: Default::default(),
				logs: vec![
					LogEntry { address: Default::default(), topics: vec![], data: vec![4], },
				],
			}
		]);

		// when
		let block1 = BlockView::new(&b1);
		let block2 = BlockView::new(&b2);
		let logs1 = bc.logs(vec![1, 2], |_| true, None);
		let logs2 = bc.logs(vec![1, 2], |_| true, Some(1));

		// then
		assert_eq!(logs1, vec![
			LocalizedLogEntry {
				entry: LogEntry { address: Default::default(), topics: vec![], data: vec![1] },
				block_hash: block1.hash(),
				block_number: block1.header().number(),
				transaction_hash: tx_hash1.clone(),
				transaction_index: 0,
				transaction_log_index: 0,
				log_index: 0,
			},
			LocalizedLogEntry {
				entry: LogEntry { address: Default::default(), topics: vec![], data: vec![2] },
				block_hash: block1.hash(),
				block_number: block1.header().number(),
				transaction_hash: tx_hash1.clone(),
				transaction_index: 0,
				transaction_log_index: 1,
				log_index: 1,
			},
			LocalizedLogEntry {
				entry: LogEntry { address: Default::default(), topics: vec![], data: vec![3] },
				block_hash: block1.hash(),
				block_number: block1.header().number(),
				transaction_hash: tx_hash2.clone(),
				transaction_index: 1,
				transaction_log_index: 0,
				log_index: 2,
			},
			LocalizedLogEntry {
				entry: LogEntry { address: Default::default(), topics: vec![], data: vec![4] },
				block_hash: block2.hash(),
				block_number: block2.header().number(),
				transaction_hash: tx_hash3.clone(),
				transaction_index: 0,
				transaction_log_index: 0,
				log_index: 0,
			}
		]);
		assert_eq!(logs2, vec![
			LocalizedLogEntry {
				entry: LogEntry { address: Default::default(), topics: vec![], data: vec![4] },
				block_hash: block2.hash(),
				block_number: block2.header().number(),
				transaction_hash: tx_hash3.clone(),
				transaction_index: 0,
				transaction_log_index: 0,
	#[test]
	fn test_bloom_filter_simple() {
		// TODO: From here
		let bloom_b1: H2048 = "00000020000000000000000000000000000000000000000002000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000002000".into();
		let bloom_b2: H2048 = "00000000000000000000000000000000000000000000020000001000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".into();
		let bloom_ba: H2048 = "00000000000000000000000000000000000000000000020000000800000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".into();
		let mut canon_chain = ChainGenerator::default();
		let mut finalizer = BlockFinalizer::default();
		let genesis = canon_chain.generate(&mut finalizer).unwrap();
		let mut fork = canon_chain.fork(1);
		let mut fork_finalizer = finalizer.fork();
		let b1 = fork.with_bloom(bloom_b1.clone()).generate(&mut fork_finalizer).unwrap();
		let b2 = fork.with_bloom(bloom_b2.clone()).generate(&mut fork_finalizer).unwrap();
		let b3 = fork.with_bloom(bloom_ba.clone()).generate(&mut fork_finalizer).unwrap();
		let b1a = canon_chain.with_bloom(bloom_ba.clone()).generate(&mut finalizer).unwrap();
		let b2a = canon_chain.with_bloom(bloom_ba.clone()).generate(&mut finalizer).unwrap();

keorn's avatar
keorn committed
		let bc = new_chain(&genesis, db.clone());
Marek Kotewicz's avatar
Marek Kotewicz committed
		let blocks_b1 = bc.blocks_with_bloom(&bloom_b1, 0, 5);
		let blocks_b2 = bc.blocks_with_bloom(&bloom_b2, 0, 5);
Tomasz Drwięga's avatar
Tomasz Drwięga committed
		assert_eq!(blocks_b1, Vec::<BlockNumber>::new());
		assert_eq!(blocks_b2, Vec::<BlockNumber>::new());
Tomasz Drwięga's avatar
Tomasz Drwięga committed
		insert_block(&db, &bc, &b1, vec![]);
Marek Kotewicz's avatar
Marek Kotewicz committed
		let blocks_b1 = bc.blocks_with_bloom(&bloom_b1, 0, 5);
		let blocks_b2 = bc.blocks_with_bloom(&bloom_b2, 0, 5);
		assert_eq!(blocks_b1, vec![1]);
Tomasz Drwięga's avatar
Tomasz Drwięga committed
		assert_eq!(blocks_b2, Vec::<BlockNumber>::new());
Tomasz Drwięga's avatar
Tomasz Drwięga committed
		insert_block(&db, &bc, &b2, vec![]);
Marek Kotewicz's avatar
Marek Kotewicz committed
		let blocks_b1 = bc.blocks_with_bloom(&bloom_b1, 0, 5);
		let blocks_b2 = bc.blocks_with_bloom(&bloom_b2, 0, 5);
		assert_eq!(blocks_b1, vec![1]);
		assert_eq!(blocks_b2, vec![2]);
Tomasz Drwięga's avatar
Tomasz Drwięga committed
		insert_block(&db, &bc, &b1a, vec![]);
Marek Kotewicz's avatar
Marek Kotewicz committed
		let blocks_b1 = bc.blocks_with_bloom(&bloom_b1, 0, 5);
		let blocks_b2 = bc.blocks_with_bloom(&bloom_b2, 0, 5);
		let blocks_ba = bc.blocks_with_bloom(&bloom_ba, 0, 5);
		assert_eq!(blocks_b1, vec![1]);
		assert_eq!(blocks_b2, vec![2]);
Tomasz Drwięga's avatar
Tomasz Drwięga committed
		assert_eq!(blocks_ba, Vec::<BlockNumber>::new());
Tomasz Drwięga's avatar
Tomasz Drwięga committed
		insert_block(&db, &bc, &b2a, vec![]);
Marek Kotewicz's avatar
Marek Kotewicz committed
		let blocks_b1 = bc.blocks_with_bloom(&bloom_b1, 0, 5);
		let blocks_b2 = bc.blocks_with_bloom(&bloom_b2, 0, 5);
		let blocks_ba = bc.blocks_with_bloom(&bloom_ba, 0, 5);
Tomasz Drwięga's avatar
Tomasz Drwięga committed
		assert_eq!(blocks_b1, Vec::<BlockNumber>::new());
		assert_eq!(blocks_b2, Vec::<BlockNumber>::new());
		assert_eq!(blocks_ba, vec![1, 2]);
Marek Kotewicz's avatar
Marek Kotewicz committed

		// fork back
Tomasz Drwięga's avatar
Tomasz Drwięga committed
		insert_block(&db, &bc, &b3, vec![]);
Marek Kotewicz's avatar
Marek Kotewicz committed
		let blocks_b1 = bc.blocks_with_bloom(&bloom_b1, 0, 5);
		let blocks_b2 = bc.blocks_with_bloom(&bloom_b2, 0, 5);
		let blocks_ba = bc.blocks_with_bloom(&bloom_ba, 0, 5);
		assert_eq!(blocks_b1, vec![1]);
		assert_eq!(blocks_b2, vec![2]);
		assert_eq!(blocks_ba, vec![3]);

	#[test]
	fn test_best_block_update() {
		let mut canon_chain = ChainGenerator::default();
		let mut finalizer = BlockFinalizer::default();
		let genesis = canon_chain.generate(&mut finalizer).unwrap();

keorn's avatar
keorn committed
			let bc = new_chain(&genesis, db.clone());
			let uncle = canon_chain.fork(1).generate(&mut finalizer.fork()).unwrap();

			let mut batch = db.transaction();
			// create a longer fork
			for _ in 0..5 {
				let canon_block = canon_chain.generate(&mut finalizer).unwrap();
				bc.insert_block(&mut batch, &canon_block, vec![]);
			}

			assert_eq!(bc.best_block_number(), 5);
			bc.insert_block(&mut batch, &uncle, vec![]);
Tomasz Drwięga's avatar
Tomasz Drwięga committed
			db.write(batch).unwrap();
		}

		// re-loading the blockchain should load the correct best block.
		let bc = new_chain(&genesis, db);
		assert_eq!(bc.best_block_number(), 5);
	}

	#[test]
	fn test_rewind() {
		let mut canon_chain = ChainGenerator::default();
		let mut finalizer = BlockFinalizer::default();
		let genesis = canon_chain.generate(&mut finalizer).unwrap();
		let first = canon_chain.generate(&mut finalizer).unwrap();
		let second = canon_chain.generate(&mut finalizer).unwrap();
		let genesis_hash = BlockView::new(&genesis).header_view().sha3();
		let first_hash = BlockView::new(&first).header_view().sha3();
		let second_hash = BlockView::new(&second).header_view().sha3();

keorn's avatar
keorn committed
		let bc = new_chain(&genesis, db.clone());
		let mut batch =db.transaction();
		bc.insert_block(&mut batch, &first, vec![]);
		bc.insert_block(&mut batch, &second, vec![]);
Tomasz Drwięga's avatar
Tomasz Drwięga committed
		db.write(batch).unwrap();

		assert_eq!(bc.rewind(), Some(first_hash.clone()));
		assert!(!bc.is_known(&second_hash));
		assert_eq!(bc.best_block_number(), 1);
		assert_eq!(bc.best_block_hash(), first_hash.clone());

		assert_eq!(bc.rewind(), Some(genesis_hash.clone()));
		assert_eq!(bc.rewind(), None);
	}

	#[test]
	fn epoch_transitions_iter() {
		use blockchain::extras::EpochTransition;

		let mut canon_chain = ChainGenerator::default();
		let mut finalizer = BlockFinalizer::default();
		let genesis = canon_chain.generate(&mut finalizer).unwrap();

		let db = new_db();
		{
			let bc = new_chain(&genesis, db.clone());
			let uncle = canon_chain.fork(1).generate(&mut finalizer.fork()).unwrap();

			let mut batch = db.transaction();
			// create a longer fork
			for i in 0..5 {
				let canon_block = canon_chain.generate(&mut finalizer).unwrap();
				let hash = BlockView::new(&canon_block).header_view().sha3();

				bc.insert_block(&mut batch, &canon_block, vec![]);
				bc.insert_epoch_transition(&mut batch, i, EpochTransition {
					block_hash: hash,
					block_number: i + 1,
					proof: vec![],
					state_proof: vec![],
				});
				bc.commit();
			}

			assert_eq!(bc.best_block_number(), 5);

			let hash = BlockView::new(&uncle).header_view().sha3();
			bc.insert_block(&mut batch, &uncle, vec![]);
			bc.insert_epoch_transition(&mut batch, 999, EpochTransition {
				block_hash: hash,
				block_number: 1,
				proof: vec![],
				state_proof: vec![]
			});

			db.write(batch).unwrap();
			bc.commit();

			// epoch 999 not in canonical chain.
			assert_eq!(bc.epoch_transitions().map(|(i, _)| i).collect::<Vec<_>>(), vec![0, 1, 2, 3, 4]);
		}

		// re-loading the blockchain should load the correct best block.
		let bc = new_chain(&genesis, db);

		assert_eq!(bc.best_block_number(), 5);
		assert_eq!(bc.epoch_transitions().map(|(i, _)| i).collect::<Vec<_>>(), vec![0, 1, 2, 3, 4]);
	}