this. Okay, so welcome to this Hyperledger Sweden Meetup. My name is Roland and I'm your guest for today's session. And as I've mentioned, today, I think we will have a great session. So that is the 10th session in this row. And I think that's a small, we have something to celebrate with this. And in this session, I will discover a special topic. So this topic is from a user request or from somebody who is watching this series. And he came up with a question, how we can use the Node.js SDK with the development network. And when I talk about development network, I mean the Docker Dev Mode, this is the network we have developed on the end of January. So we can use Docker version of that or a binary version. And this request is about the binary version. So today, we will see how we can make this, we can use this binary version from SAP and the order. And then we can write the Node.js chain code. And also how we can use the Node.js SDK to connect to this test network. And this is the session today. So, okay, a short overview. At the beginning, I will give you an overview about this development environment. So we have done this in the past. So I have linked this support material here from the 29 of January this year. And in this support material, you will find two links. One of them is broken. So I will fix that as soon as possible. And in this session from 29 of January, we have seen how we can create a binary version development environment. So this means without any Docker system, and how we can use a Docker composition to use them. And there you will find a detailed step-by-step guide how you can set up this. And today, we will use this setup. And we will try to develop or we will use this predefined chain code as a transfer basic example. And then we will show you how you can connect to this network. And that's the reason why I have divided this session into two parts. The first part is the preparation of the chain code development environment. So I will show you all the steps again. The only single missing steps are how you can build the go binaries for the B and the order and how you can clone the favorite repo from the official GitHub repository. But this information is also in this support material here. And then we will see how we can use this chain code and what is the advantage of this PDF mode. And then we will see how we can use the Node.js SDK to interact with this dev network. And yeah, support material is here. And here's a link of that. Here's the link of the support material from the previous session. And then here you will find my two links to the Hyperledger favorite documentation and then to the favorite chain code node version. It's also always a good tip to read this documentation and to see how things can work. And here a short overview of this development environment. So this is a try to make this a little bit understandable. So when we use, in this example, we are going to use the binary version. So that means that we will not use any Docker environment here. So we have the possibility that we can build and go binary for the order and then go binary for the peer. And we can run this to systems and then we can start the chain code by hand and then we can interact with this chain code. And in this scenario, we will have here a simple network. The favorite repository gives us all the binary, all the crypto material and config which we need. And that's also the key to this task. So when we look into this favorite repository, then we will find the folder called sample config. And in this sample config, we have a folder membership MSP membership service provider with all the the crypto materials and certificates we need to get this running. And yeah, so we will have this, we will use only the binary versions. So and then we need some tools to control this. So maybe we can use this with a terminal multiplexer or we can use it with the jobs command or with the age stop command. So we can because we would like to run this order on the video in the background. So we will not see the in the photo in the photo ground that the terminal is blocked in this way. And yeah, so then we have a peer and the order are running. And we have to create the Genesis block, we have to create the channel transaction, we have to create the channel, join the channel, install the chain code and approve and commit the chain code according to the new lifecycle development in fabric 2.2. And so, and this means this are the elements from this, from a typical development environment which you can have on your local machine. And then we need the favorite Node.js SDK. So we have to install it with the npm command. So current version is 2.25, I think. And then we need the connection profile. So that's an important part or the tricky part, how we can make this, how we can make this connection profile or which information we should put in the, into this connection profile. And this is an important task, how we can do this. And then we have to create an identity to interact with the network. And in the favorite sample conflicts, we will see that in this membership service provider folder, we will find an admin chart and a key store with a private key. And we need both of them to create an identity and to convert this, to convert this identity to and look to the local wallet. So the Node.js SDK works as a client. And this client has a wallet, the local wallet, the file wallet in our example. And we have to convert the existing crypto materialistic, the, the, the signing certification and the private keys to this local wallet identity, because we don't have a favorite say running here. So we cannot read just the end roll and new identity. So we have to use this one. And for this, we will create a small script. I call this edge to wallet. So you find the script or parts or elements of this script also in some favorite samples, especially in the commercial paper repository or example. And there is a similar script on this also called at two wallet shares. And with this, this is one of our first tasks. We have to create an identity for this local wallet. And then we can use this identity to interact with the network. And these are the steps we have to do here now. Okay, so, yeah, here I have a step by step in a guide here as an overview. So the first step is that we have to start the development network. And we need the chain code for this. And I have copied the asset transfer basic chain code. And we can do a little bit with them and try this to, to modify or to, to test if the chain code is working or something like that. So we need a chain code. And since this session is all, all about the Node.js. So we use the Node.js version from that. And yeah, that's the first thing. So we need the network and we need the running system with a chain code. And then we need the connection profile. So we have to create this connection profile. The connection profile is nothing more than a JSON file or a YAML file, which contains some useful information for from the network. So in this connection profile, you will set your peer, your address, a peer address, or your, your peers from the peer, a TLS certificate, for example, the order of information, or the channel information. And maybe this is also another important piece to get this running. So since this development environment is not so, I'm not sure if this is a real, real network, because we only have a limited network. And that's the reason why I think the discovery service is not working. And that's also the reason why we have to disable the discovery service in the connection part from the Node.js application. And we have to write our connection profile by ourselves. And yeah, so that's not really difficult. You only have to know what you have to fill in on the right position. And then we have to convert the identity. So Hyperledge Affair is an permissioned blockchain system. So every transaction needs an identity. And we need one identity. And we cannot take any identity which not belongs to the system. So that's the reason why, for example, you will find an admin certificate and also the private key of this admin. And then we can take these two files and then we can put this into the local wallet and create an identity which the Node.js SDK can read. And this is done with this extra wallet script. But this, you can do this also for a regular for the test network in the test network example. And you can do it also in your regular network. So that's, there's no different to do this. And then we can create a short command line interface program. So which we can start from the command line with the node profile, with the node command and then interact with the network. So I call this index.js. And then we can interact with the network. But on this position, you can also write the Node.js application, express.js application. You can use another West API framework where you can create whatever you want here. But these one, two, three, four steps are the steps we are going to do now in this session today. Okay. So I think the first, the important part here is when we have to look where we find all this information. So, and in this favorite death folder, we have created in the last session, we have also cloned this favorite repository. And then this favorite repository, we will find this sample conflict folder. So this is important for us because in the sample conflict folder here, we will find all the needed elements for our test network. We'll find here the conflict TX YAML file for the configuration. We will find here the core YAML file and also the order YAML file. The core YAML file and all the styles are important for the connection for the conflict path, the conflict path. And when we look into the MSP folder, you see here, here is admin certs, for example, and so on. And the key file from that. So we can use this information to create a local identity. And yeah, so that's important to know that we can find all the elements here in this folder. And also important to know is when we look into this conflict TX YAML file here, then we see the name of this network. So, and important here is the membership service provider ID so that we, because we have to use this in the connection profile, the name. Okay, so the first step is now that we start our network. And I use this terminal multiplexer for that. And we need two environment variables here. We need the path. So we have to extend the path with our favorite build path here. So this is the only part which I don't, I'm not showing here in this example how you can build the binaries here. So we have here the order and the beer and this conflict TX again file to create the genesis block and the trans channel transaction. But how you can do this, you will find this in the documentation. And you can find as well this in the documentation in the official fabric documentation. So but not in the 2.2 version, you will find this only in the 2.3 version. I don't know why. But in the 2.3 version, you will find also official documentation how you can use this def mode in the binary version here. So okay. Yeah, so we need the path and we need the fabric conflict path because we have seen here are all important environment files are located. So okay, so now the first step like in every system is that we have to create the genesis block. And we have here the same, we need a profile for that. And this is the sample def mode solo profile. And you find this here in the, you will find this here in the conflict TX example file here under the profile section. So sample def mode solo, here have the profile for that. But you have also here other profiles. So you can experiment also with other profiles here. But I think for the testing, that's the simplest this keep keep the thing simple. And I think that's a simple version or a simple way to do it. Here's the solo order for that. And I think that's enough. Okay, so then we can create this genesis block. Sorry, I have to look if I have done my housekeeping. So please, but we don't have any troubles here. So empty and the data folder should also be empty. Okay. So no, let's create the genesis block for that. And with the genesis block, we can start the order. And to start the order, we can do this in a single line. And we will we will, we will leave the order running in the background. So please notice this here. So we deliver the standard output and standard error to the, to the background. And that will sleep that the order not is running in the background and is not blocking the terminal here. So and also when we leave the terminal leave our session terminal session here, the order is running again. And then the order should run. We can check this with a command jobs, for example, and you see here the running order. Can you increase the phone size? So which size, the left, the left side, this side or the other side? I think here it's, this is large enough. And, and here this you can follow this both please. So I think then we will have a little bit too less space on the screen. You can follow this in the on the GitHub page. And the same document document on this link I have posted it in the chat. And then you can follow this directly there. So and okay. So now the order is running. And the same we can do with the beer. So we can start the beer. And the important part here is that we start the beer in this depth chain quote beer chain quote, the depth mode is equal to two. So, and this is the important parameter to start the beer in this mode, in this particular mode. And then we can hear, we can, this is the command here. And here we set some environment variables for this for this command. And here we have the beer decor peer file system path. This is where the blockchain live, but there's all the data. And here we have debug variable. And we have the train code listen address and the operations address. So in the documentation from the meetup from end of July, you will find both commands a little bit more explained than here. So when we have jobs, then we see here to running jobs. So we have to order a running and we have to be a running. And you can also use a stop for example, to inspect this. And then you can search for that. You see here, you're being all this running. And also when you do this with the order, you see also the order. So okay. So the jobs command help you to display the option. R is the oil running jobs means all our running jobs. So okay. And the next, now we have the beer running, we have the order running. Now we need the channel transaction. And we have to create it also with the conflict TX file program. And our channel should be channel one. And yeah. And we also use here the profile for this the sample single MSP channel profile. And this profile came also from the conflict TX YAML file, which I have shown you previously. So and then the artifacts folder. So now you have here your Genesis block and also this channel transaction. And then you can create the channel with the be a channel quit command. And then we can join the channel. And then we have to install the chain code. So and for installing the chain code, we have to follow the new life cycle chain code lifecycle approach or workflow. And that means that we have to package the chain code. Then we have to install the chain code. And then we have to improve the chain, approve the chain code. And we have to improve the chain code only for a single organization because we have only this sample organization. And then we can we can commit this chain code. But these are the same steps as you do it in a normal network here. Okay. So and here I have copied the asset transfer basic asset transfer basic example chain code. So we can look into this folder chain code. No chairs ATP. And this is the chain code here. Later, we will see a little bit more from this chain code so that we can see that this is also also running and working. So but here's the chain code. And then we have to package this chain code. And for no chairs, we have to specify the these option this line option with the value and note. So when you do it with the goal lang, then you don't have to use this because the goal is the default language. And yeah. So and for note and for Java, you have to specify here this option with and in this case, is it not for no chairs.  Okay, so then let us package this chain code. And also to do this process you find in this in my GitHub, also a session where I have detailed explanations of how you can install back edge and come and install proof and commit chain code. And what is in this. So here we create an ATP target zip file. And what is inside of this zip file. Yeah, so you can look to the session and then you will find here also information what is inside of this chain code of this package here. And why is it important. Okay, so now we have this package here. And then we can install it. So simple beer life cycle chain code install. And we have only one peer address. So it's the local running and local. So this took some takes some some seconds until this chain code chain code is built. Yeah, so now we see chain code identifier. So and we need this identifier for later. So let me check it just the same. No, it's another one. So you have to copy this. So and I export here and environment variable. The only reason is we need this environment variable here on the start command of the chain code. And so in this way I can keep this line a little bit smaller. So that's the only reason why I put this in an environment variable. And we need this here in the in the proof step as well. And then we can start the chain code and to start the chain code, we move switch into this into this chain code folder. And then we can start the chain code. And this is the place where when we change our chain code, we can stop this chain code and we can start this chain code on this position every time. And then we don't have to do the whole approved process and also the install as an upgrade process when we change the chain code as we have to do it when we use this in a normal system. So when we use it in a normal favorite system, then we can install a chain code, of course, but then when you change the make some changes to the chain code, then you have to upgrade the chain code. And that's the difference between a normal network and this deaf network. And this position here, we can stop the chain code or simple control C and the chain code is stopped. And then we can start we start the chain code with this single line. And then we can immediately test what is the which effect has our modification on the chain code with a new transaction, for example. And yeah, so there is nothing special in the only special is thing here is that we have here the the fabric chain code stop command here. And that means that we have to install the fabric. I think the fabric fabric common package, the fabric network and the fabric network package. And with the fabric common npm package, then also and fabric chain code node program will be installed. And also this information is in the last in the session from end of January. Okay, so let me stop this now. Okay, and now the chain code is running. And then now we have a blocked window. So now we have to create a new panel here in this terminal multiplexer. So we can do this with control P and comma, not comma, quote. And now we have a split that panel here. And for the same, but we have to set the environment variables again here. And then we need to identify here. All right. So and then we have the two final steps here to finish the installation process. So our sample organization has to approve this chain code. And this is done with the command be alive cycle chain code approved. And with the package here. So yeah. And that's it. And we have here a valid transaction. And then we can commit it as a final step in this process. So and then we have this chain code committed. And since this, then from this time on, we don't have to do this approve and install stuff. We only have, we can only start and stop the chain code in this terminal here. And then we can make changes to the chain code to the notorious chain code. And then we start this again. And then here on this position, we can use the CLI or the notorious SDK to interact with this chain code. And when we test this, so we can use the PR chain, chain code invoke command here. So this is the standard chain code. So let us make a short look into this. This I will make a little bit larger. So very, very notorious. So too large. So and yeah, so the important parts here of the chain code is this is the index file here. And we have a package tracing file. And then a package tracing file we need here. Yeah, but that's not important yet here for the test scenario. So when we install this notorious chain code in the test network, for example, then we have to set here the start command. And here you see also this favorite chain code node command with the start option, but not with this option as we have seen prior here. No, no, now I'm wrong. So no, okay, forget it. This was my mistake. So and yeah, but this is the important part here that the chain code is also starting. And in this library here we have this asset transfer tracing file. And this is where the chain code here is organized. And we have here an init function. So this init ledger function. And this is the function we are going to call now that we have some test data into the into our blockchain. So we can do this. So we have to be a chain code command. And we have here the invoke command. The invoke command is responsible for sending something to the order. So make an to make a new asset or to update an asset. And the query command here is only sent to the peer. So and let us set some environment. And we have here some chain code data. And then let us see if this is working. And you see here asset one, blue, five, that's one. Let us check if the invoke also works. And when we query the a one key, then you see here the owner, the price value. So or in other methods, get all assets. So this is wrong. Why is this wrong? There's a small error. Okay. And you see here the asset. So now this is our starting point of this scenario. So now we have this chain, this net, the network is running, the chain code is running. And we can also query the new chain code with the CLI commands. Okay. Okay. So I'm alone here in this session. So because of because of the chat, so I will try to ask all the questions in the end of the session. So, yeah, so it cannot moderate the session, the chat and and the session here at the same time. So I will ask, if you have any questions, write the questions into their chat. And then in the end of the session, I will try to answer all your questions. Okay. So this is the part here. So this is our starting position when you see here. So now when you we are here now, we have a channel, we have a chain code installed and we have used here the CLI with the CLI commands, we have tested this chain code. So and this is working. And now we try to make this also make this one, this chain code also callable through the Node.js SDK. And for that, so okay. The first thing is we need a new, I put this in a new folder.  And we make an npm project npm init. So we need one favorite one npm package for for this test. So we need this favorite network and we save it into the package tracing file here. So this is also part of the preparation here. So this will take one seconds. And then we need the wallet folder here. And then we can try to create these connection approaches. And then we will create we will create this at the wallet tracing file. And then this index file, index.js file to start to interact with the network. So okay. That's it. We have this in place. And now we have to create this connection profile. So I have prepared this for you. Let me copy this. So okay. So as I have mentioned, the connection profile is you can have it as a tracing file or as a YAML file in the YAML format. And the file itself is nothing more than some information about the network. And when we have the discovery service running, then we need less information. But when we don't have this, like in this scenario, we have to name all relevant information here. And one of the important part is here, the organization. So we have to name the organization. The organization is SampleArch. So we know this because we have looked earlier into the conflict TXYAML file. So and then and there are the membership organization, the name of the organization is SampleArch. So and that's there. Also the information where this client belongs to. So then the connection, timeout, peer endorser. So that's a standard value. So you can take it as it is. The second part is we need some information about the channel. This block here, in this block, we have to define the channels. So we have only one channel. This is channel one here. And channel one has other ones. And the other one is based on the local host. So we can put here local host here. And we have peers. We have only one peer. And the peer is also on the local host. And we have to say some properties for this peer. We can say the distance endorsing peer, of course. And if not, then we will not make an invoke. Then we will make chain code queries. And also when we event source. So when we want to make a chain code where we use events, and then we have also to set this to true. So it's also good for the testing, for the developing. So in this block, we have to define information about the channel. And the channel name is important. Then the order position is important. And the local and the peers are important. So and that's it. So and then some information about the organization itself. It's the sample organization. The member MSP ID is sample ARC. This is also we have seen in the ConfitDX YAML file. And the peers, we have only one peer. This is the local host on the local host. And also the order. And here's important for the order. So and per the peers here in this block and in this block here, we have to define the URL for this order and for this local peer. And here we have to set on the right part. And in this scenario, we don't use a TLS. So we don't have to use the S here. So GRPC is without TLS. And GRPCS is with TLS. We don't have any TLS here in this development environment. And that's it. And this is the connection profile in a minimum configuration, which we need to interact with this test network. No, the board is not fixed. You can we have set this in the in the configuration here. When we start this, you can change the sport. As in any other configuration of a favorite network. Okay, so, and that is the connection profile. So, but we have to find this information. And we can just we find this informations through the ConfitDX YAML file. And to the knowledge that we have to name all these things in this config, this connection profile file, because we don't, we cannot use the discover results here. Okay, so this is the connection profile. And the next step is here that we have to create the add to what I've just found. I've created this. So copy this and paste it in.  And the Node.js client can use this wallet ID to interact with the network. And this is one way to get an identity to this local wallet. And yeah, this is standard node, we need this to standard Node.js models, we need the file system and the path. And then we need the devolets object here for your favorite network module, which we have installed. And then we have here to define, we have to write the right path on our current location here. Since we have this in, we have a client folder. And then the parent folder, we have this fabric folder here. And then here's the path to the fabric and the sample config. And then you have here these admin certs folder and the admin certs PEM file, which is the sign in certificate. And the key file for this user is in the key store file. It's the private key file. And we gave them a name. So the identity label name could be any name. So we call this admin. And then we can create here a wallet object from this, this is a new file system wallet. So we can have different wallet types and the file system wallet is one of them. We can have a memory wallet system, or we can even have a couch TV version of this identity bullets here. And then we have to construct here an identity. So these are the identity credentials here, certificate and private key membership service provider. And the type is the is X five zero nine. And this is the standard type of all certificates. And I think only this type is supported at this time. Yeah, and then when we have this identity object, then we can put this into the wallet. And that's it. And here we try this, we wrap this in a try catch block. So if an error is it catches. And since this is an asset point process, well, we have here the init function. So we have a function. And when this is ready, then we can print here out that we have added some identity to our local wallet. And otherwise we have here and we catch the hour and write the trade stack here. So and if this everything is working, then so, oh, I'm creating a wallet, we need the wallet. And this folder is empty. And then we can say, okay, we call this note at two wallet script. And the identity admin successfully added to the wallet. And that means that we have now here and file admin ID. This is a JSON document. So the jku parser is very useful here on the side. So and then you can have here, you get a nice output. And you see here what, what this, what is, what is it for. So we have here, we read this certificate and bring it in the one liner and also the private key. So I think you can do this also by hand. Because the only thing what you have to do is you have to to bring the certificate in one line. And the breaks should be this backslash ends in this backslash end format. And the same for the private key here. And then we have this MSP information and discussion board. And then we have an identity, which is, which can be used from the Node.js SDK to connect. And that will be our next step. So for the next step, I need a new file I call this helper.js. And this index.js file. So the helper.js file has some helping functions for me. So I use this on several, in several examples. And the index.js is the final program file. So and then the helper file, we have here a method is called build connection profile. And, and build wallet, but I haven't used this here with the JSON string. So that is what you're formating when we receive and recite, then we can make a nicer JSON output with that. But the build connection profile here is important because it reads this connection profile JSON file. And past the only thing what this file does is it reads the connection profile JSON document here. Or if it's a YAML file, then you have to read it as a YAML file. And then we pass this content as a JSON and give this back. So this is what this helper function here is for. And main program contains this helper function and the depart module from the Node.js. And then here are some requirements for the, from the fabric side. So we need these wallets and gateways objects here. And we define some variables or constants here. So we need an, we have to set which identity we want to use, which channel we would like to use and the chain code name. So the identity is the admin identity. So that's the name, that's this name here. So the admin, the channel is the channel name and the chain code is the chain code name. So that's easy. And here we read the connection profile from the helper function. Then we create from the helper function this file system wallet here. So we have the wallet path here. And then we need the gateway. So we create the gateway. And the important part here is in the gateway connect method. So the gateway connect method needs the connection profile as in this case as a JSON document. Then the wallet information. So, which we have created here. And then the identity label, so which name admin in this case. And then this discovery information. And here we have to say, and it would false. So that's the part when you, when you use this in the normal test network, for example, then you can use your true. And then you don't need to define the channel and the order and so on. So then I think there's only some limited information needed, the TLS certificate, the, if you use the certificate authority and the PA information. And as local host true, that means that your system runs locally on the same machine. And this, it doesn't make a difference if this one in the Docker container or it's once in the primary version here. But the important part here that you say, and they will false. So that's the important part here. But if all that is true, of course, because then it's easier to get all informations for the Node.js client. And then with this information in place, we can create the network. We get the network from the channel name. Then we have the network. And then we can get the contract. And then when we have the contract, we are ready to go for our chain codes queries. And, and then so this is now my implementation here. So you can do it however you want. So I have, I have here some arguments, which I can import from the CLI command. And I say the command, the argument two are here is the method. So this is the chain code method. I would like to call. And the first is to get all assets. And then we can say contract, evaluate transaction, get all assets. And then we will receive the result here as an asynchronous process with the await here. And then we can console simply console log this here with the helper and position swing as we have seen from the helper function. And the same with the read asset. So I have also here an LSIPS block for the sweet asset functions. And we can also call the sweet asset. And we have here to name the asset, which we are going to read. And this is the name of the chain code metal. And you can to know what is in what is exactly, then you have to look into your chain code. And you see here, so this is the read asset. So this create asset. And you also update assets. So this is the standard methods you can find in this basic asset transfer example here. Okay. So let us read asset method. Okay. And then we have also created prepared to create asset and so on. And then we have, if you are finished, then we can disconnect from the gateway. And then we close the connection together. And that's all. And if this is working, we can try. So we call it a node index.js file. And then we say read asset. And what was it? I said one, for example. And you see, it works. But you see, it took a little bit on time because there is always a connection. Then it's the read process. And then it's a disconnect here. And also when we say, okay, create asset, this method create asset. And then we can read asset A5. Then you see, we have here this sunshine. And in this way, you can interact with this method. And when we want to make a small change to this, so we want to debug this a little bit more, more console lock. We can control big, zero. Then we switch. And now we stop the string code. With control C, we can stop the string code. And then we can make some modifications here. So maybe we want to read asset, read asset for the test. So now we have changed the chain code here. And when we call the read asset method, we should see here this modified text. And to start this string code, we, the only thing we have to do is we start the chain code again with this command. So now it's running. We can switch back with control B1. And then we read the asset again. And then you see here, read the asset for the test. And now you have, and in this way, you can change all the chain code, all your chain. You can develop the whole chain code step by step here and test every step, every single test, every single step. And so I think with that, you have a really good workflow to develop a chain code and to test it. And this works as well in Node.js and also in Go, for example. But in Go, you have to build the chain code before. But it's also a single keyback on your keyboard to build the chain code here. And when we look there, okay, so then we look here to the hstop command. If you see here, pnode that your peers are always running and control. And you can also leave this session with control B detach. And then when you come later back, all this is running into this subject session to make sure it's attached. So this one also. And then you can come back and do your work again. Control B zero. Stop your chain code. Remove your test. Start the chain code again. Switch back. Test your Node.js and you'll see read as that one. And in this way, you can use the Node.js SDK to interact with your test network and also the normal CLI commands, which we have seen before. So this is working as well. So when we tried to query read as that, this was a five. And you see the same result. But of course, this is a little bit faster. And that's the reason why in the Node.js application here, so you should make it's better to make an West API. And when this West API is running, then as long as West API is running, you connect only once. And during this West API, this express cheers, for example, is running, then you can call the API end points from this West API. And you don't have to connect every time, every request to their favorite network. So the connection is stable. And then the response will be much faster. And then it's here in this example, where you have always to connect. And the final part here is also you can, so if you have problems, then you can debug this. So and the Node.js SDK has a lot of has for the debugging levels here involved. And you can set environment, one environment where we're able to hear this, this hfc logging, and which this you can define here a logging level, when we see, for example, this debug, then we can set this here. So and then when you use this one, you see a lot of debugging formations here. And you see, so here we have the result. And then here, the gateway disconnect starts later. And you see here, there are a lot of debug informations, which could be very helpful when you cannot read the connection profile, when you're facing some error with the, with the connection, or with anything in there, in the, in the system in the Node.js client. And then you can use this. And you can see how far the program comes. And then you maybe it helps you to find the error a little bit more easier. So I think that's a useful information here. And you can limit this also to errors, for example. Then you can say here, so when you say debug, so you can say info running error or debug, and this is the, the, the method, and then the output here, where, where should this message up is printed, and then you can send a console, it's like this, or you can deliver it to a file. And when you say, okay, I have here the error, I want to lock the error, and I want to lock the error into the, into this error lock file. So no, it's also possible. And you can combine this. So you can make also this one. So you can say debug console error in this file. So like this. I think this will also work. So you can hide this. So sometimes it's difficult to leave this quarry, this quarrying. So when we unset this, then you can read off this information. Okay, so let's wrap up our session for today. So let's come back to this slide. And what you have seen here is how we can use an fabric depth network, how we can build this. So we have seen that we can use the binary versions. And we can let the order and the beer running in the background. We can see how we can monitor this with the jobs command or of H stop, for example. And we can use also this terminal multiplexer to control this. Then we have seen we can connect this with the CLI commands very easily. So that's the normal way. But sometimes you want to use also the Node.js SDK for that. And this is a little bit that comes with a little bit more effort. So and we need the main steps are we have to know what is the connection profile here. And we need an identity. And the identity is delivered from this sample config membership service provider file. And we have to convert this and the converting process is a simple or finish in a simple chasing document with the signing set from this user and the private key from this user. And with this information, we can create a small program. And then we can use this identity to we can use this identity and the connection profile. We need both of them to connect to the fabric test network. And then we can hear the two, we can use the evaluate transaction function or we can use the submit transaction function to interact with the fabric network. Okay, so I think I'm in the end of the session. If you have any questions. Hi. So there are a lot of comments. I will look to this. So I was trying to execute a lot of commands from the host machine, but I was able to I don't know. I haven't tried this here. So I have to maybe I have to test it, but on this I can give you an answer, I think. So there can so much. So for the CLI container is this gives me the point where I have to say the CLI commander is used in the 1.4 favorite question and not in the 2.2. So if you use 1.4, then I'm not sure how you can do this. But I think there will be a way. But this question, I don't I cannot answer it. I have a question regarding the concept stuff gets that function. Is it read the value from the word set or blockchain? Yes. So let us switch to this. So this is to get state here. The get state reads always from the word state. And the blockchain is the blockchain. With blockchain, you mean the history, the other versions of an asset. And for that, there's another command where you can query the history of an asset. But the get state gives you always the word state. You reverse it from the level to be database or from the couch to be database here. And this is always the latest, the latest version of an asset. Yes, get set returns the value of a specified key from the ledger, but always from the last, the last state of this, of this asset. Ledger is worth that in blockchain. Yeah. Just so, yeah, I don't know. So the word state. So when we talk about an asset, so an asset is an element in this fabric blockchain. And to get the information very fast, in hyperlink traffic, there is a word state. The word state is represented in the database. So in the level to be database, or in the couch to be database. And all these queries goes to the word state. The word state is also the latest state of an asset. And when you talk about the blockchain, then you mean the ledger, for example, or also the ledger. So there's, I don't know, we have to look what is the right term for that. But it's easier to understand that we have in the word state the last version of an asset, and all trio versions of an asset, the history of an asset is stored into the blocks, into the blockchain, into the ledger. So the boards, I think the boards you can change, you know, 70, 15, 70, 51. So these are standard boards for the order. But when you define the order, you can define part of your own. So for that, look a little bit into the Docker Compost, Docker Compost, YAML file, Docker Compost files in the test network. So in the test network, you find also configuration from where you use the raft ordering system. And then the raft ordering system, you can have more than one order. And then you can see how the port numbers are organized. But you can use here every port number as you want. So because to connect to this peer or to this order, you have to you have to name this port. So you have to name this in this, in some environment variables. And as long as this environment variables match the part of the peer or the order, then you can use this ledger is combinator. Okay. My first time attending is me. Thank you. Yes, you know, so you have here a playlist. So we have on the Hyperlature, on the official Hyperlature channel, we have a playlist from Hyperlature Sweden. And there you can find all the videos, all the recordings. Awesome. I would like to introduce myself, Chris Gavril in the room and talk about the fabric docs workroom group and invite everyone to get involved. Yeah, that's cool. The get history for key function is really interesting. Yes. So and that's the answer from for the get state for the get state. So they get history for key function. This function gives you the history of an asset. And the get state gives you the last state of an asset, the so-called third state. Okay, so are there any other questions? Okay, so yes. Please tell me your question. Differences for the connection profile when using certain authority. A good way to see the differences is when you start the test network, then the test network create for the organization one on the organization two. And for every new startup and new connection profile in the JSON and in the YAML format. And when you start the network, these connection profiles will be created dynamically. So when you when you test this test network, and you start this test network, then you can look into the folder crypto config organizations, and then you find the folder organization one and the organization two. And there you will find this connection profiles generated from the boot process. And in this, you will see also how you define the certified information to this connection profile. And with this file, you can see and learn how you have which information, which properties and which values you gave have to have to give to this connection profile and to see, and then you can see what is needed to define this. I think this is a good way to see how this works. But you have to start the tricky part is you have to start the test network. And when you stop when you when you when you stop the the test network, then all the material and also the connection profile will be deleted. And then it's gone. So you have to start it. And then you have to look into this folder. And then you will see in the folder for the organization one and organization two, two connection profiles, one in the JSON and one in the YAML format. Okay, for the certification, do we have to use the local container? I don't know. I don't, I don't know for the certification. So I think normally you have to the certification is on Fabric, I think Fabric 2.2. And then the documentation from Fabric 2.2, there isn't any information about how you use the development network and how to use the, I think the binary information. So this started in Fabric 2.3. I think you have to use the Docker container, but I cannot say that I don't know. So I don't know, which I have, I don't, I don't found, I haven't found any information about this. So, but I think the normal ways to use the Docker container, and I think in this way, should also the, the certification. Roland, I don't know the specific answer to that question either, but I do remember that we had had somebody from the hyper or from the Linux foundation training team come and present to the Sweden group a while back to talk about the training and certifications, so that if people are interested, that recording is also on YouTube in the Sweden playlist. Yes, thank you. Thank you for this information. Okay, so I think you, the question and the deco and they are now finished. So if nobody has any question here, so you would like to come into the session now, if I understand this correct? Yeah, yeah. So hi, everyone. My name is David Boswell. I work at Hyperledger. I also want to introduce everyone to Chris Gabriel. We, we are involved in the hyperledger fabric documentation working group. And I thought that there would be a lot of interest in that group with the people here. So, you know, like everything at Hyperledger, the fabric documentation is an open source effort and anybody is welcome to get involved. And it felt like this group would be interested in that, you know, I think you obviously are interested in technical information about hyperledger technologies and there probably are places where you would like improved documentation or new documentation. So, you know, we just wanted to talk a little bit about that group, invite you to it, you know, we always welcome your input comment contributions. And again, if you're wanting better improved or more documentation for the, you know, the content you're wanting to, you know, review as a group, you know, the group that the fabric documentation working group could be a really great place for that. So, Chris knows much more about it than I do us. I'll let him kind of give an overview, but I just wanted to say hi. And I'll drop a link here in the chat to where you can find out more about what Chris will be talking about. So, hello, everybody. Nice to meet you. Can you hear me okay? Yes, Nick and you're very nice to meet you all and very interesting presentation, by the way, Roland. This is my first time seeing your group here and very well done. My name is Chris Gabriel. I am a volunteer contributor to the documentation working group. I've been involved with the groups since almost the very beginning in 27 late 2017. We've had some turnover in the group and we're hoping to recruit more members. So, we are looking to other established groups in the community to maybe come in and share their knowledge. And there are very good instructions on how to become a contributor to documentation on the Fabric website. David can link to it. It shows you how to set up a GitHub fork for Fabric and how to contribute documentation step by step, creating pull requests and the like. So, just a quick short introduction and a pitch. We recently started to meet or decided to meet every other Friday. So, we had been meeting every week, but a lot of the document heavy lifting had been done on version changes, but there's still much more work to do. An example of that would be, you may have seen there is a change in the Fabric GitHub repo to rename the master branches from master to main. So, if you think about everywhere in the documentation in code snippets, we reference in instructions a master branch. Now, we have to go back and re-document all of that stuff to main. So, there's an example of how other groups can come in and help clean that sort of stuff up and any help is greatly appreciated. And if you're just not sure how to start or how to contribute, the best thing you can do is join our weekly documentation call, ask questions. And we also do some technical demos during that call. I am the founder of a blockchain company based on Hyperledger Fabric. We do a lot of work in a node SDK. And we have working applications and use cases that we have the APIs written for and the front-end Angular apps for the UI. So, we do a lot of demos around that as well, not just total documentation. So, anybody who's interested in that, please feel free to drop by. And David, I think, dropped a link into how to contribute. And David, if you could just put the meeting link in there, that would be great. Yeah. The good news about the meetings is they fit really well with when you're meeting regularly too. So, they're every other Friday at 8 a.m. Pacific. And I just dropped a link to the Wiki page where you can find more details about the meetings. We book an hour for that meeting. Sometimes it doesn't take that long. So, and if we go every other week, it's not a huge time commitment. But to me, how I learned Hyperledger Fabric really good was to become a volunteer in the documentation work group, because no better way to learn it than if you have to write the instruction manual for it. So, thank you. Appreciate the time. Yeah. Thank you for your input. Yeah. So, I think, by my side, I have to say documentation is very good. And I think also for the certification. So, I think to pass the certification, you only need the documentation, the official documentation. So, you'll find a lot of useful information in and also the examples. And I think the switch from 1.4 to 2.2 with the new test network, this is really, really good because you can with a single command line, we can start in the new Fabric 2.2 with the new 2.2 test network. We can start a lot of different scenarios to test and to play with. And this is really, really easy. And I think it works every time. So, it doesn't matter if you want a Fabric network within certified authority or if you want culture to be, for example, so you only have to use the proper key for that, the option for that. And then the network is starting, then you can try and play with that. And that's, I think that's an improvement to the 1.4 version because the 1.4 version was a little bit more difficult to use all the different situations. And that is really good also for starters. And in my session here, I can use a lot of different scenarios with the new network and you can start it with any effort. And that's, I think it's really cool to test and to use and of course to learn of also, and also the background scripts are very good documented so you can learn from this a lot and to see how the things work together and then you can take some snippets for your own project, for example, or learn or modify it in your own way. So, I think the 2.2 version are really good. But one question I have, so why you find the documentation through the DEFIN network here that appear DEFIN network only in the 2.3 version and not in the 2.2 version? So, if I understood you correctly, the difference between 2.2 and 2.3 is, can you repeat the question again? We have here in the documentation, we have here a 2.3 version and then this 2.3 version, we have a tutorial for the session today, one in chain code in DEF mode and this tutorial is not in the 2.2 version. You can find this only in this 2.3 version. So, the question is why? That's a good question and a lot of the people who were helping do this have left the group recently, so I would have to go back and investigate that and get back with you. There are some features available in 2.3 that are not available in less than 2.3, like the OSN admin channel join for joining the channel for the new process and so that would not be available in any of the other branches. In some cases, it was written and not backported to the prior versions, that's usually the number one reason why it doesn't make it in there. So, it's usually pushed to the latest branch. But this is working also in the 2.2 version, so I used 2.2 version and this is also working here. Under the documentation, you will not find this. So, most of the users use this 2.2 version because it's the long time support version and it's not so clear why this chain code DEF mode is only on this 2.3 version here listed. Yes, I will have to go back and look at that and to answer that question. I don't know the answer right now, but I will look at it. Okay, yeah. Is there any question from the group? So, if not, thanks for the attention. And in the next session, we will move forward with our way in the Node.js development and then we will use the test network. And with this test network, we can start then favorite CA and then we will see how we can use Node.js and interact with the favorite CA and can make some maybe asset paste the chain code examples where we can query some different properties from the user and then we can make a little bit more about the permissioning from the chain code site here. And that's the, yeah, I think that's the plan for the next session. And then maybe a short announcement. My colleague from Hyperledge of Budapest has announced also a session about favorite CA and that will be in April, I think. And maybe I will post about that in the next session, the link. And this could also be interesting for everyone here to see a little bit more about, or to hear a little bit more about the favorite CA. But this will be more from the administrator side. And my part here is a little bit more from the developer side from the chain code site. And maybe this is a good fit that Daniel will show you more from the administrator side of the favorite CA. And I will show you a little bit about the chain code side from this. Okay, so thanks for your attention. And I hope we have a great session today and we will see you next time. Thanks everyone. Bye. Do we just stay on here or do we have to leave and come back in? No, we can stay on. Hello.


Hey there friends, thanks for checking in and welcome to another video in my series called one handgun one shotgun and one rifle Today we're going to feature Classical historic firearms and we'll start right here with the handgun. It's a Browning high power Mark 3 model a beautiful single action full-size handgun that was Browning's last design It carries 10 rounds of the magazine. Now. I know Metgar makes Higher capacity magazines. I have a couple of those but this is where it started It's a double stack which was considered high power back in the day. Check that out a 4.6 inch barrel does have a magazine disconnect and A thumb safety that is ambidextrous fixed rear and front sights polymer grip $1,109 Was the MSRP when this was in production if you have one of these It's worth some money, and it's only gone up over time. Let's take a few shots and Failure to feed failure to feed. I'm not sure what's going on here. All these are Not feeding well. I may need to lube it up a bit All right, let me try that again. We'll see what happens. All right, what I did was I Have this stuff in my range bag let away And I just gave it a quick scrub down and it seemed to have done the trick But there it is Browning high power excellent handgun many people say that the the CZ 75 was modeled that off of this gun and I believe it was But I'm not a great historical buff, so I'm sure somebody will let us know now Let's get to that shotgun the shotgun that I'm featuring today is a new England firearms single shot 20 gauge check that out Many people told me that they have this shotgun. It was passed down from their grandparents They love it. They hunt small game with it and they love the 20 gauge now The 20 gauge is a good home defense choice. Everybody in the family can use it I'm not saying a single shot is the best choice. I'm just saying the load the 20 gauge load is a nice choice For home defense primarily because everybody can use it now It does have a hammer that needs to be cocked back, but once it is it's live And then it also has an ejector smooth shooting Not hard on the shoulder at all we'll go down There we go. And this is a seven shot. We'll take one more Seven shot Target load. Let's go up top there all right You got love the single shot shotguns are inexpensive pod shops is where you can pick these up cheap and It's definitely a historical firearm and I've had this for a while and I really do love it Now let's get to that rifle the rifle that I'm featuring today is a Mosin Nagant chambered in 762 by 54 are very powerful round Now you may look at this and say that doesn't look like a Mosin Nagant to me Well, it actually is this is a Franken rifle, which means all the parts Were just assembled together and you can do that with the Mosin you can take a bunch of parts And it should all work together the stock here is an ATI Monique Carlos stock and I've had this for quite a while and it works pretty well So let's go ahead and set it up and we'll take a few shots Most of the gods have heavy recoil. They were made to shoot over a thousand yards during the world wars and They used to sell for about sixty nine dollars and they really have gone up in price And the ammo has to used to be dirt cheap you get the spam cans for like eighty nine bucks now It's like over two hundred, but let's go ahead and take a few shots I've got my cheapest target and my cheapest shepherds hook just in case it gets ruined from this I Hit something there Try it again may have gone right through it Yeah, it's going right through it. That's not a 500 and even if it was It may be a little Too close and too powerful the Mosin Nagant the woodstocks actually look nicer than this But this has a bit of a recoil pad and it certainly fires those 7 6 2 by 54 our rounds quite well Thanks for watching another video in the series one handgun one shotgun one rifle Yeah, if you like videos like this, please subscribe and share I always appreciate thumbs up button Thanks for watching and you guys be safe


There are a handful of challenges and points of confusion about optimizing for web vitals that I see really frequently. So the goal of today's presentation is to cover as many of these issues as possible in the next 10 minutes. In particular, the three themes I'm going to be talking about are cumulative layout shift, third-party scripts, and rum. I'm not going to be giving you an overview of these topics. Instead, I really want to stick to discussing some of the edge cases and details that people tend to find confusing, as well as highlighting some performance techniques that you might not be aware of. I'm going to start today by walking you through how CLS measurement is implemented in code. I want to do this because I think seeing the implementation in code clears up a lot of the questions and confusion around when CLS is reported and finalized, particularly for single-page applications. CLS is measured by using a performance observer to observe for layout shift events. When a layout shift occurs, the performance observer invokes a callback function, and this callback function adds to the running layout shift score, in other words, CLS. If you wanted to, you could also add code inside that callback function to report this intermediate value of CLS. Although you can do that, it's not necessary. Ultimately, the only value of CLS that matters is the final one. Final CLS is not determined by taking a bunch of CLS entries and seeing which one occurred last. Instead, it's determined by listening for the Build Disability State Change event. User actions like navigating to a new page, switching tabs, minimizing tabs, closing the browser, they're all examples of events that cause a document's visibility state to change from visible to hidden. When a document's visibility state changes from visible to hidden, you know that the value of CLS at that moment should be reported. One tool that I really like for debugging layout shift is the Layout Shift Regions option in DevTools. You can access it from the Command Palette or the Rendering Options tab. This feature highlights page elements that have shifted as they are shifting. In other words, it's not highlighting the root cause of the layout shift, but rather the affected elements. I personally find this tool most helpful when combined with screen recording. Layout shifts can happen very, very quickly, and this can make it difficult to debug them in real time. However, with screen recordings, you can step through the page load process afterwards as many times as you want at your own pace until you figure out what's causing the layout shift. Another thing that I want to mention is that you can augment your web vitals reporting to provide you with more information about the circumstances under which a particular performance measurement was observed. This includes things like reporting on connection type or scroll position, as well as pieces of data that might be unique to your app. For example, if your app uses a debugging token. Layout shifts that occur within 500 milliseconds of user input do not count towards CLS. Asterix here, though, is that scrolling is not considered a user excluded user input. In other words, if a user scrolls on a page and a layout shift occurs immediately after, it's still going to count towards CLS. The reason why scrolling is treated a little bit differently than these other user input events is that if you think about it, if a user is scrolling on the page, there's really no good reason why a layout shift should be occurring. On the other hand, when a user is clicking on the page, it's much more likely that they're trying to navigate to a new page or opening a nav bar. And these are things that can trigger layout shifts, but they're probably layout shifts that the user doesn't mind or they're wanted because the user's trying to accomplish something. Keeping with the scrolling theme, another thing that I want to mention is that most lab tools such as Lighthouse or web page tests do not scroll down your page. And this can be a blind spot when it comes to measuring and identifying CLS in lab environments. And I'd say this probably affects mobile a little bit more than it does desktop. At the same time, though, this blind spot might not be as big as you think it is. Keep in mind that layout shifts only count towards CLS if they are visible to the user. In other words, if there's a layout shift that occurs below the fold, but the user hasn't scrolled down the page, it's not going to count towards CLS. Lastly, keep in mind that sometimes there can be no correlation between the CLS of a mobile and desktop site. The desktop and mobile versions of the same site often use different layouts. They use different UX patterns. And as a result, they can exhibit very different layout shifts. That brings me to my next point, which is that code is only part of the solution to layout shift. Some layout shifts can be fixed strictly through code. This usually consists of adding the width and height attributes to images, videos, and iframes. However, many layout shifts are largely the result of bad UX patterns. In other words, the product was designed that way. An example that I've seen really frequently is sites popping in banners at the top of a page to make an announcement. And when this banner pops in, it pushes everything else on the page down. Optimizing UX patterns for core web vitals is a whole topic in and of itself. Luckily for you, Grema will be discussing this in the talk immediately following this one. I highly recommend that you stick around and watch it. That's all I have to say about CLS. I'm now going to talk about third-party scripts. In the past year, we've heard a lot about lazy loading images and lazy loading iframes. Lazy loading can also be used to load third-party scripts. However, it's a bit more of a delicate art form, and the APIs are also different. On the screen, I've listed some APIs that are available for lazy loading scripts. There are a couple of things I want to note here. One is that the delay set by set timeout does not represent a guarantee as to when the callback function will execute. Instead, it's the minimum amount of time until that callback function will execute. This is because the callback function cannot be executed if the main thread is busy. This behavior sometimes makes that timeout frustrating to use because it makes it a little bit unpredictable. But in the context of loading third-party scripts, it's actually kind of interesting because maybe you don't want to or you shouldn't be loading third-party scripts if the main thread is busy. In addition, I want to note that if you want to trigger lazy loading based on user scrolling, you should really use Intersection Observer to do that rather than listening for the scroll event. Intersection Observer is going to much more performant than listening for the scroll event. Lastly, I don't see many people using the performance observer for lazy loading, but it does open up some really interesting possibilities for doing things like waiting for a particular performance event to occur. For example, first paint or first contentful paint and then triggering script loading. Another issue with third-party scripts that I hear a lot is that engineering teams are really frustrated because they feel like marketing teams just keep adding more scripts to their page and there's nothing they can do about it. Ideally, you would get those teams on board with performance, but if that's not an option, you might be able to make some improvements to the situation by taking advantage of some of the features available in Tag Managers. These are features that give you the ability to restrict tag usage as well as get greater visibility into the usage of tags. This slide lists some useful features of Google Tag Manager, but I would expect that you would be able to find similar features in other Tag Managers as well. In this last section, I'll be talking about techniques that you can use for improving your ROM setup. A question that I commonly get is how can you get page-level performance data? Page-level performance data is technically available in both crux and page speed insights. However, in practice, you might find that it's not available and that's because page-level data will not be exposed if there's not enough performance data available for that page. If you're running into this situation, you might find it helpful to look at Search Console. Search Console is a little bit different because it exposes performance data based on URL groups. Search Console URL groups are groupings of URLs with similar HTML structure. The idea being that structurally similar pages are going to exhibit similar performance characteristics. As a result, pages that might not have enough performance data to be displayed in PSI or crux could potentially be displayed in Search Console. In addition, this feature provides you with a way of forecasting the performance of newly added pages to your site. For example, the screenshot on the screen shows the URL groupings that Search Console detected for all the author pages on web.dev. If I were to add a new author page to web.dev, I technically don't know what that page performance is gonna be like, but I can get a pretty good idea by looking at the aggregate page performance of all the existing author pages on web.dev. Search Console is a great tool, but if you want more detailed or more frequent performance data than what Search Console provides, you will need to collect your own performance data. There are two paths that you can go down when it comes to collecting your own performance data. You can set up the tooling yourself or you can sign up for a third party service. If you wanna set up the performance tooling yourself, we recommend using the Web Vitals.js library that is available on GitHub. Web Vitals.js is a small lightweight script that you include on your page that provides an API for measuring the Web Vitals metrics. The advantage of using this script rather than something you implement yourself is that it gives you the assurance that your implementation is correct and therefore the measurements that you collect are gonna match those found in Google tooling. Alternatively, there are a wide variety of third-party services that support Web Vitals. Most of these are paid services, however, CloudFair browser insights is available for free and supports Web Vitals. That brings me to the end of this presentation. Thanks for watching, see you soon.


OK, can everyone hear me OK? OK, I'm going to get started. This is Fresh Kernels with Fedora. First of all, about me, I'm Laura Abbott. I'm a full-time redhead employee on Fedora engineering under Paul Freels. I'm one of two full-time kernel maintainers, the other being Justin Forbes. The two of us are ultimately responsible for anything that goes into the Fedora kernel. We don't work alone. There are people both inside and outside red hat that contribute to make the Fedora kernel successful. But on a day-to-day basis, we're the ones looking at bugzilla, making builds, and generally keeping the kernel flowing. The kernel is running on every Fedora system, so it tends to generate a lot of interest. My goal with this talk is to give an overview of why we as maintainers make some of the choices we do and how this overall works with what Fedora is trying to accomplish. So this is what I'm going to be covering in this time slot. I'm going to be talking about how the upstream kernel does releases, how this forces how Fedora chooses to do releases, and how this all ends up working really good together for Fedora. So first some introductory terminology to make sure we're all on the same page. Open source projects have the concept of upstream and downstream. Upstream just refers to the entire community working on the projects. You'll often hear us say this patch needs to go upstream first. And all this means is that the patch needs to be accepted by the community first and then later taken to the Fedora, which makes the Fedora kernel downstream. Having as much code upstream in the kernel as possible generally makes things much easier for maintainers. But there are some patches that we will keep out of tree and will never go upstream. So when we do a new kernel release, we typically say we are going to be rebasing the kernel. And all that means is taking patches we have out of tree and making them work with the new kernel. Finally, you may hear me make references to RCS. This is for short for release candidate and refers to a kernel version that is still actively being developed by the community. OK, let's get to the good stuff. I'm going to talk about how the upstream kernel does releases. This may have been covered in other talks, so you may have heard it elsewhere. But this is my take on the entire process. So whenever a new kernel comes out, the Linux foundation or LWN usually gets a statement like, wow, this was the busiest kernel release ever. And this is usually very true. There are people from an amazing number of companies and places while working to attribute. And every release, there are always new people contributing their first patch. And this is all, again, a pretty busy process. But despite this, the kernel is released on a very regular schedule. OK, so this is the extent of my graphic skills. This is a rough diagram representing the kernel cycle that's happening right now. To the left, you have the 4.9 release, which came out at the beginning of December. And all the way on the right is 4.10. And each block represents about a week of time. And we're somewhere around RC6 right about now. And so if all goes according to plan, there will be RC7 the week afterwards, and then 4.10 release the week afterwards. So how do we know this is the kernel release cycle? Mostly because this is what happens in the past. Linus Torvalds, the creator of Linux, still ultimately sets the kernel release cycle. And this is the process he's done for the past very long time. And he's very unlikely to change it without a good reason. So it's so predictable. You can probably guess when future kernel versions are going to be available. If you've ever been curious about the schedule, this is a handy website that will give information about what kernel version might be available on a particular date. The name is a little bit silly, but this is really useful for getting a rough idea of what kernel version might be available, which can often be helpful for things like project planning. But I always say rough idea just because things can change. The diagram I gave earlier had seven release candidates. Sometimes there's an eighth release candidates. Sometimes things get delayed by a few days. Trying to plan kernel releases down to the day is not really going to end well. Kernel developers are not interested in guaranteeing specific days. But the kernel releases are going to happen on a very cyclic basis. So let's talk about some parts of the kernel release cycle. The first part is the merge window. So right after one kernel is released, the merge window for the next kernel opens up. As the name implies, this is when all the kernel patches and trees are going to be getting merged together. This time period usually lasts about two weeks. This is a very busy time for kernel maintainers. Kernel maintainers are going to be prepping branches of patches people have sent to them, and they may be accepting pull requests themselves. There are a lot of kernel developers these days, and many of them do not actually submit to Linus Torvalds directly. They will submit to another maintainer who will eventually submit to Linus. And this is also an important point. Kernel releases are happening off of Linus' master branch. So patches may go through several maintainers tree before they finally make it to Linus' master branch, at which point you can say a patch has finally hit its final destination. A lot of maintainers will not be reviewing patches during the merge window. Greg KH, one of the top kernel maintainers, has an autoresponder for some mailing list that says, I will not look at this patch until after the merge window just because they're busy with other things. If you choose to try and communicate with the kernel community, please remember to be a little bit patient during the merge window because maintainers are busy. But it's not just busy for maintainers. Anyone who's trying to use the windows is going to use the kernel during the merge window is going to find this to be a busy time as well. Before a patch lands in Linus' tree, developers have usually made some sort of effort to make sure it gets some level of testing. But once a patch lands in Linus' master branch, it's going to get testing from a much wider audience, either use cases that developers didn't think about, or hardware they didn't have access to. So as you might expect, this is going to find bugs. And the merge window is going to be where most of the bugs are going to be introduced. The kernel is still fairly usable during the merge window. Fixes can come in fairly quickly if a specific commit can be identified. And this is why it's always important to have a wide variety of developers testing and reporting bugs for the kernel. But eventually, all good things must come to an end. And after two weeks, the merge window closes, and Linus releases RC1 off of his master branch. So the good news is at this point, things will start slowing down a lot. There will typically not be any more major features coming in. But I say typically just because some features may make their way to the merge window post, may make their way to the kernel after the merge window. But the larger the feature is, the more unhappy Linus is likely to be, and the more likely he is to reject a pull request. There's a schedule to the kernel. And the schedule is that new features need to come in during the merge window. And this is because once we hit the RC time frame, it's really time to start testing and making the next kernel stable. I mentioned that bugs are often found and fixed during the merge window. But that may not be all the bugs. Trickier bugs may be still not fully fixed or just hadn't been noticed. Some kernel developers may choose not to start testing until actually the first release candidate comes out. And so you're going to see a lot of bug fixes for the kernel set during this time. But the RC time is actually when developers are starting to look towards the subsequent kernel as well. Once the merge window closes, maintainers will often start to do more patch review. So for developers who are sending patches now, the patches will typically be queued up for the subsequent kernel. So for example, patches set now will not be queued up for 4.10. They will be queued up for 4.11. Because unless the patches are fixing newer major regressions, they really should not be going in. Because again, there's a time frame to the kernel. And requesting a maintainer take a patch in at the wrong time is not going to do anyone any good. Linux will probably reject the pull request. GreatKH has a talk on YouTube titled, I don't want your code. The title is really harsh. But it is a story about what happens when maintainers try to take code at the wrong time and why it's important to be following the schedule for the kernel. But eventually, another week passes and another release candidate happens. Each release candidate is going to follow roughly the same process. But the hope is that the number of patches going into each release candidate should be getting smaller and smaller. Sometimes this goes faster than others. But time goes on. And eventually, things start getting more stable. And Linux decides that things are stable enough and declares a release. And everyone is super excited to get a brand new kernel. But just because a major kernel version has been released doesn't actually mean it's bug free. After a kernel is released, it's going to get bug fixes for a period of time, typically until the next kernel is released. So as an example, when 4.10 is released, it's going to get kernel releases 4.10.1, 4.10.2. And these are called stable updates. And when I say the word stable update here, it has a very particular meaning. The only items in stable updates are small bug fixes that have been accepted into Linux's master branch. And this is fairly strictly enforced about what goes into a stable update. But the result of a stable update is that it's much less work for a maintainer to push out, and it's going to be much less risky for users. OK, so that's the rough story about how upstream does releases. But what about Fedora? Fedora has kernels. How are those getting kernel versions? And that kind of depends on what Fedora version you're looking at. RawHeat is the development version of Fedora that will eventually turn into a stable release. The rawHeat kernel is getting daily snapshots from Linux's master branch. So whoever is just in their eyes maintaining rawHeat is doing daily rebases of the rawHeat kernel, although most of the conflicts in rebase work is going to happen during the merge window. There can be stability problems, like you might expect. But overall, rawHeat is very usable. The laptop giving this presentation is running rawHeat right now. And as always, today's rawHeat is tomorrow's stable release. So when you're running rawHeat and reporting bugs, you're helping to make future Fedora releases stable. And speaking of stable releases, how do those get kernel updates? There are a lot of different options Fedora could take to give kernel updates. Some distros may choose a single kernel version to stick with that for the entire lifecycle. The only updates for that will typically be security updates and bug fixes. This isn't what Fedora chooses to do for a number of reasons. A kernel update is only supported by the community for so long. I described stable updates previously. Eventually, a kernel version becomes end of lights and will get no more updates from the community. When that happens, there are roughly two options. You can either move to a new kernel version that will be getting updates or try and do the stable updates for the kernel version yourself. Supporting a kernel version yourself can be a valid option, but it takes a large engineering effort. To support this, this means you need to be doing the work of doing stable updates, identifying fixes, and backporting them yourself. Backporting is not a simple task. It's very easy to make mistakes if you aren't careful, and it takes a lot of work. Confession, I've done backports incorrectly before that I've introduced subtle bugs that took months to find. And when we think about security updates, this gets even more troublesome. So when you think about something like bad sheep, bad cow, whatever they're calling it these days, you really want to make sure that backport is done correctly. Otherwise, you may still have a security vulnerability. And really, for what the Fedora project is trying to accomplish, there's really not a lot of value in trying to do this work. It makes more sense to move to a new version versus trying to stay in the old one. But other projects may choose to do this work because they have different requirements than Fedora.  These are called long-term stable releases. Generally, from one of these to come about, someone has decided it's in their project or company's best interest to support a single kernel version for a long period of time. And they found a maintainer willing to do the work for a long period of time. This is great. These are very valuable for industries like the embedded world where the lifespan of devices may be years upon years. The problem is that these releases aren't related to the Fedora release cycle at all. We know that there's going to be a kernel version release, but we don't know exactly when it's going to happen. And trying to make this up with Fedora release schedules just doesn't end up working. So the end result is that it's best to try and move to the newest kernel possible. So this is a screenshot of kernel.org while I was working on this talk. You can see some of the long-term kernels, 4.8, 4.4, 4.1 I was talking about, as well as the newer kernels. So when the screenshot was taken, raw height was on a 4.10 release candidate. F24, F25 were on 4.8.15, even though 4.9 had been released. And this is a pretty common situation for a lot of reasons. When a new kernel is released, people always want to know if they will be getting the new kernel. And the answer is almost always, yes, you will be getting new kernel. And the subsequent kernel is always, OK, but when? And can we have it right now? And the answer to that is, when we think it's ready, just because a kernel is released doesn't mean it's bug-free. I remember I talked about the stable updates, and there is a reason why they are delivered. Josh Boyer, former kernel maintainer, wrote a really good blog post talking about the fact that a newly released kernel may not be that much more stable than an RC. And rebasing a kernel and making it available before it's had some time to soak and find bugs isn't going to be a good experience for anyone. So as maintainers, we tend to want to wait at least one or two stable updates for a release kernel. From experience, this is usually good for finding most of the common bugs that people are likely to hit.  Stable maintainers may be in vacation or be at conferences, so they're going to be delayed. Ultimately, a lot of when Fedora does new kernels, ends up being dictated when the community releases. But rest assured that, yes, there will be new kernels eventually. So I've spent some time talking about why Fedora chooses to give full kernel updates as often as it does, but I'd like to talk about some of the advantages you also get by moving to brand new kernels. A big one is hardware enablement. In Fedora, we try and enable as much hardware support as possible. So if the code is available in the kernel, it should just work on your hardware. The result is that moving to a new kernel version may make hardware go from not working at all to lights on. This often affects things like displays and graphics. And this can also mean hardware may go from working poorly to working a lot better. And this is also a lot of times, while you'll see us make requests you to test on not the newest kernel version on Bugzilla, there are so many patches coming in that it can be hard to tell if a particular issue may have been fixed by a version. There's also always new features coming in. Everyone's favorite buzzword these days is containers. And the kernel is always getting support for containers, for new container features. All the work that's been done on adding various names, dates, supports, just fairly frequently we get requests for things to add patches like SE Linux support. And by running the latest kernel version, you get a chance to develop against these new features and make your applications more secure. So I've hopefully spent a lot of time convincing you that how we do kernel updates is generally good. But part of the problem with getting new kernel updates is that there may be bugs. And updates are never going to be bug-free. This is the trade-off for getting new features and new hardware support is that there may be bugs. And as maintainers, we need you to work with us and report these bugs. We sometimes get nasty grand bugzilla reports that imply we really like breaking the kernel with each update. This is the opposite from the truth. We know it's very frustrating when you update the kernel and something breaks. I don't want bugs. And if I could, I would try and fix everything. I like debugging a lot. But the reality is that even when working with the upstream community, we don't know every part of the kernel. The kernel is huge. And sometimes we just don't know why something was broken. But I really don't want to be too pessimistic here just because the kernel is a constantly evolving project. It's never going to be finished. There's always going to be new hardware and new features that are going to be added. And sometimes fixing a bug is just bringing it to the attention of the right person at the right time. Great example of this is that I reported a bug to the EFI maintainer probably back in October. And then just a few days ago, I got an email from someone saying, hey, we think we have a fix for this. Just because someone else managed to take the time to actually track down what they think the issue was. So there's always hope for getting bugs fixed. So wrapping things up here, you may have seen this reference in Matthew Miller's keynote. The fourth foundations of the Fedora community are freedom friends features first. Our kernel philosophy really captures that. We try to bring you the latest kernels with the newest features as soon as they're stable. And as maintainers, we're not just IRC bots sitting there running on a server somewhere. We're people who are trying to listen what's being told to us because our overall goal is to make the Fedora project the best it can be. And upgrading regularly to newer kernels is the best way to make that happen. So questions? OK, so the question is that if you find a problem on the Fedora kernel, would you rather have that reported on the Fedora bugzilla or the kernel upstream bugzilla? I think the answer is my preference is that because Fedora is often on new enough kernels, it's generally worth it to try and report the bug with us first and let us check to see if it's something we already know about. But in general, you should always feel free to report bugs on the kernel bugzilla. I will say that the kernel bugzilla can sometimes be hit or miss in terms of maintainers responding. Some maintainers are much better than others. Power management I know is very active on the kernel.org bugzilla, so if you have suspenders in problems, I highly encourage you to report them on the kernel.org bugzilla. And the red hack and what sort of things those were. OK, so the question is, what sort of things do we have in the Fedora kernel that don't get pushed upstream? A lot of these are what I consider like little nicety patches that just make Fedora a little bit more usable. But the upstream may just tend to quibble about. A good example is maybe disabling the floppy drive just because that's there. If a maintainer isn't able to give an output response for something, we may take a patch say to remove a warning. Perhaps drivers that are only features. We're also currently carrying the secure boot patch set just because there's ongoing work to try and get that upstream. So the hope is that everything major feature should go upstream. But there's probably a handful of just general little cleanup patches that we haven't submitted. I should probably go through one of these days and see if any of those might actually be valuable to be upstream, but yes. I guess I'm not quite sure what the question is there. It sounds like you're asking there. The question is, is that do we build third-party drivers? The answer is no, we don't build third-party drivers. A lot of this is because manpower thing. There are only two of us full-time on Fedor Engineering, so we just don't have time to be able to support all the third-party drivers, which is really unfortunate from a usability perspective, just because in ideal world, everything would be entry. But for various reasons, Nvidia, for example, you just can't, you may not be able to bring them entry. So we will oftentimes say, no, we can't support this. But we're trying to work to possibly improve this, either get testing so that you will be able to perhaps be aware if your third-party driver might break. So that's a good point. My colleague Justin Forbes has been working on a test harness to be able to test things like the Nvidia driver. So the hope is that even if we can't officially go and fix the Nvidia driver, people will be aware that the Nvidia driver may not be working. So users can go nag the Nvidia developers, or perhaps maybe wait a little bit longer to upgrade their kernel. Yes. Right now, that's really the area of Justin Forbes. He has a small kernel test harness that runs a series of small tests to verify that some things are working out. We don't really have a huge continuous integration effort, for example. It's mostly just a matter of making sure it boots up and then watching for karma on Bode, which is a reminder that if you make sure you're testing on Bode, excuse me. Any other questions? OK. Thank you very much.


The History of Moving Images Moving images surround us. Today, watching and creating videos is as easy as clicking a button. But it wasn't always this simple. It's taken almost 200 years to get to here. 1832. Simon Ritter von Stamphner invented the stroboscope. The device, when spun, created the optical illusion of moving images. In 1861, a similar device made it possible to project the images onto a wall. In 1872, the governor of California hired British photographer Edward Mybridge to help him win a bet that during a horse race, all four of the horse's hooves would leave the track. Mybridge lined up 24 cameras that each took a photo as the horses raced past. The governor won the bet. And without realizing, Mybridge had just shot the first second of cinema. In the 1890s, Louis Le Prince and Thomas Edison invented the first patent in cinema cameras. While in France, the Lumiere brothers were also pioneering the use of celluloid to capture moving images. At around the same time, the invention of the movie projector meant that an audience could watch the images. And so, cinema became a reality. A golden age of silent film brought the world to life. Greats like Charlie Chaplin and Buster Keaton introduced generations to the joy of the moving image. Then in the 1920s, it became possible to synchronize image and sound, and the talk he was born. Cinema became the primary form of visual entertainment as audiences throughout the world got to experience the joy of going to the movies. Decades of pioneering filmmaking followed, with Hollywood as the most influential producer. It was the invention of TV that revolutionized the moving image. Ordinary households could watch programs and movies in the comfort of their homes. Later, the invention of video made it possible to record and play back content. For years, these remained the main ways of watching content, but the internet was about to change everything. At first, it was virtually impossible to watch videos online. Quality was poor and connections were slow, but as technology improved, videos on sites like YouTube increased in quality. Now, advanced cameras built into mobile devices means anyone with a phone or tablet computer can instantly create and upload content. It's never been easier to share moving images with the world. And this is where a new story begins.