Skip to content

Commit

Permalink
1.add BARNARD_HARD_FORK logic 2.add version_string ban logic
Browse files Browse the repository at this point in the history
  • Loading branch information
nkysg committed Feb 14, 2023
1 parent 0bb317e commit 7b6aca0
Show file tree
Hide file tree
Showing 12 changed files with 160 additions and 3 deletions.
6 changes: 6 additions & 0 deletions chain/api/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ pub enum ConnectBlockError {
ParentNotExist(Box<BlockHeader>),
#[error("Verify block {0} failed: {1:?}")]
VerifyBlockFailed(VerifyBlockField, Error),
#[error("Barnard hard fork block: {:?} ", .0.header())]
BarnardHardFork(Box<Block>),
}

impl ConnectBlockError {
Expand All @@ -70,12 +72,15 @@ impl ConnectBlockError {
ReputationChange::new_fatal("ParentNotExist");
pub const REP_VERIFY_BLOCK_FAILED: ReputationChange =
ReputationChange::new_fatal("VerifyBlockFailed");
pub const REP_BARNARD_HARD_FORK: ReputationChange =
ReputationChange::new_fatal("BarnardHardFork");

pub fn reason(&self) -> &str {
match self {
ConnectBlockError::FutureBlock(_) => "FutureBlock",
ConnectBlockError::ParentNotExist(_) => "ParentNotExist",
ConnectBlockError::VerifyBlockFailed(_, _) => "VerifyBlockFailed",
ConnectBlockError::BarnardHardFork(_) => "BarnardHardFork",
}
}

Expand All @@ -86,6 +91,7 @@ impl ConnectBlockError {
ConnectBlockError::VerifyBlockFailed(_, _) => {
ConnectBlockError::REP_VERIFY_BLOCK_FAILED
}
ConnectBlockError::BarnardHardFork(_) => ConnectBlockError::REP_BARNARD_HARD_FORK,
}
}
}
15 changes: 15 additions & 0 deletions network/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ use std::collections::HashMap;
use std::ops::RangeInclusive;
use std::sync::Arc;

const BARNARD_HARD_FORK_PEER_VERSION_STRING_PREFIX: &str = "barnard_rollback_block_fix";

pub struct NetworkActorService {
worker: Option<NetworkWorker>,
inner: Inner,
Expand Down Expand Up @@ -135,6 +137,19 @@ impl EventHandler<Self, Event> for NetworkActorService {
"Connected peer {:?}, protocol: {}, notif_protocols: {:?}, rpc_protocols: {:?}",
remote, protocol, notif_protocols, rpc_protocols
);
if info.chain_id().is_barnard() {
// XXX FIXME YSG
if let Some(ref ver_str) = version_string {
if !ver_str.contains(BARNARD_HARD_FORK_PEER_VERSION_STRING_PREFIX) {
info!(
"ban {} peer {:?} ver_str {}",
BARNARD_HARD_FORK_PEER_VERSION_STRING_PREFIX, remote, ver_str
);
self.inner.network_service.ban_peer(remote, true);
return;
}
}
}
let peer_event = PeerEvent::Open(remote.into(), info.clone());
self.inner.on_peer_connected(
remote.into(),
Expand Down
1 change: 1 addition & 0 deletions node/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ impl NodeService {

let start_time = SystemTime::now();
storage_instance.check_upgrade()?;
storage_instance.barnard_hard_fork(config.clone())?;
let upgrade_time = SystemTime::now().duration_since(start_time)?;
let storage = Arc::new(Storage::new(storage_instance)?);
registry.put_shared(storage.clone()).await?;
Expand Down
2 changes: 1 addition & 1 deletion storage/src/block/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ define_storage!(
#[derive(Clone)]
pub struct BlockStorage {
block_store: BlockInnerStorage,
header_store: BlockHeaderStorage,
pub(crate) header_store: BlockHeaderStorage,
body_store: BlockBodyStorage,
block_txns_store: BlockTransactionsStorage,
block_txn_infos_store: BlockTransactionInfosStorage,
Expand Down
18 changes: 17 additions & 1 deletion storage/src/chain_info/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::storage::{ColumnFamily, InnerStorage, KVStore};
use crate::{StorageVersion, CHAIN_INFO_PREFIX_NAME};
use anyhow::Result;
use starcoin_crypto::HashValue;
use starcoin_types::startup_info::{SnapshotRange, StartupInfo};
use starcoin_types::startup_info::{BarnardHardFork, SnapshotRange, StartupInfo};
use std::convert::{TryFrom, TryInto};

#[derive(Clone)]
Expand All @@ -27,6 +27,7 @@ impl ChainInfoStorage {
const GENESIS_KEY: &'static str = "genesis";
const STORAGE_VERSION_KEY: &'static str = "storage_version";
const SNAPSHOT_RANGE_KEY: &'static str = "snapshot_height";
const BARNARD_HARD_FORK: &'static str = "barnard_hard_fork";

pub fn get_startup_info(&self) -> Result<Option<StartupInfo>> {
self.get(Self::STARTUP_INFO_KEY.as_bytes())
Expand Down Expand Up @@ -95,4 +96,19 @@ impl ChainInfoStorage {
snapshot_range.try_into()?,
)
}

pub fn get_barnard_hard_fork(&self) -> Result<Option<BarnardHardFork>> {
self.get(Self::BARNARD_HARD_FORK.as_bytes())
.and_then(|bytes| match bytes {
Some(bytes) => Ok(Some(bytes.try_into()?)),
None => Ok(None),
})
}

pub fn save_barnard_hard_fork(&self, barnard_hard_fork: BarnardHardFork) -> Result<()> {
self.put_sync(
Self::BARNARD_HARD_FORK.as_bytes().to_vec(),
barnard_hard_fork.try_into()?,
)
}
}
2 changes: 2 additions & 0 deletions storage/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ use starcoin_types::{
use std::collections::BTreeMap;
use std::fmt::{Debug, Display, Formatter};
use std::sync::Arc;
pub use upgrade::BARNARD_HARD_FORK_HASH;
pub use upgrade::BARNARD_HARD_FORK_HEIGHT;

pub mod accumulator;
pub mod batch;
Expand Down
10 changes: 10 additions & 0 deletions storage/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ use crate::db_storage::{DBStorage, SchemaIterator};
use crate::upgrade::DBUpgrade;
use anyhow::{bail, format_err, Result};
use byteorder::{BigEndian, ReadBytesExt};
use starcoin_config::NodeConfig;
use starcoin_crypto::HashValue;
use starcoin_logger::prelude::info;
use starcoin_vm_types::state_store::table::TableHandle;
use std::convert::TryInto;
use std::fmt::Debug;
Expand Down Expand Up @@ -108,6 +110,14 @@ impl StorageInstance {
pub fn check_upgrade(&mut self) -> Result<()> {
DBUpgrade::check_upgrade(self)
}

pub fn barnard_hard_fork(&mut self, config: Arc<NodeConfig>) -> Result<()> {
if config.net().id().chain_id().is_barnard() {
info!("barnard_hard_fork in");
return DBUpgrade::barnard_hard_fork(self);
}
Ok(())
}
}

impl InnerStore for StorageInstance {
Expand Down
52 changes: 52 additions & 0 deletions storage/src/upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,24 @@ use crate::{
BLOCK_BODY_PREFIX_NAME, TRANSACTION_INFO_PREFIX_NAME,
};
use anyhow::{bail, ensure, format_err, Result};
use once_cell::sync::Lazy;
use starcoin_crypto::HashValue;
use starcoin_logger::prelude::{debug, info, warn};
use starcoin_types::block::BlockNumber;
use starcoin_types::startup_info::{BarnardHardFork, StartupInfo};
use starcoin_types::transaction::Transaction;
use std::cmp::Ordering;

pub struct DBUpgrade;

pub static BARNARD_HARD_FORK_HEIGHT: BlockNumber = 9716880;
pub static BARNARD_HARD_FORK_HASH: Lazy<HashValue> = Lazy::new(|| {
HashValue::from_hex_literal(
"0x98f32397569e26540985f0d487c5e7cc229a8c9be9afe10f973b3d95204d06d7",
)
.expect("")
});

impl DBUpgrade {
pub fn check_upgrade(instance: &mut StorageInstance) -> Result<()> {
let version_in_db = {
Expand Down Expand Up @@ -181,4 +193,44 @@ impl DBUpgrade {
}
Ok(())
}

pub fn barnard_hard_fork(instance: &mut StorageInstance) -> Result<()> {
let block_storage = BlockStorage::new(instance.clone());
let chain_info_storage = ChainInfoStorage::new(instance.clone());
let barnard_hard_fork = chain_info_storage.get_barnard_hard_fork()?;

let barnard_info = BarnardHardFork::new(BARNARD_HARD_FORK_HEIGHT, *BARNARD_HARD_FORK_HASH);
if barnard_hard_fork == Some(barnard_info.clone()) {
info!("barnard had forked");
return Ok(());
}

let block = block_storage.get_block_by_hash(*BARNARD_HARD_FORK_HASH)?;
if let Some(block) = block {
if block.header().number() == BARNARD_HARD_FORK_HEIGHT {
info!("barnard hard fork rollback height");
let mut processed_count = 0;
let block_info_storage = BlockInfoStorage::new(instance.clone());
let mut iter = block_storage.header_store.iter()?;
iter.seek_to_first();
for item in iter {
let (id, block_header) = item?;
if block_header.number() >= BARNARD_HARD_FORK_HEIGHT {
block_info_storage.remove(id)?;
processed_count += 1;
if processed_count % 10000 == 0 {
info!(
"barnard hard fork rollback height processed items: {}",
processed_count
);
}
}
}
let main_hash = block.header().parent_hash();
chain_info_storage.save_barnard_hard_fork(barnard_info)?;
chain_info_storage.save_startup_info(StartupInfo::new(main_hash))?;
}
}
Ok(())
}
}
10 changes: 10 additions & 0 deletions sync/src/block_connector/write_block_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,12 @@ where

fn connect_inner(&mut self, block: Block) -> Result<ConnectOk> {
let block_id = block.id();
if block_id == *starcoin_storage::BARNARD_HARD_FORK_HASH
&& block.header().number() == starcoin_storage::BARNARD_HARD_FORK_HEIGHT
{
debug!("barnard hard fork {}", block_id);
return Err(ConnectBlockError::BarnardHardFork(Box::new(block)).into());
}
if self.main.current_header().id() == block_id {
debug!("Repeat connect, current header is {} already.", block_id);
return Ok(ConnectOk::Duplicate);
Expand Down Expand Up @@ -430,6 +436,10 @@ where
block: block.clone(),
block_info,
})?;
info!(
"Block {} main has been processed, trigger head selection",
block_id
);
self.do_new_head(executed_block, 1, vec![block], 0, vec![])?;
Ok(ConnectOk::Connect)
}
Expand Down
8 changes: 8 additions & 0 deletions sync/src/tasks/block_sync_task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use starcoin_chain::{verifier::BasicVerifier, BlockChain};
use starcoin_chain_api::{ChainReader, ChainWriter, ConnectBlockError, ExecutedBlock};
use starcoin_config::G_CRATE_VERSION;
use starcoin_logger::prelude::*;
use starcoin_storage::BARNARD_HARD_FORK_HASH;
use starcoin_sync_api::SyncTarget;
use starcoin_types::block::{Block, BlockIdAndNumber, BlockInfo, BlockNumber};
use std::collections::HashMap;
Expand Down Expand Up @@ -236,6 +237,13 @@ where
return Err(format_err!("collect previous failed block:{}", block.id()));
}
}
if block.id() == *BARNARD_HARD_FORK_HASH {
if let Some(peer) = peer_id {
warn!("[barnard hard fork] ban peer {}", peer);
self.peer_provider.ban_peer(peer, true);
}
return Err(format_err!("reject barnard hard fork block:{}", block.id()));
}
let apply_result = if self.skip_pow_verify {
self.chain
.apply_with_verifier::<BasicVerifier>(block.clone())
Expand Down
37 changes: 37 additions & 0 deletions types/src/startup_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,3 +234,40 @@ impl TryInto<Vec<u8>> for SnapshotRange {
self.encode()
}
}

#[derive(Eq, PartialEq, Hash, Deserialize, Serialize, Clone, Debug)]
pub struct BarnardHardFork {
// [number, ...) block will remove
number: BlockNumber,
hash: HashValue,
}

impl BarnardHardFork {
pub fn new(number: BlockNumber, hash: HashValue) -> Self {
Self { number, hash }
}

pub fn get_number(&self) -> BlockNumber {
self.number
}

pub fn get_hash(&self) -> HashValue {
self.hash
}
}

impl TryFrom<Vec<u8>> for BarnardHardFork {
type Error = anyhow::Error;

fn try_from(value: Vec<u8>) -> Result<Self> {
BarnardHardFork::decode(value.as_slice())
}
}

impl TryInto<Vec<u8>> for BarnardHardFork {
type Error = anyhow::Error;

fn try_into(self) -> Result<Vec<u8>> {
self.encode()
}
}
2 changes: 1 addition & 1 deletion vm/move-package-manager/src/release.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub const DEFAULT_RELEASE_DIR: &str = "release";
pub struct Release {
#[clap(name = "move-version", long = "move-version", default_value="4", possible_values=&["4", "6"])]
/// specify the move lang version for the release.
/// currently, only v3, v4 are supported.
/// currently, only v4, v6 are supported.
language_version: u8,

#[clap(name="release-dir", long, parse(from_os_str), default_value=DEFAULT_RELEASE_DIR)]
Expand Down

0 comments on commit 7b6aca0

Please sign in to comment.