Skip to content

Commit 4acaf02

Browse files
author
platfowner
authored
Merge pull request #1170 from ainblockchain/release/v1.0.14
Release/v1.0.14
2 parents 9ca9812 + ed5668f commit 4acaf02

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1992
-429
lines changed

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM node:16.14
1+
FROM node:18.16
22
WORKDIR /app/ain-blockchain
33
COPY . /app/ain-blockchain
44
RUN yarn install

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,13 @@ You can use some environment variables, and these have the following options.
170170
-e ACCOUNT_INJECTION_OPTION={private_key|keystore|mnemonic}
171171
-e SYNC_MODE={fast|full|peer}
172172
-e STAKE=<YOUR_TARGET_STAKE>
173+
-e HOSTING_ENV={local|comcom|gcp|aws}
174+
```
175+
You can mount a volume when you meet some wants.
176+
1. Want to preserve blockchain data in the docker container when changing the docker image due to an update.
177+
2. Want to save your keystore file in the docker container when injecting your account into the blockchain automatically.
178+
```
179+
-v <YOUR_VOLUME>:/home/ain_blockchain_data
173180
```
174181
After the node is executed, you should inject your account into the node.
175182
```
@@ -180,7 +187,7 @@ node inject_node_account.js <NODE_ENDPOINT_URL> --mnemonic
180187
If you want to inject your account automatically, add one of these environment variables before running the node.
181188
```
182189
-e ACCOUNT_INJECTION_OPTION=private_key -e PRIVATE_KEY=<YOUR_PRIVATE_KEY>
183-
-e ACCOUNT_INJECTION_OPTION=keystore -e KEYSTORE_FILE_PATH="/path/to/keystore" -e PASSWORD=<YOUR_PASSWORD>
190+
-e ACCOUNT_INJECTION_OPTION=keystore -e KEYSTORE_FILE_PATH="/home/ain_blockchain_data/<KEYSTORE>" -e PASSWORD=<YOUR_PASSWORD>
184191
-e ACCOUNT_INJECTION_OPTION=mnemonic -e MNEMONIC="your mnemonic"
185192
```
186193

client/protocol_versions.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,5 +116,8 @@
116116
},
117117
"1.0.13": {
118118
"min": "1.0.0"
119+
},
120+
"1.0.14": {
121+
"min": "1.0.0"
119122
}
120123
}

common/common-util.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,10 @@ class CommonUtil {
146146
return ruleUtil.isValidatorOffenseType(type);
147147
}
148148

149+
static isValidUrlWhitelistItem(url) {
150+
return ruleUtil.isValidUrlWhitelistItem(url);
151+
}
152+
149153
static isValidUrl(url) {
150154
return ruleUtil.isValidUrl(url);
151155
}

common/constants.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,18 @@ function setNodeConfigs() {
131131
setNodeConfigs();
132132

133133
// ** Enums **
134+
/**
135+
* Hosting Environments.
136+
*
137+
* @enum {string}
138+
*/
139+
const HostingEnvs = {
140+
AWS: 'aws', // Amazon AWS
141+
COMCOM: 'comcom', // ComCom On-Premise
142+
LOCAL: 'local', // Local
143+
GCP: 'gcp', // Google Cloud Platform
144+
};
145+
134146
/**
135147
* Types of P2P network messages.
136148
*
@@ -821,6 +833,7 @@ module.exports = {
821833
TimerFlagEnabledBandageMap,
822834
BlockchainParams,
823835
NodeConfigs,
836+
HostingEnvs,
824837
P2pMessageTypes,
825838
BlockchainNodeStates,
826839
P2pNetworkStates,

common/network-util.js

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@ const logger = new (require('../logger'))('NETWORK-UTIL');
22

33
const _ = require('lodash');
44
const axios = require('axios');
5-
const { BlockchainConsts, NodeConfigs } = require('../common/constants');
5+
const { BlockchainConsts, NodeConfigs, HostingEnvs } = require('../common/constants');
66
const ip = require('ip');
77
const extIp = require('ext-ip')();
88
const CommonUtil = require('../common/common-util');
99
const DB = require('../db');
1010
const { JSON_RPC_METHODS } = require('../json_rpc/constants');
11-
const GCP_EXTERNAL_IP_URL = 'http://metadata.google.internal/computeMetadata/v1/instance' +
12-
'/network-interfaces/0/access-configs/0/external-ip';
13-
const GCP_INTERNAL_IP_URL = 'http://metadata.google.internal/computeMetadata/v1/instance' +
14-
'/network-interfaces/0/ip';
11+
const GCP_EXTERNAL_IP_URL = 'http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip';
12+
const GCP_INTERNAL_IP_URL = 'http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip';
13+
const AWS_TOKEN_URL = 'http://169.254.169.254/latest/api/token';
14+
const AWS_EXTERNAL_IP_URL = 'http://169.254.169.254/latest/meta-data/public-ipv4';
15+
const AWS_INTERNAL_IP_URL = 'http://169.254.169.254/latest/meta-data/local-ipv4';
1516

1617
axios.defaults.timeout = NodeConfigs.DEFAULT_AXIOS_REQUEST_TIMEOUT;
1718

@@ -96,7 +97,7 @@ function sendGetRequest(endpoint, method, params) {
9697
function getIpAddress(internal = false) {
9798
return Promise.resolve()
9899
.then(() => {
99-
if (NodeConfigs.HOSTING_ENV === 'gcp') {
100+
if (NodeConfigs.HOSTING_ENV === HostingEnvs.GCP) {
100101
return axios.get(internal ? GCP_INTERNAL_IP_URL : GCP_EXTERNAL_IP_URL, {
101102
headers: {'Metadata-Flavor': 'Google'},
102103
timeout: 3000
@@ -108,6 +109,28 @@ function getIpAddress(internal = false) {
108109
CommonUtil.finishWithStackTrace(
109110
logger, `Failed to get ip address: ${JSON.stringify(err, null, 2)}`);
110111
});
112+
} else if (NodeConfigs.HOSTING_ENV === HostingEnvs.AWS) {
113+
const token = axios.put(AWS_TOKEN_URL, { }, {
114+
headers: {'X-aws-ec2-metadata-token-ttl-seconds': 21600}
115+
})
116+
.then((res) => {
117+
return res.data;
118+
})
119+
.catch((err) => {
120+
CommonUtil.finishWithStackTrace(
121+
logger, `Failed to get aws token: ${JSON.stringify(err, null, 2)}`);
122+
});
123+
return axios.get(internal ? AWS_INTERNAL_IP_URL : AWS_EXTERNAL_IP_URL, {
124+
headers: {'X-aws-ec2-metadata-token': token},
125+
timeout: 3000
126+
})
127+
.then((res) => {
128+
return res.data;
129+
})
130+
.catch((err) => {
131+
CommonUtil.finishWithStackTrace(
132+
logger, `Failed to get ip address: ${JSON.stringify(err, null, 2)}`);
133+
});
111134
} else {
112135
if (internal) {
113136
return ip.address();

config_client_api_ip_whitelist.sh

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,13 @@ printf "Enter password: "
7272
read -s PASSWORD
7373
printf "\n\n"
7474
if [[ $SEASON = "mainnet" ]]; then
75+
CHAIN_ID="1"
7576
KEYSTORE_DIR="mainnet_prod_keys"
7677
elif [[ $SEASON = "spring" ]] || [[ $SEASON = "summer" ]]; then
78+
CHAIN_ID="0"
7779
KEYSTORE_DIR="testnet_prod_keys"
7880
else
81+
CHAIN_ID="0"
7982
KEYSTORE_DIR="testnet_dev_staging_keys"
8083
fi
8184

@@ -87,14 +90,18 @@ else
8790
COMMAND_NODE_JS_FILE="getDevClientApiIpWhitelist.js"
8891
fi
8992

93+
printf "CHAIN_ID=$CHAIN_ID\n"
94+
printf "KEYSTORE_DIR=$KEYSTORE_DIR\n"
95+
printf "COMMAND_NODE_JS_FILE=$COMMAND_NODE_JS_FILE\n"
96+
9097
function config_node() {
9198
local node_index="$1"
9299
local node_ip_addr=${IP_ADDR_LIST[${node_index}]}
93100

94101
printf "\n\n<<< Configuring ip whitelist of node $node_index ($node_ip_addr) >>>\n\n"
95102

96103
KEYSTORE_FILE_PATH="$KEYSTORE_DIR/keystore_node_$node_index.json"
97-
CONFIG_NODE_CMD="node tools/api-access/$COMMAND_NODE_JS_FILE $node_ip_addr 0 keystore $KEYSTORE_FILE_PATH"
104+
CONFIG_NODE_CMD="node tools/api-access/$COMMAND_NODE_JS_FILE $node_ip_addr $CHAIN_ID keystore $KEYSTORE_FILE_PATH"
98105
if [[ ! $COMMAND = "get" ]]; then
99106
CONFIG_NODE_CMD="$CONFIG_NODE_CMD '$IP_ADDR'"
100107
fi

config_node_param.sh

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ function usage() {
88
printf "Example: bash config_node_param.sh dev add DEV_CLIENT_API_IP_WHITELIST '*'\n"
99
printf "Example: bash config_node_param.sh dev remove DEV_CLIENT_API_IP_WHITELIST 32.190.239.181\n"
1010
printf "Example: bash config_node_param.sh dev set DEV_CLIENT_API_IP_WHITELIST '*'\n"
11+
printf "Example: bash config_node_param.sh dev get CORS_WHITELIST\n"
1112
printf "\n"
1213
exit
1314
}
@@ -80,10 +81,13 @@ printf "Enter password: "
8081
read -s PASSWORD
8182
printf "\n\n"
8283
if [[ $SEASON = "mainnet" ]]; then
84+
CHAIN_ID="1"
8385
KEYSTORE_DIR="mainnet_prod_keys"
8486
elif [[ $SEASON = "spring" ]] || [[ $SEASON = "summer" ]]; then
87+
CHAIN_ID="0"
8588
KEYSTORE_DIR="testnet_prod_keys"
8689
else
90+
CHAIN_ID="0"
8791
KEYSTORE_DIR="testnet_dev_staging_keys"
8892
fi
8993

@@ -97,14 +101,18 @@ else
97101
COMMAND_NODE_JS_FILE="getNodeParam.js"
98102
fi
99103

104+
printf "CHAIN_ID=$CHAIN_ID\n"
105+
printf "KEYSTORE_DIR=$KEYSTORE_DIR\n"
106+
printf "COMMAND_NODE_JS_FILE=$COMMAND_NODE_JS_FILE\n"
107+
100108
function config_node() {
101109
local node_index="$1"
102110
local node_ip_addr=${IP_ADDR_LIST[${node_index}]}
103111

104112
printf "\n\n<<< Configuring ip whitelist of node $node_index ($node_ip_addr) >>>\n\n"
105113

106114
KEYSTORE_FILE_PATH="$KEYSTORE_DIR/keystore_node_$node_index.json"
107-
CONFIG_NODE_CMD="node tools/api-access/$COMMAND_NODE_JS_FILE $node_ip_addr 0 keystore $KEYSTORE_FILE_PATH $PARAM"
115+
CONFIG_NODE_CMD="node tools/api-access/$COMMAND_NODE_JS_FILE $node_ip_addr $CHAIN_ID keystore $KEYSTORE_FILE_PATH $PARAM"
108116
if [[ ! $COMMAND = "get" ]]; then
109117
CONFIG_NODE_CMD="$CONFIG_NODE_CMD '$VALUE'"
110118
fi

consensus/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const PushId = require('../db/push-id');
1212
const {
1313
BlockchainConsts,
1414
NodeConfigs,
15+
HostingEnvs,
1516
WriteDbOperations,
1617
PredefinedDbPaths,
1718
StateVersions,
@@ -155,7 +156,7 @@ class Consensus {
155156
this.isInEpochTransition = true;
156157
this.node.tryFinalizeChain();
157158
let currentTime = Date.now();
158-
if (NodeConfigs.HOSTING_ENV !== 'local' &&
159+
if (NodeConfigs.HOSTING_ENV !== HostingEnvs.LOCAL &&
159160
(this.epoch % 10 === 0 || CommonUtil.timestampExceedsThreshold(
160161
this.ntpData.syncedAt, healthThresholdEpoch * epochMs))) {
161162
// adjust time

db/functions.js

Lines changed: 55 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ class Functions {
154154
const timestamp = _.get(options, 'timestamp', null);
155155
const blockNumber = _.get(options, 'blockNumber', null);
156156
const blockTime = _.get(options, 'blockTime', null);
157+
const eventSource = _.get(options, 'eventSource', null);
157158
let triggerCount = 0;
158159
let failCount = 0;
159160
const promises = [];
@@ -190,7 +191,6 @@ class Functions {
190191
const newAuth = Object.assign(
191192
{}, auth, { fid: functionEntry.function_id, fids: this.getFids() });
192193
let result = null;
193-
const eventSource = _.get(options, 'eventSource', null);
194194
try {
195195
result = nativeFunction.func(
196196
value,
@@ -208,11 +208,11 @@ class Functions {
208208
blockNumber,
209209
blockTime,
210210
options,
211+
eventSource,
211212
auth: newAuth,
212213
opResultList: [],
213214
otherGasAmount: 0,
214215
...blockchainParams,
215-
eventSource,
216216
});
217217
funcResults[functionEntry.function_id] = result;
218218
if (DevFlags.enableRichFunctionLogging) {
@@ -236,51 +236,64 @@ class Functions {
236236
}
237237
}
238238
} else if (functionEntry.function_type === FunctionTypes.REST) {
239-
if (NodeConfigs.ENABLE_REST_FUNCTION_CALL && functionEntry.function_url &&
240-
CommonUtil.isWhitelistedUrl(functionEntry.function_url, this.db.getRestFunctionsUrlWhitelist())) {
241-
if (DevFlags.enableRichFunctionLogging) {
239+
// NOTE: Skipped when the event source is null.
240+
if (NodeConfigs.ENABLE_REST_FUNCTION_CALL &&
241+
eventSource !== null &&
242+
functionEntry.function_url) {
243+
const restFunctionUrlWhitelist = this.db.getRestFunctionsUrlWhitelist();
244+
if (!CommonUtil.isWhitelistedUrl(functionEntry.function_url, restFunctionUrlWhitelist)) {
245+
// NOTE: Skipped when the function url is not in the whitelist.
242246
logger.info(
243-
` ==> Triggering REST function [[ ${functionEntry.function_id} ]] of ` +
244-
`function_url '${functionEntry.function_url}' with:\n` +
247+
`Skipped triggering REST function [[ ${functionEntry.function_id} ]] of ` +
248+
`function_url '${functionEntry.function_url}' which is NOT in the whitelist: \n` +
249+
`${JSON.stringify(restFunctionUrlWhitelist)}` +
245250
formattedParams);
246-
}
247-
const newAuth = Object.assign(
248-
{}, auth, { fid: functionEntry.function_id, fids: this.getFids() });
249-
promises.push(axios.post(functionEntry.function_url, {
250-
fid: functionEntry.function_id,
251-
function: functionEntry,
252-
valuePath,
253-
functionPath,
254-
value,
255-
prevValue,
256-
params,
257-
timestamp,
258-
executedAt,
259-
transaction,
260-
blockNumber,
261-
blockTime,
262-
options,
263-
auth: newAuth,
264-
chainId: blockchainParams.chainId,
265-
networkId: blockchainParams.networkId,
266-
}, {
267-
timeout: NodeConfigs.REST_FUNCTION_CALL_TIMEOUT_MS
268-
}).catch((error) => {
251+
} else {
269252
if (DevFlags.enableRichFunctionLogging) {
270-
logger.error(
271-
`Failed to trigger REST function [[ ${functionEntry.function_id} ]] of ` +
272-
`function_url '${functionEntry.function_url}' with error: \n` +
273-
`${JSON.stringify(error)}` +
253+
logger.info(
254+
` ==> Triggering REST function [[ ${functionEntry.function_id} ]] of ` +
255+
`function_url '${functionEntry.function_url}' with:\n` +
274256
formattedParams);
275257
}
276-
failCount++;
277-
return true;
278-
}));
279-
funcResults[functionEntry.function_id] = {
280-
code: FunctionResultCode.SUCCESS,
281-
bandwidth_gas_amount: blockchainParams.restFunctionCallGasAmount,
282-
};
283-
triggerCount++;
258+
const newAuth = Object.assign(
259+
{}, auth, { fid: functionEntry.function_id, fids: this.getFids() });
260+
promises.push(axios.post(functionEntry.function_url, {
261+
fid: functionEntry.function_id,
262+
function: functionEntry,
263+
valuePath,
264+
functionPath,
265+
value,
266+
prevValue,
267+
params,
268+
timestamp,
269+
executedAt,
270+
transaction,
271+
blockNumber,
272+
blockTime,
273+
options,
274+
eventSource,
275+
auth: newAuth,
276+
chainId: blockchainParams.chainId,
277+
networkId: blockchainParams.networkId,
278+
}, {
279+
timeout: NodeConfigs.REST_FUNCTION_CALL_TIMEOUT_MS
280+
}).catch((error) => {
281+
if (DevFlags.enableRichFunctionLogging) {
282+
logger.error(
283+
`Failed to trigger REST function [[ ${functionEntry.function_id} ]] of ` +
284+
`function_url '${functionEntry.function_url}' with error: \n` +
285+
`${JSON.stringify(error)}` +
286+
formattedParams);
287+
}
288+
failCount++;
289+
return true;
290+
}));
291+
funcResults[functionEntry.function_id] = {
292+
code: FunctionResultCode.SUCCESS,
293+
bandwidth_gas_amount: blockchainParams.restFunctionCallGasAmount,
294+
};
295+
triggerCount++;
296+
}
284297
}
285298
}
286299
}

0 commit comments

Comments
 (0)