penumbra-zone / galileo Goto Github PK
View Code? Open in Web Editor NEWDiscord bot for the Penumbra discord
Discord bot for the Penumbra discord
Galileo can find messages from itself and try sending tokens based on them. Minor unexpected behavior that should be fixed sometime.
Adding a user ID filter would resolve this.
We only rebuild and redeploy Galileo when we launch a new Penumbra testnet. It's important that the dependencies from Penumbra are the tagged version from the release, as building from main
can cause breakage. We used to pin the tag in the Cargo.toml
, but stopped in #18. Instead of reverting to that practice, let's adjust the container build workflow to accept a build arg for the Penumbra version to use, defaulting to "main".
That way, we can trigger builds of a specific tagged version, and set that explicit tagged version in the deployment, so that even if the Galileo service is restarted, it won't repull a newer, and potentially incompatible, version.
We just did this in the Osiris repo, see:
After deployment of Testnet 53 (), tried to update galileo to use --node https://grpc.testnet.penumbra.zone
, but encountered an error:
Jun 01 22:00:06 galileo galileo[1631028]: Error: status: Internal, message: "protocol error: received message with invalid compression flag: 52 (valid flags are 0 and 1) while receiving response with status: 404 Not Found", details: [], metadata: MetadataMap { headers: {"content-type": "text/plain; charset=utf-8", "x-content-type-options": "nosniff", "content-length": "19", "date": "Thu, 01 Jun 2023 22:00:06 GMT"} }
Jun 01 22:00:06 galileo systemd[1]: galileo.service: Main process exited, code=exited, status=1/FAILURE
Jun 01 22:00:06 galileo systemd[1]: galileo.service: Failed with result 'exit-code'.
Oddly Osiris works just fine with the grpc https endpoint, and most of that logic in osiris was lifted directly from galileo. All other Penumbra tooling works well with the new endpoint, so figure out what's different about galileo. Might be a stale build env, but I was careful to run a cargo update
when debugging.
Release build fails with the msg below. Haven't investigated yet, will take a closer look to update galileo to match the most recent interfaces.
error[E0432]: unresolved import `penumbra_custody::SoftKms`
--> src/opt/serve.rs:6:5
|
6 | use penumbra_custody::SoftKms;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ no `SoftKms` in the root
|
help: consider importing this struct instead
|
6 | use penumbra_custody::soft_kms::SoftKms;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0432]: unresolved import `penumbra_proto::Protobuf`
--> src/wallet.rs:151:13
|
151 | use penumbra_proto::Protobuf;
| ^^^^^^^^^^^^^^^^^^^^^^^^ no `Protobuf` in the root
|
help: a similar name exists in the module
|
151 | use penumbra_proto::protobuf;
| ~~~~~~~~
help: consider importing this trait instead
|
151 | use tendermint_proto::Protobuf;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0599]: no method named `encode_to_vec` found for reference `&penumbra_transaction::Transaction` in the current scope
--> src/wallet.rs:161:45
|
161 | "params": [&transaction.encode_to_vec()],
| ^^^^^^^^^^^^^ method not found in `&penumbra_transaction::Transaction`
|
= help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
|
1 | use penumbra_proto::DomainType;
|
Some errors have detailed explanations: E0432, E0599.
For more information about an error, try `rustc --explain E0432`.
error: could not compile `galileo` due to 3 previous errors
There are two problems:
We'll need to make those changes for a successful build on 51.
Galileo always emits colored logs, which breaks log-level detection when aggregating events and searching across them. As we've done in e.g. pd
, let's conditionally disable colorization of log messages when no tty exists. That way, devs can still see colored events, but log slurpers will not have their ingestion polluted with escape codes.
During deploy of 037-megaclite.1
(penumbra-zone/penumbra#1699), encountered an error during "catch-up". From the galileo logs:
Dec 06 17:26:42.693 ERROR galileo::catchup: failed to send tokens user_id=UserId(<REDACTED>) response=Response { succeeded: [], failed: [(penumbrav2t1kdkntdcvx9evg0xwqzzwwy2nflxazzjr4x7rs8n6gh0a9eftjrwgfsejj2rfesys2uyz0avldjfnhjdd08enp6sz8y3slvxaqnr0uh7s8mf27xdz2a6grsk2lqxa9eq6ux6772, "Error submitting transaction: code 1, log: nullifier 0a0d7727bba46013b4a437bfff6f8578a5cff69078e2335cacc6a43775907008 was already spent in NoteSource::Transaction(20f8238319d50f5aa1135b848a6faea5756a37d687f6419340487f561a9bccec)")], unparsed: [], remaining: [] }
Despite that logged error, the catch-up process succeeded, and folks received their tokens. @plaidfinch suggested this may indicate a race condition, where spends are attempted before chain history was fully up to date.
When Galileo responds to a Discord user, it emits a message like:
Successfully sent tokens to the following addresses:
penumbrav2t1k4yd4zdartyt9e8rt9s4fhc4… (try pcli v tx 137dd196e2d1d13c3104b37ad90a21c8d95655a1e8e633f2fba883401e28fb8e)
Let's update that message so that the tx id is a URL, viewable within the extension.
Over the weekend the wallet ran out of pizza
[sic] tokens, and disbursements started failing with this message:
"error fetching notes: requested amount of 10 exceeds total of 0";
To resolve, I compared the denoms included on the service with the output from the bot's pcli view balance
and concluded it was pizza
that was missing. Removing the denom from the args and bouncing the service resolved.
Ideally, the error message would include the denom. Low-priority, but look to update the message when making other changes. See relevant Discord discussion.
Galileo currently listens to chatter in all Discord channels it has access to, and responds by default. This means that addresses can get posted in a lot of different channels, and our Discord admins have to explicitly ban Galileo from responding in those channels. That's no good. Instead, let's add a --watched-channel
flag, which can be repeated, then we'll narrowly target only specific channels that Galileo will listen for messages on.
See here: https://github.com/penumbra-zone/galileo/actions/runs/5214482918 Every step of that job failed:
and yet GitHub reports the job as Passing ✔️ . Why? Fix it.
The bot is designed to disburse funds to any valid penumbra wallet address, currently prefixed with penumbrav2t
. Folks new to the platform may mistakenly share secrets, such as a full viewing key. Let's consider warning those folks about the need to rotate those secrets if shared in the bot channel. For reference, see the list of BECH32_PREFIX values in https://github.com/penumbra-zone/penumbra/blob/main/proto/src/serializers/bech32str.rs#L168
From galileo logs:
ERROR galileo::catchup: failed to send tokens user_id=UserId([REDACTED]) response=Response { succeeded: [], failed: [(penumbrav2t1u9aysnt5c3lfrfh7pn7qlkxtxwlzt5suqwajcn9k3ehcpqphzf22qtwz0ywcqvqd7z5ma6pdlzjc0wra8mlj36ly7llvz9wjtje3575sknhkjfky36rxnunxp5mzxu0kl9hqkv, "Error submitting transaction: code 1, log: proof did not verify")], unparsed: [], remaining: [] }
When debugging Galileo, it'd be nice to have some dry-run options to facilitate local testing, such as "don't send txs, only log what would be sent" and "don't send any discord messages, only log what would be sent". Adding these options would make it a lot easier to iterate on Galileo configs in a less disruptive manner, as the current code requires us to run code changes against the actual Discord, and put up with notifications and sends.
STR:
cargo update
We get a bunch of errors when compiling the ibc-proto
dependency:
error[E0277]: the trait bound `SignedHeader: prost::Message` is not satisfied
--> /root/.cargo/git/checkouts/ibc-rs-6a90942b4438b630/09a244b/proto/src/prost/ibc.lightclients.tendermint.v1.rs:85:28
|
85 | #[derive(Clone, PartialEq, ::prost::Message)]
| ^^^^^^^^^^^^^^^^ the trait `prost::Message` is not implemented for `SignedHeader`
|
note: required by a bound in `prost::encoding::message::encoded_len`
--> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/prost-0.9.0/src/encoding.rs:1104:12
|
1104 | M: Message,
| ^^^^^^^ required by this bound in `prost::encoding::message::encoded_len`
= note: this error originates in the derive macro `::prost::Message` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `ValidatorSet: prost::Message` is not satisfied
--> /root/.cargo/git/checkouts/ibc-rs-6a90942b4438b630/09a244b/proto/src/prost/ibc.lightclients.tendermint.v1.rs:85:28
|
85 | #[derive(Clone, PartialEq, ::prost::Message)]
| ^^^^^^^^^^^^^^^^ the trait `prost::Message` is not implemented for `ValidatorSet`
|
note: required by a bound in `prost::encoding::message::encoded_len`
--> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/prost-0.9.0/src/encoding.rs:1104:12
|
1104 | M: Message,
| ^^^^^^^ required by this bound in `prost::encoding::message::encoded_len`
= note: this error originates in the derive macro `::prost::Message` (in Nightly builds, run with -Z macro-backtrace for more info)
The most recent testnet (penumbra-zone/penumbra#1699) shows errors when using the faucet:
Dec 06 00:46:01.715 ERROR galileo::catchup: failed to send tokens user_id=UserId(<REDACTED>) response=Response { succeeded: [], failed: [(penumbrav2t1mccl4m4jp7x75arhdevawd5cu5cyruf0q2x3t92t2esvewulyyjmqtghk6rdsn5ymt523u2ul24hz2ne5xkkcfwq76dge258q0rct29rvlqd5594awqh0sxlt62zmknhwx3n5h, "can't build send transaction")], unparsed: [], remaining: [] }
(That's my ephemeral penumbra address; i've redacted the discord user id.) Why is this failing? May be related to recent upstream code changes.
Logs:
Feb 06 22:10:45 galileo systemd[1]: Started Galileo, the Discord bot for dispending Penumbra testnet tokens.
Feb 06 22:10:45 galileo galileo[781578]: Error: invalid type: string "<REDACTED>", expected struct penumbra.core.crypto.v1alpha1.SpendKey at line 1 column 90
Feb 06 22:10:45 galileo systemd[1]: galileo.service: Main process exited, code=exited, status=1/FAILURE
Feb 06 22:10:45 galileo systemd[1]: galileo.service: Failed with result 'exit-code'.
Feb 06 22:12:00 galileo systemd[1]: Stopped Galileo, the Discord bot for dispending Penumbra testnet tokens.
The <REDACTED>
string is the full spendkey for the Galileo bot. Will update the code to match the latest protos.
A CI run on this repo currently takes about ~20m. If changes are required, that's ~45m round-trip for a small change like #18. Can we make it faster? Consider more aggressive caching of previous builds, upgrading to a third-party runner (as we do in the main "penumbra" repo), or selectively targeting push/pull for certain workflows.
See also #17 for planned CI improvements.
As part of the weekly testnet deploy process, we use galileo
to read through the recent Discord history and collect disbursements for those requesting funds via the faucet. Rather than asking a human to run these steps interactively, let's automate that step. The process is documented step by step here: https://github.com/penumbra-zone/penumbra/pull/1658/files#diff-83c75d0833c2c520a465acf2286aad6646d817bc143f82edb12d606b57f97c89L41-L52
We should also stop pinning specific tags in Galileo's Cargo.toml
: we can just track main, and respond if and when things break. (Changes such as #15 are substantive; much of the recent galileo history in contrast is bumps to the pinned tags.)
See discussion in penumbra-zone/penumbra#1658 for additional context.
Syncing takes a long time: currently ~15m for 200k blocks, or one week of a testnet. This time to sync will grow. Currently, restarting Galileo for any reason, such as deploying a code fix (#72), causes ~15m of downtime while the service syncs.
If Galileo had a /healthz
endpoint, we could return non-200 while view server is syncing, and 200 OK when it's ready. Doing that would allow us to roll over Galileo deployments with minimal downtime.
However, at root we want syncing to be fast.
Saw an interesting failure mode today:
"Worker failed: status: Unavailable, message: "error querying abci: response error\n\nCaused by:\n Internal error: height 9307 must be less than or equal to the current blockchain height 9306 (code: -32603)\n\nLocation:\n /usr/local/cargo/registry/src/index.crates.io-6f17d22bba15001f/flex-error-0.4.4/src/tracer_impl/eyre.rs:10:9", details: [], metadata: MetadataMap { headers: {"content-type": "application/grpc", "date": "Tue, 22 Aug 2023 10:46:17 GMT", "content-length": "0"} }", details: [], metadata: MetadataMap { headers: {"content-type": "application/grpc"} })
Galileo was stuck, sending that message on every faucet request. Simply bouncing the service via kubectl rollout restart deployment galileo
was enough to get it working again, but we should figure out how that failure occurred.
See related discussion in #26 (comment)
As of Testnet 60, Galileo builds cleanly (cf. penumbra-zone/osiris#21), but on service start fails with:
Error: status: Internal, message: "protocol error: received message with invalid compression flag: 52 (valid flags are 0 and 1) while receiving response with status: 404 Not Found", details: [], metadata: MetadataMap { headers: {"content-type": "text/plain; charset=utf-8", "x-content-type-options": "nosniff", "content-length": "19", "date": "Mon, 11 Sep 2023 20:11:46 GMT"} }
Let's figure that out.
Today we released 045-metis
(penumbra-zone/penumbra#1987) and building Galileo fails with:
error[E0308]: mismatched types
--> src/wallet.rs:145:13
|
138 | let plan = plan::send(
| ---------- arguments to this function are incorrect
...
145 | source_address,
| ^^^^^^^^^^^^^^ expected struct `penumbra_crypto::keys::AddressIndex`, found enum `std::option::Option`
|
= note: expected struct `penumbra_crypto::keys::AddressIndex`
found enum `std::option::Option<u64>`
Tried a naive approach to satisfy the type-checker, but got stuck on an allegedly missing FromStr impl for penumbra_crypto::keys::AddressIndex
. Will take a closer at related PR penumbra-zone/penumbra#1994 (comment) and try again, possibly pulling in some consult with @aubrika.
While debugging the service today, I wanted to request several disbursements, to ensure things were working as I expected. Normally only one disbursement per 24h is allowed, but there's a CLI flag:
-r, --rate-limit <RATE_LIMIT>
Per-user rate limit (e.g. "10m" or "1day") [default: 1day]
Restarting the service with e.g. --rate-limit 5m
is enough for quick interactive testing, but it'd be nice if galileo were smart enough to recognize Discord admins (typically, but not always, Penumbra Labs staff) and declined to rate limit them.
In #43 we opted-in to using an in-memory db for galileo, so it doesn't need to rely on a filepath for the pcli db. That's rad, and we're excited to use it. We're not using it yet though, since we merged that PR right after Testnet 51 went out (technically after v0.51.2, which was a bumpy ride). Just checked, and Galileo is currently running off commit 9cf69ef.
During a debugging pairing session on Osiris, which reuses a fair amount of Galileo code, we observed some surprising behavior related to the in-memory database. Our current strategy is to limit the connection pool to 1 if-and-only-if we're using in-memory db. We should make the corresponding change to Galileo, too, or else revert to using the on-disk db.
Galileo fails to build due to being unable to resolve Git LFS pointers is the dependency penumbra-proof-params
. This can be seen in this CI job.
@plaidfinch found this issue indicating that Git LFS assets in dependencies is not supported by cargo: rust-lang/cargo#9692
During release of Lysithea (penumbra-zone/penumbra#2005) we temporarily used a path dependency to get galileo to build.
Another option suggested by @plaidfinch is to use a submodule, which @conorsch volunteered to take a look at.
During release of testnet 49, we updated galileo with a new --catch-up
URL, as usual. There were only a handful (i.e. single-digits) of messages it needed to catch up on, but it started sending a lot of messages about catching up, tagging dozens of users. Rather than debug, since we'd just resolved #37, I removed the catch-up URL from the service config and restarted it.
For reference, see context in discord starting around https://discord.com/channels/824484045370818580/915710851917439060/1090698486049148938.
We may encounter again on 50 and need to debug.
The changes to the wallet architecture have broken the Galileo code, so it needs to be rewritten to match the new architecture. Fortunately, this should be much easier than before.
The basic shape of the new structure should, initially, look roughly like:
ViewService
that syncs with the chain;SoftHSM
that stores the spend key;Because the mpsc sender is clonable, it can be fed by two tasks: one that's responsible for catching up on backlog, and another that's responsible for responding to current requests, or whatever other setup makes sense for the existing architecture.
This is an MVP implementation of the new architecture. In the future, it could be straightforwardly extended to allow the worker more parallelism and reduced latency, by having the worker keep a (time-limited) cache of notes it may have spent, or by creating custom transaction plans that rebalance its funds across N notes, etc. But because the code doesn't currently work, we should do the simplest possible thing to get it working again, before extending it.
When Galileo "catches up" after a service restart, typically done during a testnet deploy, it scans all history messages more recent than a specific message, searches them for penumbra addresses via regex, and dispenses to those addresses. Now that Galileo replies to requests, with the requester's address included in the reply text, Galileo double-counts the first requester. This affects both the history
command (which we rarely run) and the catch-up logic, with draws on history logic.
Simply instructing galileo to skip considering messages that it sent itself would be enough to resolve the bug.
We've reorganized all of our protobuf files, which has broken Galileo.
We should also make sure that we are using the latest version of serenity
which has important fixes related to Tokio.
❯ cargo build --release
Updating git repository `https://github.com/penumbra-zone/ibc-types`
Updating crates.io index
error: failed to select a version for `ibc-proto`.
... required by package `ibc-types-core-channel v0.2.0 (https://github.com/penumbra-zone/ibc-types?branch=main#6a40a65f)`
... which satisfies git dependency `ibc-types-core-channel` of package `ibc-types2 v0.2.0 (https://github.com/penumbra-zone/ibc-types?branch=main#6a40a65f)`
... which satisfies git dependency `ibc-types2` of package `penumbra-ibc v0.54.0 (/home/conor/src/penumbra/crates/core/component/ibc)`
... which satisfies path dependency `penumbra-ibc` of package `penumbra-app v0.54.0 (/home/conor/src/penumbra/crates/core/app)`
... which satisfies path dependency `penumbra-app` of package `penumbra-view v0.54.0 (/home/conor/src/penumbra/crates/view)`
... which satisfies path dependency `penumbra-view` of package `galileo v0.1.0 (/home/conor/src/galileo)`
versions that meet the requirements `^0.31.0` are: 0.31.0
all possible versions conflict with previously selected packages.
previously selected package `ibc-proto v0.31.0-alpha.1`
... which satisfies dependency `ibc-proto = "=0.31.0-alpha.1"` (locked to 0.31.0-alpha.1) of package `ibc-types v0.2.0 (https://github.com/penumbra-zone/ibc-types?branch=0.2.x#0557a7b6)`
... which satisfies git dependency `ibc-types` (locked to 0.2.0) of package `penumbra-app v0.54.0 (/home/conor/src/penumbra/crates/core/app)`
... which satisfies path dependency `penumbra-app` of package `penumbra-view v0.54.0 (/home/conor/src/penumbra/crates/view)`
... which satisfies path dependency `penumbra-view` of package `galileo v0.1.0 (/home/conor/src/galileo)`
failed to select a version for `ibc-proto` which could resolve this conflict
Build fail against latest testnet release, 49 penumbra-zone/penumbra#2255
cargo build --release
Compiling galileo v0.1.0 (/home/conor/src/galileo)
error[E0061]: this function takes 3 arguments but 4 arguments were supplied
--> src/opt/serve.rs:110:28
|
110 | let view_storage = penumbra_view::Storage::load_or_initialize(
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
116 | self.node.clone(),
| ----------------- expected struct `Url`, found struct `String`
117 | self.pd_port,
| ------------ argument of type `u16` unexpected
|
note: associated function defined here
--> /home/conor/.cargo/git/checkouts/penumbra-54633d8978d5e293/4dd9fa3/view/src/storage.rs:52:18
|
52 | pub async fn load_or_initialize(
| ^^^^^^^^^^^^^^^^^^
help: remove the extra argument
|
110 ~ let view_storage = penumbra_view::Storage::load_or_initialize(view_file
111 + .to_str()
112 + .ok_or_else(|| anyhow::anyhow!("Non-UTF8 view path"))?
113 + .to_string(), &fvk, /* url::Url */)
|
error[E0061]: this function takes 2 arguments but 3 arguments were supplied
--> src/opt/serve.rs:120:28
|
120 | let view_service = ViewService::new(view_storage, self.node.clone(), self.pd_port).await?;
| ^^^^^^^^^^^^^^^^ ----------------- ------------ argument of type `u16` unexpected
| |
| expected struct `Url`, found struct `String`
|
note: associated function defined here
--> /home/conor/.cargo/git/checkouts/penumbra-54633d8978d5e293/4dd9fa3/view/src/service.rs:90:18
|
90 | pub async fn new(storage: Storage, node: Url) -> Result<Self, anyhow::Error> {
| ^^^
help: remove the extra argument
|
120 | let view_service = ViewService::new(view_storage, /* url::Url */).await?;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0277]: the trait bound `penumbra_transaction::WitnessData: From<penumbra_proto::core::transaction::v1alpha1::AuthorizationData>` is not satisfied
--> src/sender.rs:89:18
|
89 | .try_into()?;
| ^^^^^^^^ the trait `From<penumbra_proto::core::transaction::v1alpha1::AuthorizationData>` is not implemented for `penumbra_transaction::WitnessData`
|
= note: required for `penumbra_proto::core::transaction::v1alpha1::AuthorizationData` to implement `Into<penumbra_transaction::WitnessData>`
= note: required for `penumbra_transaction::WitnessData` to implement `TryFrom<penumbra_proto::core::transaction::v1alpha1::AuthorizationData>`
= note: required for `penumbra_proto::core::transaction::v1alpha1::AuthorizationData` to implement `TryInto<penumbra_transaction::WitnessData>`
error[E0061]: this method takes 3 arguments but 4 arguments were supplied
--> src/sender.rs:95:18
|
95 | .build_concurrent(OsRng, &self2.fvk, auth_data, witness_data)
| ^^^^^^^^^^^^^^^^ ------------ argument of type `penumbra_transaction::WitnessData` unexpected
|
note: associated function defined here
--> /home/conor/.cargo/git/checkouts/penumbra-54633d8978d5e293/4dd9fa3/transaction/src/plan/build.rs:182:18
|
182 | pub async fn build_concurrent<R: CryptoRng + RngCore>(
| ^^^^^^^^^^^^^^^^
help: remove the extra argument
|
95 | .build_concurrent(OsRng, &self2.fvk, auth_data)
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0308]: mismatched types
--> src/sender.rs:99:46
|
99 | self2.view.broadcast_transaction(tx, true).await
| --------------------- ^^ expected struct `Transaction`, found struct `UnauthTransaction`
| |
| arguments to this method are incorrect
|
note: associated function defined here
--> /home/conor/.cargo/git/checkouts/penumbra-54633d8978d5e293/4dd9fa3/view/src/client.rs:175:8
|
175 | fn broadcast_transaction(
| ^^^^^^^^^^^^^^^^^^^^^
Some errors have detailed explanations: E0061, E0277, E0308.
For more information about an error, try `rustc --explain E0061`.
error: could not compile `galileo` due to 5 previous errors
At least one of the changes relates to penumbra-zone/penumbra#2196 ; others will take some more spelunking. Looking into it.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.