在树莓派RaspberryPi 4(模型B)上运行以太坊完整节点

介绍

我的妻子最近为我提供了最新的Raspberry Pi 4(B型)4GB。因此,我很高兴尝试在第一台单板计算机(SBC)上同步以太坊完整节点

同步以太坊一直是许多人的痛苦点,因为这是一个复杂的过程,有多种选择,包括不同的验证模式,需要不同的设置,这可能会花费很多钱,并且需要花费数周的时间进行同步。

这是可用于将以太坊区块链与Geth(Go-Ethereum)同步的不同选项的摘要:

区块链同步模式[ --syncmode]:

  • fullsync:完全同步会下载所有数据(块标题和块主体),一次处理整个区块链一个链接,并重播历史上曾经发生的所有交易(交易处理和PoW验证)。此方法是最传统且最稳定的方法,但是可能需要很长时间(最多几周),并且需要功能更强大的计算机。在该过程结束时,该节点是完整节点。
  • fastsync:快速同步也会下载所有数据(块标题和块主体),但会交易所处理能力以使用带宽。快速同步无需处理所有曾经发生的交易,而是下载所有交易收据和整个近期状态数据库并执行PoW验证。当链达到最近状态(头数-1024块)时,geth切换到完全同步模式,导入剩余的块并按照经典同步(完全)的方式处理它们,以获得完整的节点。
  • lightsync:轻量模式直接同步到最后几个块,不将整个区块链存储在数据库中。与完整和快速不同,它不是完整节点,因为它不存储整个区块链,而仅存储块头,并且取决于完整节点。但是这种方法安全性较低,更适合物联网/移动设备,仅使用100MB的空间。

区块链垃圾收集模式[ --gcmode]: 垃圾收集用于丢弃旧的状态尝试并节省一些空间。

  • --gcmode full使垃圾回收仅将最新的128次尝试保留在内存中。这样可以节省大量空间,并且在此阶段(2019年9月)仅需要不到200 GB的空间来运行此设置中的完整节点。
  • --gcmode archive自创世以来,禁用垃圾收集并将所有历史状态数据块保留在以太坊块之后。(请记住,这需要超过2.3 TB的空间)。但是很少有人(例如Block Explorer)需要一个存档节点。

在本指南中,我们将遵循第二种同步模式,即快速(具有完整的垃圾回收),以在RaspberryPi 4上运行全节点。有些人可能会问,运行自己的节点有什么好处。这里有些例子:

  • 您将拥有一个可信赖的以太坊堆栈,您可以依靠该堆栈来管理资产并自行将交易发送到网络(远程节点通常是可靠的,但受第三方控制,通常会限制大量使用)。
  • 您可以帮助保护网络;运行的独立节点越多,区块链的副本就越多,它的弹性就越大。
  • 您想使网络更快,更安全;节点越多,共享块的等待时间越短,并且存在的区块链副本越多。
  • 很好玩

硬件

我们将从使用Raspberry Pi 4,SSD和所有必需组件进行设置的示例开始。但是您可以尝试替代和等效的解决方案,这些解决方案应根据以下要求起作用:

  • 记忆体:4GB RAM DDR3
  • 快速SSD(如果板卡具有PCIe接口,建议使用NVME SSD – RPi4则不是这种情况
  • 高速上网

如前所述,该板是最新的Raspberry 4(B型)-4GB,具有以下规格:

建议价格: $55

SD卡

要托管操作系统(OS),我使用SanDisk 16GB Ultra microSD

建议价格: 5美元

磁盘固态硬盘

为了存储需要非常高的磁盘IO性能的大型以太坊状态数据库,我们通过USB3.0 将Samsung SSD T5(500GB)连接到板上。

建议您至少使用500GB的SSD,因为快速同步后以太坊主网的实际大小约为200GB。那应该给您几年时间,然后再在更大的磁盘上重建整个事情。

建议价格: $90

电源

最后,我们使用3.5A USB-C电源为SBC 供电

建议价格: 10美元

多余的东西

  • 如果您想通过以太坊连接到Internet,则需要一条以太坊电缆
  • 对于初学者来说,无头安装可能很困难,因此有时通过HDMI(微型)和键盘将Pi连接到屏幕更容易。
  • 建议使用散热器以保持CPU散热并减少由于过热导致的硬件故障风险。
  • 保护主板的外壳。

总消耗

此设置的总成本为160美元,估计每年的经常性用电成本为10美元/年。

零件 成本
Raspberry Pi 4(B型)4GB $55
16GB SanDisk Ultra Class 10 MicroSD 五块
三星SSD T5(500GB) $90
3.5A USB-C电源 $10
$160

硬件安装结果

安装

安装和配置操作系统

在安装的第一部分中,我们将安装Raspbian Linux操作系统并以可靠和安全的方式对其进行配置。

1.下载适用于RaspberryPi的最新版本的Raspbian Linux OS。

转到下载页面,然后下载Raspbian Buster Lite

  • Raspbian是Raspberry Pi的基于Debian的计算机操作系统。
  • Buster Lite是Raspbian的最低版本,不包含桌面或推荐软件。我们可以使用此版本从全新,轻巧和全新的安装开始。

2.解压缩存档以获取图像 2019-07-10-raspbian-buster-lite.img

3.将SD卡(最小8GB)插入笔记本电脑

4.使用Etcher并刷新SD卡上的图像

下载Etcher即可安全,轻松地将OS映像闪存到SD卡和USB驱动器。

启动Etcher,首先选择Raspbian提取的图像,选择Media(SD卡),然后单击Flash。

5.刷新后,导航到/bootSD卡的文件夹并创建一个空文件ssh

$cd /media//boot
$touch ssh

6.从笔记本电脑上拔下SD卡,然后将其插入Raspberry Pi

7.将电源插入Raspberry Pi和以太坊电缆

8.确定其IP地址(计算机的默认主机名是raspberrypi

您的网络路由器应通过以太坊和WIFI提供所有已连接设备的列表。

示例-VirginMedia Hub
9.通过SSH与默认用户连接,pi然后输入默认密码raspberry

默认情况下,我们在步骤5中启用了ssh,因此可以通过SSH从Linux终端(如果使用Windows,则使用Putty)远程连接到系统。

$ssh pi@192.168.0.38
pi@192.168.0.38's password: raspberry
Linux raspberrypi 4.19.57-v7l+ #1244 SMP Thu Jul 4 18:48:07 BST 2019 armv7l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.

SSH is enabled and the default password for the 'pi' user has not been changed.
This is a security risk - please login as the 'pi' user and type 'passwd' to set a new password.

10.更改用户的默认密码 pi

Raspbian配置的默认密码是众所周知的,因此强烈建议将其更改为其他密码:

$passwd
Changing password for pi.
Current password: raspberry
New password: $3cret
Retype new password: $3cret
passwd: password updated successfully

11.将VIM安装为命令行编辑器

$sudo apt install vim

11.更改主机名

Raspbian赋予的默认主机名是raspberrypi,如果您有多个设备,这会引起混乱,因此建议使用与用途相关的更特定的主机名来重命名计算机。

打开文件,/etc/hostname并用以下内容替换内容geth

$sudo vi /etc/hostname

然后,更改/etc/hosts和替换行127.0.1.1 raspberrypi通过127.0.1.1 geth

$sudo vi /etc/hosts

12.升级操作系统

升级系统以获得最新的补丁程序。

$sudo apt-get update && sudo apt-get upgrade

13.配置静态IP

现在,我们将配置静态IP,192.168.0.24以便路由器在每次Raspberry PI重新启动时都不会分配不同的IP。您可以通过路由器DHCP配置或直接在计算机的网络配置中,甚至在两者的网络配置中进行此操作。

一种。使用路由器为Raspberry Pi分配静态专用IP地址

转到网络路由器控制台,然后在DHCP部分中配置静态IP。

示例-VirginMedia Hub
b。使用dhcpcd为Raspberry Pi分配静态专用IP地址

编辑文件/etc/dhcpcd.conf并在末尾添加以下行

$sudo vi /etc/dhcpcd.conf

interface eth0
static ip_address=192.168.0.24/24
static routers=192.168.0.1
static domain_name_servers=192.168.100.4

eth0根据您的网络配置,更改接口,路由器地址和DNS服务器。

14.重新启动

重新启动计算机,然后使用静态IP和新密码登录。

$sudo reboot

(... wait a few seconds)

$ssh pi@192.168.0.24
pi@192.168.0.24's password: 

挂载SSD

在本指南的第二部分中,我们将安装连接到两个USB3.0端口之一的SSD。

如前所述,只有SSD足够快(I / O速度)才能将Geth同步到以太坊主网。

1.将SSD插入USB3.0(蓝色)端口

2.查找磁盘名称(驱动器)

运行命令fdisk -l以列出所有已连接到系统的磁盘(包括RAM),然后尝试识别SSD。放置在其中的磁盘大小为465.6 GiB,型号名称为Portable SSD T5/dev/sda

$sudo fdisk -l
Disk /dev/ram0: 4 MiB, 4194304 bytes, 8192 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes

(...)

Disk /dev/sda: 465.8 GiB, 500107862016 bytes, 976773168 sectors
Disk model: Portable SSD T5 
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 33553920 bytes
Disklabel type: dos
Disk identifier: 0x41d0909f

3.创建一个分区

如果磁盘是新磁盘且刚在软件包中,则需要创建一个分区。

$sudo mkfs.ext4 /dev/sda
mke2fs 1.44.5 (15-Dec-2018)
/dev/sda contains a ext4 file system
    last mounted on /mnt/ssd on Mon Sep  9 21:06:47 2019
Proceed anyway? (y,N) y
Creating filesystem with 58609664 4k blocks and 14655488 inodes
Filesystem UUID: 5c3a8481-682c-4834-9814-17dba166f591
Superblock backups stored on blocks: 
    32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
    4096000, 7962624, 11239424, 20480000, 23887872

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (262144 blocks): 
done
Writing superblocks and filesystem accounting information: done     

4.手动安装磁盘

您可以手动将磁盘安装到文件夹中/mnt/ssd

$sudo mkdir /mnt/ssd
$sudo chown -R pi:pi /mnt/ssd/
$sudo mount /dev/sda /mnt/ssd

5.启动时自动安装磁盘

下一步包括配置fstab为在系统启动时自动安装磁盘。

首先,您需要使用命令找到磁盘的唯一ID blkid

$sudo blkid

/dev/mmcblk0p1: LABEL_FATBOOT="boot" LABEL="boot" UUID="F661-303B" TYPE="vfat" PARTUUID="a91dd8a2-01"
/dev/mmcblk0p2: LABEL="rootfs" UUID="8d008fde-f12a-47f7-8519-197ea707d3d4" TYPE="ext4" PARTUUID="a91dd8a2-02"
/dev/mmcblk0: PTUUID="a91dd8a2" PTTYPE="dos"
/dev/sda: UUID="5c3a8481-682c-4834-9814-17dba166f591" TYPE="ext4"

我们位于的SSD /dev/sda具有唯一的ID 5c3a8481-682c-4834-8814-17dba166f591

编辑文件/etc/fstab并添加以下行,以配置启动时自动安装磁盘。

$sudo vi /etc/fstab

在末尾添加以下行:

UUID=5c3a8481-682c-4834-9814-17dba166f591 /mnt/ssd ext4 defaults 0 0

重新启动系统

$sudo reboot

您可以使用以下命令来验证磁盘在启动时是否正确安装:

$df -ha /dev/sda
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda        458G   73M  435G   1% /mnt/ssd

6.在SSD上配置交易所

Geth在同步过程中会消耗大量内存,因此强烈建议您创建一个交易所文件(溢出RAM),以防止发生任何OutOfMemory错误。强烈建议将交易所文件放在最快的磁盘上,在本例中为SSD。

编辑档案 /etc/dphys-swapfile

  • 代替CONF_SWAPSIZE=100通过CONF_SWAPSIZE=8192分配一个8GB SWAP
  • 替换CONF_SWAPFILE=/var/swapCONF_SWAPFILE=/mnt/ssd/swap.file以找到SSD上的交易所
$sudo vi /etc/dphys-swapfile

CONF_SWAPSIZE=8192
CONF_MAXSWAP=8192
CONF_SWAPFILE=/mnt/ssd/swap.file

重新启动交易所

$sudo /etc/init.d/dphys-swapfile restart

7.磁盘性能检查点

在继续之前,您的设置需要非常高的磁盘IO吞吐量。您可以使用以下命令测试SSD磁盘的性能:

磁盘写入:

$dd if=/dev/zero  of=/mnt/ssd/deleteme.dat bs=32M count=64 oflag=direct
64+0 records in
64+0 records out
2147483648 bytes (2.1 GB, 2.0 GiB) copied, 13.6021 s, 158 MB/s

磁盘读取:

$dd if=/mnt/ssd/deleteme.dat of=/dev/null bs=32M count=64 iflag=direct
64+0 records in
64+0 records out
2147483648 bytes (2.1 GB, 2.0 GiB) copied, 22.3361 s, 96.1 MB/s

低于50MB / s(写/读)时,我不建议尝试同步Geth节点,因为您可能永远无法到达头部并完成同步。

/mnt/ssd/deleteme.dat性能测试后卸下。

其他配置

转发端口

为了与其他对等方正确通信,Geth需要从外部接受端口30303上的连接。您将相应地配置防火墙,以允许端口30303上的传入请求通过端口转发或端口触发到达计算机。

示例-VirginMedia集线器(端口转发)
必备软件

安装此过程中可能需要的以下软件。

$sudo apt-get install git sysstat -y

安装和配置Geth

现在,我们的系统已准备就绪,可以安装和配置Geth。

一种。安装和配置Golang

  1. 将档案下载到 ~/download

对于Raspberry Pi 4,我们需要下载 Golang for Architecture ARMv6:go1.13.1.linux-armv6l.tar.gz

$mkdir ~/download
$cd ~/download
$wget https://dl.google.com/go/go1.13.1.linux-armv6l.tar.gz
  1. 提取到 /usr/local
$sudo tar -C /usr/local -xvf go1.13.1.linux-armv6l.tar.gz
  1. 将所有者更改为root,并更改权限
$sudo chown root:root /usr/local/go
$sudo chmod 755 /usr/local/go
  1. 设置环境变量。编辑文件,/etc/profile并在末尾添加以下行:
$sudo vi /etc/profile 
export P新高=$P新高:/usr/local/go/bin
  1. 重启
$sudo reboot
  1. 试试吧
$go version
go version go1.13.1 linux/arm

b。从源代码安装Geth

要安装以太坊客户端Geth,我们将从GitHub源码编译它。

  1. 克隆存储库
$git clone https://github.com/ethereum/go-ethereum.git --branch v

--branch v如果要使用最新代码(不稳定),请删除。

  1. 进入文件夹并构建geth
$cd go-ethereum
$make geth
(wait a couple of minutes...)
  1. 将二进制文件移到/ usr / local / bin
$sudo mv ~/go-ethereum/build/bin/geth /usr/local/bin
  1. 试试吧
$geth version 
Geth
Version: 1.9.6-stable
Git Commit: bd05968077f27f7eb083404dd8448157996a8788
Architecture: arm
Protocol Versions: [63]
Network Id: 1
Go Version: go1.13.1
Operating System: linux
GOP新高=
GOROOT=/usr/local/go

C。配置并运行Geth

首先,我们需要使用flag 将Geth配置为以快速模式进行同步--syncmode fast

Geth还具有一个--cache选项,用于指定客户端可以使用的RAM数量。Raspberry Pi 4具有4GB RAM,因此我们可以使用--cache 256而不会遇到内存不足错误。

默认情况下,所有数据都存储在~/.ethereum/geth/SD卡上。我们想将以太坊数据存储在SSD上。为此,我们可以使用该选项--datadir /mnt/ssd/ethereum告诉Geth读取/写入SSD上的数据存储。

  1. 在具有pi权限的SSD上创建数据目录
$sudo mkdir /mnt/ssd/ethereum
$sudo chown -R pi:pi /mnt/ssd/ethereum
  1. 运行以下命令以查看Geth是否开始正确同步区块链。
$geth --syncmode fast --cache 256 --datadir /mnt/ssd/ethereum

Ctrl+C to stop it

请参阅文档以获取命令行选项

d。将Geth配置为服务(systemd)

我们希望将Geth作为服务运行,并在关闭会话后使进程在后台运行,并能够从崩盘中自动恢复。我们需要安装一个systemctl服务(systemd说明

  1. 创建以下文件:
$sudo vi /etc/systemd/system/geth.service
[Unit]
Description=Geth Node
After=network.target auditd.service
Wants=network.target
[Service]
WorkingDirectory=/home/pi
ExecStart=/usr/local/bin/geth --syncmode fast --cache 256 --datadir /mnt/ssd/ethereum
User=pi
Group=pi
Restart=always
RestartSec=5s

[Install]
WantedBy=multi-user.target
Alias=geth.service
  1. 启动服务

以下命令使用我们的服务文件定义更新守护程序列表并在后台启动Geth

$sudo systemctl daemon-reload
$sudo systemctl start geth
  1. 配置服务以在启动时启动

以下命令将Geth配置为在重新启动后自动启动。

$sudo systemctl enable geth
  1. 查看日志

您可以通过查看文件来可视化服务日志 /var/log/syslog

$tail -f /var/log/syslog 

Sep 23 15:35:36 geth geth[1876]: INFO [09-23|15:35:36.953] Imported new state entries               count=744  elapsed=101.921ms  processed=37498448 pending=52340  retry=29  duplicate=1259 unexpected=7938
Sep 23 15:35:37 geth geth[1876]: INFO [09-23|15:35:37.468] Imported new state entries               count=1051 elapsed=90.277ms   processed=37499499 pending=52294  retry=1   duplicate=1259 unexpected=7938
Sep 23 15:35:37 geth geth[1876]: INFO [09-23|15:35:37.953] Imported new state entries               count=1200 elapsed=45.520ms   processed=37500699 pending=53140  retry=10  duplicate=1259 unexpected=7938
Sep 23 15:35:38 geth geth[1876]: INFO [09-23|15:35:38.772] Imported new state entries               count=1007 elapsed=494.883ms  processed=37501706 pending=55936  retry=15  duplicate=1259 unexpected=7938
Sep 23 15:35:39 geth geth[1876]: INFO [09-23|15:35:39.046] Imported new state entries               count=1042 elapsed=10.600ms   processed=37502748 pending=58575  retry=10  duplicate=1259 unexpected=7938
Sep 23 15:35:39 geth geth[1876]: INFO [09-23|15:35:39.340] Imported new state entries               count=966  elapsed=5.002ms    processed=37503714 pending=61462  retry=10  duplicate=1259 unexpected=7938
Sep 23 15:35:39 geth geth[1876]: INFO [09-23|15:35:39.950] Imported new state entries               count=1028 elapsed=35.258ms   processed=37504742 pending=62667  retry=16  duplicate=1259 unexpected=7938
Sep 23 15:35:40 geth geth[1876]: INFO [09-23|15:35:40.419] Imported new state entries               count=1350 elapsed=73.530ms   processed=37506092 pending=61650  retry=19  duplicate=1259 unexpected=7938
Sep 23 15:35:40 geth geth[1876]: INFO [09-23|15:35:40.657] Imported new block headers               count=2048 elapsed=12.619s    number=3369149 hash=e7fe02…172100 age=2y6mo2w

正在同步

我们已经安装并配置了Geth,因此现在我们需要等待几天,直到同步结束。同时,让我分享一些有关同步过程以及幕后动态的见解。

首先,在快速同步节点中,同步过程由并行运行的两个阶段组成:块同步状态Trie下载。为了拥有完整的节点并切换到执行和验证每个事务的完整模式,都需要完成两个阶段。

块同步下载所有的块的信息(标题,交易)。此阶段使用大量CPU和空间来存储所有数据。您可以在日志中观察到此过程,并提及“导入块标题和块收据”

INFO [09-26|09:25:19.045] Imported new block headers               count=1    elapsed=80.177ms     number=8623429 hash=c064e8…4daa8b age=1m1s
INFO [09-26|09:19:52.655] Imported new block receipts              count=65   elapsed=396.964ms    number=8623342 hash=2ef982…20344e age=17m32s    size=2.35MiB

但是,在快速模式下,不会执行任何交易,因此我们没有任何可用的帐户状态(即余额,随机数,智能合约代码和数据)。盖斯需要下载状态列表并与最新阻止进行交叉检查。此阶段称为状态Trie下载,通常比块同步花费更多的时间。通过以下语句在日志中描述此阶段:

INFO [09-26|09:29:27.542] Imported new state entries               count=1152 elapsed=16.372ms     processed=338933905 pending=2630   retry=0   duplicate=16797 unexpected=352359
INFO [09-26|09:29:30.307] Imported new state entries               count=768  elapsed=10.657ms     processed=338934673 pending=3075   retry=0   duplicate=16797 unexpected=352359

下图显示了同步过程中的一些指标。我们观察到,一旦块同步完成,我们将存储更少的数据并消耗更少的CPU和内存。但是,格思仍在贬低并以很高的速度写入状态项。

阅读本文,了解如何使用GoogleSheet监视Geth。

在此过程中,您将观察到许多人常见的奇怪行为。

  • 以太坊后面的64到128个区块之间 完成区块同步阶段之后以及在状态Trie下载阶段期间,区块编号计数将始终在以太坊上开采的最新区块之后的64到128个区块之间振荡。在状态Trie下载阶段结束并且您的节点完全同步之前,这是正常的。
  • 透视图变得过时 如果您无法在30分钟内下载所有状态(剧透警报:您无法),则需要“透视图”。透视图意味着切换到新的启动块,然后再次开始同步。数据透视并不是从头开始,而是增加了下载和验证状态所花费的时间。
WARN [09-25|09:29:05.328] Pivot became stale, moving               old=8616956 new=8617021
  • 丢弃对等点 Geth连接到多个对等点,以便检索运行完整节点所需的信息。但是,同伴有时可能会出现功能异常。这就是为什么Geth在检测到异常时会自动将其丢弃。
WARN [09-26|07:20:30.946] Stalling state sync, dropping peer       peer=68938142fde11a0d

WARN [09-26|09:03:22.737] Dropping unsynced node during fast sync  id=032cb470bedcc353 conn=inbound addr=54.224.xx.xx:43396   type=Geth/v1.8.27-stable-4bcc0a37/linux-amd64/go1.11.9

过渡到全节点

经过3天23小时49分钟,我们观察到了从快速模式到完全模式的过渡:

INFO [09-27|11:23:14.601] Fast sync complete, auto disabling

那你应该看到

INFO [09-27|11:24:14.848] Block synchronisation started
INFO [09-27|11:24:29.351] Importing sidechain segment              start=8630211 end=8630283
INFO [09-27|11:24:37.381] Imported new chain segment               blocks=4 txs=739 mgas=39.838 elapsed=8.029s mgasps=4.961 number=8630214 hash=0bcc00…b0ec25 age=19m27s dirty=4.79MiB
INFO [09-27|11:24:46.358] Imported new chain segment               blocks=8 txs=736 mgas=59.772 elapsed=8.977s mgasps=6.658 number=8630222 hash=5bd330…be76b7 age=17m40s dirty=10.36MiB
INFO [09-27|11:24:54.970] Imported new chain segment               blocks=8 txs=706 mgas=69.874 elapsed=8.612s mgasps=8.113 number=8630230 hash=0be45c…f85f32 age=16m34s dirty=15.65MiB

网站ethstats实时获取以太坊主网的最新状态,我们可以进行比较以查看是否已同步。

结论

总而言之,本文显示了在以太坊主网上运行全节点并为网络的良好运行状况做出贡献是多么简单和负担得起。

特别感谢

本指南从讨论以太坊节点稳定并在单板计算机上同步的难度开始。因此,感谢您进行了有趣的讨论,并感谢您在过去几周内为使该实验取得成功提供的帮助

  • 库根·布伦南(Coogan Brennan)
  • 丹尼尔·埃里森
  • 洛伦佐·西西利亚(Lorenzo Sicilia)

参考文献

原文 Kauri
提示:投资有风险,入市需谨慎,本资讯不作为投资理财建议。请理性投资,切实提高风险防范意识;如有发现的违法犯罪线索,可积极向有关部门举报反映。
你可能还喜欢