Concurrent Price Stream (feeds) is a module within BandChain that provides a decentralized mechanism for signal voting, price submission, and price updates. Validators play a key role in this process by collecting and submitting price data based on signals (symbols) requested by participants on BandChain. These signals are prioritized through signal voting, and the top 300 signals, determined by stake-weighted votes, are the ones for which validators need to retrieve price data. Validators then submit this data to BandChain at the end of each block.
Adding a New Signal
If you want a new signal to be included on BandChain for price data providing, you need to participate in the voting process. The ability to vote is based on your Band staking and delegation power. New signals must have a reference source listed in the ReferenceSourceConfig
on BandChain. If the desired source is not listed, you will need to contact the administrator to request its addition.
Example of Voting for a New Signal
To vote for a signal, use the MsgVote
message format. Below is the structure of the MsgVote
message:
// MsgVote is the transaction message to vote signals.
message MsgVote {
option (cosmos.msg.v1.signer) = "voter";
option (amino.name) = "feeds/MsgVote";
// voter is the address of the voter that wants to vote signals.
string voter = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"];
// signals is a list of submitted signals.
repeated Signal signals = 2 [(gogoproto.nullable) = false];
}
// Signal is the data structure that contains signal id and power of that signal.
message Signal {
option (gogoproto.equal) = true;
// id is the id of the signal.
string id = 1 [(gogoproto.customname) = "ID"];
// power is the power of the corresponding signal id.
int64 power = 2;
}
After sending the MsgVote
message, the voting results are computed based on the CurrentFeedsUpdateInterval
. This interval specifies how often new votes are calculated and integrated into the system. Currently, the CurrentFeedsUpdateInterval
is set to 86,400 blocks, which equates to approximately one day. At the end of each interval, the vote results determine the top 300 signals, which validators are then required to source and submit price data for.
ReferenceSourceConfig
. Contact the administrator if the source is not available.The Tunnel Module plays a critical role in decentralized packet creation by enabling the configuration of intervals and deviations for transmitting price data from Concurrent Price Stream to Ethereum Virtual Machine (EVM)-compatible blockchains, as well as other Cosmos-based blockchains. It integrates with key technologies such as Threshold Signature Schemes (TSS), Inter-Blockchain Communication (IBC), and other bridge technologies to ensure secure and efficient data transmission.
The x/tunnel
module defines a Tunnel
type that specifies details such as the way to send the data to the destination route, the type of price data to encode, the address of the fee payer responsible for covering packet fees, and the total deposit of the tunnel (which must meet a minimum requirement to activate now is 1000000000 uband
) and the interval and deviation settings applied to price data during packet production at each end-block.
Users can create a new tunnel by submitting a MsgCreateTunnel
message to BandChain, specifying the desired signals, deviations, intervals, and the route to which the data should be sent. The available routes for tunnels are detailed in the route section.
// MsgCreateTunnel is the transaction message to create a new tunnel.
message MsgCreateTunnel {
option (cosmos.msg.v1.signer) = "creator";
option (amino.name) = "tunnel/MsgCreateTunnel";
// signal_deviations is the list of signal deviations.
repeated SignalDeviation signal_deviations = 1 [(gogoproto.nullable) = false];
// interval is the interval for delivering the signal prices in seconds.
uint64 interval = 2;
// route is the route for delivering the signal prices
google.protobuf.Any route = 3 [(cosmos_proto.accepts_interface) = "RouteI"];
// initial_deposit is the deposit value that must be paid at tunnel creation.
repeated cosmos.base.v1beta1.Coin initial_deposit = 4 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
(amino.dont_omitempty) = true
];
// creator is the address of the creator.
string creator = 5 [(cosmos_proto.scalar) = "cosmos.AddressString"];
}
// SignalDeviation is the type for a signal with soft and hard deviation
message SignalDeviation {
option (gogoproto.equal) = true;
// signal_id is the signal ID
string signal_id = 1 [(gogoproto.customname) = "SignalID"];
// deviation_bps is the deviation in basis points
uint64 deviation_bps = 2 [(gogoproto.customname) = "SoftDeviationBPS"];
}
A Route defines the secure method for transmitting price data to a destination chain using a tunnel. It specifies the pathway and protocols that ensure safe and reliable data delivery from BandChain to other EVM-compatible chains or Cosmos-based blockchains.
IBC Route
The IBC Route enables the transmission of data from BandChain to Cosmos-compatible chains via the Inter-Blockchain Communication (IBC) protocol. This route allows for secure and efficient cross-chain communication, leveraging the standardized IBC protocol to transmit packets of data between chains.
bandd tx tunnel create-tunnel ibc [initial-deposit] [interval] [signalInfos-json-file]
signal_infos.json example
{
"signal_deviations": [
{
"signal_id": "CS:BTC-USD",
"deviation_bps": 200
},
{
"signal_id": "CS:ETH-USD",
"deviation_bps": 400
}
]
}
TSS Route
The TSS Route enables the tunnel to send data securely from BandChain to the destination chain using a TSS (Threshold Signature Scheme) signature. This approach ensures secure data signing within a decentralized network.
The tunnel requests the BandTSS module to sign the tunnel packet. Once the signing process is complete, a relayer captures the signed message and relays it to the destination chain. The destination chain can also verify that the data originates from BandChain without any modifications, ensuring data integrity.
bandd tx tunnel create-tunnel tss [destination-chain-id] [destination-contract-address] [initial-deposit] [interval] [signalDeviations-json-file]
Router Route
This is what we are currently working on, with the specifications shown below.
The Router route is one of the routes provided by the Tunnel module for transmitting price data from BandChain to other chains using Router bridge technology. This route ensures secure and efficient data transfer leveraging Router's capabilities.
Create a new Router tunnel:
Use the following command to create a Router tunnel:
ββββbandd tx tunnel create-tunnel router [dest-chain-id] [dest-contract-address] [dest-gas-limit] [dest-gas-price] [initial-deposit] [interval] [signalDeviations-json-file]
Deposit BAND for the tunnel:
Ensure the tunnel meets the minimum deposit requirement of 1000000000 uband
. You can include the deposit in the create-tunnel message or deposit separately using the following command:
ββββbandd tx tunnel deposit-to-tunnel [tunnel-id] [amount]
Fund the fee payer:
Add funds to the fee payer account to cover the base fee and route fee for each packet creation.
Note: The fee_payer address will be generated by BandChain after the tunnel is created.
TBD: fund the ROUTE
on the router contract to pay the bridge fee for the tunnel. For example, deposit 500 ROUTE
for tunnel ID 1 or for the address matching the fee_payer
address hashed to the router address.
Activate the tunnel:
Once the tunnel is funded, activate it to start producing packets at the end of each block based on the specified interval and deviation settings.
A router packet will be produced by calling the IBC hook at the end of the block, based on signal (symbol) deviation and the interval settings of each tunnel.
ββββ{
ββββ "wasm": {
ββββ "contract": "router17c2txg2px6vna8a6v4ql4eh4ruvprerhytxvwt2ugp4qr473pajsyj9pgm",
ββββ "msg": {
ββββ "receive_band_data": {
ββββ "dest_chain_id": "17000",
ββββ "dest_contract_address": "0xDFCfEbF22e85193eDc37b8b136d4F3394987d1AE",
ββββ "gas_limit": 300000,
ββββ "gas_price": 10000000,
ββββ "payload": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZyMsxwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCVEMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEZ4w",
ββββ "nonce": 0,
ββββ "signature": ""
ββββ }
ββββ }
ββββ }
ββββ}
ββββpacketType, _ = abi.NewType("tuple", "", []abi.ArgumentMarshaling{
ββββ {Name: "TunnelID", Type: "uint64"},
ββββ {Name: "Sequence", Type: "uint64"},
ββββ {
ββββ Name: "SignalPrices",
ββββ Type: "tuple[]",
ββββ Components: []abi.ArgumentMarshaling{
ββββ {Name: "SignalID", Type: "bytes32"},
ββββ {Name: "Price", Type: "uint64"},
ββββ },
ββββ },
ββββ {Name: "CreatedAt", Type: "int64"},
ββββ})
By following these steps, users can successfully create and manage a router tunnel, ensuring seamless price data transmission between BandChain and other chains.
Sources:
https://github.com/bandprotocol/chain/tree/master/x/feeds
https://github.com/bandprotocol/chain/tree/master/x/tunnel